1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3 2008, 2009 Free Software Foundation, Inc.
4 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
27 #include "opcode/ia64.h"
35 #define LOG_SECTION_ALIGN 3
39 #define LOG_SECTION_ALIGN 2
42 /* THE RULES for all the stuff the linker creates --
44 GOT Entries created in response to LTOFF or LTOFF_FPTR
45 relocations. Dynamic relocs created for dynamic
46 symbols in an application; REL relocs for locals
49 FPTR The canonical function descriptor. Created for local
50 symbols in applications. Descriptors for dynamic symbols
51 and local symbols in shared libraries are created by
52 ld.so. Thus there are no dynamic relocs against these
53 objects. The FPTR relocs for such _are_ passed through
54 to the dynamic relocation tables.
56 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
57 Requires the creation of a PLTOFF entry. This does not
58 require any dynamic relocations.
60 PLTOFF Created by PLTOFF relocations. For local symbols, this
61 is an alternate function descriptor, and in shared libraries
62 requires two REL relocations. Note that this cannot be
63 transformed into an FPTR relocation, since it must be in
64 range of the GP. For dynamic symbols, this is a function
65 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
67 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
68 does not require dynamic relocations. */
70 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
72 typedef struct bfd_hash_entry
*(*new_hash_entry_func
)
73 PARAMS ((struct bfd_hash_entry
*, struct bfd_hash_table
*, const char *));
75 /* In dynamically (linker-) created sections, we generally need to keep track
76 of the place a symbol or expression got allocated to. This is done via hash
77 tables that store entries of the following type. */
79 struct elfNN_ia64_dyn_sym_info
81 /* The addend for which this entry is relevant. */
86 bfd_vma pltoff_offset
;
90 bfd_vma dtpmod_offset
;
91 bfd_vma dtprel_offset
;
93 /* The symbol table entry, if any, that this was derived from. */
94 struct elf_link_hash_entry
*h
;
96 /* Used to count non-got, non-plt relocations for delayed sizing
97 of relocation sections. */
98 struct elfNN_ia64_dyn_reloc_entry
100 struct elfNN_ia64_dyn_reloc_entry
*next
;
105 /* Is this reloc against readonly section? */
109 /* TRUE when the section contents have been updated. */
110 unsigned got_done
: 1;
111 unsigned fptr_done
: 1;
112 unsigned pltoff_done
: 1;
113 unsigned tprel_done
: 1;
114 unsigned dtpmod_done
: 1;
115 unsigned dtprel_done
: 1;
117 /* TRUE for the different kinds of linker data we want created. */
118 unsigned want_got
: 1;
119 unsigned want_gotx
: 1;
120 unsigned want_fptr
: 1;
121 unsigned want_ltoff_fptr
: 1;
122 unsigned want_plt
: 1;
123 unsigned want_plt2
: 1;
124 unsigned want_pltoff
: 1;
125 unsigned want_tprel
: 1;
126 unsigned want_dtpmod
: 1;
127 unsigned want_dtprel
: 1;
130 struct elfNN_ia64_local_hash_entry
134 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
136 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
137 unsigned int sorted_count
;
138 /* The size of elfNN_ia64_dyn_sym_info array. */
140 /* The array of elfNN_ia64_dyn_sym_info. */
141 struct elfNN_ia64_dyn_sym_info
*info
;
143 /* TRUE if this hash entry's addends was translated for
144 SHF_MERGE optimization. */
145 unsigned sec_merge_done
: 1;
148 struct elfNN_ia64_link_hash_entry
150 struct elf_link_hash_entry root
;
151 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
153 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
154 unsigned int sorted_count
;
155 /* The size of elfNN_ia64_dyn_sym_info array. */
157 /* The array of elfNN_ia64_dyn_sym_info. */
158 struct elfNN_ia64_dyn_sym_info
*info
;
161 struct elfNN_ia64_link_hash_table
163 /* The main hash table. */
164 struct elf_link_hash_table root
;
166 asection
*fptr_sec
; /* function descriptor table (or NULL) */
167 asection
*rel_fptr_sec
; /* dynamic relocation section for same */
168 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
169 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
171 bfd_size_type minplt_entries
; /* number of minplt entries */
172 unsigned reltext
: 1; /* are there relocs against readonly sections? */
173 unsigned self_dtpmod_done
: 1;/* has self DTPMOD entry been finished? */
174 bfd_vma self_dtpmod_offset
; /* .got offset to self DTPMOD entry */
175 /* There are maybe R_IA64_GPREL22 relocations, including those
176 optimized from R_IA64_LTOFF22X, against non-SHF_IA_64_SHORT
177 sections. We need to record those sections so that we can choose
178 a proper GP to cover all R_IA64_GPREL22 relocations. */
179 asection
*max_short_sec
; /* maximum short output section */
180 bfd_vma max_short_offset
; /* maximum short offset */
181 asection
*min_short_sec
; /* minimum short output section */
182 bfd_vma min_short_offset
; /* minimum short offset */
184 htab_t loc_hash_table
;
185 void *loc_hash_memory
;
188 struct elfNN_ia64_allocate_data
190 struct bfd_link_info
*info
;
192 bfd_boolean only_got
;
195 #define elfNN_ia64_hash_table(p) \
196 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
198 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
199 (struct elfNN_ia64_link_hash_table
*ia64_info
,
200 struct elf_link_hash_entry
*h
,
201 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
);
202 static bfd_boolean elfNN_ia64_dynamic_symbol_p
203 (struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
, int);
204 static bfd_reloc_status_type elfNN_ia64_install_value
205 (bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
);
206 static bfd_boolean elfNN_ia64_choose_gp
207 (bfd
*abfd
, struct bfd_link_info
*info
);
208 static void elfNN_ia64_relax_ldxmov
209 (bfd_byte
*contents
, bfd_vma off
);
210 static void elfNN_ia64_dyn_sym_traverse
211 (struct elfNN_ia64_link_hash_table
*ia64_info
,
212 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
214 static bfd_boolean allocate_global_data_got
215 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
216 static bfd_boolean allocate_global_fptr_got
217 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
218 static bfd_boolean allocate_local_got
219 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
220 static bfd_boolean elfNN_ia64_hpux_vec
221 (const bfd_target
*vec
);
222 static bfd_boolean allocate_dynrel_entries
223 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
224 static asection
*get_pltoff
225 (bfd
*abfd
, struct bfd_link_info
*info
,
226 struct elfNN_ia64_link_hash_table
*ia64_info
);
228 /* ia64-specific relocation. */
230 /* Perform a relocation. Not much to do here as all the hard work is
231 done in elfNN_ia64_final_link_relocate. */
232 static bfd_reloc_status_type
233 elfNN_ia64_reloc (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*reloc
,
234 asymbol
*sym ATTRIBUTE_UNUSED
,
235 PTR data ATTRIBUTE_UNUSED
, asection
*input_section
,
236 bfd
*output_bfd
, char **error_message
)
240 reloc
->address
+= input_section
->output_offset
;
244 if (input_section
->flags
& SEC_DEBUGGING
)
245 return bfd_reloc_continue
;
247 *error_message
= "Unsupported call to elfNN_ia64_reloc";
248 return bfd_reloc_notsupported
;
251 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
252 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
253 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
255 /* This table has to be sorted according to increasing number of the
257 static reloc_howto_type ia64_howto_table
[] =
259 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, FALSE
, TRUE
),
261 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, FALSE
, TRUE
),
262 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, FALSE
, TRUE
),
263 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, FALSE
, TRUE
),
264 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, FALSE
, TRUE
),
265 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, FALSE
, TRUE
),
266 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, FALSE
, TRUE
),
267 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, FALSE
, TRUE
),
269 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, FALSE
, TRUE
),
270 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, FALSE
, TRUE
),
271 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, FALSE
, TRUE
),
272 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, FALSE
, TRUE
),
273 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, FALSE
, TRUE
),
274 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, FALSE
, TRUE
),
276 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, FALSE
, TRUE
),
277 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, FALSE
, TRUE
),
279 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, FALSE
, TRUE
),
280 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, FALSE
, TRUE
),
281 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, FALSE
, TRUE
),
282 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, FALSE
, TRUE
),
284 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, FALSE
, TRUE
),
285 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, FALSE
, TRUE
),
286 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, FALSE
, TRUE
),
287 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, FALSE
, TRUE
),
288 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, FALSE
, TRUE
),
290 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, TRUE
, TRUE
),
291 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, TRUE
, TRUE
),
292 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, TRUE
, TRUE
),
293 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, TRUE
, TRUE
),
294 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, TRUE
, TRUE
),
295 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, TRUE
, TRUE
),
296 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, TRUE
, TRUE
),
297 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, TRUE
, TRUE
),
299 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, FALSE
, TRUE
),
300 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, FALSE
, TRUE
),
301 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, FALSE
, TRUE
),
302 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, FALSE
, TRUE
),
303 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, FALSE
, TRUE
),
304 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, FALSE
, TRUE
),
306 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, FALSE
, TRUE
),
307 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, FALSE
, TRUE
),
308 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, FALSE
, TRUE
),
309 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, FALSE
, TRUE
),
311 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, FALSE
, TRUE
),
312 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, FALSE
, TRUE
),
313 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, FALSE
, TRUE
),
314 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, FALSE
, TRUE
),
316 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, FALSE
, TRUE
),
317 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, FALSE
, TRUE
),
318 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, FALSE
, TRUE
),
319 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, FALSE
, TRUE
),
321 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, FALSE
, TRUE
),
322 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, FALSE
, TRUE
),
323 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, FALSE
, TRUE
),
324 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, FALSE
, TRUE
),
326 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, TRUE
, TRUE
),
327 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, TRUE
, TRUE
),
328 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, TRUE
, TRUE
),
330 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, FALSE
, TRUE
),
331 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, FALSE
, TRUE
),
332 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, FALSE
, TRUE
),
333 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, FALSE
, TRUE
),
334 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, FALSE
, TRUE
),
336 IA64_HOWTO (R_IA64_TPREL14
, "TPREL14", 0, FALSE
, FALSE
),
337 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, FALSE
, FALSE
),
338 IA64_HOWTO (R_IA64_TPREL64I
, "TPREL64I", 0, FALSE
, FALSE
),
339 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 4, FALSE
, FALSE
),
340 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 4, FALSE
, FALSE
),
341 IA64_HOWTO (R_IA64_LTOFF_TPREL22
, "LTOFF_TPREL22", 0, FALSE
, FALSE
),
343 IA64_HOWTO (R_IA64_DTPMOD64MSB
, "DTPMOD64MSB", 4, FALSE
, FALSE
),
344 IA64_HOWTO (R_IA64_DTPMOD64LSB
, "DTPMOD64LSB", 4, FALSE
, FALSE
),
345 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22
, "LTOFF_DTPMOD22", 0, FALSE
, FALSE
),
347 IA64_HOWTO (R_IA64_DTPREL14
, "DTPREL14", 0, FALSE
, FALSE
),
348 IA64_HOWTO (R_IA64_DTPREL22
, "DTPREL22", 0, FALSE
, FALSE
),
349 IA64_HOWTO (R_IA64_DTPREL64I
, "DTPREL64I", 0, FALSE
, FALSE
),
350 IA64_HOWTO (R_IA64_DTPREL32MSB
, "DTPREL32MSB", 2, FALSE
, FALSE
),
351 IA64_HOWTO (R_IA64_DTPREL32LSB
, "DTPREL32LSB", 2, FALSE
, FALSE
),
352 IA64_HOWTO (R_IA64_DTPREL64MSB
, "DTPREL64MSB", 4, FALSE
, FALSE
),
353 IA64_HOWTO (R_IA64_DTPREL64LSB
, "DTPREL64LSB", 4, FALSE
, FALSE
),
354 IA64_HOWTO (R_IA64_LTOFF_DTPREL22
, "LTOFF_DTPREL22", 0, FALSE
, FALSE
),
357 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
359 /* Given a BFD reloc type, return the matching HOWTO structure. */
361 static reloc_howto_type
*
362 lookup_howto (unsigned int rtype
)
364 static int inited
= 0;
371 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
372 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
373 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
376 if (rtype
> R_IA64_MAX_RELOC_CODE
)
378 i
= elf_code_to_howto_index
[rtype
];
379 if (i
>= NELEMS (ia64_howto_table
))
381 return ia64_howto_table
+ i
;
384 static reloc_howto_type
*
385 elfNN_ia64_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
386 bfd_reloc_code_real_type bfd_code
)
392 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
394 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
395 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
396 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
398 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
399 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
400 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
401 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
403 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
404 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
405 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
406 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
407 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
408 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
410 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
411 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
413 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
414 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
415 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
416 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
417 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
418 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
419 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
420 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
421 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
423 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
424 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
425 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
426 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
427 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
428 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
429 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
430 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
431 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
432 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
433 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
435 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
436 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
437 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
438 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
439 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
440 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
442 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
443 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
444 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
445 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
447 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
448 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
449 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
450 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
452 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
453 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
454 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
455 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
457 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
458 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
459 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
460 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
462 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
463 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
464 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
465 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
466 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
468 case BFD_RELOC_IA64_TPREL14
: rtype
= R_IA64_TPREL14
; break;
469 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
470 case BFD_RELOC_IA64_TPREL64I
: rtype
= R_IA64_TPREL64I
; break;
471 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
472 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
473 case BFD_RELOC_IA64_LTOFF_TPREL22
: rtype
= R_IA64_LTOFF_TPREL22
; break;
475 case BFD_RELOC_IA64_DTPMOD64MSB
: rtype
= R_IA64_DTPMOD64MSB
; break;
476 case BFD_RELOC_IA64_DTPMOD64LSB
: rtype
= R_IA64_DTPMOD64LSB
; break;
477 case BFD_RELOC_IA64_LTOFF_DTPMOD22
: rtype
= R_IA64_LTOFF_DTPMOD22
; break;
479 case BFD_RELOC_IA64_DTPREL14
: rtype
= R_IA64_DTPREL14
; break;
480 case BFD_RELOC_IA64_DTPREL22
: rtype
= R_IA64_DTPREL22
; break;
481 case BFD_RELOC_IA64_DTPREL64I
: rtype
= R_IA64_DTPREL64I
; break;
482 case BFD_RELOC_IA64_DTPREL32MSB
: rtype
= R_IA64_DTPREL32MSB
; break;
483 case BFD_RELOC_IA64_DTPREL32LSB
: rtype
= R_IA64_DTPREL32LSB
; break;
484 case BFD_RELOC_IA64_DTPREL64MSB
: rtype
= R_IA64_DTPREL64MSB
; break;
485 case BFD_RELOC_IA64_DTPREL64LSB
: rtype
= R_IA64_DTPREL64LSB
; break;
486 case BFD_RELOC_IA64_LTOFF_DTPREL22
: rtype
= R_IA64_LTOFF_DTPREL22
; break;
490 return lookup_howto (rtype
);
493 static reloc_howto_type
*
494 elfNN_ia64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
500 i
< sizeof (ia64_howto_table
) / sizeof (ia64_howto_table
[0]);
502 if (ia64_howto_table
[i
].name
!= NULL
503 && strcasecmp (ia64_howto_table
[i
].name
, r_name
) == 0)
504 return &ia64_howto_table
[i
];
509 /* Given a ELF reloc, return the matching HOWTO structure. */
512 elfNN_ia64_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
514 Elf_Internal_Rela
*elf_reloc
)
517 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
520 #define PLT_HEADER_SIZE (3 * 16)
521 #define PLT_MIN_ENTRY_SIZE (1 * 16)
522 #define PLT_FULL_ENTRY_SIZE (2 * 16)
523 #define PLT_RESERVED_WORDS 3
525 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
527 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
528 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
529 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
530 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
531 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
532 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
533 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
534 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
535 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
538 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
540 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
541 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
542 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
545 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
547 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
548 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
549 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
550 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
551 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
552 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
555 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
557 static const bfd_byte oor_brl
[16] =
559 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
561 0x00, 0x00, 0x00, 0xc0
564 static const bfd_byte oor_ip
[48] =
566 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
567 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
568 0x01, 0x00, 0x00, 0x60,
569 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
570 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
571 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
572 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
573 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
574 0x60, 0x00, 0x80, 0x00 /* br b6;; */
577 static size_t oor_branch_size
= sizeof (oor_brl
);
580 bfd_elfNN_ia64_after_parse (int itanium
)
582 oor_branch_size
= itanium
? sizeof (oor_ip
) : sizeof (oor_brl
);
585 #define BTYPE_SHIFT 6
592 #define OPCODE_SHIFT 37
594 #define OPCODE_BITS (0xfLL << OPCODE_SHIFT)
595 #define X6_BITS (0x3fLL << X6_SHIFT)
596 #define X4_BITS (0xfLL << X4_SHIFT)
597 #define X3_BITS (0x7LL << X3_SHIFT)
598 #define X2_BITS (0x3LL << X2_SHIFT)
599 #define X_BITS (0x1LL << X_SHIFT)
600 #define Y_BITS (0x1LL << Y_SHIFT)
601 #define BTYPE_BITS (0x7LL << BTYPE_SHIFT)
602 #define PREDICATE_BITS (0x3fLL)
604 #define IS_NOP_B(i) \
605 (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
606 #define IS_NOP_F(i) \
607 (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
608 == (0x1LL << X6_SHIFT))
609 #define IS_NOP_I(i) \
610 (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
611 == (0x1LL << X6_SHIFT))
612 #define IS_NOP_M(i) \
613 (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
614 == (0x1LL << X4_SHIFT))
615 #define IS_BR_COND(i) \
616 (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
617 #define IS_BR_CALL(i) \
618 (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
621 elfNN_ia64_relax_br (bfd_byte
*contents
, bfd_vma off
)
623 unsigned int template_val
, mlx
;
624 bfd_vma t0
, t1
, s0
, s1
, s2
, br_code
;
628 hit_addr
= (bfd_byte
*) (contents
+ off
);
629 br_slot
= (long) hit_addr
& 0x3;
631 t0
= bfd_getl64 (hit_addr
+ 0);
632 t1
= bfd_getl64 (hit_addr
+ 8);
634 /* Check if we can turn br into brl. A label is always at the start
635 of the bundle. Even if there are predicates on NOPs, we still
636 perform this optimization. */
637 template_val
= t0
& 0x1e;
638 s0
= (t0
>> 5) & 0x1ffffffffffLL
;
639 s1
= ((t0
>> 46) | (t1
<< 18)) & 0x1ffffffffffLL
;
640 s2
= (t1
>> 23) & 0x1ffffffffffLL
;
644 /* Check if slot 1 and slot 2 are NOPs. Possible template is
645 BBB. We only need to check nop.b. */
646 if (!(IS_NOP_B (s1
) && IS_NOP_B (s2
)))
651 /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
652 For BBB, slot 0 also has to be nop.b. */
653 if (!((template_val
== 0x12 /* MBB */
655 || (template_val
== 0x16 /* BBB */
662 /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
663 MMB and MFB. For BBB, slot 0 also has to be nop.b. */
664 if (!((template_val
== 0x10 /* MIB */
666 || (template_val
== 0x12 /* MBB */
668 || (template_val
== 0x16 /* BBB */
671 || (template_val
== 0x18 /* MMB */
673 || (template_val
== 0x1c /* MFB */
679 /* It should never happen. */
683 /* We can turn br.cond/br.call into brl.cond/brl.call. */
684 if (!(IS_BR_COND (br_code
) || IS_BR_CALL (br_code
)))
687 /* Turn br into brl by setting bit 40. */
688 br_code
|= 0x1LL
<< 40;
690 /* Turn the old bundle into a MLX bundle with the same stop-bit
697 if (template_val
== 0x16)
699 /* For BBB, we need to put nop.m in slot 0. We keep the original
700 predicate only if slot 0 isn't br. */
704 t0
&= PREDICATE_BITS
<< 5;
705 t0
|= 0x1LL
<< (X4_SHIFT
+ 5);
709 /* Keep the original instruction in slot 0. */
710 t0
&= 0x1ffffffffffLL
<< 5;
715 /* Put brl in slot 1. */
718 bfd_putl64 (t0
, hit_addr
);
719 bfd_putl64 (t1
, hit_addr
+ 8);
724 elfNN_ia64_relax_brl (bfd_byte
*contents
, bfd_vma off
)
728 bfd_vma t0
, t1
, i0
, i1
, i2
;
730 hit_addr
= (bfd_byte
*) (contents
+ off
);
731 hit_addr
-= (long) hit_addr
& 0x3;
732 t0
= bfd_getl64 (hit_addr
);
733 t1
= bfd_getl64 (hit_addr
+ 8);
735 /* Keep the instruction in slot 0. */
736 i0
= (t0
>> 5) & 0x1ffffffffffLL
;
737 /* Use nop.b for slot 1. */
739 /* For slot 2, turn brl into br by masking out bit 40. */
740 i2
= (t1
>> 23) & 0x0ffffffffffLL
;
742 /* Turn a MLX bundle into a MBB bundle with the same stop-bit
748 t0
= (i1
<< 46) | (i0
<< 5) | template_val
;
749 t1
= (i2
<< 23) | (i1
>> 18);
751 bfd_putl64 (t0
, hit_addr
);
752 bfd_putl64 (t1
, hit_addr
+ 8);
755 /* Rename some of the generic section flags to better document how they
757 #define skip_relax_pass_0 need_finalize_relax
758 #define skip_relax_pass_1 has_gp_reloc
761 /* These functions do relaxation for IA-64 ELF. */
764 elfNN_ia64_update_short_info (asection
*sec
, bfd_vma offset
,
765 struct elfNN_ia64_link_hash_table
*ia64_info
)
767 /* Skip ABS and SHF_IA_64_SHORT sections. */
768 if (sec
== bfd_abs_section_ptr
769 || (sec
->flags
& SEC_SMALL_DATA
) != 0)
772 if (!ia64_info
->min_short_sec
)
774 ia64_info
->max_short_sec
= sec
;
775 ia64_info
->max_short_offset
= offset
;
776 ia64_info
->min_short_sec
= sec
;
777 ia64_info
->min_short_offset
= offset
;
779 else if (sec
== ia64_info
->max_short_sec
780 && offset
> ia64_info
->max_short_offset
)
781 ia64_info
->max_short_offset
= offset
;
782 else if (sec
== ia64_info
->min_short_sec
783 && offset
< ia64_info
->min_short_offset
)
784 ia64_info
->min_short_offset
= offset
;
785 else if (sec
->output_section
->vma
786 > ia64_info
->max_short_sec
->vma
)
788 ia64_info
->max_short_sec
= sec
;
789 ia64_info
->max_short_offset
= offset
;
791 else if (sec
->output_section
->vma
792 < ia64_info
->min_short_sec
->vma
)
794 ia64_info
->min_short_sec
= sec
;
795 ia64_info
->min_short_offset
= offset
;
800 elfNN_ia64_relax_section (bfd
*abfd
, asection
*sec
,
801 struct bfd_link_info
*link_info
,
806 struct one_fixup
*next
;
812 Elf_Internal_Shdr
*symtab_hdr
;
813 Elf_Internal_Rela
*internal_relocs
;
814 Elf_Internal_Rela
*irel
, *irelend
;
816 Elf_Internal_Sym
*isymbuf
= NULL
;
817 struct elfNN_ia64_link_hash_table
*ia64_info
;
818 struct one_fixup
*fixups
= NULL
;
819 bfd_boolean changed_contents
= FALSE
;
820 bfd_boolean changed_relocs
= FALSE
;
821 bfd_boolean changed_got
= FALSE
;
822 bfd_boolean skip_relax_pass_0
= TRUE
;
823 bfd_boolean skip_relax_pass_1
= TRUE
;
826 /* Assume we're not going to change any sizes, and we'll only need
830 if (link_info
->relocatable
)
831 (*link_info
->callbacks
->einfo
)
832 (_("%P%F: --relax and -r may not be used together\n"));
834 /* Don't even try to relax for non-ELF outputs. */
835 if (!is_elf_hash_table (link_info
->hash
))
838 /* Nothing to do if there are no relocations or there is no need for
840 if ((sec
->flags
& SEC_RELOC
) == 0
841 || sec
->reloc_count
== 0
842 || (link_info
->relax_pass
== 0 && sec
->skip_relax_pass_0
)
843 || (link_info
->relax_pass
== 1 && sec
->skip_relax_pass_1
))
846 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
848 /* Load the relocations for this section. */
849 internal_relocs
= (_bfd_elf_link_read_relocs
850 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
851 link_info
->keep_memory
));
852 if (internal_relocs
== NULL
)
855 ia64_info
= elfNN_ia64_hash_table (link_info
);
856 irelend
= internal_relocs
+ sec
->reloc_count
;
858 /* Get the section contents. */
859 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
860 contents
= elf_section_data (sec
)->this_hdr
.contents
;
863 if (!bfd_malloc_and_get_section (abfd
, sec
, &contents
))
867 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
869 unsigned long r_type
= ELFNN_R_TYPE (irel
->r_info
);
870 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
874 bfd_boolean is_branch
;
875 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
880 case R_IA64_PCREL21B
:
881 case R_IA64_PCREL21BI
:
882 case R_IA64_PCREL21M
:
883 case R_IA64_PCREL21F
:
884 /* In pass 1, all br relaxations are done. We can skip it. */
885 if (link_info
->relax_pass
== 1)
887 skip_relax_pass_0
= FALSE
;
891 case R_IA64_PCREL60B
:
892 /* We can't optimize brl to br in pass 0 since br relaxations
893 will increase the code size. Defer it to pass 1. */
894 if (link_info
->relax_pass
== 0)
896 skip_relax_pass_1
= FALSE
;
903 /* Update max_short_sec/min_short_sec. */
905 case R_IA64_LTOFF22X
:
907 /* We can't relax ldx/mov in pass 0 since br relaxations will
908 increase the code size. Defer it to pass 1. */
909 if (link_info
->relax_pass
== 0)
911 skip_relax_pass_1
= FALSE
;
921 /* Get the value of the symbol referred to by the reloc. */
922 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
924 /* A local symbol. */
925 Elf_Internal_Sym
*isym
;
927 /* Read this BFD's local symbols. */
930 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
932 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
933 symtab_hdr
->sh_info
, 0,
939 isym
= isymbuf
+ ELFNN_R_SYM (irel
->r_info
);
940 if (isym
->st_shndx
== SHN_UNDEF
)
941 continue; /* We can't do anything with undefined symbols. */
942 else if (isym
->st_shndx
== SHN_ABS
)
943 tsec
= bfd_abs_section_ptr
;
944 else if (isym
->st_shndx
== SHN_COMMON
)
945 tsec
= bfd_com_section_ptr
;
946 else if (isym
->st_shndx
== SHN_IA_64_ANSI_COMMON
)
947 tsec
= bfd_com_section_ptr
;
949 tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
951 toff
= isym
->st_value
;
952 dyn_i
= get_dyn_sym_info (ia64_info
, NULL
, abfd
, irel
, FALSE
);
953 symtype
= ELF_ST_TYPE (isym
->st_info
);
958 struct elf_link_hash_entry
*h
;
960 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
961 h
= elf_sym_hashes (abfd
)[indx
];
962 BFD_ASSERT (h
!= NULL
);
964 while (h
->root
.type
== bfd_link_hash_indirect
965 || h
->root
.type
== bfd_link_hash_warning
)
966 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
968 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, FALSE
);
970 /* For branches to dynamic symbols, we're interested instead
971 in a branch to the PLT entry. */
972 if (is_branch
&& dyn_i
&& dyn_i
->want_plt2
)
974 /* Internal branches shouldn't be sent to the PLT.
975 Leave this for now and we'll give an error later. */
976 if (r_type
!= R_IA64_PCREL21B
)
979 tsec
= ia64_info
->root
.splt
;
980 toff
= dyn_i
->plt2_offset
;
981 BFD_ASSERT (irel
->r_addend
== 0);
984 /* Can't do anything else with dynamic symbols. */
985 else if (elfNN_ia64_dynamic_symbol_p (h
, link_info
, r_type
))
990 /* We can't do anything with undefined symbols. */
991 if (h
->root
.type
== bfd_link_hash_undefined
992 || h
->root
.type
== bfd_link_hash_undefweak
)
995 tsec
= h
->root
.u
.def
.section
;
996 toff
= h
->root
.u
.def
.value
;
1002 if (tsec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
1004 /* At this stage in linking, no SEC_MERGE symbol has been
1005 adjusted, so all references to such symbols need to be
1006 passed through _bfd_merged_section_offset. (Later, in
1007 relocate_section, all SEC_MERGE symbols *except* for
1008 section symbols have been adjusted.)
1010 gas may reduce relocations against symbols in SEC_MERGE
1011 sections to a relocation against the section symbol when
1012 the original addend was zero. When the reloc is against
1013 a section symbol we should include the addend in the
1014 offset passed to _bfd_merged_section_offset, since the
1015 location of interest is the original symbol. On the
1016 other hand, an access to "sym+addend" where "sym" is not
1017 a section symbol should not include the addend; Such an
1018 access is presumed to be an offset from "sym"; The
1019 location of interest is just "sym". */
1020 if (symtype
== STT_SECTION
)
1021 toff
+= irel
->r_addend
;
1023 toff
= _bfd_merged_section_offset (abfd
, &tsec
,
1024 elf_section_data (tsec
)->sec_info
,
1027 if (symtype
!= STT_SECTION
)
1028 toff
+= irel
->r_addend
;
1031 toff
+= irel
->r_addend
;
1033 symaddr
= tsec
->output_section
->vma
+ tsec
->output_offset
+ toff
;
1035 roff
= irel
->r_offset
;
1039 bfd_signed_vma offset
;
1041 reladdr
= (sec
->output_section
->vma
1042 + sec
->output_offset
1043 + roff
) & (bfd_vma
) -4;
1045 /* The .plt section is aligned at 32byte and the .text section
1046 is aligned at 64byte. The .text section is right after the
1047 .plt section. After the first relaxation pass, linker may
1048 increase the gap between the .plt and .text sections up
1049 to 32byte. We assume linker will always insert 32byte
1050 between the .plt and .text sections after the the first
1052 if (tsec
== ia64_info
->root
.splt
)
1053 offset
= -0x1000000 + 32;
1055 offset
= -0x1000000;
1057 /* If the branch is in range, no need to do anything. */
1058 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= offset
1059 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
1061 /* If the 60-bit branch is in 21-bit range, optimize it. */
1062 if (r_type
== R_IA64_PCREL60B
)
1064 elfNN_ia64_relax_brl (contents
, roff
);
1067 = ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1070 /* If the original relocation offset points to slot
1071 1, change it to slot 2. */
1072 if ((irel
->r_offset
& 3) == 1)
1073 irel
->r_offset
+= 1;
1078 else if (r_type
== R_IA64_PCREL60B
)
1080 else if (elfNN_ia64_relax_br (contents
, roff
))
1083 = ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1086 /* Make the relocation offset point to slot 1. */
1087 irel
->r_offset
= (irel
->r_offset
& ~((bfd_vma
) 0x3)) + 1;
1091 /* We can't put a trampoline in a .init/.fini section. Issue
1093 if (strcmp (sec
->output_section
->name
, ".init") == 0
1094 || strcmp (sec
->output_section
->name
, ".fini") == 0)
1096 (*_bfd_error_handler
)
1097 (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
1098 sec
->owner
, sec
, (unsigned long) roff
);
1099 bfd_set_error (bfd_error_bad_value
);
1103 /* If the branch and target are in the same section, you've
1104 got one honking big section and we can't help you unless
1105 you are branching backwards. You'll get an error message
1107 if (tsec
== sec
&& toff
> roff
)
1110 /* Look for an existing fixup to this address. */
1111 for (f
= fixups
; f
; f
= f
->next
)
1112 if (f
->tsec
== tsec
&& f
->toff
== toff
)
1117 /* Two alternatives: If it's a branch to a PLT entry, we can
1118 make a copy of the FULL_PLT entry. Otherwise, we'll have
1119 to use a `brl' insn to get where we're going. */
1123 if (tsec
== ia64_info
->root
.splt
)
1124 size
= sizeof (plt_full_entry
);
1126 size
= oor_branch_size
;
1128 /* Resize the current section to make room for the new branch. */
1129 trampoff
= (sec
->size
+ 15) & (bfd_vma
) -16;
1131 /* If trampoline is out of range, there is nothing we
1133 offset
= trampoff
- (roff
& (bfd_vma
) -4);
1134 if (offset
< -0x1000000 || offset
> 0x0FFFFF0)
1137 amt
= trampoff
+ size
;
1138 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
1139 if (contents
== NULL
)
1143 if (tsec
== ia64_info
->root
.splt
)
1145 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
1147 /* Hijack the old relocation for use as the PLTOFF reloc. */
1148 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1150 irel
->r_offset
= trampoff
;
1154 if (size
== sizeof (oor_ip
))
1156 memcpy (contents
+ trampoff
, oor_ip
, size
);
1157 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1159 irel
->r_addend
-= 16;
1160 irel
->r_offset
= trampoff
+ 2;
1164 memcpy (contents
+ trampoff
, oor_brl
, size
);
1165 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1167 irel
->r_offset
= trampoff
+ 2;
1172 /* Record the fixup so we don't do it again this section. */
1173 f
= (struct one_fixup
*)
1174 bfd_malloc ((bfd_size_type
) sizeof (*f
));
1178 f
->trampoff
= trampoff
;
1183 /* If trampoline is out of range, there is nothing we
1185 offset
= f
->trampoff
- (roff
& (bfd_vma
) -4);
1186 if (offset
< -0x1000000 || offset
> 0x0FFFFF0)
1189 /* Nop out the reloc, since we're finalizing things here. */
1190 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
1193 /* Fix up the existing branch to hit the trampoline. */
1194 if (elfNN_ia64_install_value (contents
+ roff
, offset
, r_type
)
1198 changed_contents
= TRUE
;
1199 changed_relocs
= TRUE
;
1206 bfd
*obfd
= sec
->output_section
->owner
;
1207 gp
= _bfd_get_gp_value (obfd
);
1210 if (!elfNN_ia64_choose_gp (obfd
, link_info
))
1212 gp
= _bfd_get_gp_value (obfd
);
1216 /* If the data is out of range, do nothing. */
1217 if ((bfd_signed_vma
) (symaddr
- gp
) >= 0x200000
1218 ||(bfd_signed_vma
) (symaddr
- gp
) < -0x200000)
1221 if (r_type
== R_IA64_GPREL22
)
1222 elfNN_ia64_update_short_info (tsec
->output_section
,
1223 tsec
->output_offset
+ toff
,
1225 else if (r_type
== R_IA64_LTOFF22X
)
1227 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1229 changed_relocs
= TRUE
;
1230 if (dyn_i
->want_gotx
)
1232 dyn_i
->want_gotx
= 0;
1233 changed_got
|= !dyn_i
->want_got
;
1236 elfNN_ia64_update_short_info (tsec
->output_section
,
1237 tsec
->output_offset
+ toff
,
1242 elfNN_ia64_relax_ldxmov (contents
, roff
);
1243 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
1244 changed_contents
= TRUE
;
1245 changed_relocs
= TRUE
;
1250 /* ??? If we created fixups, this may push the code segment large
1251 enough that the data segment moves, which will change the GP.
1252 Reset the GP so that we re-calculate next round. We need to
1253 do this at the _beginning_ of the next round; now will not do. */
1255 /* Clean up and go home. */
1258 struct one_fixup
*f
= fixups
;
1259 fixups
= fixups
->next
;
1264 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1266 if (! link_info
->keep_memory
)
1270 /* Cache the symbols for elf_link_input_bfd. */
1271 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1275 if (contents
!= NULL
1276 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1278 if (!changed_contents
&& !link_info
->keep_memory
)
1282 /* Cache the section contents for elf_link_input_bfd. */
1283 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1287 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
1289 if (!changed_relocs
)
1290 free (internal_relocs
);
1292 elf_section_data (sec
)->relocs
= internal_relocs
;
1297 struct elfNN_ia64_allocate_data data
;
1298 data
.info
= link_info
;
1300 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
1302 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
1303 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
1304 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
1305 ia64_info
->root
.sgot
->size
= data
.ofs
;
1307 if (ia64_info
->root
.dynamic_sections_created
1308 && ia64_info
->root
.srelgot
!= NULL
)
1310 /* Resize .rela.got. */
1311 ia64_info
->root
.srelgot
->size
= 0;
1312 if (link_info
->shared
1313 && ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
1314 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1315 data
.only_got
= TRUE
;
1316 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
,
1321 if (link_info
->relax_pass
== 0)
1323 /* Pass 0 is only needed to relax br. */
1324 sec
->skip_relax_pass_0
= skip_relax_pass_0
;
1325 sec
->skip_relax_pass_1
= skip_relax_pass_1
;
1328 *again
= changed_contents
|| changed_relocs
;
1332 if (isymbuf
!= NULL
&& (unsigned char *) isymbuf
!= symtab_hdr
->contents
)
1334 if (contents
!= NULL
1335 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1337 if (internal_relocs
!= NULL
1338 && elf_section_data (sec
)->relocs
!= internal_relocs
)
1339 free (internal_relocs
);
1342 #undef skip_relax_pass_0
1343 #undef skip_relax_pass_1
1346 elfNN_ia64_relax_ldxmov (bfd_byte
*contents
, bfd_vma off
)
1349 bfd_vma dword
, insn
;
1351 switch ((int)off
& 0x3)
1353 case 0: shift
= 5; break;
1354 case 1: shift
= 14; off
+= 3; break;
1355 case 2: shift
= 23; off
+= 6; break;
1360 dword
= bfd_getl64 (contents
+ off
);
1361 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
1363 r1
= (insn
>> 6) & 127;
1364 r3
= (insn
>> 20) & 127;
1366 insn
= 0x8000000; /* nop */
1368 insn
= (insn
& 0x7f01fff) | 0x10800000000LL
; /* (qp) mov r1 = r3 */
1370 dword
&= ~(0x1ffffffffffLL
<< shift
);
1371 dword
|= (insn
<< shift
);
1372 bfd_putl64 (dword
, contents
+ off
);
1375 /* Return TRUE if NAME is an unwind table section name. */
1377 static inline bfd_boolean
1378 is_unwind_section_name (bfd
*abfd
, const char *name
)
1380 if (elfNN_ia64_hpux_vec (abfd
->xvec
)
1381 && !strcmp (name
, ELF_STRING_ia64_unwind_hdr
))
1384 return ((CONST_STRNEQ (name
, ELF_STRING_ia64_unwind
)
1385 && ! CONST_STRNEQ (name
, ELF_STRING_ia64_unwind_info
))
1386 || CONST_STRNEQ (name
, ELF_STRING_ia64_unwind_once
));
1389 /* Handle an IA-64 specific section when reading an object file. This
1390 is called when bfd_section_from_shdr finds a section with an unknown
1394 elfNN_ia64_section_from_shdr (bfd
*abfd
,
1395 Elf_Internal_Shdr
*hdr
,
1401 /* There ought to be a place to keep ELF backend specific flags, but
1402 at the moment there isn't one. We just keep track of the
1403 sections by their name, instead. Fortunately, the ABI gives
1404 suggested names for all the MIPS specific sections, so we will
1405 probably get away with this. */
1406 switch (hdr
->sh_type
)
1408 case SHT_IA_64_UNWIND
:
1409 case SHT_IA_64_HP_OPT_ANOT
:
1413 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1421 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
1423 newsect
= hdr
->bfd_section
;
1428 /* Convert IA-64 specific section flags to bfd internal section flags. */
1430 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1434 elfNN_ia64_section_flags (flagword
*flags
,
1435 const Elf_Internal_Shdr
*hdr
)
1437 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1438 *flags
|= SEC_SMALL_DATA
;
1443 /* Set the correct type for an IA-64 ELF section. We do this by the
1444 section name, which is a hack, but ought to work. */
1447 elfNN_ia64_fake_sections (bfd
*abfd
, Elf_Internal_Shdr
*hdr
,
1450 register const char *name
;
1452 name
= bfd_get_section_name (abfd
, sec
);
1454 if (is_unwind_section_name (abfd
, name
))
1456 /* We don't have the sections numbered at this point, so sh_info
1457 is set later, in elfNN_ia64_final_write_processing. */
1458 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1459 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1461 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1462 hdr
->sh_type
= SHT_IA_64_EXT
;
1463 else if (strcmp (name
, ".HP.opt_annot") == 0)
1464 hdr
->sh_type
= SHT_IA_64_HP_OPT_ANOT
;
1465 else if (strcmp (name
, ".reloc") == 0)
1466 /* This is an ugly, but unfortunately necessary hack that is
1467 needed when producing EFI binaries on IA-64. It tells
1468 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1469 containing ELF relocation info. We need this hack in order to
1470 be able to generate ELF binaries that can be translated into
1471 EFI applications (which are essentially COFF objects). Those
1472 files contain a COFF ".reloc" section inside an ELFNN object,
1473 which would normally cause BFD to segfault because it would
1474 attempt to interpret this section as containing relocation
1475 entries for section "oc". With this hack enabled, ".reloc"
1476 will be treated as a normal data section, which will avoid the
1477 segfault. However, you won't be able to create an ELFNN binary
1478 with a section named "oc" that needs relocations, but that's
1479 the kind of ugly side-effects you get when detecting section
1480 types based on their names... In practice, this limitation is
1481 unlikely to bite. */
1482 hdr
->sh_type
= SHT_PROGBITS
;
1484 if (sec
->flags
& SEC_SMALL_DATA
)
1485 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1487 /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
1489 if (elfNN_ia64_hpux_vec (abfd
->xvec
) && (sec
->flags
& SHF_TLS
))
1490 hdr
->sh_flags
|= SHF_IA_64_HP_TLS
;
1495 /* The final processing done just before writing out an IA-64 ELF
1499 elfNN_ia64_final_write_processing (bfd
*abfd
,
1500 bfd_boolean linker ATTRIBUTE_UNUSED
)
1502 Elf_Internal_Shdr
*hdr
;
1505 for (s
= abfd
->sections
; s
; s
= s
->next
)
1507 hdr
= &elf_section_data (s
)->this_hdr
;
1508 switch (hdr
->sh_type
)
1510 case SHT_IA_64_UNWIND
:
1511 /* The IA-64 processor-specific ABI requires setting sh_link
1512 to the unwind section, whereas HP-UX requires sh_info to
1513 do so. For maximum compatibility, we'll set both for
1515 hdr
->sh_info
= hdr
->sh_link
;
1520 if (! elf_flags_init (abfd
))
1522 unsigned long flags
= 0;
1524 if (abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
)
1525 flags
|= EF_IA_64_BE
;
1526 if (bfd_get_mach (abfd
) == bfd_mach_ia64_elf64
)
1527 flags
|= EF_IA_64_ABI64
;
1529 elf_elfheader(abfd
)->e_flags
= flags
;
1530 elf_flags_init (abfd
) = TRUE
;
1534 /* Hook called by the linker routine which adds symbols from an object
1535 file. We use it to put .comm items in .sbss, and not .bss. */
1538 elfNN_ia64_add_symbol_hook (bfd
*abfd
,
1539 struct bfd_link_info
*info
,
1540 Elf_Internal_Sym
*sym
,
1541 const char **namep ATTRIBUTE_UNUSED
,
1542 flagword
*flagsp ATTRIBUTE_UNUSED
,
1546 if (sym
->st_shndx
== SHN_COMMON
1547 && !info
->relocatable
1548 && sym
->st_size
<= elf_gp_size (abfd
))
1550 /* Common symbols less than or equal to -G nn bytes are
1551 automatically put into .sbss. */
1553 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1557 scomm
= bfd_make_section_with_flags (abfd
, ".scommon",
1560 | SEC_LINKER_CREATED
));
1566 *valp
= sym
->st_size
;
1572 /* Return the number of additional phdrs we will need. */
1575 elfNN_ia64_additional_program_headers (bfd
*abfd
,
1576 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1581 /* See if we need a PT_IA_64_ARCHEXT segment. */
1582 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1583 if (s
&& (s
->flags
& SEC_LOAD
))
1586 /* Count how many PT_IA_64_UNWIND segments we need. */
1587 for (s
= abfd
->sections
; s
; s
= s
->next
)
1588 if (is_unwind_section_name (abfd
, s
->name
) && (s
->flags
& SEC_LOAD
))
1595 elfNN_ia64_modify_segment_map (bfd
*abfd
,
1596 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1598 struct elf_segment_map
*m
, **pm
;
1599 Elf_Internal_Shdr
*hdr
;
1602 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1603 all PT_LOAD segments. */
1604 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1605 if (s
&& (s
->flags
& SEC_LOAD
))
1607 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1608 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1612 m
= ((struct elf_segment_map
*)
1613 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1617 m
->p_type
= PT_IA_64_ARCHEXT
;
1621 /* We want to put it after the PHDR and INTERP segments. */
1622 pm
= &elf_tdata (abfd
)->segment_map
;
1624 && ((*pm
)->p_type
== PT_PHDR
1625 || (*pm
)->p_type
== PT_INTERP
))
1633 /* Install PT_IA_64_UNWIND segments, if needed. */
1634 for (s
= abfd
->sections
; s
; s
= s
->next
)
1636 hdr
= &elf_section_data (s
)->this_hdr
;
1637 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1640 if (s
&& (s
->flags
& SEC_LOAD
))
1642 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1643 if (m
->p_type
== PT_IA_64_UNWIND
)
1647 /* Look through all sections in the unwind segment
1648 for a match since there may be multiple sections
1650 for (i
= m
->count
- 1; i
>= 0; --i
)
1651 if (m
->sections
[i
] == s
)
1660 m
= ((struct elf_segment_map
*)
1661 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1665 m
->p_type
= PT_IA_64_UNWIND
;
1670 /* We want to put it last. */
1671 pm
= &elf_tdata (abfd
)->segment_map
;
1682 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1683 the input sections for each output section in the segment and testing
1684 for SHF_IA_64_NORECOV on each. */
1687 elfNN_ia64_modify_program_headers (bfd
*abfd
,
1688 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1690 struct elf_obj_tdata
*tdata
= elf_tdata (abfd
);
1691 struct elf_segment_map
*m
;
1692 Elf_Internal_Phdr
*p
;
1694 for (p
= tdata
->phdr
, m
= tdata
->segment_map
; m
!= NULL
; m
= m
->next
, p
++)
1695 if (m
->p_type
== PT_LOAD
)
1698 for (i
= m
->count
- 1; i
>= 0; --i
)
1700 struct bfd_link_order
*order
= m
->sections
[i
]->map_head
.link_order
;
1702 while (order
!= NULL
)
1704 if (order
->type
== bfd_indirect_link_order
)
1706 asection
*is
= order
->u
.indirect
.section
;
1707 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1708 if (flags
& SHF_IA_64_NORECOV
)
1710 p
->p_flags
|= PF_IA_64_NORECOV
;
1714 order
= order
->next
;
1723 /* According to the Tahoe assembler spec, all labels starting with a
1727 elfNN_ia64_is_local_label_name (bfd
*abfd ATTRIBUTE_UNUSED
,
1730 return name
[0] == '.';
1733 /* Should we do dynamic things to this symbol? */
1736 elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry
*h
,
1737 struct bfd_link_info
*info
, int r_type
)
1739 bfd_boolean ignore_protected
1740 = ((r_type
& 0xf8) == 0x40 /* FPTR relocs */
1741 || (r_type
& 0xf8) == 0x50); /* LTOFF_FPTR relocs */
1743 return _bfd_elf_dynamic_symbol_p (h
, info
, ignore_protected
);
1746 static struct bfd_hash_entry
*
1747 elfNN_ia64_new_elf_hash_entry (struct bfd_hash_entry
*entry
,
1748 struct bfd_hash_table
*table
,
1751 struct elfNN_ia64_link_hash_entry
*ret
;
1752 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1754 /* Allocate the structure if it has not already been allocated by a
1757 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1762 /* Call the allocation method of the superclass. */
1763 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1764 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1769 ret
->sorted_count
= 0;
1771 return (struct bfd_hash_entry
*) ret
;
1775 elfNN_ia64_hash_copy_indirect (struct bfd_link_info
*info
,
1776 struct elf_link_hash_entry
*xdir
,
1777 struct elf_link_hash_entry
*xind
)
1779 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1781 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1782 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1784 /* Copy down any references that we may have already seen to the
1785 symbol which just became indirect. */
1787 dir
->root
.ref_dynamic
|= ind
->root
.ref_dynamic
;
1788 dir
->root
.ref_regular
|= ind
->root
.ref_regular
;
1789 dir
->root
.ref_regular_nonweak
|= ind
->root
.ref_regular_nonweak
;
1790 dir
->root
.needs_plt
|= ind
->root
.needs_plt
;
1792 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1795 /* Copy over the got and plt data. This would have been done
1798 if (ind
->info
!= NULL
)
1800 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1806 dir
->info
= ind
->info
;
1807 dir
->count
= ind
->count
;
1808 dir
->sorted_count
= ind
->sorted_count
;
1809 dir
->size
= ind
->size
;
1813 ind
->sorted_count
= 0;
1816 /* Fix up the dyn_sym_info pointers to the global symbol. */
1817 for (count
= dir
->count
, dyn_i
= dir
->info
;
1820 dyn_i
->h
= &dir
->root
;
1823 /* Copy over the dynindx. */
1825 if (ind
->root
.dynindx
!= -1)
1827 if (dir
->root
.dynindx
!= -1)
1828 _bfd_elf_strtab_delref (elf_hash_table (info
)->dynstr
,
1829 dir
->root
.dynstr_index
);
1830 dir
->root
.dynindx
= ind
->root
.dynindx
;
1831 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1832 ind
->root
.dynindx
= -1;
1833 ind
->root
.dynstr_index
= 0;
1838 elfNN_ia64_hash_hide_symbol (struct bfd_link_info
*info
,
1839 struct elf_link_hash_entry
*xh
,
1840 bfd_boolean force_local
)
1842 struct elfNN_ia64_link_hash_entry
*h
;
1843 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1846 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1848 _bfd_elf_link_hash_hide_symbol (info
, &h
->root
, force_local
);
1850 for (count
= h
->count
, dyn_i
= h
->info
;
1854 dyn_i
->want_plt2
= 0;
1855 dyn_i
->want_plt
= 0;
1859 /* Compute a hash of a local hash entry. */
1862 elfNN_ia64_local_htab_hash (const void *ptr
)
1864 struct elfNN_ia64_local_hash_entry
*entry
1865 = (struct elfNN_ia64_local_hash_entry
*) ptr
;
1867 return ELF_LOCAL_SYMBOL_HASH (entry
->id
, entry
->r_sym
);
1870 /* Compare local hash entries. */
1873 elfNN_ia64_local_htab_eq (const void *ptr1
, const void *ptr2
)
1875 struct elfNN_ia64_local_hash_entry
*entry1
1876 = (struct elfNN_ia64_local_hash_entry
*) ptr1
;
1877 struct elfNN_ia64_local_hash_entry
*entry2
1878 = (struct elfNN_ia64_local_hash_entry
*) ptr2
;
1880 return entry1
->id
== entry2
->id
&& entry1
->r_sym
== entry2
->r_sym
;
1883 /* Create the derived linker hash table. The IA-64 ELF port uses this
1884 derived hash table to keep information specific to the IA-64 ElF
1885 linker (without using static variables). */
1887 static struct bfd_link_hash_table
*
1888 elfNN_ia64_hash_table_create (bfd
*abfd
)
1890 struct elfNN_ia64_link_hash_table
*ret
;
1892 ret
= bfd_zmalloc ((bfd_size_type
) sizeof (*ret
));
1896 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1897 elfNN_ia64_new_elf_hash_entry
,
1898 sizeof (struct elfNN_ia64_link_hash_entry
)))
1904 ret
->loc_hash_table
= htab_try_create (1024, elfNN_ia64_local_htab_hash
,
1905 elfNN_ia64_local_htab_eq
, NULL
);
1906 ret
->loc_hash_memory
= objalloc_create ();
1907 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
1913 return &ret
->root
.root
;
1916 /* Free the global elfNN_ia64_dyn_sym_info array. */
1919 elfNN_ia64_global_dyn_info_free (void **xentry
,
1920 PTR unused ATTRIBUTE_UNUSED
)
1922 struct elfNN_ia64_link_hash_entry
*entry
1923 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1925 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
1926 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
1933 entry
->sorted_count
= 0;
1940 /* Free the local elfNN_ia64_dyn_sym_info array. */
1943 elfNN_ia64_local_dyn_info_free (void **slot
,
1944 PTR unused ATTRIBUTE_UNUSED
)
1946 struct elfNN_ia64_local_hash_entry
*entry
1947 = (struct elfNN_ia64_local_hash_entry
*) *slot
;
1954 entry
->sorted_count
= 0;
1961 /* Destroy IA-64 linker hash table. */
1964 elfNN_ia64_hash_table_free (struct bfd_link_hash_table
*hash
)
1966 struct elfNN_ia64_link_hash_table
*ia64_info
1967 = (struct elfNN_ia64_link_hash_table
*) hash
;
1968 if (ia64_info
->loc_hash_table
)
1970 htab_traverse (ia64_info
->loc_hash_table
,
1971 elfNN_ia64_local_dyn_info_free
, NULL
);
1972 htab_delete (ia64_info
->loc_hash_table
);
1974 if (ia64_info
->loc_hash_memory
)
1975 objalloc_free ((struct objalloc
*) ia64_info
->loc_hash_memory
);
1976 elf_link_hash_traverse (&ia64_info
->root
,
1977 elfNN_ia64_global_dyn_info_free
, NULL
);
1978 _bfd_generic_link_hash_table_free (hash
);
1981 /* Traverse both local and global hash tables. */
1983 struct elfNN_ia64_dyn_sym_traverse_data
1985 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
);
1990 elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry
*xentry
,
1993 struct elfNN_ia64_link_hash_entry
*entry
1994 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1995 struct elfNN_ia64_dyn_sym_traverse_data
*data
1996 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1997 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2000 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
2001 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
2003 for (count
= entry
->count
, dyn_i
= entry
->info
;
2006 if (! (*data
->func
) (dyn_i
, data
->data
))
2012 elfNN_ia64_local_dyn_sym_thunk (void **slot
, PTR xdata
)
2014 struct elfNN_ia64_local_hash_entry
*entry
2015 = (struct elfNN_ia64_local_hash_entry
*) *slot
;
2016 struct elfNN_ia64_dyn_sym_traverse_data
*data
2017 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
2018 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2021 for (count
= entry
->count
, dyn_i
= entry
->info
;
2024 if (! (*data
->func
) (dyn_i
, data
->data
))
2030 elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table
*ia64_info
,
2031 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
2034 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
2039 elf_link_hash_traverse (&ia64_info
->root
,
2040 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
2041 htab_traverse (ia64_info
->loc_hash_table
,
2042 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
2046 elfNN_ia64_create_dynamic_sections (bfd
*abfd
,
2047 struct bfd_link_info
*info
)
2049 struct elfNN_ia64_link_hash_table
*ia64_info
;
2052 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
2055 ia64_info
= elfNN_ia64_hash_table (info
);
2058 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->root
.sgot
);
2059 bfd_set_section_flags (abfd
, ia64_info
->root
.sgot
,
2060 SEC_SMALL_DATA
| flags
);
2061 /* The .got section is always aligned at 8 bytes. */
2062 bfd_set_section_alignment (abfd
, ia64_info
->root
.sgot
, 3);
2065 if (!get_pltoff (abfd
, info
, ia64_info
))
2068 s
= bfd_make_section_with_flags (abfd
, ".rela.IA_64.pltoff",
2069 (SEC_ALLOC
| SEC_LOAD
2072 | SEC_LINKER_CREATED
2075 || !bfd_set_section_alignment (abfd
, s
, LOG_SECTION_ALIGN
))
2077 ia64_info
->rel_pltoff_sec
= s
;
2082 /* Find and/or create a hash entry for local symbol. */
2083 static struct elfNN_ia64_local_hash_entry
*
2084 get_local_sym_hash (struct elfNN_ia64_link_hash_table
*ia64_info
,
2085 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
2088 struct elfNN_ia64_local_hash_entry e
, *ret
;
2089 asection
*sec
= abfd
->sections
;
2090 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
,
2091 ELFNN_R_SYM (rel
->r_info
));
2095 e
.r_sym
= ELFNN_R_SYM (rel
->r_info
);
2096 slot
= htab_find_slot_with_hash (ia64_info
->loc_hash_table
, &e
, h
,
2097 create
? INSERT
: NO_INSERT
);
2103 return (struct elfNN_ia64_local_hash_entry
*) *slot
;
2105 ret
= (struct elfNN_ia64_local_hash_entry
*)
2106 objalloc_alloc ((struct objalloc
*) ia64_info
->loc_hash_memory
,
2107 sizeof (struct elfNN_ia64_local_hash_entry
));
2110 memset (ret
, 0, sizeof (*ret
));
2112 ret
->r_sym
= ELFNN_R_SYM (rel
->r_info
);
2118 /* Used to sort elfNN_ia64_dyn_sym_info array. */
2121 addend_compare (const void *xp
, const void *yp
)
2123 const struct elfNN_ia64_dyn_sym_info
*x
2124 = (const struct elfNN_ia64_dyn_sym_info
*) xp
;
2125 const struct elfNN_ia64_dyn_sym_info
*y
2126 = (const struct elfNN_ia64_dyn_sym_info
*) yp
;
2128 return x
->addend
< y
->addend
? -1 : x
->addend
> y
->addend
? 1 : 0;
2131 /* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
2134 sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info
*info
,
2137 bfd_vma curr
, prev
, got_offset
;
2138 unsigned int i
, kept
, dup
, diff
, dest
, src
, len
;
2140 qsort (info
, count
, sizeof (*info
), addend_compare
);
2142 /* Find the first duplicate. */
2143 prev
= info
[0].addend
;
2144 got_offset
= info
[0].got_offset
;
2145 for (i
= 1; i
< count
; i
++)
2147 curr
= info
[i
].addend
;
2150 /* For duplicates, make sure that GOT_OFFSET is valid. */
2151 if (got_offset
== (bfd_vma
) -1)
2152 got_offset
= info
[i
].got_offset
;
2155 got_offset
= info
[i
].got_offset
;
2159 /* We may move a block of elements to here. */
2162 /* Remove duplicates. */
2167 /* For duplicates, make sure that the kept one has a valid
2170 if (got_offset
!= (bfd_vma
) -1)
2171 info
[kept
].got_offset
= got_offset
;
2173 curr
= info
[i
].addend
;
2174 got_offset
= info
[i
].got_offset
;
2176 /* Move a block of elements whose first one is different from
2180 for (src
= i
+ 1; src
< count
; src
++)
2182 if (info
[src
].addend
!= curr
)
2184 /* For duplicates, make sure that GOT_OFFSET is
2186 if (got_offset
== (bfd_vma
) -1)
2187 got_offset
= info
[src
].got_offset
;
2190 /* Make sure that the kept one has a valid got_offset. */
2191 if (got_offset
!= (bfd_vma
) -1)
2192 info
[kept
].got_offset
= got_offset
;
2200 /* Find the next duplicate. SRC will be kept. */
2201 prev
= info
[src
].addend
;
2202 got_offset
= info
[src
].got_offset
;
2203 for (dup
= src
+ 1; dup
< count
; dup
++)
2205 curr
= info
[dup
].addend
;
2208 /* Make sure that got_offset is valid. */
2209 if (got_offset
== (bfd_vma
) -1)
2210 got_offset
= info
[dup
].got_offset
;
2212 /* For duplicates, make sure that the kept one has
2213 a valid got_offset. */
2214 if (got_offset
!= (bfd_vma
) -1)
2215 info
[dup
- 1].got_offset
= got_offset
;
2218 got_offset
= info
[dup
].got_offset
;
2222 /* How much to move. */
2226 if (len
== 1 && dup
< count
)
2228 /* If we only move 1 element, we combine it with the next
2229 one. There must be at least a duplicate. Find the
2230 next different one. */
2231 for (diff
= dup
+ 1, src
++; diff
< count
; diff
++, src
++)
2233 if (info
[diff
].addend
!= curr
)
2235 /* Make sure that got_offset is valid. */
2236 if (got_offset
== (bfd_vma
) -1)
2237 got_offset
= info
[diff
].got_offset
;
2240 /* Makre sure that the last duplicated one has an valid
2242 BFD_ASSERT (curr
== prev
);
2243 if (got_offset
!= (bfd_vma
) -1)
2244 info
[diff
- 1].got_offset
= got_offset
;
2248 /* Find the next duplicate. Track the current valid
2250 prev
= info
[diff
].addend
;
2251 got_offset
= info
[diff
].got_offset
;
2252 for (dup
= diff
+ 1; dup
< count
; dup
++)
2254 curr
= info
[dup
].addend
;
2257 /* For duplicates, make sure that GOT_OFFSET
2259 if (got_offset
== (bfd_vma
) -1)
2260 got_offset
= info
[dup
].got_offset
;
2263 got_offset
= info
[dup
].got_offset
;
2268 len
= diff
- src
+ 1;
2273 memmove (&info
[dest
], &info
[src
], len
* sizeof (*info
));
2282 /* When we get here, either there is no duplicate at all or
2283 the only duplicate is the last element. */
2286 /* If the last element is a duplicate, make sure that the
2287 kept one has a valid got_offset. We also update count. */
2288 if (got_offset
!= (bfd_vma
) -1)
2289 info
[dest
- 1].got_offset
= got_offset
;
2297 /* Find and/or create a descriptor for dynamic symbol info. This will
2298 vary based on global or local symbol, and the addend to the reloc.
2300 We don't sort when inserting. Also, we sort and eliminate
2301 duplicates if there is an unsorted section. Typically, this will
2302 only happen once, because we do all insertions before lookups. We
2303 then use bsearch to do a lookup. This also allows lookups to be
2304 fast. So we have fast insertion (O(log N) due to duplicate check),
2305 fast lookup (O(log N)) and one sort (O(N log N) expected time).
2306 Previously, all lookups were O(N) because of the use of the linked
2307 list and also all insertions were O(N) because of the check for
2308 duplicates. There are some complications here because the array
2309 size grows occasionally, which may add an O(N) factor, but this
2310 should be rare. Also, we free the excess array allocation, which
2311 requires a copy which is O(N), but this only happens once. */
2313 static struct elfNN_ia64_dyn_sym_info
*
2314 get_dyn_sym_info (struct elfNN_ia64_link_hash_table
*ia64_info
,
2315 struct elf_link_hash_entry
*h
, bfd
*abfd
,
2316 const Elf_Internal_Rela
*rel
, bfd_boolean create
)
2318 struct elfNN_ia64_dyn_sym_info
**info_p
, *info
, *dyn_i
, key
;
2319 unsigned int *count_p
, *sorted_count_p
, *size_p
;
2320 unsigned int count
, sorted_count
, size
;
2321 bfd_vma addend
= rel
? rel
->r_addend
: 0;
2326 struct elfNN_ia64_link_hash_entry
*global_h
;
2328 global_h
= (struct elfNN_ia64_link_hash_entry
*) h
;
2329 info_p
= &global_h
->info
;
2330 count_p
= &global_h
->count
;
2331 sorted_count_p
= &global_h
->sorted_count
;
2332 size_p
= &global_h
->size
;
2336 struct elfNN_ia64_local_hash_entry
*loc_h
;
2338 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
2341 BFD_ASSERT (!create
);
2345 info_p
= &loc_h
->info
;
2346 count_p
= &loc_h
->count
;
2347 sorted_count_p
= &loc_h
->sorted_count
;
2348 size_p
= &loc_h
->size
;
2352 sorted_count
= *sorted_count_p
;
2357 /* When we create the array, we don't check for duplicates,
2358 except in the previously sorted section if one exists, and
2359 against the last inserted entry. This allows insertions to
2365 /* Try bsearch first on the sorted section. */
2366 key
.addend
= addend
;
2367 dyn_i
= bsearch (&key
, info
, sorted_count
,
2368 sizeof (*info
), addend_compare
);
2376 /* Do a quick check for the last inserted entry. */
2377 dyn_i
= info
+ count
- 1;
2378 if (dyn_i
->addend
== addend
)
2386 /* It is the very first element. We create the array of size
2389 amt
= size
* sizeof (*info
);
2390 info
= bfd_malloc (amt
);
2392 else if (size
<= count
)
2394 /* We double the array size every time when we reach the
2397 amt
= size
* sizeof (*info
);
2398 info
= bfd_realloc (info
, amt
);
2409 /* Append the new one to the array. */
2410 dyn_i
= info
+ count
;
2411 memset (dyn_i
, 0, sizeof (*dyn_i
));
2412 dyn_i
->got_offset
= (bfd_vma
) -1;
2413 dyn_i
->addend
= addend
;
2415 /* We increment count only since the new ones are unsorted and
2416 may have duplicate. */
2421 /* It is a lookup without insertion. Sort array if part of the
2422 array isn't sorted. */
2423 if (count
!= sorted_count
)
2425 count
= sort_dyn_sym_info (info
, count
);
2427 *sorted_count_p
= count
;
2430 /* Free unused memory. */
2433 amt
= count
* sizeof (*info
);
2434 info
= bfd_malloc (amt
);
2437 memcpy (info
, *info_p
, amt
);
2444 key
.addend
= addend
;
2445 dyn_i
= bsearch (&key
, info
, count
,
2446 sizeof (*info
), addend_compare
);
2453 get_got (bfd
*abfd
, struct bfd_link_info
*info
,
2454 struct elfNN_ia64_link_hash_table
*ia64_info
)
2459 got
= ia64_info
->root
.sgot
;
2464 dynobj
= ia64_info
->root
.dynobj
;
2466 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2467 if (!_bfd_elf_create_got_section (dynobj
, info
))
2470 got
= ia64_info
->root
.sgot
;
2472 /* The .got section is always aligned at 8 bytes. */
2473 if (!bfd_set_section_alignment (abfd
, got
, 3))
2476 flags
= bfd_get_section_flags (abfd
, got
);
2477 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
2483 /* Create function descriptor section (.opd). This section is called .opd
2484 because it contains "official procedure descriptors". The "official"
2485 refers to the fact that these descriptors are used when taking the address
2486 of a procedure, thus ensuring a unique address for each procedure. */
2489 get_fptr (bfd
*abfd
, struct bfd_link_info
*info
,
2490 struct elfNN_ia64_link_hash_table
*ia64_info
)
2495 fptr
= ia64_info
->fptr_sec
;
2498 dynobj
= ia64_info
->root
.dynobj
;
2500 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2502 fptr
= bfd_make_section_with_flags (dynobj
, ".opd",
2507 | (info
->pie
? 0 : SEC_READONLY
)
2508 | SEC_LINKER_CREATED
));
2510 || !bfd_set_section_alignment (abfd
, fptr
, 4))
2516 ia64_info
->fptr_sec
= fptr
;
2521 fptr_rel
= bfd_make_section_with_flags (dynobj
, ".rela.opd",
2522 (SEC_ALLOC
| SEC_LOAD
2525 | SEC_LINKER_CREATED
2527 if (fptr_rel
== NULL
2528 || !bfd_set_section_alignment (abfd
, fptr_rel
,
2535 ia64_info
->rel_fptr_sec
= fptr_rel
;
2543 get_pltoff (bfd
*abfd
, struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
2544 struct elfNN_ia64_link_hash_table
*ia64_info
)
2549 pltoff
= ia64_info
->pltoff_sec
;
2552 dynobj
= ia64_info
->root
.dynobj
;
2554 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2556 pltoff
= bfd_make_section_with_flags (dynobj
,
2557 ELF_STRING_ia64_pltoff
,
2563 | SEC_LINKER_CREATED
));
2565 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
2571 ia64_info
->pltoff_sec
= pltoff
;
2578 get_reloc_section (bfd
*abfd
,
2579 struct elfNN_ia64_link_hash_table
*ia64_info
,
2580 asection
*sec
, bfd_boolean create
)
2582 const char *srel_name
;
2586 srel_name
= (bfd_elf_string_from_elf_section
2587 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
2588 elf_section_data(sec
)->rel_hdr
.sh_name
));
2589 if (srel_name
== NULL
)
2592 BFD_ASSERT ((CONST_STRNEQ (srel_name
, ".rela")
2593 && strcmp (bfd_get_section_name (abfd
, sec
),
2595 || (CONST_STRNEQ (srel_name
, ".rel")
2596 && strcmp (bfd_get_section_name (abfd
, sec
),
2597 srel_name
+4) == 0));
2599 dynobj
= ia64_info
->root
.dynobj
;
2601 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2603 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
2604 if (srel
== NULL
&& create
)
2606 srel
= bfd_make_section_with_flags (dynobj
, srel_name
,
2607 (SEC_ALLOC
| SEC_LOAD
2610 | SEC_LINKER_CREATED
2613 || !bfd_set_section_alignment (dynobj
, srel
,
2622 count_dyn_reloc (bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
2623 asection
*srel
, int type
, bfd_boolean reltext
)
2625 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2627 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2628 if (rent
->srel
== srel
&& rent
->type
== type
)
2633 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
2634 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
2638 rent
->next
= dyn_i
->reloc_entries
;
2642 dyn_i
->reloc_entries
= rent
;
2644 rent
->reltext
= reltext
;
2651 elfNN_ia64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
2653 const Elf_Internal_Rela
*relocs
)
2655 struct elfNN_ia64_link_hash_table
*ia64_info
;
2656 const Elf_Internal_Rela
*relend
;
2657 Elf_Internal_Shdr
*symtab_hdr
;
2658 const Elf_Internal_Rela
*rel
;
2659 asection
*got
, *fptr
, *srel
, *pltoff
;
2668 NEED_LTOFF_FPTR
= 128,
2674 struct elf_link_hash_entry
*h
;
2675 unsigned long r_symndx
;
2676 bfd_boolean maybe_dynamic
;
2678 if (info
->relocatable
)
2681 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2682 ia64_info
= elfNN_ia64_hash_table (info
);
2684 got
= fptr
= srel
= pltoff
= NULL
;
2686 relend
= relocs
+ sec
->reloc_count
;
2688 /* We scan relocations first to create dynamic relocation arrays. We
2689 modified get_dyn_sym_info to allow fast insertion and support fast
2690 lookup in the next loop. */
2691 for (rel
= relocs
; rel
< relend
; ++rel
)
2693 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2694 if (r_symndx
>= symtab_hdr
->sh_info
)
2696 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2697 h
= elf_sym_hashes (abfd
)[indx
];
2698 while (h
->root
.type
== bfd_link_hash_indirect
2699 || h
->root
.type
== bfd_link_hash_warning
)
2700 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2705 /* We can only get preliminary data on whether a symbol is
2706 locally or externally defined, as not all of the input files
2707 have yet been processed. Do something with what we know, as
2708 this may help reduce memory usage and processing time later. */
2709 maybe_dynamic
= (h
&& ((!info
->executable
2710 && (!SYMBOLIC_BIND (info
, h
)
2711 || info
->unresolved_syms_in_shared_libs
== RM_IGNORE
))
2713 || h
->root
.type
== bfd_link_hash_defweak
));
2716 switch (ELFNN_R_TYPE (rel
->r_info
))
2718 case R_IA64_TPREL64MSB
:
2719 case R_IA64_TPREL64LSB
:
2720 if (info
->shared
|| maybe_dynamic
)
2721 need_entry
= NEED_DYNREL
;
2724 case R_IA64_LTOFF_TPREL22
:
2725 need_entry
= NEED_TPREL
;
2727 info
->flags
|= DF_STATIC_TLS
;
2730 case R_IA64_DTPREL32MSB
:
2731 case R_IA64_DTPREL32LSB
:
2732 case R_IA64_DTPREL64MSB
:
2733 case R_IA64_DTPREL64LSB
:
2734 if (info
->shared
|| maybe_dynamic
)
2735 need_entry
= NEED_DYNREL
;
2738 case R_IA64_LTOFF_DTPREL22
:
2739 need_entry
= NEED_DTPREL
;
2742 case R_IA64_DTPMOD64MSB
:
2743 case R_IA64_DTPMOD64LSB
:
2744 if (info
->shared
|| maybe_dynamic
)
2745 need_entry
= NEED_DYNREL
;
2748 case R_IA64_LTOFF_DTPMOD22
:
2749 need_entry
= NEED_DTPMOD
;
2752 case R_IA64_LTOFF_FPTR22
:
2753 case R_IA64_LTOFF_FPTR64I
:
2754 case R_IA64_LTOFF_FPTR32MSB
:
2755 case R_IA64_LTOFF_FPTR32LSB
:
2756 case R_IA64_LTOFF_FPTR64MSB
:
2757 case R_IA64_LTOFF_FPTR64LSB
:
2758 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2761 case R_IA64_FPTR64I
:
2762 case R_IA64_FPTR32MSB
:
2763 case R_IA64_FPTR32LSB
:
2764 case R_IA64_FPTR64MSB
:
2765 case R_IA64_FPTR64LSB
:
2766 if (info
->shared
|| h
)
2767 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2769 need_entry
= NEED_FPTR
;
2772 case R_IA64_LTOFF22
:
2773 case R_IA64_LTOFF64I
:
2774 need_entry
= NEED_GOT
;
2777 case R_IA64_LTOFF22X
:
2778 need_entry
= NEED_GOTX
;
2781 case R_IA64_PLTOFF22
:
2782 case R_IA64_PLTOFF64I
:
2783 case R_IA64_PLTOFF64MSB
:
2784 case R_IA64_PLTOFF64LSB
:
2785 need_entry
= NEED_PLTOFF
;
2789 need_entry
|= NEED_MIN_PLT
;
2793 (*info
->callbacks
->warning
)
2794 (info
, _("@pltoff reloc against local symbol"), 0,
2795 abfd
, 0, (bfd_vma
) 0);
2799 case R_IA64_PCREL21B
:
2800 case R_IA64_PCREL60B
:
2801 /* Depending on where this symbol is defined, we may or may not
2802 need a full plt entry. Only skip if we know we'll not need
2803 the entry -- static or symbolic, and the symbol definition
2804 has already been seen. */
2805 if (maybe_dynamic
&& rel
->r_addend
== 0)
2806 need_entry
= NEED_FULL_PLT
;
2812 case R_IA64_DIR32MSB
:
2813 case R_IA64_DIR32LSB
:
2814 case R_IA64_DIR64MSB
:
2815 case R_IA64_DIR64LSB
:
2816 /* Shared objects will always need at least a REL relocation. */
2817 if (info
->shared
|| maybe_dynamic
)
2818 need_entry
= NEED_DYNREL
;
2821 case R_IA64_IPLTMSB
:
2822 case R_IA64_IPLTLSB
:
2823 /* Shared objects will always need at least a REL relocation. */
2824 if (info
->shared
|| maybe_dynamic
)
2825 need_entry
= NEED_DYNREL
;
2828 case R_IA64_PCREL22
:
2829 case R_IA64_PCREL64I
:
2830 case R_IA64_PCREL32MSB
:
2831 case R_IA64_PCREL32LSB
:
2832 case R_IA64_PCREL64MSB
:
2833 case R_IA64_PCREL64LSB
:
2835 need_entry
= NEED_DYNREL
;
2842 if ((need_entry
& NEED_FPTR
) != 0
2845 (*info
->callbacks
->warning
)
2846 (info
, _("non-zero addend in @fptr reloc"), 0,
2847 abfd
, 0, (bfd_vma
) 0);
2850 if (get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, TRUE
) == NULL
)
2854 /* Now, we only do lookup without insertion, which is very fast
2855 with the modified get_dyn_sym_info. */
2856 for (rel
= relocs
; rel
< relend
; ++rel
)
2858 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2859 int dynrel_type
= R_IA64_NONE
;
2861 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2862 if (r_symndx
>= symtab_hdr
->sh_info
)
2864 /* We're dealing with a global symbol -- find its hash entry
2865 and mark it as being referenced. */
2866 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2867 h
= elf_sym_hashes (abfd
)[indx
];
2868 while (h
->root
.type
== bfd_link_hash_indirect
2869 || h
->root
.type
== bfd_link_hash_warning
)
2870 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2877 /* We can only get preliminary data on whether a symbol is
2878 locally or externally defined, as not all of the input files
2879 have yet been processed. Do something with what we know, as
2880 this may help reduce memory usage and processing time later. */
2881 maybe_dynamic
= (h
&& ((!info
->executable
2882 && (!SYMBOLIC_BIND (info
, h
)
2883 || info
->unresolved_syms_in_shared_libs
== RM_IGNORE
))
2885 || h
->root
.type
== bfd_link_hash_defweak
));
2888 switch (ELFNN_R_TYPE (rel
->r_info
))
2890 case R_IA64_TPREL64MSB
:
2891 case R_IA64_TPREL64LSB
:
2892 if (info
->shared
|| maybe_dynamic
)
2893 need_entry
= NEED_DYNREL
;
2894 dynrel_type
= R_IA64_TPREL64LSB
;
2896 info
->flags
|= DF_STATIC_TLS
;
2899 case R_IA64_LTOFF_TPREL22
:
2900 need_entry
= NEED_TPREL
;
2902 info
->flags
|= DF_STATIC_TLS
;
2905 case R_IA64_DTPREL32MSB
:
2906 case R_IA64_DTPREL32LSB
:
2907 case R_IA64_DTPREL64MSB
:
2908 case R_IA64_DTPREL64LSB
:
2909 if (info
->shared
|| maybe_dynamic
)
2910 need_entry
= NEED_DYNREL
;
2911 dynrel_type
= R_IA64_DTPRELNNLSB
;
2914 case R_IA64_LTOFF_DTPREL22
:
2915 need_entry
= NEED_DTPREL
;
2918 case R_IA64_DTPMOD64MSB
:
2919 case R_IA64_DTPMOD64LSB
:
2920 if (info
->shared
|| maybe_dynamic
)
2921 need_entry
= NEED_DYNREL
;
2922 dynrel_type
= R_IA64_DTPMOD64LSB
;
2925 case R_IA64_LTOFF_DTPMOD22
:
2926 need_entry
= NEED_DTPMOD
;
2929 case R_IA64_LTOFF_FPTR22
:
2930 case R_IA64_LTOFF_FPTR64I
:
2931 case R_IA64_LTOFF_FPTR32MSB
:
2932 case R_IA64_LTOFF_FPTR32LSB
:
2933 case R_IA64_LTOFF_FPTR64MSB
:
2934 case R_IA64_LTOFF_FPTR64LSB
:
2935 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2938 case R_IA64_FPTR64I
:
2939 case R_IA64_FPTR32MSB
:
2940 case R_IA64_FPTR32LSB
:
2941 case R_IA64_FPTR64MSB
:
2942 case R_IA64_FPTR64LSB
:
2943 if (info
->shared
|| h
)
2944 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2946 need_entry
= NEED_FPTR
;
2947 dynrel_type
= R_IA64_FPTRNNLSB
;
2950 case R_IA64_LTOFF22
:
2951 case R_IA64_LTOFF64I
:
2952 need_entry
= NEED_GOT
;
2955 case R_IA64_LTOFF22X
:
2956 need_entry
= NEED_GOTX
;
2959 case R_IA64_PLTOFF22
:
2960 case R_IA64_PLTOFF64I
:
2961 case R_IA64_PLTOFF64MSB
:
2962 case R_IA64_PLTOFF64LSB
:
2963 need_entry
= NEED_PLTOFF
;
2967 need_entry
|= NEED_MIN_PLT
;
2971 case R_IA64_PCREL21B
:
2972 case R_IA64_PCREL60B
:
2973 /* Depending on where this symbol is defined, we may or may not
2974 need a full plt entry. Only skip if we know we'll not need
2975 the entry -- static or symbolic, and the symbol definition
2976 has already been seen. */
2977 if (maybe_dynamic
&& rel
->r_addend
== 0)
2978 need_entry
= NEED_FULL_PLT
;
2984 case R_IA64_DIR32MSB
:
2985 case R_IA64_DIR32LSB
:
2986 case R_IA64_DIR64MSB
:
2987 case R_IA64_DIR64LSB
:
2988 /* Shared objects will always need at least a REL relocation. */
2989 if (info
->shared
|| maybe_dynamic
)
2990 need_entry
= NEED_DYNREL
;
2991 dynrel_type
= R_IA64_DIRNNLSB
;
2994 case R_IA64_IPLTMSB
:
2995 case R_IA64_IPLTLSB
:
2996 /* Shared objects will always need at least a REL relocation. */
2997 if (info
->shared
|| maybe_dynamic
)
2998 need_entry
= NEED_DYNREL
;
2999 dynrel_type
= R_IA64_IPLTLSB
;
3002 case R_IA64_PCREL22
:
3003 case R_IA64_PCREL64I
:
3004 case R_IA64_PCREL32MSB
:
3005 case R_IA64_PCREL32LSB
:
3006 case R_IA64_PCREL64MSB
:
3007 case R_IA64_PCREL64LSB
:
3009 need_entry
= NEED_DYNREL
;
3010 dynrel_type
= R_IA64_PCRELNNLSB
;
3017 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, FALSE
);
3019 /* Record whether or not this is a local symbol. */
3022 /* Create what's needed. */
3023 if (need_entry
& (NEED_GOT
| NEED_GOTX
| NEED_TPREL
3024 | NEED_DTPMOD
| NEED_DTPREL
))
3028 got
= get_got (abfd
, info
, ia64_info
);
3032 if (need_entry
& NEED_GOT
)
3033 dyn_i
->want_got
= 1;
3034 if (need_entry
& NEED_GOTX
)
3035 dyn_i
->want_gotx
= 1;
3036 if (need_entry
& NEED_TPREL
)
3037 dyn_i
->want_tprel
= 1;
3038 if (need_entry
& NEED_DTPMOD
)
3039 dyn_i
->want_dtpmod
= 1;
3040 if (need_entry
& NEED_DTPREL
)
3041 dyn_i
->want_dtprel
= 1;
3043 if (need_entry
& NEED_FPTR
)
3047 fptr
= get_fptr (abfd
, info
, ia64_info
);
3052 /* FPTRs for shared libraries are allocated by the dynamic
3053 linker. Make sure this local symbol will appear in the
3054 dynamic symbol table. */
3055 if (!h
&& info
->shared
)
3057 if (! (bfd_elf_link_record_local_dynamic_symbol
3058 (info
, abfd
, (long) r_symndx
)))
3062 dyn_i
->want_fptr
= 1;
3064 if (need_entry
& NEED_LTOFF_FPTR
)
3065 dyn_i
->want_ltoff_fptr
= 1;
3066 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
3068 if (!ia64_info
->root
.dynobj
)
3069 ia64_info
->root
.dynobj
= abfd
;
3071 dyn_i
->want_plt
= 1;
3073 if (need_entry
& NEED_FULL_PLT
)
3074 dyn_i
->want_plt2
= 1;
3075 if (need_entry
& NEED_PLTOFF
)
3077 /* This is needed here, in case @pltoff is used in a non-shared
3081 pltoff
= get_pltoff (abfd
, info
, ia64_info
);
3086 dyn_i
->want_pltoff
= 1;
3088 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
3092 srel
= get_reloc_section (abfd
, ia64_info
, sec
, TRUE
);
3096 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
,
3097 (sec
->flags
& SEC_READONLY
) != 0))
3105 /* For cleanliness, and potentially faster dynamic loading, allocate
3106 external GOT entries first. */
3109 allocate_global_data_got (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3112 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3114 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
3115 && ! dyn_i
->want_fptr
3116 && elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3118 dyn_i
->got_offset
= x
->ofs
;
3121 if (dyn_i
->want_tprel
)
3123 dyn_i
->tprel_offset
= x
->ofs
;
3126 if (dyn_i
->want_dtpmod
)
3128 if (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3130 dyn_i
->dtpmod_offset
= x
->ofs
;
3135 struct elfNN_ia64_link_hash_table
*ia64_info
;
3137 ia64_info
= elfNN_ia64_hash_table (x
->info
);
3138 if (ia64_info
->self_dtpmod_offset
== (bfd_vma
) -1)
3140 ia64_info
->self_dtpmod_offset
= x
->ofs
;
3143 dyn_i
->dtpmod_offset
= ia64_info
->self_dtpmod_offset
;
3146 if (dyn_i
->want_dtprel
)
3148 dyn_i
->dtprel_offset
= x
->ofs
;
3154 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
3157 allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3160 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3164 && elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, R_IA64_FPTRNNLSB
))
3166 dyn_i
->got_offset
= x
->ofs
;
3172 /* Lastly, allocate all the GOT entries for local data. */
3175 allocate_local_got (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3178 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3180 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
3181 && !elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3183 dyn_i
->got_offset
= x
->ofs
;
3189 /* Search for the index of a global symbol in it's defining object file. */
3192 global_sym_index (struct elf_link_hash_entry
*h
)
3194 struct elf_link_hash_entry
**p
;
3197 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
3198 || h
->root
.type
== bfd_link_hash_defweak
);
3200 obj
= h
->root
.u
.def
.section
->owner
;
3201 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
3204 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
3207 /* Allocate function descriptors. We can do these for every function
3208 in a main executable that is not exported. */
3211 allocate_fptr (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
)
3213 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3215 if (dyn_i
->want_fptr
)
3217 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3220 while (h
->root
.type
== bfd_link_hash_indirect
3221 || h
->root
.type
== bfd_link_hash_warning
)
3222 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3224 if (!x
->info
->executable
3226 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
3227 || (h
->root
.type
!= bfd_link_hash_undefweak
3228 && h
->root
.type
!= bfd_link_hash_undefined
)))
3230 if (h
&& h
->dynindx
== -1)
3232 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
3233 || (h
->root
.type
== bfd_link_hash_defweak
));
3235 if (!bfd_elf_link_record_local_dynamic_symbol
3236 (x
->info
, h
->root
.u
.def
.section
->owner
,
3237 global_sym_index (h
)))
3241 dyn_i
->want_fptr
= 0;
3243 else if (h
== NULL
|| h
->dynindx
== -1)
3245 dyn_i
->fptr_offset
= x
->ofs
;
3249 dyn_i
->want_fptr
= 0;
3254 /* Allocate all the minimal PLT entries. */
3257 allocate_plt_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3260 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3262 if (dyn_i
->want_plt
)
3264 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3267 while (h
->root
.type
== bfd_link_hash_indirect
3268 || h
->root
.type
== bfd_link_hash_warning
)
3269 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3271 /* ??? Versioned symbols seem to lose NEEDS_PLT. */
3272 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
, 0))
3274 bfd_size_type offset
= x
->ofs
;
3276 offset
= PLT_HEADER_SIZE
;
3277 dyn_i
->plt_offset
= offset
;
3278 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
3280 dyn_i
->want_pltoff
= 1;
3284 dyn_i
->want_plt
= 0;
3285 dyn_i
->want_plt2
= 0;
3291 /* Allocate all the full PLT entries. */
3294 allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3297 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3299 if (dyn_i
->want_plt2
)
3301 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3302 bfd_size_type ofs
= x
->ofs
;
3304 dyn_i
->plt2_offset
= ofs
;
3305 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
3307 while (h
->root
.type
== bfd_link_hash_indirect
3308 || h
->root
.type
== bfd_link_hash_warning
)
3309 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3310 dyn_i
->h
->plt
.offset
= ofs
;
3315 /* Allocate all the PLTOFF entries requested by relocations and
3316 plt entries. We can't share space with allocated FPTR entries,
3317 because the latter are not necessarily addressable by the GP.
3318 ??? Relaxation might be able to determine that they are. */
3321 allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3324 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3326 if (dyn_i
->want_pltoff
)
3328 dyn_i
->pltoff_offset
= x
->ofs
;
3334 /* Allocate dynamic relocations for those symbols that turned out
3338 allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3341 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3342 struct elfNN_ia64_link_hash_table
*ia64_info
;
3343 struct elfNN_ia64_dyn_reloc_entry
*rent
;
3344 bfd_boolean dynamic_symbol
, shared
, resolved_zero
;
3346 ia64_info
= elfNN_ia64_hash_table (x
->info
);
3348 /* Note that this can't be used in relation to FPTR relocs below. */
3349 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0);
3351 shared
= x
->info
->shared
;
3352 resolved_zero
= (dyn_i
->h
3353 && ELF_ST_VISIBILITY (dyn_i
->h
->other
)
3354 && dyn_i
->h
->root
.type
== bfd_link_hash_undefweak
);
3356 /* Take care of the GOT and PLT relocations. */
3359 && (dynamic_symbol
|| shared
)
3360 && (dyn_i
->want_got
|| dyn_i
->want_gotx
))
3361 || (dyn_i
->want_ltoff_fptr
3363 && dyn_i
->h
->dynindx
!= -1))
3365 if (!dyn_i
->want_ltoff_fptr
3368 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
3369 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
3371 if ((dynamic_symbol
|| shared
) && dyn_i
->want_tprel
)
3372 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
3373 if (dynamic_symbol
&& dyn_i
->want_dtpmod
)
3374 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
3375 if (dynamic_symbol
&& dyn_i
->want_dtprel
)
3376 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
3381 if (ia64_info
->rel_fptr_sec
&& dyn_i
->want_fptr
)
3383 if (dyn_i
->h
== NULL
|| dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
3384 ia64_info
->rel_fptr_sec
->size
+= sizeof (ElfNN_External_Rela
);
3387 if (!resolved_zero
&& dyn_i
->want_pltoff
)
3389 bfd_size_type t
= 0;
3391 /* Dynamic symbols get one IPLT relocation. Local symbols in
3392 shared libraries get two REL relocations. Local symbols in
3393 main applications get nothing. */
3395 t
= sizeof (ElfNN_External_Rela
);
3397 t
= 2 * sizeof (ElfNN_External_Rela
);
3399 ia64_info
->rel_pltoff_sec
->size
+= t
;
3402 /* Take care of the normal data relocations. */
3404 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
3406 int count
= rent
->count
;
3410 case R_IA64_FPTR32LSB
:
3411 case R_IA64_FPTR64LSB
:
3412 /* Allocate one iff !want_fptr and not PIE, which by this point
3413 will be true only if we're actually allocating one statically
3414 in the main executable. Position independent executables
3415 need a relative reloc. */
3416 if (dyn_i
->want_fptr
&& !x
->info
->pie
)
3419 case R_IA64_PCREL32LSB
:
3420 case R_IA64_PCREL64LSB
:
3421 if (!dynamic_symbol
)
3424 case R_IA64_DIR32LSB
:
3425 case R_IA64_DIR64LSB
:
3426 if (!dynamic_symbol
&& !shared
)
3429 case R_IA64_IPLTLSB
:
3430 if (!dynamic_symbol
&& !shared
)
3432 /* Use two REL relocations for IPLT relocations
3433 against local symbols. */
3434 if (!dynamic_symbol
)
3437 case R_IA64_DTPREL32LSB
:
3438 case R_IA64_TPREL64LSB
:
3439 case R_IA64_DTPREL64LSB
:
3440 case R_IA64_DTPMOD64LSB
:
3446 ia64_info
->reltext
= 1;
3447 rent
->srel
->size
+= sizeof (ElfNN_External_Rela
) * count
;
3454 elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
3455 struct elf_link_hash_entry
*h
)
3457 /* ??? Undefined symbols with PLT entries should be re-defined
3458 to be the PLT entry. */
3460 /* If this is a weak symbol, and there is a real definition, the
3461 processor independent code will have arranged for us to see the
3462 real definition first, and we can just use the same value. */
3463 if (h
->u
.weakdef
!= NULL
)
3465 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
3466 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
3467 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
3468 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
3472 /* If this is a reference to a symbol defined by a dynamic object which
3473 is not a function, we might allocate the symbol in our .dynbss section
3474 and allocate a COPY dynamic relocation.
3476 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
3483 elfNN_ia64_size_dynamic_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
3484 struct bfd_link_info
*info
)
3486 struct elfNN_ia64_allocate_data data
;
3487 struct elfNN_ia64_link_hash_table
*ia64_info
;
3490 bfd_boolean relplt
= FALSE
;
3492 dynobj
= elf_hash_table(info
)->dynobj
;
3493 ia64_info
= elfNN_ia64_hash_table (info
);
3494 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
3495 BFD_ASSERT(dynobj
!= NULL
);
3498 /* Set the contents of the .interp section to the interpreter. */
3499 if (ia64_info
->root
.dynamic_sections_created
3500 && info
->executable
)
3502 sec
= bfd_get_section_by_name (dynobj
, ".interp");
3503 BFD_ASSERT (sec
!= NULL
);
3504 sec
->contents
= (bfd_byte
*) ELF_DYNAMIC_INTERPRETER
;
3505 sec
->size
= strlen (ELF_DYNAMIC_INTERPRETER
) + 1;
3508 /* Allocate the GOT entries. */
3510 if (ia64_info
->root
.sgot
)
3513 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
3514 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
3515 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
3516 ia64_info
->root
.sgot
->size
= data
.ofs
;
3519 /* Allocate the FPTR entries. */
3521 if (ia64_info
->fptr_sec
)
3524 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
3525 ia64_info
->fptr_sec
->size
= data
.ofs
;
3528 /* Now that we've seen all of the input files, we can decide which
3529 symbols need plt entries. Allocate the minimal PLT entries first.
3530 We do this even though dynamic_sections_created may be FALSE, because
3531 this has the side-effect of clearing want_plt and want_plt2. */
3534 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
3536 ia64_info
->minplt_entries
= 0;
3539 ia64_info
->minplt_entries
3540 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
3543 /* Align the pointer for the plt2 entries. */
3544 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
3546 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
3547 if (data
.ofs
!= 0 || ia64_info
->root
.dynamic_sections_created
)
3549 /* FIXME: we always reserve the memory for dynamic linker even if
3550 there are no PLT entries since dynamic linker may assume the
3551 reserved memory always exists. */
3553 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
3555 ia64_info
->root
.splt
->size
= data
.ofs
;
3557 /* If we've got a .plt, we need some extra memory for the dynamic
3558 linker. We stuff these in .got.plt. */
3559 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
3560 sec
->size
= 8 * PLT_RESERVED_WORDS
;
3563 /* Allocate the PLTOFF entries. */
3565 if (ia64_info
->pltoff_sec
)
3568 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
3569 ia64_info
->pltoff_sec
->size
= data
.ofs
;
3572 if (ia64_info
->root
.dynamic_sections_created
)
3574 /* Allocate space for the dynamic relocations that turned out to be
3577 if (info
->shared
&& ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
3578 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
3579 data
.only_got
= FALSE
;
3580 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
3583 /* We have now determined the sizes of the various dynamic sections.
3584 Allocate memory for them. */
3585 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
3589 if (!(sec
->flags
& SEC_LINKER_CREATED
))
3592 /* If we don't need this section, strip it from the output file.
3593 There were several sections primarily related to dynamic
3594 linking that must be create before the linker maps input
3595 sections to output sections. The linker does that before
3596 bfd_elf_size_dynamic_sections is called, and it is that
3597 function which decides whether anything needs to go into
3600 strip
= (sec
->size
== 0);
3602 if (sec
== ia64_info
->root
.sgot
)
3604 else if (sec
== ia64_info
->root
.srelgot
)
3607 ia64_info
->root
.srelgot
= NULL
;
3609 /* We use the reloc_count field as a counter if we need to
3610 copy relocs into the output file. */
3611 sec
->reloc_count
= 0;
3613 else if (sec
== ia64_info
->fptr_sec
)
3616 ia64_info
->fptr_sec
= NULL
;
3618 else if (sec
== ia64_info
->rel_fptr_sec
)
3621 ia64_info
->rel_fptr_sec
= NULL
;
3623 /* We use the reloc_count field as a counter if we need to
3624 copy relocs into the output file. */
3625 sec
->reloc_count
= 0;
3627 else if (sec
== ia64_info
->root
.splt
)
3630 ia64_info
->root
.splt
= NULL
;
3632 else if (sec
== ia64_info
->pltoff_sec
)
3635 ia64_info
->pltoff_sec
= NULL
;
3637 else if (sec
== ia64_info
->rel_pltoff_sec
)
3640 ia64_info
->rel_pltoff_sec
= NULL
;
3644 /* We use the reloc_count field as a counter if we need to
3645 copy relocs into the output file. */
3646 sec
->reloc_count
= 0;
3653 /* It's OK to base decisions on the section name, because none
3654 of the dynobj section names depend upon the input files. */
3655 name
= bfd_get_section_name (dynobj
, sec
);
3657 if (strcmp (name
, ".got.plt") == 0)
3659 else if (CONST_STRNEQ (name
, ".rel"))
3663 /* We use the reloc_count field as a counter if we need to
3664 copy relocs into the output file. */
3665 sec
->reloc_count
= 0;
3673 sec
->flags
|= SEC_EXCLUDE
;
3676 /* Allocate memory for the section contents. */
3677 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->size
);
3678 if (sec
->contents
== NULL
&& sec
->size
!= 0)
3683 if (elf_hash_table (info
)->dynamic_sections_created
)
3685 /* Add some entries to the .dynamic section. We fill in the values
3686 later (in finish_dynamic_sections) but we must add the entries now
3687 so that we get the correct size for the .dynamic section. */
3689 if (info
->executable
)
3691 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3693 #define add_dynamic_entry(TAG, VAL) \
3694 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3696 if (!add_dynamic_entry (DT_DEBUG
, 0))
3700 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
3702 if (!add_dynamic_entry (DT_PLTGOT
, 0))
3707 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
3708 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
3709 || !add_dynamic_entry (DT_JMPREL
, 0))
3713 if (!add_dynamic_entry (DT_RELA
, 0)
3714 || !add_dynamic_entry (DT_RELASZ
, 0)
3715 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
3718 if (ia64_info
->reltext
)
3720 if (!add_dynamic_entry (DT_TEXTREL
, 0))
3722 info
->flags
|= DF_TEXTREL
;
3726 /* ??? Perhaps force __gp local. */
3731 static bfd_reloc_status_type
3732 elfNN_ia64_install_value (bfd_byte
*hit_addr
, bfd_vma v
,
3733 unsigned int r_type
)
3735 const struct ia64_operand
*op
;
3736 int bigendian
= 0, shift
= 0;
3737 bfd_vma t0
, t1
, dword
;
3739 enum ia64_opnd opnd
;
3742 #ifdef BFD_HOST_U_64_BIT
3743 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
3748 opnd
= IA64_OPND_NIL
;
3753 return bfd_reloc_ok
;
3755 /* Instruction relocations. */
3758 case R_IA64_TPREL14
:
3759 case R_IA64_DTPREL14
:
3760 opnd
= IA64_OPND_IMM14
;
3763 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
3764 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
3765 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
3766 case R_IA64_PCREL21B
:
3767 case R_IA64_PCREL21BI
:
3768 opnd
= IA64_OPND_TGT25c
;
3772 case R_IA64_GPREL22
:
3773 case R_IA64_LTOFF22
:
3774 case R_IA64_LTOFF22X
:
3775 case R_IA64_PLTOFF22
:
3776 case R_IA64_PCREL22
:
3777 case R_IA64_LTOFF_FPTR22
:
3778 case R_IA64_TPREL22
:
3779 case R_IA64_DTPREL22
:
3780 case R_IA64_LTOFF_TPREL22
:
3781 case R_IA64_LTOFF_DTPMOD22
:
3782 case R_IA64_LTOFF_DTPREL22
:
3783 opnd
= IA64_OPND_IMM22
;
3787 case R_IA64_GPREL64I
:
3788 case R_IA64_LTOFF64I
:
3789 case R_IA64_PLTOFF64I
:
3790 case R_IA64_PCREL64I
:
3791 case R_IA64_FPTR64I
:
3792 case R_IA64_LTOFF_FPTR64I
:
3793 case R_IA64_TPREL64I
:
3794 case R_IA64_DTPREL64I
:
3795 opnd
= IA64_OPND_IMMU64
;
3798 /* Data relocations. */
3800 case R_IA64_DIR32MSB
:
3801 case R_IA64_GPREL32MSB
:
3802 case R_IA64_FPTR32MSB
:
3803 case R_IA64_PCREL32MSB
:
3804 case R_IA64_LTOFF_FPTR32MSB
:
3805 case R_IA64_SEGREL32MSB
:
3806 case R_IA64_SECREL32MSB
:
3807 case R_IA64_LTV32MSB
:
3808 case R_IA64_DTPREL32MSB
:
3809 size
= 4; bigendian
= 1;
3812 case R_IA64_DIR32LSB
:
3813 case R_IA64_GPREL32LSB
:
3814 case R_IA64_FPTR32LSB
:
3815 case R_IA64_PCREL32LSB
:
3816 case R_IA64_LTOFF_FPTR32LSB
:
3817 case R_IA64_SEGREL32LSB
:
3818 case R_IA64_SECREL32LSB
:
3819 case R_IA64_LTV32LSB
:
3820 case R_IA64_DTPREL32LSB
:
3821 size
= 4; bigendian
= 0;
3824 case R_IA64_DIR64MSB
:
3825 case R_IA64_GPREL64MSB
:
3826 case R_IA64_PLTOFF64MSB
:
3827 case R_IA64_FPTR64MSB
:
3828 case R_IA64_PCREL64MSB
:
3829 case R_IA64_LTOFF_FPTR64MSB
:
3830 case R_IA64_SEGREL64MSB
:
3831 case R_IA64_SECREL64MSB
:
3832 case R_IA64_LTV64MSB
:
3833 case R_IA64_TPREL64MSB
:
3834 case R_IA64_DTPMOD64MSB
:
3835 case R_IA64_DTPREL64MSB
:
3836 size
= 8; bigendian
= 1;
3839 case R_IA64_DIR64LSB
:
3840 case R_IA64_GPREL64LSB
:
3841 case R_IA64_PLTOFF64LSB
:
3842 case R_IA64_FPTR64LSB
:
3843 case R_IA64_PCREL64LSB
:
3844 case R_IA64_LTOFF_FPTR64LSB
:
3845 case R_IA64_SEGREL64LSB
:
3846 case R_IA64_SECREL64LSB
:
3847 case R_IA64_LTV64LSB
:
3848 case R_IA64_TPREL64LSB
:
3849 case R_IA64_DTPMOD64LSB
:
3850 case R_IA64_DTPREL64LSB
:
3851 size
= 8; bigendian
= 0;
3854 /* Unsupported / Dynamic relocations. */
3856 return bfd_reloc_notsupported
;
3861 case IA64_OPND_IMMU64
:
3862 hit_addr
-= (long) hit_addr
& 0x3;
3863 t0
= bfd_getl64 (hit_addr
);
3864 t1
= bfd_getl64 (hit_addr
+ 8);
3866 /* tmpl/s: bits 0.. 5 in t0
3867 slot 0: bits 5..45 in t0
3868 slot 1: bits 46..63 in t0, bits 0..22 in t1
3869 slot 2: bits 23..63 in t1 */
3871 /* First, clear the bits that form the 64 bit constant. */
3872 t0
&= ~(0x3ffffLL
<< 46);
3874 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
3875 | (0x01fLL
<< 22) | (0x001LL
<< 21)
3876 | (0x001LL
<< 36)) << 23));
3878 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
3879 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
3880 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
3881 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
3882 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
3883 | (((val
>> 21) & 0x001) << 21) /* ic */
3884 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
3886 bfd_putl64 (t0
, hit_addr
);
3887 bfd_putl64 (t1
, hit_addr
+ 8);
3890 case IA64_OPND_TGT64
:
3891 hit_addr
-= (long) hit_addr
& 0x3;
3892 t0
= bfd_getl64 (hit_addr
);
3893 t1
= bfd_getl64 (hit_addr
+ 8);
3895 /* tmpl/s: bits 0.. 5 in t0
3896 slot 0: bits 5..45 in t0
3897 slot 1: bits 46..63 in t0, bits 0..22 in t1
3898 slot 2: bits 23..63 in t1 */
3900 /* First, clear the bits that form the 64 bit constant. */
3901 t0
&= ~(0x3ffffLL
<< 46);
3903 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
3906 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
3907 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
3908 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
3909 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
3911 bfd_putl64 (t0
, hit_addr
);
3912 bfd_putl64 (t1
, hit_addr
+ 8);
3916 switch ((long) hit_addr
& 0x3)
3918 case 0: shift
= 5; break;
3919 case 1: shift
= 14; hit_addr
+= 3; break;
3920 case 2: shift
= 23; hit_addr
+= 6; break;
3921 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
3923 dword
= bfd_getl64 (hit_addr
);
3924 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
3926 op
= elf64_ia64_operands
+ opnd
;
3927 err
= (*op
->insert
) (op
, val
, &insn
);
3929 return bfd_reloc_overflow
;
3931 dword
&= ~(0x1ffffffffffLL
<< shift
);
3932 dword
|= (insn
<< shift
);
3933 bfd_putl64 (dword
, hit_addr
);
3937 /* A data relocation. */
3940 bfd_putb32 (val
, hit_addr
);
3942 bfd_putb64 (val
, hit_addr
);
3945 bfd_putl32 (val
, hit_addr
);
3947 bfd_putl64 (val
, hit_addr
);
3951 return bfd_reloc_ok
;
3955 elfNN_ia64_install_dyn_reloc (bfd
*abfd
, struct bfd_link_info
*info
,
3956 asection
*sec
, asection
*srel
,
3957 bfd_vma offset
, unsigned int type
,
3958 long dynindx
, bfd_vma addend
)
3960 Elf_Internal_Rela outrel
;
3963 BFD_ASSERT (dynindx
!= -1);
3964 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3965 outrel
.r_addend
= addend
;
3966 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3967 if (outrel
.r_offset
>= (bfd_vma
) -2)
3969 /* Run for the hills. We shouldn't be outputting a relocation
3970 for this. So do what everyone else does and output a no-op. */
3971 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3972 outrel
.r_addend
= 0;
3973 outrel
.r_offset
= 0;
3976 outrel
.r_offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3978 loc
= srel
->contents
;
3979 loc
+= srel
->reloc_count
++ * sizeof (ElfNN_External_Rela
);
3980 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
3981 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
<= srel
->size
);
3984 /* Store an entry for target address TARGET_ADDR in the linkage table
3985 and return the gp-relative address of the linkage table entry. */
3988 set_got_entry (bfd
*abfd
, struct bfd_link_info
*info
,
3989 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3990 long dynindx
, bfd_vma addend
, bfd_vma value
,
3991 unsigned int dyn_r_type
)
3993 struct elfNN_ia64_link_hash_table
*ia64_info
;
3998 ia64_info
= elfNN_ia64_hash_table (info
);
3999 got_sec
= ia64_info
->root
.sgot
;
4003 case R_IA64_TPREL64LSB
:
4004 done
= dyn_i
->tprel_done
;
4005 dyn_i
->tprel_done
= TRUE
;
4006 got_offset
= dyn_i
->tprel_offset
;
4008 case R_IA64_DTPMOD64LSB
:
4009 if (dyn_i
->dtpmod_offset
!= ia64_info
->self_dtpmod_offset
)
4011 done
= dyn_i
->dtpmod_done
;
4012 dyn_i
->dtpmod_done
= TRUE
;
4016 done
= ia64_info
->self_dtpmod_done
;
4017 ia64_info
->self_dtpmod_done
= TRUE
;
4020 got_offset
= dyn_i
->dtpmod_offset
;
4022 case R_IA64_DTPREL32LSB
:
4023 case R_IA64_DTPREL64LSB
:
4024 done
= dyn_i
->dtprel_done
;
4025 dyn_i
->dtprel_done
= TRUE
;
4026 got_offset
= dyn_i
->dtprel_offset
;
4029 done
= dyn_i
->got_done
;
4030 dyn_i
->got_done
= TRUE
;
4031 got_offset
= dyn_i
->got_offset
;
4035 BFD_ASSERT ((got_offset
& 7) == 0);
4039 /* Store the target address in the linkage table entry. */
4040 bfd_put_64 (abfd
, value
, got_sec
->contents
+ got_offset
);
4042 /* Install a dynamic relocation if needed. */
4045 || ELF_ST_VISIBILITY (dyn_i
->h
->other
) == STV_DEFAULT
4046 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
4047 && dyn_r_type
!= R_IA64_DTPREL32LSB
4048 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
4049 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
, dyn_r_type
)
4051 && (dyn_r_type
== R_IA64_FPTR32LSB
4052 || dyn_r_type
== R_IA64_FPTR64LSB
)))
4053 && (!dyn_i
->want_ltoff_fptr
4056 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
))
4059 && dyn_r_type
!= R_IA64_TPREL64LSB
4060 && dyn_r_type
!= R_IA64_DTPMOD64LSB
4061 && dyn_r_type
!= R_IA64_DTPREL32LSB
4062 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
4064 dyn_r_type
= R_IA64_RELNNLSB
;
4069 if (bfd_big_endian (abfd
))
4073 case R_IA64_REL32LSB
:
4074 dyn_r_type
= R_IA64_REL32MSB
;
4076 case R_IA64_DIR32LSB
:
4077 dyn_r_type
= R_IA64_DIR32MSB
;
4079 case R_IA64_FPTR32LSB
:
4080 dyn_r_type
= R_IA64_FPTR32MSB
;
4082 case R_IA64_DTPREL32LSB
:
4083 dyn_r_type
= R_IA64_DTPREL32MSB
;
4085 case R_IA64_REL64LSB
:
4086 dyn_r_type
= R_IA64_REL64MSB
;
4088 case R_IA64_DIR64LSB
:
4089 dyn_r_type
= R_IA64_DIR64MSB
;
4091 case R_IA64_FPTR64LSB
:
4092 dyn_r_type
= R_IA64_FPTR64MSB
;
4094 case R_IA64_TPREL64LSB
:
4095 dyn_r_type
= R_IA64_TPREL64MSB
;
4097 case R_IA64_DTPMOD64LSB
:
4098 dyn_r_type
= R_IA64_DTPMOD64MSB
;
4100 case R_IA64_DTPREL64LSB
:
4101 dyn_r_type
= R_IA64_DTPREL64MSB
;
4109 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
4110 ia64_info
->root
.srelgot
,
4111 got_offset
, dyn_r_type
,
4116 /* Return the address of the linkage table entry. */
4117 value
= (got_sec
->output_section
->vma
4118 + got_sec
->output_offset
4124 /* Fill in a function descriptor consisting of the function's code
4125 address and its global pointer. Return the descriptor's address. */
4128 set_fptr_entry (bfd
*abfd
, struct bfd_link_info
*info
,
4129 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
4132 struct elfNN_ia64_link_hash_table
*ia64_info
;
4135 ia64_info
= elfNN_ia64_hash_table (info
);
4136 fptr_sec
= ia64_info
->fptr_sec
;
4138 if (!dyn_i
->fptr_done
)
4140 dyn_i
->fptr_done
= 1;
4142 /* Fill in the function descriptor. */
4143 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
4144 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
4145 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
4146 if (ia64_info
->rel_fptr_sec
)
4148 Elf_Internal_Rela outrel
;
4151 if (bfd_little_endian (abfd
))
4152 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_IPLTLSB
);
4154 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_IPLTMSB
);
4155 outrel
.r_addend
= value
;
4156 outrel
.r_offset
= (fptr_sec
->output_section
->vma
4157 + fptr_sec
->output_offset
4158 + dyn_i
->fptr_offset
);
4159 loc
= ia64_info
->rel_fptr_sec
->contents
;
4160 loc
+= ia64_info
->rel_fptr_sec
->reloc_count
++
4161 * sizeof (ElfNN_External_Rela
);
4162 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
4166 /* Return the descriptor's address. */
4167 value
= (fptr_sec
->output_section
->vma
4168 + fptr_sec
->output_offset
4169 + dyn_i
->fptr_offset
);
4174 /* Fill in a PLTOFF entry consisting of the function's code address
4175 and its global pointer. Return the descriptor's address. */
4178 set_pltoff_entry (bfd
*abfd
, struct bfd_link_info
*info
,
4179 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
4180 bfd_vma value
, bfd_boolean is_plt
)
4182 struct elfNN_ia64_link_hash_table
*ia64_info
;
4183 asection
*pltoff_sec
;
4185 ia64_info
= elfNN_ia64_hash_table (info
);
4186 pltoff_sec
= ia64_info
->pltoff_sec
;
4188 /* Don't do anything if this symbol uses a real PLT entry. In
4189 that case, we'll fill this in during finish_dynamic_symbol. */
4190 if ((! dyn_i
->want_plt
|| is_plt
)
4191 && !dyn_i
->pltoff_done
)
4193 bfd_vma gp
= _bfd_get_gp_value (abfd
);
4195 /* Fill in the function descriptor. */
4196 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
4197 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
4199 /* Install dynamic relocations if needed. */
4203 || ELF_ST_VISIBILITY (dyn_i
->h
->other
) == STV_DEFAULT
4204 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
))
4206 unsigned int dyn_r_type
;
4208 if (bfd_big_endian (abfd
))
4209 dyn_r_type
= R_IA64_RELNNMSB
;
4211 dyn_r_type
= R_IA64_RELNNLSB
;
4213 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
4214 ia64_info
->rel_pltoff_sec
,
4215 dyn_i
->pltoff_offset
,
4216 dyn_r_type
, 0, value
);
4217 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
4218 ia64_info
->rel_pltoff_sec
,
4219 dyn_i
->pltoff_offset
+ ARCH_SIZE
/ 8,
4223 dyn_i
->pltoff_done
= 1;
4226 /* Return the descriptor's address. */
4227 value
= (pltoff_sec
->output_section
->vma
4228 + pltoff_sec
->output_offset
4229 + dyn_i
->pltoff_offset
);
4234 /* Return the base VMA address which should be subtracted from real addresses
4235 when resolving @tprel() relocation.
4236 Main program TLS (whose template starts at PT_TLS p_vaddr)
4237 is assigned offset round(2 * size of pointer, PT_TLS p_align). */
4240 elfNN_ia64_tprel_base (struct bfd_link_info
*info
)
4242 asection
*tls_sec
= elf_hash_table (info
)->tls_sec
;
4243 return tls_sec
->vma
- align_power ((bfd_vma
) ARCH_SIZE
/ 4,
4244 tls_sec
->alignment_power
);
4247 /* Return the base VMA address which should be subtracted from real addresses
4248 when resolving @dtprel() relocation.
4249 This is PT_TLS segment p_vaddr. */
4252 elfNN_ia64_dtprel_base (struct bfd_link_info
*info
)
4254 return elf_hash_table (info
)->tls_sec
->vma
;
4257 /* Called through qsort to sort the .IA_64.unwind section during a
4258 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
4259 to the output bfd so we can do proper endianness frobbing. */
4261 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
4264 elfNN_ia64_unwind_entry_compare (const PTR a
, const PTR b
)
4268 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
4269 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
4271 return (av
< bv
? -1 : av
> bv
? 1 : 0);
4274 /* Make sure we've got ourselves a nice fat __gp value. */
4276 elfNN_ia64_choose_gp (bfd
*abfd
, struct bfd_link_info
*info
)
4278 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
4279 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
4280 struct elf_link_hash_entry
*gp
;
4283 struct elfNN_ia64_link_hash_table
*ia64_info
;
4285 ia64_info
= elfNN_ia64_hash_table (info
);
4287 /* Find the min and max vma of all sections marked short. Also collect
4288 min and max vma of any type, for use in selecting a nice gp. */
4289 for (os
= abfd
->sections
; os
; os
= os
->next
)
4293 if ((os
->flags
& SEC_ALLOC
) == 0)
4297 hi
= os
->vma
+ (os
->rawsize
? os
->rawsize
: os
->size
);
4305 if (os
->flags
& SEC_SMALL_DATA
)
4307 if (min_short_vma
> lo
)
4309 if (max_short_vma
< hi
)
4314 if (ia64_info
->min_short_sec
)
4317 > (ia64_info
->min_short_sec
->vma
4318 + ia64_info
->min_short_offset
))
4319 min_short_vma
= (ia64_info
->min_short_sec
->vma
4320 + ia64_info
->min_short_offset
);
4322 < (ia64_info
->max_short_sec
->vma
4323 + ia64_info
->max_short_offset
))
4324 max_short_vma
= (ia64_info
->max_short_sec
->vma
4325 + ia64_info
->max_short_offset
);
4328 /* See if the user wants to force a value. */
4329 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
4333 && (gp
->root
.type
== bfd_link_hash_defined
4334 || gp
->root
.type
== bfd_link_hash_defweak
))
4336 asection
*gp_sec
= gp
->root
.u
.def
.section
;
4337 gp_val
= (gp
->root
.u
.def
.value
4338 + gp_sec
->output_section
->vma
4339 + gp_sec
->output_offset
);
4343 /* Pick a sensible value. */
4345 if (ia64_info
->min_short_sec
)
4347 bfd_vma short_range
= max_short_vma
- min_short_vma
;
4349 /* If min_short_sec is set, pick one in the middle bewteen
4350 min_short_vma and max_short_vma. */
4351 if (short_range
>= 0x400000)
4353 gp_val
= min_short_vma
+ short_range
/ 2;
4357 asection
*got_sec
= ia64_info
->root
.sgot
;
4359 /* Start with just the address of the .got. */
4361 gp_val
= got_sec
->output_section
->vma
;
4362 else if (max_short_vma
!= 0)
4363 gp_val
= min_short_vma
;
4364 else if (max_vma
- min_vma
< 0x200000)
4367 gp_val
= max_vma
- 0x200000 + 8;
4370 /* If it is possible to address the entire image, but we
4371 don't with the choice above, adjust. */
4372 if (max_vma
- min_vma
< 0x400000
4373 && (max_vma
- gp_val
>= 0x200000
4374 || gp_val
- min_vma
> 0x200000))
4375 gp_val
= min_vma
+ 0x200000;
4376 else if (max_short_vma
!= 0)
4378 /* If we don't cover all the short data, adjust. */
4379 if (max_short_vma
- gp_val
>= 0x200000)
4380 gp_val
= min_short_vma
+ 0x200000;
4382 /* If we're addressing stuff past the end, adjust back. */
4383 if (gp_val
> max_vma
)
4384 gp_val
= max_vma
- 0x200000 + 8;
4388 /* Validate whether all SHF_IA_64_SHORT sections are within
4389 range of the chosen GP. */
4391 if (max_short_vma
!= 0)
4393 if (max_short_vma
- min_short_vma
>= 0x400000)
4396 (*_bfd_error_handler
)
4397 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
4398 bfd_get_filename (abfd
),
4399 (unsigned long) (max_short_vma
- min_short_vma
));
4402 else if ((gp_val
> min_short_vma
4403 && gp_val
- min_short_vma
> 0x200000)
4404 || (gp_val
< max_short_vma
4405 && max_short_vma
- gp_val
>= 0x200000))
4407 (*_bfd_error_handler
)
4408 (_("%s: __gp does not cover short data segment"),
4409 bfd_get_filename (abfd
));
4414 _bfd_set_gp_value (abfd
, gp_val
);
4420 elfNN_ia64_final_link (bfd
*abfd
, struct bfd_link_info
*info
)
4422 struct elfNN_ia64_link_hash_table
*ia64_info
;
4423 asection
*unwind_output_sec
;
4425 ia64_info
= elfNN_ia64_hash_table (info
);
4427 /* Make sure we've got ourselves a nice fat __gp value. */
4428 if (!info
->relocatable
)
4431 struct elf_link_hash_entry
*gp
;
4433 /* We assume after gp is set, section size will only decrease. We
4434 need to adjust gp for it. */
4435 _bfd_set_gp_value (abfd
, 0);
4436 if (! elfNN_ia64_choose_gp (abfd
, info
))
4438 gp_val
= _bfd_get_gp_value (abfd
);
4440 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
4444 gp
->root
.type
= bfd_link_hash_defined
;
4445 gp
->root
.u
.def
.value
= gp_val
;
4446 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
4450 /* If we're producing a final executable, we need to sort the contents
4451 of the .IA_64.unwind section. Force this section to be relocated
4452 into memory rather than written immediately to the output file. */
4453 unwind_output_sec
= NULL
;
4454 if (!info
->relocatable
)
4456 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
4459 unwind_output_sec
= s
->output_section
;
4460 unwind_output_sec
->contents
4461 = bfd_malloc (unwind_output_sec
->size
);
4462 if (unwind_output_sec
->contents
== NULL
)
4467 /* Invoke the regular ELF backend linker to do all the work. */
4468 if (!bfd_elf_final_link (abfd
, info
))
4471 if (unwind_output_sec
)
4473 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
4474 qsort (unwind_output_sec
->contents
,
4475 (size_t) (unwind_output_sec
->size
/ 24),
4477 elfNN_ia64_unwind_entry_compare
);
4479 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
4480 unwind_output_sec
->contents
, (bfd_vma
) 0,
4481 unwind_output_sec
->size
))
4489 elfNN_ia64_relocate_section (bfd
*output_bfd
,
4490 struct bfd_link_info
*info
,
4492 asection
*input_section
,
4494 Elf_Internal_Rela
*relocs
,
4495 Elf_Internal_Sym
*local_syms
,
4496 asection
**local_sections
)
4498 struct elfNN_ia64_link_hash_table
*ia64_info
;
4499 Elf_Internal_Shdr
*symtab_hdr
;
4500 Elf_Internal_Rela
*rel
;
4501 Elf_Internal_Rela
*relend
;
4503 bfd_boolean ret_val
= TRUE
; /* for non-fatal errors */
4506 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
4507 ia64_info
= elfNN_ia64_hash_table (info
);
4509 /* Infect various flags from the input section to the output section. */
4510 if (info
->relocatable
)
4514 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
4515 flags
&= SHF_IA_64_NORECOV
;
4517 elf_section_data(input_section
->output_section
)
4518 ->this_hdr
.sh_flags
|= flags
;
4521 gp_val
= _bfd_get_gp_value (output_bfd
);
4522 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, FALSE
);
4525 relend
= relocs
+ input_section
->reloc_count
;
4526 for (; rel
< relend
; ++rel
)
4528 struct elf_link_hash_entry
*h
;
4529 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4530 bfd_reloc_status_type r
;
4531 reloc_howto_type
*howto
;
4532 unsigned long r_symndx
;
4533 Elf_Internal_Sym
*sym
;
4534 unsigned int r_type
;
4538 bfd_boolean dynamic_symbol_p
;
4539 bfd_boolean undef_weak_ref
;
4541 r_type
= ELFNN_R_TYPE (rel
->r_info
);
4542 if (r_type
> R_IA64_MAX_RELOC_CODE
)
4544 (*_bfd_error_handler
)
4545 (_("%B: unknown relocation type %d"),
4546 input_bfd
, (int) r_type
);
4547 bfd_set_error (bfd_error_bad_value
);
4552 howto
= lookup_howto (r_type
);
4553 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4557 undef_weak_ref
= FALSE
;
4559 if (r_symndx
< symtab_hdr
->sh_info
)
4561 /* Reloc against local symbol. */
4563 sym
= local_syms
+ r_symndx
;
4564 sym_sec
= local_sections
[r_symndx
];
4566 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &msec
, rel
);
4567 if (!info
->relocatable
4568 && (sym_sec
->flags
& SEC_MERGE
) != 0
4569 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
4570 && sym_sec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
4572 struct elfNN_ia64_local_hash_entry
*loc_h
;
4574 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, FALSE
);
4575 if (loc_h
&& ! loc_h
->sec_merge_done
)
4577 struct elfNN_ia64_dyn_sym_info
*dynent
;
4580 for (count
= loc_h
->count
, dynent
= loc_h
->info
;
4586 _bfd_merged_section_offset (output_bfd
, &msec
,
4587 elf_section_data (msec
)->
4591 dynent
->addend
-= sym
->st_value
;
4592 dynent
->addend
+= msec
->output_section
->vma
4593 + msec
->output_offset
4594 - sym_sec
->output_section
->vma
4595 - sym_sec
->output_offset
;
4598 /* We may have introduced duplicated entries. We need
4599 to remove them properly. */
4600 count
= sort_dyn_sym_info (loc_h
->info
, loc_h
->count
);
4601 if (count
!= loc_h
->count
)
4603 loc_h
->count
= count
;
4604 loc_h
->sorted_count
= count
;
4607 loc_h
->sec_merge_done
= 1;
4613 bfd_boolean unresolved_reloc
;
4615 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
4617 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
4618 r_symndx
, symtab_hdr
, sym_hashes
,
4620 unresolved_reloc
, warned
);
4622 if (h
->root
.type
== bfd_link_hash_undefweak
)
4623 undef_weak_ref
= TRUE
;
4628 /* For relocs against symbols from removed linkonce sections,
4629 or sections discarded by a linker script, we just want the
4630 section contents zeroed. Avoid any special processing. */
4631 if (sym_sec
!= NULL
&& elf_discarded_section (sym_sec
))
4633 _bfd_clear_contents (howto
, input_bfd
, contents
+ rel
->r_offset
);
4639 if (info
->relocatable
)
4642 hit_addr
= contents
+ rel
->r_offset
;
4643 value
+= rel
->r_addend
;
4644 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
, r_type
);
4655 case R_IA64_DIR32MSB
:
4656 case R_IA64_DIR32LSB
:
4657 case R_IA64_DIR64MSB
:
4658 case R_IA64_DIR64LSB
:
4659 /* Install a dynamic relocation for this reloc. */
4660 if ((dynamic_symbol_p
|| info
->shared
)
4662 && (input_section
->flags
& SEC_ALLOC
) != 0)
4664 unsigned int dyn_r_type
;
4668 BFD_ASSERT (srel
!= NULL
);
4675 /* ??? People shouldn't be doing non-pic code in
4676 shared libraries nor dynamic executables. */
4677 (*_bfd_error_handler
)
4678 (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4680 h
? h
->root
.root
.string
4681 : bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4690 /* If we don't need dynamic symbol lookup, find a
4691 matching RELATIVE relocation. */
4692 dyn_r_type
= r_type
;
4693 if (dynamic_symbol_p
)
4695 dynindx
= h
->dynindx
;
4696 addend
= rel
->r_addend
;
4703 case R_IA64_DIR32MSB
:
4704 dyn_r_type
= R_IA64_REL32MSB
;
4706 case R_IA64_DIR32LSB
:
4707 dyn_r_type
= R_IA64_REL32LSB
;
4709 case R_IA64_DIR64MSB
:
4710 dyn_r_type
= R_IA64_REL64MSB
;
4712 case R_IA64_DIR64LSB
:
4713 dyn_r_type
= R_IA64_REL64LSB
;
4723 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4724 srel
, rel
->r_offset
, dyn_r_type
,
4729 case R_IA64_LTV32MSB
:
4730 case R_IA64_LTV32LSB
:
4731 case R_IA64_LTV64MSB
:
4732 case R_IA64_LTV64LSB
:
4733 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4736 case R_IA64_GPREL22
:
4737 case R_IA64_GPREL64I
:
4738 case R_IA64_GPREL32MSB
:
4739 case R_IA64_GPREL32LSB
:
4740 case R_IA64_GPREL64MSB
:
4741 case R_IA64_GPREL64LSB
:
4742 if (dynamic_symbol_p
)
4744 (*_bfd_error_handler
)
4745 (_("%B: @gprel relocation against dynamic symbol %s"),
4747 h
? h
->root
.root
.string
4748 : bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4754 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4757 case R_IA64_LTOFF22
:
4758 case R_IA64_LTOFF22X
:
4759 case R_IA64_LTOFF64I
:
4760 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4761 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
4762 rel
->r_addend
, value
, R_IA64_DIRNNLSB
);
4764 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4767 case R_IA64_PLTOFF22
:
4768 case R_IA64_PLTOFF64I
:
4769 case R_IA64_PLTOFF64MSB
:
4770 case R_IA64_PLTOFF64LSB
:
4771 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4772 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, FALSE
);
4774 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4777 case R_IA64_FPTR64I
:
4778 case R_IA64_FPTR32MSB
:
4779 case R_IA64_FPTR32LSB
:
4780 case R_IA64_FPTR64MSB
:
4781 case R_IA64_FPTR64LSB
:
4782 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4783 if (dyn_i
->want_fptr
)
4785 if (!undef_weak_ref
)
4786 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4788 if (!dyn_i
->want_fptr
|| info
->pie
)
4791 unsigned int dyn_r_type
= r_type
;
4792 bfd_vma addend
= rel
->r_addend
;
4794 /* Otherwise, we expect the dynamic linker to create
4797 if (dyn_i
->want_fptr
)
4799 if (r_type
== R_IA64_FPTR64I
)
4801 /* We can't represent this without a dynamic symbol.
4802 Adjust the relocation to be against an output
4803 section symbol, which are always present in the
4804 dynamic symbol table. */
4805 /* ??? People shouldn't be doing non-pic code in
4806 shared libraries. Hork. */
4807 (*_bfd_error_handler
)
4808 (_("%B: linking non-pic code in a position independent executable"),
4815 dyn_r_type
= r_type
+ R_IA64_RELNNLSB
- R_IA64_FPTRNNLSB
;
4819 if (h
->dynindx
!= -1)
4820 dynindx
= h
->dynindx
;
4822 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4823 (info
, h
->root
.u
.def
.section
->owner
,
4824 global_sym_index (h
)));
4829 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4830 (info
, input_bfd
, (long) r_symndx
));
4834 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4835 srel
, rel
->r_offset
, dyn_r_type
,
4839 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4842 case R_IA64_LTOFF_FPTR22
:
4843 case R_IA64_LTOFF_FPTR64I
:
4844 case R_IA64_LTOFF_FPTR32MSB
:
4845 case R_IA64_LTOFF_FPTR32LSB
:
4846 case R_IA64_LTOFF_FPTR64MSB
:
4847 case R_IA64_LTOFF_FPTR64LSB
:
4851 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4852 if (dyn_i
->want_fptr
)
4854 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1);
4855 if (!undef_weak_ref
)
4856 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4861 /* Otherwise, we expect the dynamic linker to create
4865 if (h
->dynindx
!= -1)
4866 dynindx
= h
->dynindx
;
4868 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4869 (info
, h
->root
.u
.def
.section
->owner
,
4870 global_sym_index (h
)));
4873 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4874 (info
, input_bfd
, (long) r_symndx
));
4878 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
4879 rel
->r_addend
, value
, R_IA64_FPTRNNLSB
);
4881 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4885 case R_IA64_PCREL32MSB
:
4886 case R_IA64_PCREL32LSB
:
4887 case R_IA64_PCREL64MSB
:
4888 case R_IA64_PCREL64LSB
:
4889 /* Install a dynamic relocation for this reloc. */
4890 if (dynamic_symbol_p
&& r_symndx
!= 0)
4892 BFD_ASSERT (srel
!= NULL
);
4894 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4895 srel
, rel
->r_offset
, r_type
,
4896 h
->dynindx
, rel
->r_addend
);
4900 case R_IA64_PCREL21B
:
4901 case R_IA64_PCREL60B
:
4902 /* We should have created a PLT entry for any dynamic symbol. */
4905 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4907 if (dyn_i
&& dyn_i
->want_plt2
)
4909 /* Should have caught this earlier. */
4910 BFD_ASSERT (rel
->r_addend
== 0);
4912 value
= (ia64_info
->root
.splt
->output_section
->vma
4913 + ia64_info
->root
.splt
->output_offset
4914 + dyn_i
->plt2_offset
);
4918 /* Since there's no PLT entry, Validate that this is
4920 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
4922 /* If the symbol is undef_weak, we shouldn't be trying
4923 to call it. There's every chance that we'd wind up
4924 with an out-of-range fixup here. Don't bother setting
4925 any value at all. */
4931 case R_IA64_PCREL21BI
:
4932 case R_IA64_PCREL21F
:
4933 case R_IA64_PCREL21M
:
4934 case R_IA64_PCREL22
:
4935 case R_IA64_PCREL64I
:
4936 /* The PCREL21BI reloc is specifically not intended for use with
4937 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4938 fixup code, and thus probably ought not be dynamic. The
4939 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4940 if (dynamic_symbol_p
)
4944 if (r_type
== R_IA64_PCREL21BI
)
4945 msg
= _("%B: @internal branch to dynamic symbol %s");
4946 else if (r_type
== R_IA64_PCREL21F
|| r_type
== R_IA64_PCREL21M
)
4947 msg
= _("%B: speculation fixup to dynamic symbol %s");
4949 msg
= _("%B: @pcrel relocation against dynamic symbol %s");
4950 (*_bfd_error_handler
) (msg
, input_bfd
,
4951 h
? h
->root
.root
.string
4952 : bfd_elf_sym_name (input_bfd
,
4962 /* Make pc-relative. */
4963 value
-= (input_section
->output_section
->vma
4964 + input_section
->output_offset
4965 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
4966 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4969 case R_IA64_SEGREL32MSB
:
4970 case R_IA64_SEGREL32LSB
:
4971 case R_IA64_SEGREL64MSB
:
4972 case R_IA64_SEGREL64LSB
:
4974 /* Find the segment that contains the output_section. */
4975 Elf_Internal_Phdr
*p
= _bfd_elf_find_segment_containing_section
4976 (output_bfd
, input_section
->output_section
);
4980 r
= bfd_reloc_notsupported
;
4984 /* The VMA of the segment is the vaddr of the associated
4986 if (value
> p
->p_vaddr
)
4987 value
-= p
->p_vaddr
;
4990 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4995 case R_IA64_SECREL32MSB
:
4996 case R_IA64_SECREL32LSB
:
4997 case R_IA64_SECREL64MSB
:
4998 case R_IA64_SECREL64LSB
:
4999 /* Make output-section relative to section where the symbol
5000 is defined. PR 475 */
5002 value
-= sym_sec
->output_section
->vma
;
5003 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5006 case R_IA64_IPLTMSB
:
5007 case R_IA64_IPLTLSB
:
5008 /* Install a dynamic relocation for this reloc. */
5009 if ((dynamic_symbol_p
|| info
->shared
)
5010 && (input_section
->flags
& SEC_ALLOC
) != 0)
5012 BFD_ASSERT (srel
!= NULL
);
5014 /* If we don't need dynamic symbol lookup, install two
5015 RELATIVE relocations. */
5016 if (!dynamic_symbol_p
)
5018 unsigned int dyn_r_type
;
5020 if (r_type
== R_IA64_IPLTMSB
)
5021 dyn_r_type
= R_IA64_REL64MSB
;
5023 dyn_r_type
= R_IA64_REL64LSB
;
5025 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
5027 srel
, rel
->r_offset
,
5028 dyn_r_type
, 0, value
);
5029 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
5031 srel
, rel
->r_offset
+ 8,
5032 dyn_r_type
, 0, gp_val
);
5035 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
5036 srel
, rel
->r_offset
, r_type
,
5037 h
->dynindx
, rel
->r_addend
);
5040 if (r_type
== R_IA64_IPLTMSB
)
5041 r_type
= R_IA64_DIR64MSB
;
5043 r_type
= R_IA64_DIR64LSB
;
5044 elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5045 r
= elfNN_ia64_install_value (hit_addr
+ 8, gp_val
, r_type
);
5048 case R_IA64_TPREL14
:
5049 case R_IA64_TPREL22
:
5050 case R_IA64_TPREL64I
:
5051 if (elf_hash_table (info
)->tls_sec
== NULL
)
5052 goto missing_tls_sec
;
5053 value
-= elfNN_ia64_tprel_base (info
);
5054 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5057 case R_IA64_DTPREL14
:
5058 case R_IA64_DTPREL22
:
5059 case R_IA64_DTPREL64I
:
5060 case R_IA64_DTPREL32LSB
:
5061 case R_IA64_DTPREL32MSB
:
5062 case R_IA64_DTPREL64LSB
:
5063 case R_IA64_DTPREL64MSB
:
5064 if (elf_hash_table (info
)->tls_sec
== NULL
)
5065 goto missing_tls_sec
;
5066 value
-= elfNN_ia64_dtprel_base (info
);
5067 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5070 case R_IA64_LTOFF_TPREL22
:
5071 case R_IA64_LTOFF_DTPMOD22
:
5072 case R_IA64_LTOFF_DTPREL22
:
5075 long dynindx
= h
? h
->dynindx
: -1;
5076 bfd_vma r_addend
= rel
->r_addend
;
5081 case R_IA64_LTOFF_TPREL22
:
5082 if (!dynamic_symbol_p
)
5084 if (elf_hash_table (info
)->tls_sec
== NULL
)
5085 goto missing_tls_sec
;
5087 value
-= elfNN_ia64_tprel_base (info
);
5090 r_addend
+= value
- elfNN_ia64_dtprel_base (info
);
5094 got_r_type
= R_IA64_TPREL64LSB
;
5096 case R_IA64_LTOFF_DTPMOD22
:
5097 if (!dynamic_symbol_p
&& !info
->shared
)
5099 got_r_type
= R_IA64_DTPMOD64LSB
;
5101 case R_IA64_LTOFF_DTPREL22
:
5102 if (!dynamic_symbol_p
)
5104 if (elf_hash_table (info
)->tls_sec
== NULL
)
5105 goto missing_tls_sec
;
5106 value
-= elfNN_ia64_dtprel_base (info
);
5108 got_r_type
= R_IA64_DTPRELNNLSB
;
5111 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
5112 value
= set_got_entry (input_bfd
, info
, dyn_i
, dynindx
, r_addend
,
5115 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5120 r
= bfd_reloc_notsupported
;
5129 case bfd_reloc_undefined
:
5130 /* This can happen for global table relative relocs if
5131 __gp is undefined. This is a panic situation so we
5132 don't try to continue. */
5133 (*info
->callbacks
->undefined_symbol
)
5134 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
5137 case bfd_reloc_notsupported
:
5142 name
= h
->root
.root
.string
;
5144 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
5146 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
5148 input_section
, rel
->r_offset
))
5154 case bfd_reloc_dangerous
:
5155 case bfd_reloc_outofrange
:
5156 case bfd_reloc_overflow
:
5163 name
= h
->root
.root
.string
;
5165 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
5170 case R_IA64_TPREL14
:
5171 case R_IA64_TPREL22
:
5172 case R_IA64_TPREL64I
:
5173 case R_IA64_DTPREL14
:
5174 case R_IA64_DTPREL22
:
5175 case R_IA64_DTPREL64I
:
5176 case R_IA64_DTPREL32LSB
:
5177 case R_IA64_DTPREL32MSB
:
5178 case R_IA64_DTPREL64LSB
:
5179 case R_IA64_DTPREL64MSB
:
5180 case R_IA64_LTOFF_TPREL22
:
5181 case R_IA64_LTOFF_DTPMOD22
:
5182 case R_IA64_LTOFF_DTPREL22
:
5183 (*_bfd_error_handler
)
5184 (_("%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."),
5185 input_bfd
, input_section
, howto
->name
, name
,
5189 case R_IA64_PCREL21B
:
5190 case R_IA64_PCREL21BI
:
5191 case R_IA64_PCREL21M
:
5192 case R_IA64_PCREL21F
:
5193 if (is_elf_hash_table (info
->hash
))
5195 /* Relaxtion is always performed for ELF output.
5196 Overflow failures for those relocations mean
5197 that the section is too big to relax. */
5198 (*_bfd_error_handler
)
5199 (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
5200 input_bfd
, input_section
, howto
->name
, name
,
5201 rel
->r_offset
, input_section
->size
);
5205 if (!(*info
->callbacks
->reloc_overflow
) (info
,
5227 elfNN_ia64_finish_dynamic_symbol (bfd
*output_bfd
,
5228 struct bfd_link_info
*info
,
5229 struct elf_link_hash_entry
*h
,
5230 Elf_Internal_Sym
*sym
)
5232 struct elfNN_ia64_link_hash_table
*ia64_info
;
5233 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
5235 ia64_info
= elfNN_ia64_hash_table (info
);
5236 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
5238 /* Fill in the PLT data, if required. */
5239 if (dyn_i
&& dyn_i
->want_plt
)
5241 Elf_Internal_Rela outrel
;
5244 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
5246 gp_val
= _bfd_get_gp_value (output_bfd
);
5248 /* Initialize the minimal PLT entry. */
5250 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
5251 plt_sec
= ia64_info
->root
.splt
;
5252 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
5254 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
5255 elfNN_ia64_install_value (loc
, index
, R_IA64_IMM22
);
5256 elfNN_ia64_install_value (loc
+2, -dyn_i
->plt_offset
, R_IA64_PCREL21B
);
5258 plt_addr
= (plt_sec
->output_section
->vma
5259 + plt_sec
->output_offset
5260 + dyn_i
->plt_offset
);
5261 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, TRUE
);
5263 /* Initialize the FULL PLT entry, if needed. */
5264 if (dyn_i
->want_plt2
)
5266 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
5268 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
5269 elfNN_ia64_install_value (loc
, pltoff_addr
- gp_val
, R_IA64_IMM22
);
5271 /* Mark the symbol as undefined, rather than as defined in the
5272 plt section. Leave the value alone. */
5273 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
5274 first place. But perhaps elflink.c did some for us. */
5275 if (!h
->def_regular
)
5276 sym
->st_shndx
= SHN_UNDEF
;
5279 /* Create the dynamic relocation. */
5280 outrel
.r_offset
= pltoff_addr
;
5281 if (bfd_little_endian (output_bfd
))
5282 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
5284 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
5285 outrel
.r_addend
= 0;
5287 /* This is fun. In the .IA_64.pltoff section, we've got entries
5288 that correspond both to real PLT entries, and those that
5289 happened to resolve to local symbols but need to be created
5290 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
5291 relocations for the real PLT should come at the end of the
5292 section, so that they can be indexed by plt entry at runtime.
5294 We emitted all of the relocations for the non-PLT @pltoff
5295 entries during relocate_section. So we can consider the
5296 existing sec->reloc_count to be the base of the array of
5299 loc
= ia64_info
->rel_pltoff_sec
->contents
;
5300 loc
+= ((ia64_info
->rel_pltoff_sec
->reloc_count
+ index
)
5301 * sizeof (ElfNN_External_Rela
));
5302 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
5305 /* Mark some specially defined symbols as absolute. */
5306 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
5307 || h
== ia64_info
->root
.hgot
5308 || h
== ia64_info
->root
.hplt
)
5309 sym
->st_shndx
= SHN_ABS
;
5315 elfNN_ia64_finish_dynamic_sections (bfd
*abfd
,
5316 struct bfd_link_info
*info
)
5318 struct elfNN_ia64_link_hash_table
*ia64_info
;
5321 ia64_info
= elfNN_ia64_hash_table (info
);
5322 dynobj
= ia64_info
->root
.dynobj
;
5324 if (elf_hash_table (info
)->dynamic_sections_created
)
5326 ElfNN_External_Dyn
*dyncon
, *dynconend
;
5327 asection
*sdyn
, *sgotplt
;
5330 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
5331 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
5332 BFD_ASSERT (sdyn
!= NULL
);
5333 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
5334 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
5336 gp_val
= _bfd_get_gp_value (abfd
);
5338 for (; dyncon
< dynconend
; dyncon
++)
5340 Elf_Internal_Dyn dyn
;
5342 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
5347 dyn
.d_un
.d_ptr
= gp_val
;
5351 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
5352 * sizeof (ElfNN_External_Rela
));
5356 /* See the comment above in finish_dynamic_symbol. */
5357 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
5358 + ia64_info
->rel_pltoff_sec
->output_offset
5359 + (ia64_info
->rel_pltoff_sec
->reloc_count
5360 * sizeof (ElfNN_External_Rela
)));
5363 case DT_IA_64_PLT_RESERVE
:
5364 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
5365 + sgotplt
->output_offset
);
5369 /* Do not have RELASZ include JMPREL. This makes things
5370 easier on ld.so. This is not what the rest of BFD set up. */
5371 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
5372 * sizeof (ElfNN_External_Rela
));
5376 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
5379 /* Initialize the PLT0 entry. */
5380 if (ia64_info
->root
.splt
)
5382 bfd_byte
*loc
= ia64_info
->root
.splt
->contents
;
5385 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
5387 pltres
= (sgotplt
->output_section
->vma
5388 + sgotplt
->output_offset
5391 elfNN_ia64_install_value (loc
+1, pltres
, R_IA64_GPREL22
);
5398 /* ELF file flag handling: */
5400 /* Function to keep IA-64 specific file flags. */
5402 elfNN_ia64_set_private_flags (bfd
*abfd
, flagword flags
)
5404 BFD_ASSERT (!elf_flags_init (abfd
)
5405 || elf_elfheader (abfd
)->e_flags
== flags
);
5407 elf_elfheader (abfd
)->e_flags
= flags
;
5408 elf_flags_init (abfd
) = TRUE
;
5412 /* Merge backend specific data from an object file to the output
5413 object file when linking. */
5415 elfNN_ia64_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
5419 bfd_boolean ok
= TRUE
;
5421 /* Don't even pretend to support mixed-format linking. */
5422 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
5423 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
5426 in_flags
= elf_elfheader (ibfd
)->e_flags
;
5427 out_flags
= elf_elfheader (obfd
)->e_flags
;
5429 if (! elf_flags_init (obfd
))
5431 elf_flags_init (obfd
) = TRUE
;
5432 elf_elfheader (obfd
)->e_flags
= in_flags
;
5434 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
5435 && bfd_get_arch_info (obfd
)->the_default
)
5437 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
5438 bfd_get_mach (ibfd
));
5444 /* Check flag compatibility. */
5445 if (in_flags
== out_flags
)
5448 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
5449 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
5450 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
5452 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
5454 (*_bfd_error_handler
)
5455 (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5458 bfd_set_error (bfd_error_bad_value
);
5461 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
5463 (*_bfd_error_handler
)
5464 (_("%B: linking big-endian files with little-endian files"),
5467 bfd_set_error (bfd_error_bad_value
);
5470 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
5472 (*_bfd_error_handler
)
5473 (_("%B: linking 64-bit files with 32-bit files"),
5476 bfd_set_error (bfd_error_bad_value
);
5479 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
5481 (*_bfd_error_handler
)
5482 (_("%B: linking constant-gp files with non-constant-gp files"),
5485 bfd_set_error (bfd_error_bad_value
);
5488 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
5489 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
5491 (*_bfd_error_handler
)
5492 (_("%B: linking auto-pic files with non-auto-pic files"),
5495 bfd_set_error (bfd_error_bad_value
);
5503 elfNN_ia64_print_private_bfd_data (bfd
*abfd
, PTR ptr
)
5505 FILE *file
= (FILE *) ptr
;
5506 flagword flags
= elf_elfheader (abfd
)->e_flags
;
5508 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
5510 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
5511 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
5512 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
5513 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
5514 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
5515 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
5516 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
5517 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
5518 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
5520 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
5524 static enum elf_reloc_type_class
5525 elfNN_ia64_reloc_type_class (const Elf_Internal_Rela
*rela
)
5527 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
5529 case R_IA64_REL32MSB
:
5530 case R_IA64_REL32LSB
:
5531 case R_IA64_REL64MSB
:
5532 case R_IA64_REL64LSB
:
5533 return reloc_class_relative
;
5534 case R_IA64_IPLTMSB
:
5535 case R_IA64_IPLTLSB
:
5536 return reloc_class_plt
;
5538 return reloc_class_copy
;
5540 return reloc_class_normal
;
5544 static const struct bfd_elf_special_section elfNN_ia64_special_sections
[] =
5546 { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_IA_64_SHORT
},
5547 { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_IA_64_SHORT
},
5548 { NULL
, 0, 0, 0, 0 }
5552 elfNN_ia64_object_p (bfd
*abfd
)
5555 asection
*group
, *unwi
, *unw
;
5558 char *unwi_name
, *unw_name
;
5561 if (abfd
->flags
& DYNAMIC
)
5564 /* Flags for fake group section. */
5565 flags
= (SEC_LINKER_CREATED
| SEC_GROUP
| SEC_LINK_ONCE
5568 /* We add a fake section group for each .gnu.linkonce.t.* section,
5569 which isn't in a section group, and its unwind sections. */
5570 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
5572 if (elf_sec_group (sec
) == NULL
5573 && ((sec
->flags
& (SEC_LINK_ONCE
| SEC_CODE
| SEC_GROUP
))
5574 == (SEC_LINK_ONCE
| SEC_CODE
))
5575 && CONST_STRNEQ (sec
->name
, ".gnu.linkonce.t."))
5577 name
= sec
->name
+ 16;
5579 amt
= strlen (name
) + sizeof (".gnu.linkonce.ia64unwi.");
5580 unwi_name
= bfd_alloc (abfd
, amt
);
5584 strcpy (stpcpy (unwi_name
, ".gnu.linkonce.ia64unwi."), name
);
5585 unwi
= bfd_get_section_by_name (abfd
, unwi_name
);
5587 amt
= strlen (name
) + sizeof (".gnu.linkonce.ia64unw.");
5588 unw_name
= bfd_alloc (abfd
, amt
);
5592 strcpy (stpcpy (unw_name
, ".gnu.linkonce.ia64unw."), name
);
5593 unw
= bfd_get_section_by_name (abfd
, unw_name
);
5595 /* We need to create a fake group section for it and its
5597 group
= bfd_make_section_anyway_with_flags (abfd
, name
,
5602 /* Move the fake group section to the beginning. */
5603 bfd_section_list_remove (abfd
, group
);
5604 bfd_section_list_prepend (abfd
, group
);
5606 elf_next_in_group (group
) = sec
;
5608 elf_group_name (sec
) = name
;
5609 elf_next_in_group (sec
) = sec
;
5610 elf_sec_group (sec
) = group
;
5614 elf_group_name (unwi
) = name
;
5615 elf_next_in_group (unwi
) = sec
;
5616 elf_next_in_group (sec
) = unwi
;
5617 elf_sec_group (unwi
) = group
;
5622 elf_group_name (unw
) = name
;
5625 elf_next_in_group (unw
) = elf_next_in_group (unwi
);
5626 elf_next_in_group (unwi
) = unw
;
5630 elf_next_in_group (unw
) = sec
;
5631 elf_next_in_group (sec
) = unw
;
5633 elf_sec_group (unw
) = group
;
5636 /* Fake SHT_GROUP section header. */
5637 elf_section_data (group
)->this_hdr
.bfd_section
= group
;
5638 elf_section_data (group
)->this_hdr
.sh_type
= SHT_GROUP
;
5645 elfNN_ia64_hpux_vec (const bfd_target
*vec
)
5647 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec
;
5648 return (vec
== & bfd_elfNN_ia64_hpux_big_vec
);
5652 elfNN_hpux_post_process_headers (bfd
*abfd
,
5653 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
5655 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
5657 i_ehdrp
->e_ident
[EI_OSABI
] = get_elf_backend_data (abfd
)->elf_osabi
;
5658 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 1;
5662 elfNN_hpux_backend_section_from_bfd_section (bfd
*abfd ATTRIBUTE_UNUSED
,
5663 asection
*sec
, int *retval
)
5665 if (bfd_is_com_section (sec
))
5667 *retval
= SHN_IA_64_ANSI_COMMON
;
5674 elfNN_hpux_backend_symbol_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
5677 elf_symbol_type
*elfsym
= (elf_symbol_type
*) asym
;
5679 switch (elfsym
->internal_elf_sym
.st_shndx
)
5681 case SHN_IA_64_ANSI_COMMON
:
5682 asym
->section
= bfd_com_section_ptr
;
5683 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
5684 asym
->flags
&= ~BSF_GLOBAL
;
5690 elfNN_vms_section_from_shdr (bfd
*abfd
,
5691 Elf_Internal_Shdr
*hdr
,
5697 switch (hdr
->sh_type
)
5699 case SHT_IA_64_VMS_TRACE
:
5700 case SHT_IA_64_VMS_DEBUG
:
5701 case SHT_IA_64_VMS_DEBUG_STR
:
5705 return elfNN_ia64_section_from_shdr (abfd
, hdr
, name
, shindex
);
5708 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
5710 newsect
= hdr
->bfd_section
;
5716 elfNN_vms_object_p (bfd
*abfd
)
5718 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
5719 Elf_Internal_Phdr
*i_phdr
= elf_tdata (abfd
)->phdr
;
5721 unsigned int num_text
= 0;
5722 unsigned int num_data
= 0;
5723 unsigned int num_rodata
= 0;
5726 if (!elfNN_ia64_object_p (abfd
))
5729 for (i
= 0; i
< i_ehdrp
->e_phnum
; i
++, i_phdr
++)
5731 /* Is there a section for this segment? */
5732 bfd_vma base_vma
= i_phdr
->p_vaddr
;
5733 bfd_vma limit_vma
= base_vma
+ i_phdr
->p_filesz
;
5735 if (i_phdr
->p_type
!= PT_LOAD
)
5739 while (base_vma
< limit_vma
)
5741 bfd_vma next_vma
= limit_vma
;
5747 /* Find a section covering base_vma. */
5748 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
5750 if ((sec
->flags
& (SEC_ALLOC
| SEC_LOAD
)) == 0)
5752 if (sec
->vma
<= base_vma
&& sec
->vma
+ sec
->size
> base_vma
)
5754 base_vma
= sec
->vma
+ sec
->size
;
5757 if (sec
->vma
< next_vma
&& sec
->vma
+ sec
->size
>= base_vma
)
5758 next_vma
= sec
->vma
;
5761 /* No section covering [base_vma; next_vma). Create a fake one. */
5762 flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
;
5763 if (i_phdr
->p_flags
& PF_X
)
5766 if (num_text
++ == 0)
5769 sprintf (name
, ".text$%u", num_text
);
5771 else if ((i_phdr
->p_flags
& (PF_R
| PF_W
)) == PF_R
)
5773 flags
|= SEC_READONLY
;
5774 sprintf (name
, ".rodata$%u", num_rodata
++);
5779 sprintf (name
, ".data$%u", num_data
++);
5782 /* Allocate name. */
5785 size_t name_len
= strlen (name
) + 1;
5786 nname
= bfd_alloc (abfd
, name_len
);
5789 memcpy (nname
, name
, name_len
);
5792 /* Create and fill new section. */
5793 nsec
= bfd_make_section_anyway_with_flags (abfd
, nname
, flags
);
5796 nsec
->vma
= base_vma
;
5797 nsec
->size
= next_vma
- base_vma
;
5798 nsec
->filepos
= i_phdr
->p_offset
+ (base_vma
- i_phdr
->p_vaddr
);
5800 base_vma
= next_vma
;
5807 elfNN_vms_post_process_headers (bfd
*abfd
,
5808 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
5810 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
5812 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_OPENVMS
;
5813 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 2;
5817 elfNN_vms_section_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
5818 Elf_Internal_Shdr
*hdr
)
5820 if (hdr
->bfd_section
!= NULL
)
5822 const char *name
= bfd_get_section_name (abfd
, hdr
->bfd_section
);
5824 if (strcmp (name
, ".text") == 0)
5825 hdr
->sh_flags
|= SHF_IA_64_VMS_SHARED
;
5826 else if ((strcmp (name
, ".debug") == 0)
5827 || (strcmp (name
, ".debug_abbrev") == 0)
5828 || (strcmp (name
, ".debug_aranges") == 0)
5829 || (strcmp (name
, ".debug_frame") == 0)
5830 || (strcmp (name
, ".debug_info") == 0)
5831 || (strcmp (name
, ".debug_loc") == 0)
5832 || (strcmp (name
, ".debug_macinfo") == 0)
5833 || (strcmp (name
, ".debug_pubnames") == 0)
5834 || (strcmp (name
, ".debug_pubtypes") == 0))
5835 hdr
->sh_type
= SHT_IA_64_VMS_DEBUG
;
5836 else if ((strcmp (name
, ".debug_line") == 0)
5837 || (strcmp (name
, ".debug_ranges") == 0))
5838 hdr
->sh_type
= SHT_IA_64_VMS_TRACE
;
5839 else if (strcmp (name
, ".debug_str") == 0)
5840 hdr
->sh_type
= SHT_IA_64_VMS_DEBUG_STR
;
5841 else if (strcmp (name
, ".vms_display_name_info") == 0)
5845 struct elf_obj_tdata
*t
= elf_tdata (abfd
);
5847 int demangler_sym_idx
= -1;
5849 symcount
= bfd_get_symcount (abfd
);
5850 syms
= bfd_get_outsymbols (abfd
);
5851 for (idx
= 0; idx
< symcount
; idx
++)
5855 if ((sym
->flags
& (BSF_DEBUGGING
| BSF_DYNAMIC
))
5856 && strchr (sym
->name
, '@')
5857 && (strcmp (sym
->section
->name
, BFD_ABS_SECTION_NAME
) == 0))
5859 demangler_sym_idx
= sym
->udata
.i
;
5864 hdr
->sh_type
= SHT_IA_64_VMS_DISPLAY_NAME_INFO
;
5865 hdr
->sh_entsize
= 4;
5866 hdr
->sh_addralign
= 0;
5867 hdr
->sh_link
= t
->symtab_section
;
5869 /* Find symtab index of demangler routine and stuff it in
5870 the second long word of section data. */
5872 if (demangler_sym_idx
> -1)
5874 bfd_seek (abfd
, hdr
->sh_offset
, SEEK_SET
);
5875 bfd_bread (buf
, hdr
->sh_size
, abfd
);
5876 buf
[1] = demangler_sym_idx
;
5877 bfd_seek (abfd
, hdr
->sh_offset
, SEEK_SET
);
5878 bfd_bwrite (buf
, hdr
->sh_size
, abfd
);
5886 /* The final processing done just before writing out a VMS IA-64 ELF
5890 elfNN_vms_final_write_processing (bfd
*abfd
,
5891 bfd_boolean linker ATTRIBUTE_UNUSED
)
5893 Elf_Internal_Shdr
*hdr
;
5895 int unwind_info_sect_idx
= 0;
5897 for (s
= abfd
->sections
; s
; s
= s
->next
)
5899 hdr
= &elf_section_data (s
)->this_hdr
;
5901 if (strcmp (bfd_get_section_name (abfd
, hdr
->bfd_section
),
5902 ".IA_64.unwind_info") == 0)
5903 unwind_info_sect_idx
= elf_section_data (s
)->this_idx
;
5905 switch (hdr
->sh_type
)
5907 case SHT_IA_64_UNWIND
:
5908 /* VMS requires sh_info to point to the unwind info section. */
5909 hdr
->sh_info
= unwind_info_sect_idx
;
5914 if (! elf_flags_init (abfd
))
5916 unsigned long flags
= 0;
5918 if (abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
)
5919 flags
|= EF_IA_64_BE
;
5920 if (bfd_get_mach (abfd
) == bfd_mach_ia64_elf64
)
5921 flags
|= EF_IA_64_ABI64
;
5923 elf_elfheader(abfd
)->e_flags
= flags
;
5924 elf_flags_init (abfd
) = TRUE
;
5929 elfNN_vms_close_and_cleanup (bfd
*abfd
)
5931 if (bfd_get_format (abfd
) == bfd_object
)
5935 if (elf_shstrtab (abfd
) != NULL
)
5936 _bfd_elf_strtab_free (elf_shstrtab (abfd
));
5938 /* Pad to 8 byte boundary for IPF/VMS. */
5939 isize
= bfd_get_size (abfd
);
5940 if ((irsize
= isize
/8*8) < isize
)
5942 int ishort
= (irsize
+ 8) - isize
;
5943 bfd_seek (abfd
, isize
, SEEK_SET
);
5944 bfd_bwrite (bfd_zmalloc (ishort
), ishort
, abfd
);
5948 return _bfd_generic_close_and_cleanup (abfd
);
5951 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
5952 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
5953 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
5954 #define TARGET_BIG_NAME "elfNN-ia64-big"
5955 #define ELF_ARCH bfd_arch_ia64
5956 #define ELF_MACHINE_CODE EM_IA_64
5957 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
5958 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
5959 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
5960 #define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
5962 #define elf_backend_section_from_shdr \
5963 elfNN_ia64_section_from_shdr
5964 #define elf_backend_section_flags \
5965 elfNN_ia64_section_flags
5966 #define elf_backend_fake_sections \
5967 elfNN_ia64_fake_sections
5968 #define elf_backend_final_write_processing \
5969 elfNN_ia64_final_write_processing
5970 #define elf_backend_add_symbol_hook \
5971 elfNN_ia64_add_symbol_hook
5972 #define elf_backend_additional_program_headers \
5973 elfNN_ia64_additional_program_headers
5974 #define elf_backend_modify_segment_map \
5975 elfNN_ia64_modify_segment_map
5976 #define elf_backend_modify_program_headers \
5977 elfNN_ia64_modify_program_headers
5978 #define elf_info_to_howto \
5979 elfNN_ia64_info_to_howto
5981 #define bfd_elfNN_bfd_reloc_type_lookup \
5982 elfNN_ia64_reloc_type_lookup
5983 #define bfd_elfNN_bfd_reloc_name_lookup \
5984 elfNN_ia64_reloc_name_lookup
5985 #define bfd_elfNN_bfd_is_local_label_name \
5986 elfNN_ia64_is_local_label_name
5987 #define bfd_elfNN_bfd_relax_section \
5988 elfNN_ia64_relax_section
5990 #define elf_backend_object_p \
5993 /* Stuff for the BFD linker: */
5994 #define bfd_elfNN_bfd_link_hash_table_create \
5995 elfNN_ia64_hash_table_create
5996 #define bfd_elfNN_bfd_link_hash_table_free \
5997 elfNN_ia64_hash_table_free
5998 #define elf_backend_create_dynamic_sections \
5999 elfNN_ia64_create_dynamic_sections
6000 #define elf_backend_check_relocs \
6001 elfNN_ia64_check_relocs
6002 #define elf_backend_adjust_dynamic_symbol \
6003 elfNN_ia64_adjust_dynamic_symbol
6004 #define elf_backend_size_dynamic_sections \
6005 elfNN_ia64_size_dynamic_sections
6006 #define elf_backend_omit_section_dynsym \
6007 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
6008 #define elf_backend_relocate_section \
6009 elfNN_ia64_relocate_section
6010 #define elf_backend_finish_dynamic_symbol \
6011 elfNN_ia64_finish_dynamic_symbol
6012 #define elf_backend_finish_dynamic_sections \
6013 elfNN_ia64_finish_dynamic_sections
6014 #define bfd_elfNN_bfd_final_link \
6015 elfNN_ia64_final_link
6017 #define bfd_elfNN_bfd_merge_private_bfd_data \
6018 elfNN_ia64_merge_private_bfd_data
6019 #define bfd_elfNN_bfd_set_private_flags \
6020 elfNN_ia64_set_private_flags
6021 #define bfd_elfNN_bfd_print_private_bfd_data \
6022 elfNN_ia64_print_private_bfd_data
6024 #define elf_backend_plt_readonly 1
6025 #define elf_backend_want_plt_sym 0
6026 #define elf_backend_plt_alignment 5
6027 #define elf_backend_got_header_size 0
6028 #define elf_backend_want_got_plt 1
6029 #define elf_backend_may_use_rel_p 1
6030 #define elf_backend_may_use_rela_p 1
6031 #define elf_backend_default_use_rela_p 1
6032 #define elf_backend_want_dynbss 0
6033 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
6034 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
6035 #define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
6036 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
6037 #define elf_backend_rela_normal 1
6038 #define elf_backend_special_sections elfNN_ia64_special_sections
6039 #define elf_backend_default_execstack 0
6041 /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
6042 SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
6043 We don't want to flood users with so many error messages. We turn
6044 off the warning for now. It will be turned on later when the Intel
6045 compiler is fixed. */
6046 #define elf_backend_link_order_error_handler NULL
6048 #include "elfNN-target.h"
6050 /* HPUX-specific vectors. */
6052 #undef TARGET_LITTLE_SYM
6053 #undef TARGET_LITTLE_NAME
6054 #undef TARGET_BIG_SYM
6055 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
6056 #undef TARGET_BIG_NAME
6057 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
6059 /* These are HP-UX specific functions. */
6061 #undef elf_backend_post_process_headers
6062 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
6064 #undef elf_backend_section_from_bfd_section
6065 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
6067 #undef elf_backend_symbol_processing
6068 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
6070 #undef elf_backend_want_p_paddr_set_to_zero
6071 #define elf_backend_want_p_paddr_set_to_zero 1
6073 #undef ELF_COMMONPAGESIZE
6075 #define ELF_OSABI ELFOSABI_HPUX
6078 #define elfNN_bed elfNN_ia64_hpux_bed
6080 #include "elfNN-target.h"
6082 /* VMS-specific vectors. */
6084 #undef TARGET_LITTLE_SYM
6085 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_vms_vec
6086 #undef TARGET_LITTLE_NAME
6087 #define TARGET_LITTLE_NAME "elfNN-ia64-vms"
6088 #undef TARGET_BIG_SYM
6089 #undef TARGET_BIG_NAME
6091 /* These are VMS specific functions. */
6093 #undef elf_backend_object_p
6094 #define elf_backend_object_p elfNN_vms_object_p
6096 #undef elf_backend_section_from_shdr
6097 #define elf_backend_section_from_shdr elfNN_vms_section_from_shdr
6099 #undef elf_backend_post_process_headers
6100 #define elf_backend_post_process_headers elfNN_vms_post_process_headers
6102 #undef elf_backend_section_processing
6103 #define elf_backend_section_processing elfNN_vms_section_processing
6105 #undef elf_backend_final_write_processing
6106 #define elf_backend_final_write_processing elfNN_vms_final_write_processing
6108 #undef bfd_elfNN_close_and_cleanup
6109 #define bfd_elfNN_close_and_cleanup elfNN_vms_close_and_cleanup
6111 #undef elf_backend_section_from_bfd_section
6113 #undef elf_backend_symbol_processing
6115 #undef elf_backend_want_p_paddr_set_to_zero
6118 #define ELF_OSABI ELFOSABI_OPENVMS
6120 #undef ELF_MAXPAGESIZE
6121 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
6124 #define elfNN_bed elfNN_ia64_vms_bed
6126 #include "elfNN-target.h"