1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 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
*got_sec
; /* the linkage table section (or NULL) */
167 asection
*rel_got_sec
; /* dynamic relocation section for same */
168 asection
*fptr_sec
; /* function descriptor table (or NULL) */
169 asection
*rel_fptr_sec
; /* dynamic relocation section for same */
170 asection
*plt_sec
; /* the primary plt section (or NULL) */
171 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
172 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
174 bfd_size_type minplt_entries
; /* number of minplt entries */
175 unsigned reltext
: 1; /* are there relocs against readonly sections? */
176 unsigned self_dtpmod_done
: 1;/* has self DTPMOD entry been finished? */
177 bfd_vma self_dtpmod_offset
; /* .got offset to self DTPMOD entry */
179 htab_t loc_hash_table
;
180 void *loc_hash_memory
;
183 struct elfNN_ia64_allocate_data
185 struct bfd_link_info
*info
;
187 bfd_boolean only_got
;
190 #define elfNN_ia64_hash_table(p) \
191 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
193 static bfd_reloc_status_type elfNN_ia64_reloc
194 PARAMS ((bfd
*abfd
, arelent
*reloc
, asymbol
*sym
, PTR data
,
195 asection
*input_section
, bfd
*output_bfd
, char **error_message
));
196 static reloc_howto_type
* lookup_howto
197 PARAMS ((unsigned int rtype
));
198 static reloc_howto_type
*elfNN_ia64_reloc_type_lookup
199 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type bfd_code
));
200 static void elfNN_ia64_info_to_howto
201 PARAMS ((bfd
*abfd
, arelent
*bfd_reloc
, Elf_Internal_Rela
*elf_reloc
));
202 static bfd_boolean elfNN_ia64_relax_section
203 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
204 bfd_boolean
*again
));
205 static void elfNN_ia64_relax_ldxmov
206 PARAMS((bfd_byte
*contents
, bfd_vma off
));
207 static bfd_boolean is_unwind_section_name
208 PARAMS ((bfd
*abfd
, const char *));
209 static bfd_boolean elfNN_ia64_section_flags
210 PARAMS ((flagword
*, const Elf_Internal_Shdr
*));
211 static bfd_boolean elfNN_ia64_fake_sections
212 PARAMS ((bfd
*abfd
, Elf_Internal_Shdr
*hdr
, asection
*sec
));
213 static void elfNN_ia64_final_write_processing
214 PARAMS ((bfd
*abfd
, bfd_boolean linker
));
215 static bfd_boolean elfNN_ia64_add_symbol_hook
216 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, Elf_Internal_Sym
*sym
,
217 const char **namep
, flagword
*flagsp
, asection
**secp
,
219 static bfd_boolean elfNN_ia64_is_local_label_name
220 PARAMS ((bfd
*abfd
, const char *name
));
221 static bfd_boolean elfNN_ia64_dynamic_symbol_p
222 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
, int));
223 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
224 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
225 const char *string
));
226 static void elfNN_ia64_hash_copy_indirect
227 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*,
228 struct elf_link_hash_entry
*));
229 static void elfNN_ia64_hash_hide_symbol
230 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*, bfd_boolean
));
231 static hashval_t elfNN_ia64_local_htab_hash
PARAMS ((const void *));
232 static int elfNN_ia64_local_htab_eq
PARAMS ((const void *ptr1
,
234 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
235 PARAMS ((bfd
*abfd
));
236 static void elfNN_ia64_hash_table_free
237 PARAMS ((struct bfd_link_hash_table
*hash
));
238 static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
239 PARAMS ((struct bfd_hash_entry
*, PTR
));
240 static int elfNN_ia64_local_dyn_sym_thunk
241 PARAMS ((void **, PTR
));
242 static void elfNN_ia64_dyn_sym_traverse
243 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
244 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
246 static bfd_boolean elfNN_ia64_create_dynamic_sections
247 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
248 static struct elfNN_ia64_local_hash_entry
* get_local_sym_hash
249 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
250 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
));
251 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
252 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
253 struct elf_link_hash_entry
*h
,
254 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
));
255 static asection
*get_got
256 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
257 struct elfNN_ia64_link_hash_table
*ia64_info
));
258 static asection
*get_fptr
259 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
260 struct elfNN_ia64_link_hash_table
*ia64_info
));
261 static asection
*get_pltoff
262 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
263 struct elfNN_ia64_link_hash_table
*ia64_info
));
264 static asection
*get_reloc_section
265 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
266 asection
*sec
, bfd_boolean create
));
267 static bfd_boolean elfNN_ia64_check_relocs
268 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
269 const Elf_Internal_Rela
*relocs
));
270 static bfd_boolean elfNN_ia64_adjust_dynamic_symbol
271 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
272 static long global_sym_index
273 PARAMS ((struct elf_link_hash_entry
*h
));
274 static bfd_boolean allocate_fptr
275 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
276 static bfd_boolean allocate_global_data_got
277 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
278 static bfd_boolean allocate_global_fptr_got
279 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
280 static bfd_boolean allocate_local_got
281 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
282 static bfd_boolean allocate_pltoff_entries
283 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
284 static bfd_boolean allocate_plt_entries
285 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
286 static bfd_boolean allocate_plt2_entries
287 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
288 static bfd_boolean allocate_dynrel_entries
289 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
290 static bfd_boolean elfNN_ia64_size_dynamic_sections
291 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
292 static bfd_reloc_status_type elfNN_ia64_install_value
293 PARAMS ((bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
294 static void elfNN_ia64_install_dyn_reloc
295 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
296 asection
*srel
, bfd_vma offset
, unsigned int type
,
297 long dynindx
, bfd_vma addend
));
298 static bfd_vma set_got_entry
299 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
300 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
301 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
302 static bfd_vma set_fptr_entry
303 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
304 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
306 static bfd_vma set_pltoff_entry
307 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
308 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
309 bfd_vma value
, bfd_boolean
));
310 static bfd_vma elfNN_ia64_tprel_base
311 PARAMS ((struct bfd_link_info
*info
));
312 static bfd_vma elfNN_ia64_dtprel_base
313 PARAMS ((struct bfd_link_info
*info
));
314 static int elfNN_ia64_unwind_entry_compare
315 PARAMS ((const PTR
, const PTR
));
316 static bfd_boolean elfNN_ia64_choose_gp
317 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
318 static bfd_boolean elfNN_ia64_final_link
319 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
320 static bfd_boolean elfNN_ia64_relocate_section
321 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
322 asection
*input_section
, bfd_byte
*contents
,
323 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
324 asection
**local_sections
));
325 static bfd_boolean elfNN_ia64_finish_dynamic_symbol
326 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
327 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
328 static bfd_boolean elfNN_ia64_finish_dynamic_sections
329 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
330 static bfd_boolean elfNN_ia64_set_private_flags
331 PARAMS ((bfd
*abfd
, flagword flags
));
332 static bfd_boolean elfNN_ia64_merge_private_bfd_data
333 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
334 static bfd_boolean elfNN_ia64_print_private_bfd_data
335 PARAMS ((bfd
*abfd
, PTR ptr
));
336 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
337 PARAMS ((const Elf_Internal_Rela
*));
338 static bfd_boolean elfNN_ia64_hpux_vec
339 PARAMS ((const bfd_target
*vec
));
340 static void elfNN_hpux_post_process_headers
341 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
342 bfd_boolean elfNN_hpux_backend_section_from_bfd_section
343 PARAMS ((bfd
*abfd
, asection
*sec
, int *retval
));
345 /* ia64-specific relocation. */
347 /* Perform a relocation. Not much to do here as all the hard work is
348 done in elfNN_ia64_final_link_relocate. */
349 static bfd_reloc_status_type
350 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
351 output_bfd
, error_message
)
352 bfd
*abfd ATTRIBUTE_UNUSED
;
354 asymbol
*sym ATTRIBUTE_UNUSED
;
355 PTR data ATTRIBUTE_UNUSED
;
356 asection
*input_section
;
358 char **error_message
;
362 reloc
->address
+= input_section
->output_offset
;
366 if (input_section
->flags
& SEC_DEBUGGING
)
367 return bfd_reloc_continue
;
369 *error_message
= "Unsupported call to elfNN_ia64_reloc";
370 return bfd_reloc_notsupported
;
373 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
374 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
375 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
377 /* This table has to be sorted according to increasing number of the
379 static reloc_howto_type ia64_howto_table
[] =
381 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, FALSE
, TRUE
),
383 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, FALSE
, TRUE
),
384 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, FALSE
, TRUE
),
385 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, FALSE
, TRUE
),
386 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, FALSE
, TRUE
),
387 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, FALSE
, TRUE
),
388 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, FALSE
, TRUE
),
389 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, FALSE
, TRUE
),
391 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, FALSE
, TRUE
),
392 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, FALSE
, TRUE
),
393 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, FALSE
, TRUE
),
394 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, FALSE
, TRUE
),
395 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, FALSE
, TRUE
),
396 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, FALSE
, TRUE
),
398 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, FALSE
, TRUE
),
399 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, FALSE
, TRUE
),
401 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, FALSE
, TRUE
),
402 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, FALSE
, TRUE
),
403 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, FALSE
, TRUE
),
404 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, FALSE
, TRUE
),
406 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, FALSE
, TRUE
),
407 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, FALSE
, TRUE
),
408 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, FALSE
, TRUE
),
409 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, FALSE
, TRUE
),
410 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, FALSE
, TRUE
),
412 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, TRUE
, TRUE
),
413 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, TRUE
, TRUE
),
414 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, TRUE
, TRUE
),
415 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, TRUE
, TRUE
),
416 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, TRUE
, TRUE
),
417 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, TRUE
, TRUE
),
418 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, TRUE
, TRUE
),
419 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, TRUE
, TRUE
),
421 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, FALSE
, TRUE
),
422 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, FALSE
, TRUE
),
423 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, FALSE
, TRUE
),
424 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, FALSE
, TRUE
),
425 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, FALSE
, TRUE
),
426 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, FALSE
, TRUE
),
428 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, FALSE
, TRUE
),
429 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, FALSE
, TRUE
),
430 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, FALSE
, TRUE
),
431 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, FALSE
, TRUE
),
433 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, FALSE
, TRUE
),
434 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, FALSE
, TRUE
),
435 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, FALSE
, TRUE
),
436 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, FALSE
, TRUE
),
438 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, FALSE
, TRUE
),
439 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, FALSE
, TRUE
),
440 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, FALSE
, TRUE
),
441 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, FALSE
, TRUE
),
443 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, FALSE
, TRUE
),
444 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, FALSE
, TRUE
),
445 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, FALSE
, TRUE
),
446 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, FALSE
, TRUE
),
448 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, TRUE
, TRUE
),
449 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, TRUE
, TRUE
),
450 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, TRUE
, TRUE
),
452 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, FALSE
, TRUE
),
453 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, FALSE
, TRUE
),
454 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, FALSE
, TRUE
),
455 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, FALSE
, TRUE
),
456 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, FALSE
, TRUE
),
458 IA64_HOWTO (R_IA64_TPREL14
, "TPREL14", 0, FALSE
, FALSE
),
459 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, FALSE
, FALSE
),
460 IA64_HOWTO (R_IA64_TPREL64I
, "TPREL64I", 0, FALSE
, FALSE
),
461 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 4, FALSE
, FALSE
),
462 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 4, FALSE
, FALSE
),
463 IA64_HOWTO (R_IA64_LTOFF_TPREL22
, "LTOFF_TPREL22", 0, FALSE
, FALSE
),
465 IA64_HOWTO (R_IA64_DTPMOD64MSB
, "DTPMOD64MSB", 4, FALSE
, FALSE
),
466 IA64_HOWTO (R_IA64_DTPMOD64LSB
, "DTPMOD64LSB", 4, FALSE
, FALSE
),
467 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22
, "LTOFF_DTPMOD22", 0, FALSE
, FALSE
),
469 IA64_HOWTO (R_IA64_DTPREL14
, "DTPREL14", 0, FALSE
, FALSE
),
470 IA64_HOWTO (R_IA64_DTPREL22
, "DTPREL22", 0, FALSE
, FALSE
),
471 IA64_HOWTO (R_IA64_DTPREL64I
, "DTPREL64I", 0, FALSE
, FALSE
),
472 IA64_HOWTO (R_IA64_DTPREL32MSB
, "DTPREL32MSB", 2, FALSE
, FALSE
),
473 IA64_HOWTO (R_IA64_DTPREL32LSB
, "DTPREL32LSB", 2, FALSE
, FALSE
),
474 IA64_HOWTO (R_IA64_DTPREL64MSB
, "DTPREL64MSB", 4, FALSE
, FALSE
),
475 IA64_HOWTO (R_IA64_DTPREL64LSB
, "DTPREL64LSB", 4, FALSE
, FALSE
),
476 IA64_HOWTO (R_IA64_LTOFF_DTPREL22
, "LTOFF_DTPREL22", 0, FALSE
, FALSE
),
479 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
481 /* Given a BFD reloc type, return the matching HOWTO structure. */
483 static reloc_howto_type
*
487 static int inited
= 0;
494 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
495 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
496 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
499 if (rtype
> R_IA64_MAX_RELOC_CODE
)
501 i
= elf_code_to_howto_index
[rtype
];
502 if (i
>= NELEMS (ia64_howto_table
))
504 return ia64_howto_table
+ i
;
507 static reloc_howto_type
*
508 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
509 bfd
*abfd ATTRIBUTE_UNUSED
;
510 bfd_reloc_code_real_type bfd_code
;
516 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
518 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
519 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
520 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
522 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
523 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
524 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
525 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
527 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
528 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
529 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
530 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
531 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
532 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
534 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
535 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
537 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
538 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
539 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
540 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
541 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
542 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
543 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
544 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
545 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
547 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
548 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
549 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
550 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
551 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
552 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
553 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
554 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
555 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
556 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
557 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
559 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
560 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
561 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
562 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
563 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
564 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
566 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
567 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
568 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
569 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
571 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
572 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
573 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
574 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
576 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
577 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
578 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
579 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
581 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
582 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
583 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
584 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
586 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
587 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
588 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
589 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
590 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
592 case BFD_RELOC_IA64_TPREL14
: rtype
= R_IA64_TPREL14
; break;
593 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
594 case BFD_RELOC_IA64_TPREL64I
: rtype
= R_IA64_TPREL64I
; break;
595 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
596 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
597 case BFD_RELOC_IA64_LTOFF_TPREL22
: rtype
= R_IA64_LTOFF_TPREL22
; break;
599 case BFD_RELOC_IA64_DTPMOD64MSB
: rtype
= R_IA64_DTPMOD64MSB
; break;
600 case BFD_RELOC_IA64_DTPMOD64LSB
: rtype
= R_IA64_DTPMOD64LSB
; break;
601 case BFD_RELOC_IA64_LTOFF_DTPMOD22
: rtype
= R_IA64_LTOFF_DTPMOD22
; break;
603 case BFD_RELOC_IA64_DTPREL14
: rtype
= R_IA64_DTPREL14
; break;
604 case BFD_RELOC_IA64_DTPREL22
: rtype
= R_IA64_DTPREL22
; break;
605 case BFD_RELOC_IA64_DTPREL64I
: rtype
= R_IA64_DTPREL64I
; break;
606 case BFD_RELOC_IA64_DTPREL32MSB
: rtype
= R_IA64_DTPREL32MSB
; break;
607 case BFD_RELOC_IA64_DTPREL32LSB
: rtype
= R_IA64_DTPREL32LSB
; break;
608 case BFD_RELOC_IA64_DTPREL64MSB
: rtype
= R_IA64_DTPREL64MSB
; break;
609 case BFD_RELOC_IA64_DTPREL64LSB
: rtype
= R_IA64_DTPREL64LSB
; break;
610 case BFD_RELOC_IA64_LTOFF_DTPREL22
: rtype
= R_IA64_LTOFF_DTPREL22
; break;
614 return lookup_howto (rtype
);
617 static reloc_howto_type
*
618 elfNN_ia64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
624 i
< sizeof (ia64_howto_table
) / sizeof (ia64_howto_table
[0]);
626 if (ia64_howto_table
[i
].name
!= NULL
627 && strcasecmp (ia64_howto_table
[i
].name
, r_name
) == 0)
628 return &ia64_howto_table
[i
];
633 /* Given a ELF reloc, return the matching HOWTO structure. */
636 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
637 bfd
*abfd ATTRIBUTE_UNUSED
;
639 Elf_Internal_Rela
*elf_reloc
;
642 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
645 #define PLT_HEADER_SIZE (3 * 16)
646 #define PLT_MIN_ENTRY_SIZE (1 * 16)
647 #define PLT_FULL_ENTRY_SIZE (2 * 16)
648 #define PLT_RESERVED_WORDS 3
650 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
652 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
653 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
654 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
655 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
656 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
657 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
658 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
659 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
660 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
663 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
665 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
666 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
667 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
670 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
672 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
673 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
674 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
675 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
676 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
677 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
680 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
682 static const bfd_byte oor_brl
[16] =
684 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
686 0x00, 0x00, 0x00, 0xc0
689 static const bfd_byte oor_ip
[48] =
691 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
692 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
693 0x01, 0x00, 0x00, 0x60,
694 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
695 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
696 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
697 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
698 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
699 0x60, 0x00, 0x80, 0x00 /* br b6;; */
702 static size_t oor_branch_size
= sizeof (oor_brl
);
705 bfd_elfNN_ia64_after_parse (int itanium
)
707 oor_branch_size
= itanium
? sizeof (oor_ip
) : sizeof (oor_brl
);
710 #define BTYPE_SHIFT 6
717 #define OPCODE_SHIFT 37
719 #define OPCODE_BITS (0xfLL << OPCODE_SHIFT)
720 #define X6_BITS (0x3fLL << X6_SHIFT)
721 #define X4_BITS (0xfLL << X4_SHIFT)
722 #define X3_BITS (0x7LL << X3_SHIFT)
723 #define X2_BITS (0x3LL << X2_SHIFT)
724 #define X_BITS (0x1LL << X_SHIFT)
725 #define Y_BITS (0x1LL << Y_SHIFT)
726 #define BTYPE_BITS (0x7LL << BTYPE_SHIFT)
727 #define PREDICATE_BITS (0x3fLL)
729 #define IS_NOP_B(i) \
730 (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
731 #define IS_NOP_F(i) \
732 (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
733 == (0x1LL << X6_SHIFT))
734 #define IS_NOP_I(i) \
735 (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
736 == (0x1LL << X6_SHIFT))
737 #define IS_NOP_M(i) \
738 (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
739 == (0x1LL << X4_SHIFT))
740 #define IS_BR_COND(i) \
741 (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
742 #define IS_BR_CALL(i) \
743 (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
746 elfNN_ia64_relax_br (bfd_byte
*contents
, bfd_vma off
)
748 unsigned int template, mlx
;
749 bfd_vma t0
, t1
, s0
, s1
, s2
, br_code
;
753 hit_addr
= (bfd_byte
*) (contents
+ off
);
754 br_slot
= (long) hit_addr
& 0x3;
756 t0
= bfd_getl64 (hit_addr
+ 0);
757 t1
= bfd_getl64 (hit_addr
+ 8);
759 /* Check if we can turn br into brl. A label is always at the start
760 of the bundle. Even if there are predicates on NOPs, we still
761 perform this optimization. */
762 template = t0
& 0x1e;
763 s0
= (t0
>> 5) & 0x1ffffffffffLL
;
764 s1
= ((t0
>> 46) | (t1
<< 18)) & 0x1ffffffffffLL
;
765 s2
= (t1
>> 23) & 0x1ffffffffffLL
;
769 /* Check if slot 1 and slot 2 are NOPs. Possible template is
770 BBB. We only need to check nop.b. */
771 if (!(IS_NOP_B (s1
) && IS_NOP_B (s2
)))
776 /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
777 For BBB, slot 0 also has to be nop.b. */
778 if (!((template == 0x12 /* MBB */
780 || (template == 0x16 /* BBB */
787 /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
788 MMB and MFB. For BBB, slot 0 also has to be nop.b. */
789 if (!((template == 0x10 /* MIB */
791 || (template == 0x12 /* MBB */
793 || (template == 0x16 /* BBB */
796 || (template == 0x18 /* MMB */
798 || (template == 0x1c /* MFB */
804 /* It should never happen. */
808 /* We can turn br.cond/br.call into brl.cond/brl.call. */
809 if (!(IS_BR_COND (br_code
) || IS_BR_CALL (br_code
)))
812 /* Turn br into brl by setting bit 40. */
813 br_code
|= 0x1LL
<< 40;
815 /* Turn the old bundle into a MLX bundle with the same stop-bit
822 if (template == 0x16)
824 /* For BBB, we need to put nop.m in slot 0. We keep the original
825 predicate only if slot 0 isn't br. */
829 t0
&= PREDICATE_BITS
<< 5;
830 t0
|= 0x1LL
<< (X4_SHIFT
+ 5);
834 /* Keep the original instruction in slot 0. */
835 t0
&= 0x1ffffffffffLL
<< 5;
840 /* Put brl in slot 1. */
843 bfd_putl64 (t0
, hit_addr
);
844 bfd_putl64 (t1
, hit_addr
+ 8);
849 elfNN_ia64_relax_brl (bfd_byte
*contents
, bfd_vma off
)
853 bfd_vma t0
, t1
, i0
, i1
, i2
;
855 hit_addr
= (bfd_byte
*) (contents
+ off
);
856 hit_addr
-= (long) hit_addr
& 0x3;
857 t0
= bfd_getl64 (hit_addr
);
858 t1
= bfd_getl64 (hit_addr
+ 8);
860 /* Keep the instruction in slot 0. */
861 i0
= (t0
>> 5) & 0x1ffffffffffLL
;
862 /* Use nop.b for slot 1. */
864 /* For slot 2, turn brl into br by masking out bit 40. */
865 i2
= (t1
>> 23) & 0x0ffffffffffLL
;
867 /* Turn a MLX bundle into a MBB bundle with the same stop-bit
873 t0
= (i1
<< 46) | (i0
<< 5) | template;
874 t1
= (i2
<< 23) | (i1
>> 18);
876 bfd_putl64 (t0
, hit_addr
);
877 bfd_putl64 (t1
, hit_addr
+ 8);
880 /* Rename some of the generic section flags to better document how they
882 #define skip_relax_pass_0 need_finalize_relax
883 #define skip_relax_pass_1 has_gp_reloc
886 /* These functions do relaxation for IA-64 ELF. */
889 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
892 struct bfd_link_info
*link_info
;
897 struct one_fixup
*next
;
903 Elf_Internal_Shdr
*symtab_hdr
;
904 Elf_Internal_Rela
*internal_relocs
;
905 Elf_Internal_Rela
*irel
, *irelend
;
907 Elf_Internal_Sym
*isymbuf
= NULL
;
908 struct elfNN_ia64_link_hash_table
*ia64_info
;
909 struct one_fixup
*fixups
= NULL
;
910 bfd_boolean changed_contents
= FALSE
;
911 bfd_boolean changed_relocs
= FALSE
;
912 bfd_boolean changed_got
= FALSE
;
913 bfd_boolean skip_relax_pass_0
= TRUE
;
914 bfd_boolean skip_relax_pass_1
= TRUE
;
917 /* Assume we're not going to change any sizes, and we'll only need
921 /* Don't even try to relax for non-ELF outputs. */
922 if (!is_elf_hash_table (link_info
->hash
))
925 /* Nothing to do if there are no relocations or there is no need for
927 if ((sec
->flags
& SEC_RELOC
) == 0
928 || sec
->reloc_count
== 0
929 || (link_info
->relax_pass
== 0 && sec
->skip_relax_pass_0
)
930 || (link_info
->relax_pass
== 1 && sec
->skip_relax_pass_1
))
933 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
935 /* Load the relocations for this section. */
936 internal_relocs
= (_bfd_elf_link_read_relocs
937 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
938 link_info
->keep_memory
));
939 if (internal_relocs
== NULL
)
942 ia64_info
= elfNN_ia64_hash_table (link_info
);
943 irelend
= internal_relocs
+ sec
->reloc_count
;
945 /* Get the section contents. */
946 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
947 contents
= elf_section_data (sec
)->this_hdr
.contents
;
950 if (!bfd_malloc_and_get_section (abfd
, sec
, &contents
))
954 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
956 unsigned long r_type
= ELFNN_R_TYPE (irel
->r_info
);
957 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
961 bfd_boolean is_branch
;
962 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
967 case R_IA64_PCREL21B
:
968 case R_IA64_PCREL21BI
:
969 case R_IA64_PCREL21M
:
970 case R_IA64_PCREL21F
:
971 /* In pass 1, all br relaxations are done. We can skip it. */
972 if (link_info
->relax_pass
== 1)
974 skip_relax_pass_0
= FALSE
;
978 case R_IA64_PCREL60B
:
979 /* We can't optimize brl to br in pass 0 since br relaxations
980 will increase the code size. Defer it to pass 1. */
981 if (link_info
->relax_pass
== 0)
983 skip_relax_pass_1
= FALSE
;
989 case R_IA64_LTOFF22X
:
991 /* We can't relax ldx/mov in pass 0 since br relaxations will
992 increase the code size. Defer it to pass 1. */
993 if (link_info
->relax_pass
== 0)
995 skip_relax_pass_1
= FALSE
;
1005 /* Get the value of the symbol referred to by the reloc. */
1006 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1008 /* A local symbol. */
1009 Elf_Internal_Sym
*isym
;
1011 /* Read this BFD's local symbols. */
1012 if (isymbuf
== NULL
)
1014 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1015 if (isymbuf
== NULL
)
1016 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
1017 symtab_hdr
->sh_info
, 0,
1023 isym
= isymbuf
+ ELFNN_R_SYM (irel
->r_info
);
1024 if (isym
->st_shndx
== SHN_UNDEF
)
1025 continue; /* We can't do anything with undefined symbols. */
1026 else if (isym
->st_shndx
== SHN_ABS
)
1027 tsec
= bfd_abs_section_ptr
;
1028 else if (isym
->st_shndx
== SHN_COMMON
)
1029 tsec
= bfd_com_section_ptr
;
1030 else if (isym
->st_shndx
== SHN_IA_64_ANSI_COMMON
)
1031 tsec
= bfd_com_section_ptr
;
1033 tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1035 toff
= isym
->st_value
;
1036 dyn_i
= get_dyn_sym_info (ia64_info
, NULL
, abfd
, irel
, FALSE
);
1037 symtype
= ELF_ST_TYPE (isym
->st_info
);
1042 struct elf_link_hash_entry
*h
;
1044 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
1045 h
= elf_sym_hashes (abfd
)[indx
];
1046 BFD_ASSERT (h
!= NULL
);
1048 while (h
->root
.type
== bfd_link_hash_indirect
1049 || h
->root
.type
== bfd_link_hash_warning
)
1050 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1052 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, FALSE
);
1054 /* For branches to dynamic symbols, we're interested instead
1055 in a branch to the PLT entry. */
1056 if (is_branch
&& dyn_i
&& dyn_i
->want_plt2
)
1058 /* Internal branches shouldn't be sent to the PLT.
1059 Leave this for now and we'll give an error later. */
1060 if (r_type
!= R_IA64_PCREL21B
)
1063 tsec
= ia64_info
->plt_sec
;
1064 toff
= dyn_i
->plt2_offset
;
1065 BFD_ASSERT (irel
->r_addend
== 0);
1068 /* Can't do anything else with dynamic symbols. */
1069 else if (elfNN_ia64_dynamic_symbol_p (h
, link_info
, r_type
))
1074 /* We can't do anything with undefined symbols. */
1075 if (h
->root
.type
== bfd_link_hash_undefined
1076 || h
->root
.type
== bfd_link_hash_undefweak
)
1079 tsec
= h
->root
.u
.def
.section
;
1080 toff
= h
->root
.u
.def
.value
;
1086 if (tsec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
1088 /* At this stage in linking, no SEC_MERGE symbol has been
1089 adjusted, so all references to such symbols need to be
1090 passed through _bfd_merged_section_offset. (Later, in
1091 relocate_section, all SEC_MERGE symbols *except* for
1092 section symbols have been adjusted.)
1094 gas may reduce relocations against symbols in SEC_MERGE
1095 sections to a relocation against the section symbol when
1096 the original addend was zero. When the reloc is against
1097 a section symbol we should include the addend in the
1098 offset passed to _bfd_merged_section_offset, since the
1099 location of interest is the original symbol. On the
1100 other hand, an access to "sym+addend" where "sym" is not
1101 a section symbol should not include the addend; Such an
1102 access is presumed to be an offset from "sym"; The
1103 location of interest is just "sym". */
1104 if (symtype
== STT_SECTION
)
1105 toff
+= irel
->r_addend
;
1107 toff
= _bfd_merged_section_offset (abfd
, &tsec
,
1108 elf_section_data (tsec
)->sec_info
,
1111 if (symtype
!= STT_SECTION
)
1112 toff
+= irel
->r_addend
;
1115 toff
+= irel
->r_addend
;
1117 symaddr
= tsec
->output_section
->vma
+ tsec
->output_offset
+ toff
;
1119 roff
= irel
->r_offset
;
1123 bfd_signed_vma offset
;
1125 reladdr
= (sec
->output_section
->vma
1126 + sec
->output_offset
1127 + roff
) & (bfd_vma
) -4;
1129 /* If the branch is in range, no need to do anything. */
1130 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
1131 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
1133 /* If the 60-bit branch is in 21-bit range, optimize it. */
1134 if (r_type
== R_IA64_PCREL60B
)
1136 elfNN_ia64_relax_brl (contents
, roff
);
1139 = ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1142 /* If the original relocation offset points to slot
1143 1, change it to slot 2. */
1144 if ((irel
->r_offset
& 3) == 1)
1145 irel
->r_offset
+= 1;
1150 else if (r_type
== R_IA64_PCREL60B
)
1152 else if (elfNN_ia64_relax_br (contents
, roff
))
1155 = ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1158 /* Make the relocation offset point to slot 1. */
1159 irel
->r_offset
= (irel
->r_offset
& ~((bfd_vma
) 0x3)) + 1;
1163 /* We can't put a trampoline in a .init/.fini section. Issue
1165 if (strcmp (sec
->output_section
->name
, ".init") == 0
1166 || strcmp (sec
->output_section
->name
, ".fini") == 0)
1168 (*_bfd_error_handler
)
1169 (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
1170 sec
->owner
, sec
, (unsigned long) roff
);
1171 bfd_set_error (bfd_error_bad_value
);
1175 /* If the branch and target are in the same section, you've
1176 got one honking big section and we can't help you unless
1177 you are branching backwards. You'll get an error message
1179 if (tsec
== sec
&& toff
> roff
)
1182 /* Look for an existing fixup to this address. */
1183 for (f
= fixups
; f
; f
= f
->next
)
1184 if (f
->tsec
== tsec
&& f
->toff
== toff
)
1189 /* Two alternatives: If it's a branch to a PLT entry, we can
1190 make a copy of the FULL_PLT entry. Otherwise, we'll have
1191 to use a `brl' insn to get where we're going. */
1195 if (tsec
== ia64_info
->plt_sec
)
1196 size
= sizeof (plt_full_entry
);
1198 size
= oor_branch_size
;
1200 /* Resize the current section to make room for the new branch. */
1201 trampoff
= (sec
->size
+ 15) & (bfd_vma
) -16;
1203 /* If trampoline is out of range, there is nothing we
1205 offset
= trampoff
- (roff
& (bfd_vma
) -4);
1206 if (offset
< -0x1000000 || offset
> 0x0FFFFF0)
1209 amt
= trampoff
+ size
;
1210 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
1211 if (contents
== NULL
)
1215 if (tsec
== ia64_info
->plt_sec
)
1217 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
1219 /* Hijack the old relocation for use as the PLTOFF reloc. */
1220 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1222 irel
->r_offset
= trampoff
;
1226 if (size
== sizeof (oor_ip
))
1228 memcpy (contents
+ trampoff
, oor_ip
, size
);
1229 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1231 irel
->r_addend
-= 16;
1232 irel
->r_offset
= trampoff
+ 2;
1236 memcpy (contents
+ trampoff
, oor_brl
, size
);
1237 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1239 irel
->r_offset
= trampoff
+ 2;
1244 /* Record the fixup so we don't do it again this section. */
1245 f
= (struct one_fixup
*)
1246 bfd_malloc ((bfd_size_type
) sizeof (*f
));
1250 f
->trampoff
= trampoff
;
1255 /* If trampoline is out of range, there is nothing we
1257 offset
= f
->trampoff
- (roff
& (bfd_vma
) -4);
1258 if (offset
< -0x1000000 || offset
> 0x0FFFFF0)
1261 /* Nop out the reloc, since we're finalizing things here. */
1262 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
1265 /* Fix up the existing branch to hit the trampoline. */
1266 if (elfNN_ia64_install_value (contents
+ roff
, offset
, r_type
)
1270 changed_contents
= TRUE
;
1271 changed_relocs
= TRUE
;
1278 bfd
*obfd
= sec
->output_section
->owner
;
1279 gp
= _bfd_get_gp_value (obfd
);
1282 if (!elfNN_ia64_choose_gp (obfd
, link_info
))
1284 gp
= _bfd_get_gp_value (obfd
);
1288 /* If the data is out of range, do nothing. */
1289 if ((bfd_signed_vma
) (symaddr
- gp
) >= 0x200000
1290 ||(bfd_signed_vma
) (symaddr
- gp
) < -0x200000)
1293 if (r_type
== R_IA64_LTOFF22X
)
1295 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1297 changed_relocs
= TRUE
;
1298 if (dyn_i
->want_gotx
)
1300 dyn_i
->want_gotx
= 0;
1301 changed_got
|= !dyn_i
->want_got
;
1306 elfNN_ia64_relax_ldxmov (contents
, roff
);
1307 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
1308 changed_contents
= TRUE
;
1309 changed_relocs
= TRUE
;
1314 /* ??? If we created fixups, this may push the code segment large
1315 enough that the data segment moves, which will change the GP.
1316 Reset the GP so that we re-calculate next round. We need to
1317 do this at the _beginning_ of the next round; now will not do. */
1319 /* Clean up and go home. */
1322 struct one_fixup
*f
= fixups
;
1323 fixups
= fixups
->next
;
1328 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1330 if (! link_info
->keep_memory
)
1334 /* Cache the symbols for elf_link_input_bfd. */
1335 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1339 if (contents
!= NULL
1340 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1342 if (!changed_contents
&& !link_info
->keep_memory
)
1346 /* Cache the section contents for elf_link_input_bfd. */
1347 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1351 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
1353 if (!changed_relocs
)
1354 free (internal_relocs
);
1356 elf_section_data (sec
)->relocs
= internal_relocs
;
1361 struct elfNN_ia64_allocate_data data
;
1362 data
.info
= link_info
;
1364 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
1366 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
1367 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
1368 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
1369 ia64_info
->got_sec
->size
= data
.ofs
;
1371 if (ia64_info
->root
.dynamic_sections_created
1372 && ia64_info
->rel_got_sec
!= NULL
)
1374 /* Resize .rela.got. */
1375 ia64_info
->rel_got_sec
->size
= 0;
1376 if (link_info
->shared
1377 && ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
1378 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
1379 data
.only_got
= TRUE
;
1380 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
,
1385 if (link_info
->relax_pass
== 0)
1387 /* Pass 0 is only needed to relax br. */
1388 sec
->skip_relax_pass_0
= skip_relax_pass_0
;
1389 sec
->skip_relax_pass_1
= skip_relax_pass_1
;
1392 *again
= changed_contents
|| changed_relocs
;
1396 if (isymbuf
!= NULL
&& (unsigned char *) isymbuf
!= symtab_hdr
->contents
)
1398 if (contents
!= NULL
1399 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1401 if (internal_relocs
!= NULL
1402 && elf_section_data (sec
)->relocs
!= internal_relocs
)
1403 free (internal_relocs
);
1406 #undef skip_relax_pass_0
1407 #undef skip_relax_pass_1
1410 elfNN_ia64_relax_ldxmov (contents
, off
)
1415 bfd_vma dword
, insn
;
1417 switch ((int)off
& 0x3)
1419 case 0: shift
= 5; break;
1420 case 1: shift
= 14; off
+= 3; break;
1421 case 2: shift
= 23; off
+= 6; break;
1426 dword
= bfd_getl64 (contents
+ off
);
1427 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
1429 r1
= (insn
>> 6) & 127;
1430 r3
= (insn
>> 20) & 127;
1432 insn
= 0x8000000; /* nop */
1434 insn
= (insn
& 0x7f01fff) | 0x10800000000LL
; /* (qp) mov r1 = r3 */
1436 dword
&= ~(0x1ffffffffffLL
<< shift
);
1437 dword
|= (insn
<< shift
);
1438 bfd_putl64 (dword
, contents
+ off
);
1441 /* Return TRUE if NAME is an unwind table section name. */
1443 static inline bfd_boolean
1444 is_unwind_section_name (bfd
*abfd
, const char *name
)
1446 if (elfNN_ia64_hpux_vec (abfd
->xvec
)
1447 && !strcmp (name
, ELF_STRING_ia64_unwind_hdr
))
1450 return ((CONST_STRNEQ (name
, ELF_STRING_ia64_unwind
)
1451 && ! CONST_STRNEQ (name
, ELF_STRING_ia64_unwind_info
))
1452 || CONST_STRNEQ (name
, ELF_STRING_ia64_unwind_once
));
1455 /* Handle an IA-64 specific section when reading an object file. This
1456 is called when bfd_section_from_shdr finds a section with an unknown
1460 elfNN_ia64_section_from_shdr (bfd
*abfd
,
1461 Elf_Internal_Shdr
*hdr
,
1467 /* There ought to be a place to keep ELF backend specific flags, but
1468 at the moment there isn't one. We just keep track of the
1469 sections by their name, instead. Fortunately, the ABI gives
1470 suggested names for all the MIPS specific sections, so we will
1471 probably get away with this. */
1472 switch (hdr
->sh_type
)
1474 case SHT_IA_64_UNWIND
:
1475 case SHT_IA_64_HP_OPT_ANOT
:
1479 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1487 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
1489 newsect
= hdr
->bfd_section
;
1494 /* Convert IA-64 specific section flags to bfd internal section flags. */
1496 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1500 elfNN_ia64_section_flags (flags
, hdr
)
1502 const Elf_Internal_Shdr
*hdr
;
1504 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1505 *flags
|= SEC_SMALL_DATA
;
1510 /* Set the correct type for an IA-64 ELF section. We do this by the
1511 section name, which is a hack, but ought to work. */
1514 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1515 bfd
*abfd ATTRIBUTE_UNUSED
;
1516 Elf_Internal_Shdr
*hdr
;
1519 register const char *name
;
1521 name
= bfd_get_section_name (abfd
, sec
);
1523 if (is_unwind_section_name (abfd
, name
))
1525 /* We don't have the sections numbered at this point, so sh_info
1526 is set later, in elfNN_ia64_final_write_processing. */
1527 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1528 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1530 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1531 hdr
->sh_type
= SHT_IA_64_EXT
;
1532 else if (strcmp (name
, ".HP.opt_annot") == 0)
1533 hdr
->sh_type
= SHT_IA_64_HP_OPT_ANOT
;
1534 else if (strcmp (name
, ".reloc") == 0)
1535 /* This is an ugly, but unfortunately necessary hack that is
1536 needed when producing EFI binaries on IA-64. It tells
1537 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1538 containing ELF relocation info. We need this hack in order to
1539 be able to generate ELF binaries that can be translated into
1540 EFI applications (which are essentially COFF objects). Those
1541 files contain a COFF ".reloc" section inside an ELFNN object,
1542 which would normally cause BFD to segfault because it would
1543 attempt to interpret this section as containing relocation
1544 entries for section "oc". With this hack enabled, ".reloc"
1545 will be treated as a normal data section, which will avoid the
1546 segfault. However, you won't be able to create an ELFNN binary
1547 with a section named "oc" that needs relocations, but that's
1548 the kind of ugly side-effects you get when detecting section
1549 types based on their names... In practice, this limitation is
1550 unlikely to bite. */
1551 hdr
->sh_type
= SHT_PROGBITS
;
1553 if (sec
->flags
& SEC_SMALL_DATA
)
1554 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1556 /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
1558 if (elfNN_ia64_hpux_vec (abfd
->xvec
) && (sec
->flags
& SHF_TLS
))
1559 hdr
->sh_flags
|= SHF_IA_64_HP_TLS
;
1564 /* The final processing done just before writing out an IA-64 ELF
1568 elfNN_ia64_final_write_processing (abfd
, linker
)
1570 bfd_boolean linker ATTRIBUTE_UNUSED
;
1572 Elf_Internal_Shdr
*hdr
;
1575 for (s
= abfd
->sections
; s
; s
= s
->next
)
1577 hdr
= &elf_section_data (s
)->this_hdr
;
1578 switch (hdr
->sh_type
)
1580 case SHT_IA_64_UNWIND
:
1581 /* The IA-64 processor-specific ABI requires setting sh_link
1582 to the unwind section, whereas HP-UX requires sh_info to
1583 do so. For maximum compatibility, we'll set both for
1585 hdr
->sh_info
= hdr
->sh_link
;
1590 if (! elf_flags_init (abfd
))
1592 unsigned long flags
= 0;
1594 if (abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
)
1595 flags
|= EF_IA_64_BE
;
1596 if (bfd_get_mach (abfd
) == bfd_mach_ia64_elf64
)
1597 flags
|= EF_IA_64_ABI64
;
1599 elf_elfheader(abfd
)->e_flags
= flags
;
1600 elf_flags_init (abfd
) = TRUE
;
1604 /* Hook called by the linker routine which adds symbols from an object
1605 file. We use it to put .comm items in .sbss, and not .bss. */
1608 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1610 struct bfd_link_info
*info
;
1611 Elf_Internal_Sym
*sym
;
1612 const char **namep ATTRIBUTE_UNUSED
;
1613 flagword
*flagsp ATTRIBUTE_UNUSED
;
1617 if (sym
->st_shndx
== SHN_COMMON
1618 && !info
->relocatable
1619 && sym
->st_size
<= elf_gp_size (abfd
))
1621 /* Common symbols less than or equal to -G nn bytes are
1622 automatically put into .sbss. */
1624 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1628 scomm
= bfd_make_section_with_flags (abfd
, ".scommon",
1631 | SEC_LINKER_CREATED
));
1637 *valp
= sym
->st_size
;
1643 /* Return the number of additional phdrs we will need. */
1646 elfNN_ia64_additional_program_headers (bfd
*abfd
,
1647 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1652 /* See if we need a PT_IA_64_ARCHEXT segment. */
1653 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1654 if (s
&& (s
->flags
& SEC_LOAD
))
1657 /* Count how many PT_IA_64_UNWIND segments we need. */
1658 for (s
= abfd
->sections
; s
; s
= s
->next
)
1659 if (is_unwind_section_name (abfd
, s
->name
) && (s
->flags
& SEC_LOAD
))
1666 elfNN_ia64_modify_segment_map (bfd
*abfd
,
1667 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1669 struct elf_segment_map
*m
, **pm
;
1670 Elf_Internal_Shdr
*hdr
;
1673 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1674 all PT_LOAD segments. */
1675 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1676 if (s
&& (s
->flags
& SEC_LOAD
))
1678 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1679 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1683 m
= ((struct elf_segment_map
*)
1684 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1688 m
->p_type
= PT_IA_64_ARCHEXT
;
1692 /* We want to put it after the PHDR and INTERP segments. */
1693 pm
= &elf_tdata (abfd
)->segment_map
;
1695 && ((*pm
)->p_type
== PT_PHDR
1696 || (*pm
)->p_type
== PT_INTERP
))
1704 /* Install PT_IA_64_UNWIND segments, if needed. */
1705 for (s
= abfd
->sections
; s
; s
= s
->next
)
1707 hdr
= &elf_section_data (s
)->this_hdr
;
1708 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1711 if (s
&& (s
->flags
& SEC_LOAD
))
1713 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1714 if (m
->p_type
== PT_IA_64_UNWIND
)
1718 /* Look through all sections in the unwind segment
1719 for a match since there may be multiple sections
1721 for (i
= m
->count
- 1; i
>= 0; --i
)
1722 if (m
->sections
[i
] == s
)
1731 m
= ((struct elf_segment_map
*)
1732 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1736 m
->p_type
= PT_IA_64_UNWIND
;
1741 /* We want to put it last. */
1742 pm
= &elf_tdata (abfd
)->segment_map
;
1753 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1754 the input sections for each output section in the segment and testing
1755 for SHF_IA_64_NORECOV on each. */
1758 elfNN_ia64_modify_program_headers (bfd
*abfd
,
1759 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1761 struct elf_obj_tdata
*tdata
= elf_tdata (abfd
);
1762 struct elf_segment_map
*m
;
1763 Elf_Internal_Phdr
*p
;
1765 for (p
= tdata
->phdr
, m
= tdata
->segment_map
; m
!= NULL
; m
= m
->next
, p
++)
1766 if (m
->p_type
== PT_LOAD
)
1769 for (i
= m
->count
- 1; i
>= 0; --i
)
1771 struct bfd_link_order
*order
= m
->sections
[i
]->map_head
.link_order
;
1773 while (order
!= NULL
)
1775 if (order
->type
== bfd_indirect_link_order
)
1777 asection
*is
= order
->u
.indirect
.section
;
1778 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1779 if (flags
& SHF_IA_64_NORECOV
)
1781 p
->p_flags
|= PF_IA_64_NORECOV
;
1785 order
= order
->next
;
1794 /* According to the Tahoe assembler spec, all labels starting with a
1798 elfNN_ia64_is_local_label_name (abfd
, name
)
1799 bfd
*abfd ATTRIBUTE_UNUSED
;
1802 return name
[0] == '.';
1805 /* Should we do dynamic things to this symbol? */
1808 elfNN_ia64_dynamic_symbol_p (h
, info
, r_type
)
1809 struct elf_link_hash_entry
*h
;
1810 struct bfd_link_info
*info
;
1813 bfd_boolean ignore_protected
1814 = ((r_type
& 0xf8) == 0x40 /* FPTR relocs */
1815 || (r_type
& 0xf8) == 0x50); /* LTOFF_FPTR relocs */
1817 return _bfd_elf_dynamic_symbol_p (h
, info
, ignore_protected
);
1820 static struct bfd_hash_entry
*
1821 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1822 struct bfd_hash_entry
*entry
;
1823 struct bfd_hash_table
*table
;
1826 struct elfNN_ia64_link_hash_entry
*ret
;
1827 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1829 /* Allocate the structure if it has not already been allocated by a
1832 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1837 /* Call the allocation method of the superclass. */
1838 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1839 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1844 ret
->sorted_count
= 0;
1846 return (struct bfd_hash_entry
*) ret
;
1850 elfNN_ia64_hash_copy_indirect (info
, xdir
, xind
)
1851 struct bfd_link_info
*info
;
1852 struct elf_link_hash_entry
*xdir
, *xind
;
1854 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1856 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1857 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1859 /* Copy down any references that we may have already seen to the
1860 symbol which just became indirect. */
1862 dir
->root
.ref_dynamic
|= ind
->root
.ref_dynamic
;
1863 dir
->root
.ref_regular
|= ind
->root
.ref_regular
;
1864 dir
->root
.ref_regular_nonweak
|= ind
->root
.ref_regular_nonweak
;
1865 dir
->root
.needs_plt
|= ind
->root
.needs_plt
;
1867 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1870 /* Copy over the got and plt data. This would have been done
1873 if (ind
->info
!= NULL
)
1875 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1881 dir
->info
= ind
->info
;
1882 dir
->count
= ind
->count
;
1883 dir
->sorted_count
= ind
->sorted_count
;
1884 dir
->size
= ind
->size
;
1888 ind
->sorted_count
= 0;
1891 /* Fix up the dyn_sym_info pointers to the global symbol. */
1892 for (count
= dir
->count
, dyn_i
= dir
->info
;
1895 dyn_i
->h
= &dir
->root
;
1898 /* Copy over the dynindx. */
1900 if (ind
->root
.dynindx
!= -1)
1902 if (dir
->root
.dynindx
!= -1)
1903 _bfd_elf_strtab_delref (elf_hash_table (info
)->dynstr
,
1904 dir
->root
.dynstr_index
);
1905 dir
->root
.dynindx
= ind
->root
.dynindx
;
1906 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1907 ind
->root
.dynindx
= -1;
1908 ind
->root
.dynstr_index
= 0;
1913 elfNN_ia64_hash_hide_symbol (info
, xh
, force_local
)
1914 struct bfd_link_info
*info
;
1915 struct elf_link_hash_entry
*xh
;
1916 bfd_boolean force_local
;
1918 struct elfNN_ia64_link_hash_entry
*h
;
1919 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1922 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1924 _bfd_elf_link_hash_hide_symbol (info
, &h
->root
, force_local
);
1926 for (count
= h
->count
, dyn_i
= h
->info
;
1930 dyn_i
->want_plt2
= 0;
1931 dyn_i
->want_plt
= 0;
1935 /* Compute a hash of a local hash entry. */
1938 elfNN_ia64_local_htab_hash (ptr
)
1941 struct elfNN_ia64_local_hash_entry
*entry
1942 = (struct elfNN_ia64_local_hash_entry
*) ptr
;
1944 return (((entry
->id
& 0xff) << 24) | ((entry
->id
& 0xff00) << 8))
1945 ^ entry
->r_sym
^ (entry
->id
>> 16);
1948 /* Compare local hash entries. */
1951 elfNN_ia64_local_htab_eq (ptr1
, ptr2
)
1952 const void *ptr1
, *ptr2
;
1954 struct elfNN_ia64_local_hash_entry
*entry1
1955 = (struct elfNN_ia64_local_hash_entry
*) ptr1
;
1956 struct elfNN_ia64_local_hash_entry
*entry2
1957 = (struct elfNN_ia64_local_hash_entry
*) ptr2
;
1959 return entry1
->id
== entry2
->id
&& entry1
->r_sym
== entry2
->r_sym
;
1962 /* Create the derived linker hash table. The IA-64 ELF port uses this
1963 derived hash table to keep information specific to the IA-64 ElF
1964 linker (without using static variables). */
1966 static struct bfd_link_hash_table
*
1967 elfNN_ia64_hash_table_create (abfd
)
1970 struct elfNN_ia64_link_hash_table
*ret
;
1972 ret
= bfd_zmalloc ((bfd_size_type
) sizeof (*ret
));
1976 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1977 elfNN_ia64_new_elf_hash_entry
,
1978 sizeof (struct elfNN_ia64_link_hash_entry
)))
1984 ret
->loc_hash_table
= htab_try_create (1024, elfNN_ia64_local_htab_hash
,
1985 elfNN_ia64_local_htab_eq
, NULL
);
1986 ret
->loc_hash_memory
= objalloc_create ();
1987 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
1993 return &ret
->root
.root
;
1996 /* Free the global elfNN_ia64_dyn_sym_info array. */
1999 elfNN_ia64_global_dyn_info_free (void **xentry
,
2000 PTR unused ATTRIBUTE_UNUSED
)
2002 struct elfNN_ia64_link_hash_entry
*entry
2003 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
2005 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
2006 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
2013 entry
->sorted_count
= 0;
2020 /* Free the local elfNN_ia64_dyn_sym_info array. */
2023 elfNN_ia64_local_dyn_info_free (void **slot
,
2024 PTR unused ATTRIBUTE_UNUSED
)
2026 struct elfNN_ia64_local_hash_entry
*entry
2027 = (struct elfNN_ia64_local_hash_entry
*) *slot
;
2034 entry
->sorted_count
= 0;
2041 /* Destroy IA-64 linker hash table. */
2044 elfNN_ia64_hash_table_free (hash
)
2045 struct bfd_link_hash_table
*hash
;
2047 struct elfNN_ia64_link_hash_table
*ia64_info
2048 = (struct elfNN_ia64_link_hash_table
*) hash
;
2049 if (ia64_info
->loc_hash_table
)
2051 htab_traverse (ia64_info
->loc_hash_table
,
2052 elfNN_ia64_local_dyn_info_free
, NULL
);
2053 htab_delete (ia64_info
->loc_hash_table
);
2055 if (ia64_info
->loc_hash_memory
)
2056 objalloc_free ((struct objalloc
*) ia64_info
->loc_hash_memory
);
2057 elf_link_hash_traverse (&ia64_info
->root
,
2058 elfNN_ia64_global_dyn_info_free
, NULL
);
2059 _bfd_generic_link_hash_table_free (hash
);
2062 /* Traverse both local and global hash tables. */
2064 struct elfNN_ia64_dyn_sym_traverse_data
2066 bfd_boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
2071 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
2072 struct bfd_hash_entry
*xentry
;
2075 struct elfNN_ia64_link_hash_entry
*entry
2076 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
2077 struct elfNN_ia64_dyn_sym_traverse_data
*data
2078 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
2079 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2082 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
2083 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
2085 for (count
= entry
->count
, dyn_i
= entry
->info
;
2088 if (! (*data
->func
) (dyn_i
, data
->data
))
2094 elfNN_ia64_local_dyn_sym_thunk (slot
, xdata
)
2098 struct elfNN_ia64_local_hash_entry
*entry
2099 = (struct elfNN_ia64_local_hash_entry
*) *slot
;
2100 struct elfNN_ia64_dyn_sym_traverse_data
*data
2101 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
2102 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2105 for (count
= entry
->count
, dyn_i
= entry
->info
;
2108 if (! (*data
->func
) (dyn_i
, data
->data
))
2114 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
2115 struct elfNN_ia64_link_hash_table
*ia64_info
;
2116 bfd_boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
2119 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
2124 elf_link_hash_traverse (&ia64_info
->root
,
2125 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
2126 htab_traverse (ia64_info
->loc_hash_table
,
2127 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
2131 elfNN_ia64_create_dynamic_sections (abfd
, info
)
2133 struct bfd_link_info
*info
;
2135 struct elfNN_ia64_link_hash_table
*ia64_info
;
2138 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
2141 ia64_info
= elfNN_ia64_hash_table (info
);
2143 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
2144 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
2147 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
2148 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
2149 /* The .got section is always aligned at 8 bytes. */
2150 bfd_set_section_alignment (abfd
, ia64_info
->got_sec
, 3);
2153 if (!get_pltoff (abfd
, info
, ia64_info
))
2156 s
= bfd_make_section_with_flags (abfd
, ".rela.IA_64.pltoff",
2157 (SEC_ALLOC
| SEC_LOAD
2160 | SEC_LINKER_CREATED
2163 || !bfd_set_section_alignment (abfd
, s
, LOG_SECTION_ALIGN
))
2165 ia64_info
->rel_pltoff_sec
= s
;
2167 s
= bfd_make_section_with_flags (abfd
, ".rela.got",
2168 (SEC_ALLOC
| SEC_LOAD
2171 | SEC_LINKER_CREATED
2174 || !bfd_set_section_alignment (abfd
, s
, LOG_SECTION_ALIGN
))
2176 ia64_info
->rel_got_sec
= s
;
2181 /* Find and/or create a hash entry for local symbol. */
2182 static struct elfNN_ia64_local_hash_entry
*
2183 get_local_sym_hash (ia64_info
, abfd
, rel
, create
)
2184 struct elfNN_ia64_link_hash_table
*ia64_info
;
2186 const Elf_Internal_Rela
*rel
;
2189 struct elfNN_ia64_local_hash_entry e
, *ret
;
2190 asection
*sec
= abfd
->sections
;
2191 hashval_t h
= (((sec
->id
& 0xff) << 24) | ((sec
->id
& 0xff00) << 8))
2192 ^ ELFNN_R_SYM (rel
->r_info
) ^ (sec
->id
>> 16);
2196 e
.r_sym
= ELFNN_R_SYM (rel
->r_info
);
2197 slot
= htab_find_slot_with_hash (ia64_info
->loc_hash_table
, &e
, h
,
2198 create
? INSERT
: NO_INSERT
);
2204 return (struct elfNN_ia64_local_hash_entry
*) *slot
;
2206 ret
= (struct elfNN_ia64_local_hash_entry
*)
2207 objalloc_alloc ((struct objalloc
*) ia64_info
->loc_hash_memory
,
2208 sizeof (struct elfNN_ia64_local_hash_entry
));
2211 memset (ret
, 0, sizeof (*ret
));
2213 ret
->r_sym
= ELFNN_R_SYM (rel
->r_info
);
2219 /* Used to sort elfNN_ia64_dyn_sym_info array. */
2222 addend_compare (const void *xp
, const void *yp
)
2224 const struct elfNN_ia64_dyn_sym_info
*x
2225 = (const struct elfNN_ia64_dyn_sym_info
*) xp
;
2226 const struct elfNN_ia64_dyn_sym_info
*y
2227 = (const struct elfNN_ia64_dyn_sym_info
*) yp
;
2229 return x
->addend
< y
->addend
? -1 : x
->addend
> y
->addend
? 1 : 0;
2232 /* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
2235 sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info
*info
,
2238 bfd_vma curr
, prev
, got_offset
;
2239 unsigned int i
, kept
, dup
, diff
, dest
, src
, len
;
2241 qsort (info
, count
, sizeof (*info
), addend_compare
);
2243 /* Find the first duplicate. */
2244 prev
= info
[0].addend
;
2245 got_offset
= info
[0].got_offset
;
2246 for (i
= 1; i
< count
; i
++)
2248 curr
= info
[i
].addend
;
2251 /* For duplicates, make sure that GOT_OFFSET is valid. */
2252 if (got_offset
== (bfd_vma
) -1)
2253 got_offset
= info
[i
].got_offset
;
2256 got_offset
= info
[i
].got_offset
;
2260 /* We may move a block of elements to here. */
2263 /* Remove duplicates. */
2268 /* For duplicates, make sure that the kept one has a valid
2271 if (got_offset
!= (bfd_vma
) -1)
2272 info
[kept
].got_offset
= got_offset
;
2274 curr
= info
[i
].addend
;
2275 got_offset
= info
[i
].got_offset
;
2277 /* Move a block of elements whose first one is different from
2281 for (src
= i
+ 1; src
< count
; src
++)
2283 if (info
[src
].addend
!= curr
)
2285 /* For duplicates, make sure that GOT_OFFSET is
2287 if (got_offset
== (bfd_vma
) -1)
2288 got_offset
= info
[src
].got_offset
;
2291 /* Make sure that the kept one has a valid got_offset. */
2292 if (got_offset
!= (bfd_vma
) -1)
2293 info
[kept
].got_offset
= got_offset
;
2301 /* Find the next duplicate. SRC will be kept. */
2302 prev
= info
[src
].addend
;
2303 got_offset
= info
[src
].got_offset
;
2304 for (dup
= src
+ 1; dup
< count
; dup
++)
2306 curr
= info
[dup
].addend
;
2309 /* Make sure that got_offset is valid. */
2310 if (got_offset
== (bfd_vma
) -1)
2311 got_offset
= info
[dup
].got_offset
;
2313 /* For duplicates, make sure that the kept one has
2314 a valid got_offset. */
2315 if (got_offset
!= (bfd_vma
) -1)
2316 info
[dup
- 1].got_offset
= got_offset
;
2319 got_offset
= info
[dup
].got_offset
;
2323 /* How much to move. */
2327 if (len
== 1 && dup
< count
)
2329 /* If we only move 1 element, we combine it with the next
2330 one. There must be at least a duplicate. Find the
2331 next different one. */
2332 for (diff
= dup
+ 1, src
++; diff
< count
; diff
++, src
++)
2334 if (info
[diff
].addend
!= curr
)
2336 /* Make sure that got_offset is valid. */
2337 if (got_offset
== (bfd_vma
) -1)
2338 got_offset
= info
[diff
].got_offset
;
2341 /* Makre sure that the last duplicated one has an valid
2343 BFD_ASSERT (curr
== prev
);
2344 if (got_offset
!= (bfd_vma
) -1)
2345 info
[diff
- 1].got_offset
= got_offset
;
2349 /* Find the next duplicate. Track the current valid
2351 prev
= info
[diff
].addend
;
2352 got_offset
= info
[diff
].got_offset
;
2353 for (dup
= diff
+ 1; dup
< count
; dup
++)
2355 curr
= info
[dup
].addend
;
2358 /* For duplicates, make sure that GOT_OFFSET
2360 if (got_offset
== (bfd_vma
) -1)
2361 got_offset
= info
[dup
].got_offset
;
2364 got_offset
= info
[dup
].got_offset
;
2369 len
= diff
- src
+ 1;
2374 memmove (&info
[dest
], &info
[src
], len
* sizeof (*info
));
2383 /* When we get here, either there is no duplicate at all or
2384 the only duplicate is the last element. */
2387 /* If the last element is a duplicate, make sure that the
2388 kept one has a valid got_offset. We also update count. */
2389 if (got_offset
!= (bfd_vma
) -1)
2390 info
[dest
- 1].got_offset
= got_offset
;
2398 /* Find and/or create a descriptor for dynamic symbol info. This will
2399 vary based on global or local symbol, and the addend to the reloc.
2401 We don't sort when inserting. Also, we sort and eliminate
2402 duplicates if there is an unsorted section. Typically, this will
2403 only happen once, because we do all insertions before lookups. We
2404 then use bsearch to do a lookup. This also allows lookups to be
2405 fast. So we have fast insertion (O(log N) due to duplicate check),
2406 fast lookup (O(log N)) and one sort (O(N log N) expected time).
2407 Previously, all lookups were O(N) because of the use of the linked
2408 list and also all insertions were O(N) because of the check for
2409 duplicates. There are some complications here because the array
2410 size grows occasionally, which may add an O(N) factor, but this
2411 should be rare. Also, we free the excess array allocation, which
2412 requires a copy which is O(N), but this only happens once. */
2414 static struct elfNN_ia64_dyn_sym_info
*
2415 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
2416 struct elfNN_ia64_link_hash_table
*ia64_info
;
2417 struct elf_link_hash_entry
*h
;
2419 const Elf_Internal_Rela
*rel
;
2422 struct elfNN_ia64_dyn_sym_info
**info_p
, *info
, *dyn_i
, key
;
2423 unsigned int *count_p
, *sorted_count_p
, *size_p
;
2424 unsigned int count
, sorted_count
, size
;
2425 bfd_vma addend
= rel
? rel
->r_addend
: 0;
2430 struct elfNN_ia64_link_hash_entry
*global_h
;
2432 global_h
= (struct elfNN_ia64_link_hash_entry
*) h
;
2433 info_p
= &global_h
->info
;
2434 count_p
= &global_h
->count
;
2435 sorted_count_p
= &global_h
->sorted_count
;
2436 size_p
= &global_h
->size
;
2440 struct elfNN_ia64_local_hash_entry
*loc_h
;
2442 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
2445 BFD_ASSERT (!create
);
2449 info_p
= &loc_h
->info
;
2450 count_p
= &loc_h
->count
;
2451 sorted_count_p
= &loc_h
->sorted_count
;
2452 size_p
= &loc_h
->size
;
2456 sorted_count
= *sorted_count_p
;
2461 /* When we create the array, we don't check for duplicates,
2462 except in the previously sorted section if one exists, and
2463 against the last inserted entry. This allows insertions to
2469 /* Try bsearch first on the sorted section. */
2470 key
.addend
= addend
;
2471 dyn_i
= bsearch (&key
, info
, sorted_count
,
2472 sizeof (*info
), addend_compare
);
2480 /* Do a quick check for the last inserted entry. */
2481 dyn_i
= info
+ count
- 1;
2482 if (dyn_i
->addend
== addend
)
2490 /* It is the very first element. We create the array of size
2493 amt
= size
* sizeof (*info
);
2494 info
= bfd_malloc (amt
);
2496 else if (size
<= count
)
2498 /* We double the array size every time when we reach the
2501 amt
= size
* sizeof (*info
);
2502 info
= bfd_realloc (info
, amt
);
2513 /* Append the new one to the array. */
2514 dyn_i
= info
+ count
;
2515 memset (dyn_i
, 0, sizeof (*dyn_i
));
2516 dyn_i
->got_offset
= (bfd_vma
) -1;
2517 dyn_i
->addend
= addend
;
2519 /* We increment count only since the new ones are unsorted and
2520 may have duplicate. */
2525 /* It is a lookup without insertion. Sort array if part of the
2526 array isn't sorted. */
2527 if (count
!= sorted_count
)
2529 count
= sort_dyn_sym_info (info
, count
);
2531 *sorted_count_p
= count
;
2534 /* Free unused memory. */
2537 amt
= count
* sizeof (*info
);
2538 info
= bfd_malloc (amt
);
2541 memcpy (info
, *info_p
, amt
);
2548 key
.addend
= addend
;
2549 dyn_i
= bsearch (&key
, info
, count
,
2550 sizeof (*info
), addend_compare
);
2557 get_got (abfd
, info
, ia64_info
)
2559 struct bfd_link_info
*info
;
2560 struct elfNN_ia64_link_hash_table
*ia64_info
;
2565 got
= ia64_info
->got_sec
;
2570 dynobj
= ia64_info
->root
.dynobj
;
2572 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2573 if (!_bfd_elf_create_got_section (dynobj
, info
))
2576 got
= bfd_get_section_by_name (dynobj
, ".got");
2578 ia64_info
->got_sec
= got
;
2580 /* The .got section is always aligned at 8 bytes. */
2581 if (!bfd_set_section_alignment (abfd
, got
, 3))
2584 flags
= bfd_get_section_flags (abfd
, got
);
2585 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
2591 /* Create function descriptor section (.opd). This section is called .opd
2592 because it contains "official procedure descriptors". The "official"
2593 refers to the fact that these descriptors are used when taking the address
2594 of a procedure, thus ensuring a unique address for each procedure. */
2597 get_fptr (abfd
, info
, ia64_info
)
2599 struct bfd_link_info
*info
;
2600 struct elfNN_ia64_link_hash_table
*ia64_info
;
2605 fptr
= ia64_info
->fptr_sec
;
2608 dynobj
= ia64_info
->root
.dynobj
;
2610 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2612 fptr
= bfd_make_section_with_flags (dynobj
, ".opd",
2617 | (info
->pie
? 0 : SEC_READONLY
)
2618 | SEC_LINKER_CREATED
));
2620 || !bfd_set_section_alignment (abfd
, fptr
, 4))
2626 ia64_info
->fptr_sec
= fptr
;
2631 fptr_rel
= bfd_make_section_with_flags (dynobj
, ".rela.opd",
2632 (SEC_ALLOC
| SEC_LOAD
2635 | SEC_LINKER_CREATED
2637 if (fptr_rel
== NULL
2638 || !bfd_set_section_alignment (abfd
, fptr_rel
,
2645 ia64_info
->rel_fptr_sec
= fptr_rel
;
2653 get_pltoff (abfd
, info
, ia64_info
)
2655 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2656 struct elfNN_ia64_link_hash_table
*ia64_info
;
2661 pltoff
= ia64_info
->pltoff_sec
;
2664 dynobj
= ia64_info
->root
.dynobj
;
2666 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2668 pltoff
= bfd_make_section_with_flags (dynobj
,
2669 ELF_STRING_ia64_pltoff
,
2675 | SEC_LINKER_CREATED
));
2677 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
2683 ia64_info
->pltoff_sec
= pltoff
;
2690 get_reloc_section (abfd
, ia64_info
, sec
, create
)
2692 struct elfNN_ia64_link_hash_table
*ia64_info
;
2696 const char *srel_name
;
2700 srel_name
= (bfd_elf_string_from_elf_section
2701 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
2702 elf_section_data(sec
)->rel_hdr
.sh_name
));
2703 if (srel_name
== NULL
)
2706 BFD_ASSERT ((CONST_STRNEQ (srel_name
, ".rela")
2707 && strcmp (bfd_get_section_name (abfd
, sec
),
2709 || (CONST_STRNEQ (srel_name
, ".rel")
2710 && strcmp (bfd_get_section_name (abfd
, sec
),
2711 srel_name
+4) == 0));
2713 dynobj
= ia64_info
->root
.dynobj
;
2715 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2717 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
2718 if (srel
== NULL
&& create
)
2720 srel
= bfd_make_section_with_flags (dynobj
, srel_name
,
2721 (SEC_ALLOC
| SEC_LOAD
2724 | SEC_LINKER_CREATED
2727 || !bfd_set_section_alignment (dynobj
, srel
,
2736 count_dyn_reloc (bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
2737 asection
*srel
, int type
, bfd_boolean reltext
)
2739 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2741 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2742 if (rent
->srel
== srel
&& rent
->type
== type
)
2747 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
2748 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
2752 rent
->next
= dyn_i
->reloc_entries
;
2756 dyn_i
->reloc_entries
= rent
;
2758 rent
->reltext
= reltext
;
2765 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
2767 struct bfd_link_info
*info
;
2769 const Elf_Internal_Rela
*relocs
;
2771 struct elfNN_ia64_link_hash_table
*ia64_info
;
2772 const Elf_Internal_Rela
*relend
;
2773 Elf_Internal_Shdr
*symtab_hdr
;
2774 const Elf_Internal_Rela
*rel
;
2775 asection
*got
, *fptr
, *srel
, *pltoff
;
2784 NEED_LTOFF_FPTR
= 128,
2790 struct elf_link_hash_entry
*h
;
2791 unsigned long r_symndx
;
2792 bfd_boolean maybe_dynamic
;
2794 if (info
->relocatable
)
2797 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2798 ia64_info
= elfNN_ia64_hash_table (info
);
2800 got
= fptr
= srel
= pltoff
= NULL
;
2802 relend
= relocs
+ sec
->reloc_count
;
2804 /* We scan relocations first to create dynamic relocation arrays. We
2805 modified get_dyn_sym_info to allow fast insertion and support fast
2806 lookup in the next loop. */
2807 for (rel
= relocs
; rel
< relend
; ++rel
)
2809 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2810 if (r_symndx
>= symtab_hdr
->sh_info
)
2812 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2813 h
= elf_sym_hashes (abfd
)[indx
];
2814 while (h
->root
.type
== bfd_link_hash_indirect
2815 || h
->root
.type
== bfd_link_hash_warning
)
2816 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2821 /* We can only get preliminary data on whether a symbol is
2822 locally or externally defined, as not all of the input files
2823 have yet been processed. Do something with what we know, as
2824 this may help reduce memory usage and processing time later. */
2825 maybe_dynamic
= (h
&& ((!info
->executable
2826 && (!SYMBOLIC_BIND (info
, h
)
2827 || info
->unresolved_syms_in_shared_libs
== RM_IGNORE
))
2829 || h
->root
.type
== bfd_link_hash_defweak
));
2832 switch (ELFNN_R_TYPE (rel
->r_info
))
2834 case R_IA64_TPREL64MSB
:
2835 case R_IA64_TPREL64LSB
:
2836 if (info
->shared
|| maybe_dynamic
)
2837 need_entry
= NEED_DYNREL
;
2840 case R_IA64_LTOFF_TPREL22
:
2841 need_entry
= NEED_TPREL
;
2843 info
->flags
|= DF_STATIC_TLS
;
2846 case R_IA64_DTPREL32MSB
:
2847 case R_IA64_DTPREL32LSB
:
2848 case R_IA64_DTPREL64MSB
:
2849 case R_IA64_DTPREL64LSB
:
2850 if (info
->shared
|| maybe_dynamic
)
2851 need_entry
= NEED_DYNREL
;
2854 case R_IA64_LTOFF_DTPREL22
:
2855 need_entry
= NEED_DTPREL
;
2858 case R_IA64_DTPMOD64MSB
:
2859 case R_IA64_DTPMOD64LSB
:
2860 if (info
->shared
|| maybe_dynamic
)
2861 need_entry
= NEED_DYNREL
;
2864 case R_IA64_LTOFF_DTPMOD22
:
2865 need_entry
= NEED_DTPMOD
;
2868 case R_IA64_LTOFF_FPTR22
:
2869 case R_IA64_LTOFF_FPTR64I
:
2870 case R_IA64_LTOFF_FPTR32MSB
:
2871 case R_IA64_LTOFF_FPTR32LSB
:
2872 case R_IA64_LTOFF_FPTR64MSB
:
2873 case R_IA64_LTOFF_FPTR64LSB
:
2874 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2877 case R_IA64_FPTR64I
:
2878 case R_IA64_FPTR32MSB
:
2879 case R_IA64_FPTR32LSB
:
2880 case R_IA64_FPTR64MSB
:
2881 case R_IA64_FPTR64LSB
:
2882 if (info
->shared
|| h
)
2883 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2885 need_entry
= NEED_FPTR
;
2888 case R_IA64_LTOFF22
:
2889 case R_IA64_LTOFF64I
:
2890 need_entry
= NEED_GOT
;
2893 case R_IA64_LTOFF22X
:
2894 need_entry
= NEED_GOTX
;
2897 case R_IA64_PLTOFF22
:
2898 case R_IA64_PLTOFF64I
:
2899 case R_IA64_PLTOFF64MSB
:
2900 case R_IA64_PLTOFF64LSB
:
2901 need_entry
= NEED_PLTOFF
;
2905 need_entry
|= NEED_MIN_PLT
;
2909 (*info
->callbacks
->warning
)
2910 (info
, _("@pltoff reloc against local symbol"), 0,
2911 abfd
, 0, (bfd_vma
) 0);
2915 case R_IA64_PCREL21B
:
2916 case R_IA64_PCREL60B
:
2917 /* Depending on where this symbol is defined, we may or may not
2918 need a full plt entry. Only skip if we know we'll not need
2919 the entry -- static or symbolic, and the symbol definition
2920 has already been seen. */
2921 if (maybe_dynamic
&& rel
->r_addend
== 0)
2922 need_entry
= NEED_FULL_PLT
;
2928 case R_IA64_DIR32MSB
:
2929 case R_IA64_DIR32LSB
:
2930 case R_IA64_DIR64MSB
:
2931 case R_IA64_DIR64LSB
:
2932 /* Shared objects will always need at least a REL relocation. */
2933 if (info
->shared
|| maybe_dynamic
)
2934 need_entry
= NEED_DYNREL
;
2937 case R_IA64_IPLTMSB
:
2938 case R_IA64_IPLTLSB
:
2939 /* Shared objects will always need at least a REL relocation. */
2940 if (info
->shared
|| maybe_dynamic
)
2941 need_entry
= NEED_DYNREL
;
2944 case R_IA64_PCREL22
:
2945 case R_IA64_PCREL64I
:
2946 case R_IA64_PCREL32MSB
:
2947 case R_IA64_PCREL32LSB
:
2948 case R_IA64_PCREL64MSB
:
2949 case R_IA64_PCREL64LSB
:
2951 need_entry
= NEED_DYNREL
;
2958 if ((need_entry
& NEED_FPTR
) != 0
2961 (*info
->callbacks
->warning
)
2962 (info
, _("non-zero addend in @fptr reloc"), 0,
2963 abfd
, 0, (bfd_vma
) 0);
2966 if (get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, TRUE
) == NULL
)
2970 /* Now, we only do lookup without insertion, which is very fast
2971 with the modified get_dyn_sym_info. */
2972 for (rel
= relocs
; rel
< relend
; ++rel
)
2974 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2975 int dynrel_type
= R_IA64_NONE
;
2977 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2978 if (r_symndx
>= symtab_hdr
->sh_info
)
2980 /* We're dealing with a global symbol -- find its hash entry
2981 and mark it as being referenced. */
2982 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2983 h
= elf_sym_hashes (abfd
)[indx
];
2984 while (h
->root
.type
== bfd_link_hash_indirect
2985 || h
->root
.type
== bfd_link_hash_warning
)
2986 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2993 /* We can only get preliminary data on whether a symbol is
2994 locally or externally defined, as not all of the input files
2995 have yet been processed. Do something with what we know, as
2996 this may help reduce memory usage and processing time later. */
2997 maybe_dynamic
= (h
&& ((!info
->executable
2998 && (!SYMBOLIC_BIND (info
, h
)
2999 || info
->unresolved_syms_in_shared_libs
== RM_IGNORE
))
3001 || h
->root
.type
== bfd_link_hash_defweak
));
3004 switch (ELFNN_R_TYPE (rel
->r_info
))
3006 case R_IA64_TPREL64MSB
:
3007 case R_IA64_TPREL64LSB
:
3008 if (info
->shared
|| maybe_dynamic
)
3009 need_entry
= NEED_DYNREL
;
3010 dynrel_type
= R_IA64_TPREL64LSB
;
3012 info
->flags
|= DF_STATIC_TLS
;
3015 case R_IA64_LTOFF_TPREL22
:
3016 need_entry
= NEED_TPREL
;
3018 info
->flags
|= DF_STATIC_TLS
;
3021 case R_IA64_DTPREL32MSB
:
3022 case R_IA64_DTPREL32LSB
:
3023 case R_IA64_DTPREL64MSB
:
3024 case R_IA64_DTPREL64LSB
:
3025 if (info
->shared
|| maybe_dynamic
)
3026 need_entry
= NEED_DYNREL
;
3027 dynrel_type
= R_IA64_DTPRELNNLSB
;
3030 case R_IA64_LTOFF_DTPREL22
:
3031 need_entry
= NEED_DTPREL
;
3034 case R_IA64_DTPMOD64MSB
:
3035 case R_IA64_DTPMOD64LSB
:
3036 if (info
->shared
|| maybe_dynamic
)
3037 need_entry
= NEED_DYNREL
;
3038 dynrel_type
= R_IA64_DTPMOD64LSB
;
3041 case R_IA64_LTOFF_DTPMOD22
:
3042 need_entry
= NEED_DTPMOD
;
3045 case R_IA64_LTOFF_FPTR22
:
3046 case R_IA64_LTOFF_FPTR64I
:
3047 case R_IA64_LTOFF_FPTR32MSB
:
3048 case R_IA64_LTOFF_FPTR32LSB
:
3049 case R_IA64_LTOFF_FPTR64MSB
:
3050 case R_IA64_LTOFF_FPTR64LSB
:
3051 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
3054 case R_IA64_FPTR64I
:
3055 case R_IA64_FPTR32MSB
:
3056 case R_IA64_FPTR32LSB
:
3057 case R_IA64_FPTR64MSB
:
3058 case R_IA64_FPTR64LSB
:
3059 if (info
->shared
|| h
)
3060 need_entry
= NEED_FPTR
| NEED_DYNREL
;
3062 need_entry
= NEED_FPTR
;
3063 dynrel_type
= R_IA64_FPTRNNLSB
;
3066 case R_IA64_LTOFF22
:
3067 case R_IA64_LTOFF64I
:
3068 need_entry
= NEED_GOT
;
3071 case R_IA64_LTOFF22X
:
3072 need_entry
= NEED_GOTX
;
3075 case R_IA64_PLTOFF22
:
3076 case R_IA64_PLTOFF64I
:
3077 case R_IA64_PLTOFF64MSB
:
3078 case R_IA64_PLTOFF64LSB
:
3079 need_entry
= NEED_PLTOFF
;
3083 need_entry
|= NEED_MIN_PLT
;
3087 case R_IA64_PCREL21B
:
3088 case R_IA64_PCREL60B
:
3089 /* Depending on where this symbol is defined, we may or may not
3090 need a full plt entry. Only skip if we know we'll not need
3091 the entry -- static or symbolic, and the symbol definition
3092 has already been seen. */
3093 if (maybe_dynamic
&& rel
->r_addend
== 0)
3094 need_entry
= NEED_FULL_PLT
;
3100 case R_IA64_DIR32MSB
:
3101 case R_IA64_DIR32LSB
:
3102 case R_IA64_DIR64MSB
:
3103 case R_IA64_DIR64LSB
:
3104 /* Shared objects will always need at least a REL relocation. */
3105 if (info
->shared
|| maybe_dynamic
)
3106 need_entry
= NEED_DYNREL
;
3107 dynrel_type
= R_IA64_DIRNNLSB
;
3110 case R_IA64_IPLTMSB
:
3111 case R_IA64_IPLTLSB
:
3112 /* Shared objects will always need at least a REL relocation. */
3113 if (info
->shared
|| maybe_dynamic
)
3114 need_entry
= NEED_DYNREL
;
3115 dynrel_type
= R_IA64_IPLTLSB
;
3118 case R_IA64_PCREL22
:
3119 case R_IA64_PCREL64I
:
3120 case R_IA64_PCREL32MSB
:
3121 case R_IA64_PCREL32LSB
:
3122 case R_IA64_PCREL64MSB
:
3123 case R_IA64_PCREL64LSB
:
3125 need_entry
= NEED_DYNREL
;
3126 dynrel_type
= R_IA64_PCRELNNLSB
;
3133 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, FALSE
);
3135 /* Record whether or not this is a local symbol. */
3138 /* Create what's needed. */
3139 if (need_entry
& (NEED_GOT
| NEED_GOTX
| NEED_TPREL
3140 | NEED_DTPMOD
| NEED_DTPREL
))
3144 got
= get_got (abfd
, info
, ia64_info
);
3148 if (need_entry
& NEED_GOT
)
3149 dyn_i
->want_got
= 1;
3150 if (need_entry
& NEED_GOTX
)
3151 dyn_i
->want_gotx
= 1;
3152 if (need_entry
& NEED_TPREL
)
3153 dyn_i
->want_tprel
= 1;
3154 if (need_entry
& NEED_DTPMOD
)
3155 dyn_i
->want_dtpmod
= 1;
3156 if (need_entry
& NEED_DTPREL
)
3157 dyn_i
->want_dtprel
= 1;
3159 if (need_entry
& NEED_FPTR
)
3163 fptr
= get_fptr (abfd
, info
, ia64_info
);
3168 /* FPTRs for shared libraries are allocated by the dynamic
3169 linker. Make sure this local symbol will appear in the
3170 dynamic symbol table. */
3171 if (!h
&& info
->shared
)
3173 if (! (bfd_elf_link_record_local_dynamic_symbol
3174 (info
, abfd
, (long) r_symndx
)))
3178 dyn_i
->want_fptr
= 1;
3180 if (need_entry
& NEED_LTOFF_FPTR
)
3181 dyn_i
->want_ltoff_fptr
= 1;
3182 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
3184 if (!ia64_info
->root
.dynobj
)
3185 ia64_info
->root
.dynobj
= abfd
;
3187 dyn_i
->want_plt
= 1;
3189 if (need_entry
& NEED_FULL_PLT
)
3190 dyn_i
->want_plt2
= 1;
3191 if (need_entry
& NEED_PLTOFF
)
3193 /* This is needed here, in case @pltoff is used in a non-shared
3197 pltoff
= get_pltoff (abfd
, info
, ia64_info
);
3202 dyn_i
->want_pltoff
= 1;
3204 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
3208 srel
= get_reloc_section (abfd
, ia64_info
, sec
, TRUE
);
3212 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
,
3213 (sec
->flags
& SEC_READONLY
) != 0))
3221 /* For cleanliness, and potentially faster dynamic loading, allocate
3222 external GOT entries first. */
3225 allocate_global_data_got (dyn_i
, data
)
3226 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3229 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3231 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
3232 && ! dyn_i
->want_fptr
3233 && elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3235 dyn_i
->got_offset
= x
->ofs
;
3238 if (dyn_i
->want_tprel
)
3240 dyn_i
->tprel_offset
= x
->ofs
;
3243 if (dyn_i
->want_dtpmod
)
3245 if (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3247 dyn_i
->dtpmod_offset
= x
->ofs
;
3252 struct elfNN_ia64_link_hash_table
*ia64_info
;
3254 ia64_info
= elfNN_ia64_hash_table (x
->info
);
3255 if (ia64_info
->self_dtpmod_offset
== (bfd_vma
) -1)
3257 ia64_info
->self_dtpmod_offset
= x
->ofs
;
3260 dyn_i
->dtpmod_offset
= ia64_info
->self_dtpmod_offset
;
3263 if (dyn_i
->want_dtprel
)
3265 dyn_i
->dtprel_offset
= x
->ofs
;
3271 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
3274 allocate_global_fptr_got (dyn_i
, data
)
3275 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3278 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3282 && elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, R_IA64_FPTRNNLSB
))
3284 dyn_i
->got_offset
= x
->ofs
;
3290 /* Lastly, allocate all the GOT entries for local data. */
3293 allocate_local_got (dyn_i
, data
)
3294 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_got
|| dyn_i
->want_gotx
)
3300 && !elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3302 dyn_i
->got_offset
= x
->ofs
;
3308 /* Search for the index of a global symbol in it's defining object file. */
3311 global_sym_index (h
)
3312 struct elf_link_hash_entry
*h
;
3314 struct elf_link_hash_entry
**p
;
3317 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
3318 || h
->root
.type
== bfd_link_hash_defweak
);
3320 obj
= h
->root
.u
.def
.section
->owner
;
3321 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
3324 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
3327 /* Allocate function descriptors. We can do these for every function
3328 in a main executable that is not exported. */
3331 allocate_fptr (dyn_i
, data
)
3332 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3335 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3337 if (dyn_i
->want_fptr
)
3339 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3342 while (h
->root
.type
== bfd_link_hash_indirect
3343 || h
->root
.type
== bfd_link_hash_warning
)
3344 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3346 if (!x
->info
->executable
3348 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
3349 || (h
->root
.type
!= bfd_link_hash_undefweak
3350 && h
->root
.type
!= bfd_link_hash_undefined
)))
3352 if (h
&& h
->dynindx
== -1)
3354 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
3355 || (h
->root
.type
== bfd_link_hash_defweak
));
3357 if (!bfd_elf_link_record_local_dynamic_symbol
3358 (x
->info
, h
->root
.u
.def
.section
->owner
,
3359 global_sym_index (h
)))
3363 dyn_i
->want_fptr
= 0;
3365 else if (h
== NULL
|| h
->dynindx
== -1)
3367 dyn_i
->fptr_offset
= x
->ofs
;
3371 dyn_i
->want_fptr
= 0;
3376 /* Allocate all the minimal PLT entries. */
3379 allocate_plt_entries (dyn_i
, data
)
3380 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3383 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3385 if (dyn_i
->want_plt
)
3387 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3390 while (h
->root
.type
== bfd_link_hash_indirect
3391 || h
->root
.type
== bfd_link_hash_warning
)
3392 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3394 /* ??? Versioned symbols seem to lose NEEDS_PLT. */
3395 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
, 0))
3397 bfd_size_type offset
= x
->ofs
;
3399 offset
= PLT_HEADER_SIZE
;
3400 dyn_i
->plt_offset
= offset
;
3401 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
3403 dyn_i
->want_pltoff
= 1;
3407 dyn_i
->want_plt
= 0;
3408 dyn_i
->want_plt2
= 0;
3414 /* Allocate all the full PLT entries. */
3417 allocate_plt2_entries (dyn_i
, data
)
3418 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3421 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3423 if (dyn_i
->want_plt2
)
3425 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3426 bfd_size_type ofs
= x
->ofs
;
3428 dyn_i
->plt2_offset
= ofs
;
3429 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
3431 while (h
->root
.type
== bfd_link_hash_indirect
3432 || h
->root
.type
== bfd_link_hash_warning
)
3433 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3434 dyn_i
->h
->plt
.offset
= ofs
;
3439 /* Allocate all the PLTOFF entries requested by relocations and
3440 plt entries. We can't share space with allocated FPTR entries,
3441 because the latter are not necessarily addressable by the GP.
3442 ??? Relaxation might be able to determine that they are. */
3445 allocate_pltoff_entries (dyn_i
, data
)
3446 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3449 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3451 if (dyn_i
->want_pltoff
)
3453 dyn_i
->pltoff_offset
= x
->ofs
;
3459 /* Allocate dynamic relocations for those symbols that turned out
3463 allocate_dynrel_entries (dyn_i
, data
)
3464 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3467 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3468 struct elfNN_ia64_link_hash_table
*ia64_info
;
3469 struct elfNN_ia64_dyn_reloc_entry
*rent
;
3470 bfd_boolean dynamic_symbol
, shared
, resolved_zero
;
3472 ia64_info
= elfNN_ia64_hash_table (x
->info
);
3474 /* Note that this can't be used in relation to FPTR relocs below. */
3475 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0);
3477 shared
= x
->info
->shared
;
3478 resolved_zero
= (dyn_i
->h
3479 && ELF_ST_VISIBILITY (dyn_i
->h
->other
)
3480 && dyn_i
->h
->root
.type
== bfd_link_hash_undefweak
);
3482 /* Take care of the GOT and PLT relocations. */
3485 && (dynamic_symbol
|| shared
)
3486 && (dyn_i
->want_got
|| dyn_i
->want_gotx
))
3487 || (dyn_i
->want_ltoff_fptr
3489 && dyn_i
->h
->dynindx
!= -1))
3491 if (!dyn_i
->want_ltoff_fptr
3494 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
3495 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
3497 if ((dynamic_symbol
|| shared
) && dyn_i
->want_tprel
)
3498 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
3499 if (dynamic_symbol
&& dyn_i
->want_dtpmod
)
3500 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
3501 if (dynamic_symbol
&& dyn_i
->want_dtprel
)
3502 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
3507 if (ia64_info
->rel_fptr_sec
&& dyn_i
->want_fptr
)
3509 if (dyn_i
->h
== NULL
|| dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
3510 ia64_info
->rel_fptr_sec
->size
+= sizeof (ElfNN_External_Rela
);
3513 if (!resolved_zero
&& dyn_i
->want_pltoff
)
3515 bfd_size_type t
= 0;
3517 /* Dynamic symbols get one IPLT relocation. Local symbols in
3518 shared libraries get two REL relocations. Local symbols in
3519 main applications get nothing. */
3521 t
= sizeof (ElfNN_External_Rela
);
3523 t
= 2 * sizeof (ElfNN_External_Rela
);
3525 ia64_info
->rel_pltoff_sec
->size
+= t
;
3528 /* Take care of the normal data relocations. */
3530 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
3532 int count
= rent
->count
;
3536 case R_IA64_FPTR32LSB
:
3537 case R_IA64_FPTR64LSB
:
3538 /* Allocate one iff !want_fptr and not PIE, which by this point
3539 will be true only if we're actually allocating one statically
3540 in the main executable. Position independent executables
3541 need a relative reloc. */
3542 if (dyn_i
->want_fptr
&& !x
->info
->pie
)
3545 case R_IA64_PCREL32LSB
:
3546 case R_IA64_PCREL64LSB
:
3547 if (!dynamic_symbol
)
3550 case R_IA64_DIR32LSB
:
3551 case R_IA64_DIR64LSB
:
3552 if (!dynamic_symbol
&& !shared
)
3555 case R_IA64_IPLTLSB
:
3556 if (!dynamic_symbol
&& !shared
)
3558 /* Use two REL relocations for IPLT relocations
3559 against local symbols. */
3560 if (!dynamic_symbol
)
3563 case R_IA64_DTPREL32LSB
:
3564 case R_IA64_TPREL64LSB
:
3565 case R_IA64_DTPREL64LSB
:
3566 case R_IA64_DTPMOD64LSB
:
3572 ia64_info
->reltext
= 1;
3573 rent
->srel
->size
+= sizeof (ElfNN_External_Rela
) * count
;
3580 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
3581 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
3582 struct elf_link_hash_entry
*h
;
3584 /* ??? Undefined symbols with PLT entries should be re-defined
3585 to be the PLT entry. */
3587 /* If this is a weak symbol, and there is a real definition, the
3588 processor independent code will have arranged for us to see the
3589 real definition first, and we can just use the same value. */
3590 if (h
->u
.weakdef
!= NULL
)
3592 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
3593 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
3594 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
3595 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
3599 /* If this is a reference to a symbol defined by a dynamic object which
3600 is not a function, we might allocate the symbol in our .dynbss section
3601 and allocate a COPY dynamic relocation.
3603 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
3610 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
3611 bfd
*output_bfd ATTRIBUTE_UNUSED
;
3612 struct bfd_link_info
*info
;
3614 struct elfNN_ia64_allocate_data data
;
3615 struct elfNN_ia64_link_hash_table
*ia64_info
;
3618 bfd_boolean relplt
= FALSE
;
3620 dynobj
= elf_hash_table(info
)->dynobj
;
3621 ia64_info
= elfNN_ia64_hash_table (info
);
3622 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
3623 BFD_ASSERT(dynobj
!= NULL
);
3626 /* Set the contents of the .interp section to the interpreter. */
3627 if (ia64_info
->root
.dynamic_sections_created
3628 && info
->executable
)
3630 sec
= bfd_get_section_by_name (dynobj
, ".interp");
3631 BFD_ASSERT (sec
!= NULL
);
3632 sec
->contents
= (bfd_byte
*) ELF_DYNAMIC_INTERPRETER
;
3633 sec
->size
= strlen (ELF_DYNAMIC_INTERPRETER
) + 1;
3636 /* Allocate the GOT entries. */
3638 if (ia64_info
->got_sec
)
3641 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
3642 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
3643 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
3644 ia64_info
->got_sec
->size
= data
.ofs
;
3647 /* Allocate the FPTR entries. */
3649 if (ia64_info
->fptr_sec
)
3652 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
3653 ia64_info
->fptr_sec
->size
= data
.ofs
;
3656 /* Now that we've seen all of the input files, we can decide which
3657 symbols need plt entries. Allocate the minimal PLT entries first.
3658 We do this even though dynamic_sections_created may be FALSE, because
3659 this has the side-effect of clearing want_plt and want_plt2. */
3662 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
3664 ia64_info
->minplt_entries
= 0;
3667 ia64_info
->minplt_entries
3668 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
3671 /* Align the pointer for the plt2 entries. */
3672 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
3674 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
3675 if (data
.ofs
!= 0 || ia64_info
->root
.dynamic_sections_created
)
3677 /* FIXME: we always reserve the memory for dynamic linker even if
3678 there are no PLT entries since dynamic linker may assume the
3679 reserved memory always exists. */
3681 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
3683 ia64_info
->plt_sec
->size
= data
.ofs
;
3685 /* If we've got a .plt, we need some extra memory for the dynamic
3686 linker. We stuff these in .got.plt. */
3687 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
3688 sec
->size
= 8 * PLT_RESERVED_WORDS
;
3691 /* Allocate the PLTOFF entries. */
3693 if (ia64_info
->pltoff_sec
)
3696 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
3697 ia64_info
->pltoff_sec
->size
= data
.ofs
;
3700 if (ia64_info
->root
.dynamic_sections_created
)
3702 /* Allocate space for the dynamic relocations that turned out to be
3705 if (info
->shared
&& ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
3706 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
3707 data
.only_got
= FALSE
;
3708 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
3711 /* We have now determined the sizes of the various dynamic sections.
3712 Allocate memory for them. */
3713 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
3717 if (!(sec
->flags
& SEC_LINKER_CREATED
))
3720 /* If we don't need this section, strip it from the output file.
3721 There were several sections primarily related to dynamic
3722 linking that must be create before the linker maps input
3723 sections to output sections. The linker does that before
3724 bfd_elf_size_dynamic_sections is called, and it is that
3725 function which decides whether anything needs to go into
3728 strip
= (sec
->size
== 0);
3730 if (sec
== ia64_info
->got_sec
)
3732 else if (sec
== ia64_info
->rel_got_sec
)
3735 ia64_info
->rel_got_sec
= NULL
;
3737 /* We use the reloc_count field as a counter if we need to
3738 copy relocs into the output file. */
3739 sec
->reloc_count
= 0;
3741 else if (sec
== ia64_info
->fptr_sec
)
3744 ia64_info
->fptr_sec
= NULL
;
3746 else if (sec
== ia64_info
->rel_fptr_sec
)
3749 ia64_info
->rel_fptr_sec
= NULL
;
3751 /* We use the reloc_count field as a counter if we need to
3752 copy relocs into the output file. */
3753 sec
->reloc_count
= 0;
3755 else if (sec
== ia64_info
->plt_sec
)
3758 ia64_info
->plt_sec
= NULL
;
3760 else if (sec
== ia64_info
->pltoff_sec
)
3763 ia64_info
->pltoff_sec
= NULL
;
3765 else if (sec
== ia64_info
->rel_pltoff_sec
)
3768 ia64_info
->rel_pltoff_sec
= NULL
;
3772 /* We use the reloc_count field as a counter if we need to
3773 copy relocs into the output file. */
3774 sec
->reloc_count
= 0;
3781 /* It's OK to base decisions on the section name, because none
3782 of the dynobj section names depend upon the input files. */
3783 name
= bfd_get_section_name (dynobj
, sec
);
3785 if (strcmp (name
, ".got.plt") == 0)
3787 else if (CONST_STRNEQ (name
, ".rel"))
3791 /* We use the reloc_count field as a counter if we need to
3792 copy relocs into the output file. */
3793 sec
->reloc_count
= 0;
3801 sec
->flags
|= SEC_EXCLUDE
;
3804 /* Allocate memory for the section contents. */
3805 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->size
);
3806 if (sec
->contents
== NULL
&& sec
->size
!= 0)
3811 if (elf_hash_table (info
)->dynamic_sections_created
)
3813 /* Add some entries to the .dynamic section. We fill in the values
3814 later (in finish_dynamic_sections) but we must add the entries now
3815 so that we get the correct size for the .dynamic section. */
3817 if (info
->executable
)
3819 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3821 #define add_dynamic_entry(TAG, VAL) \
3822 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3824 if (!add_dynamic_entry (DT_DEBUG
, 0))
3828 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
3830 if (!add_dynamic_entry (DT_PLTGOT
, 0))
3835 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
3836 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
3837 || !add_dynamic_entry (DT_JMPREL
, 0))
3841 if (!add_dynamic_entry (DT_RELA
, 0)
3842 || !add_dynamic_entry (DT_RELASZ
, 0)
3843 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
3846 if (ia64_info
->reltext
)
3848 if (!add_dynamic_entry (DT_TEXTREL
, 0))
3850 info
->flags
|= DF_TEXTREL
;
3854 /* ??? Perhaps force __gp local. */
3859 static bfd_reloc_status_type
3860 elfNN_ia64_install_value (hit_addr
, v
, r_type
)
3863 unsigned int r_type
;
3865 const struct ia64_operand
*op
;
3866 int bigendian
= 0, shift
= 0;
3867 bfd_vma t0
, t1
, dword
;
3869 enum ia64_opnd opnd
;
3872 #ifdef BFD_HOST_U_64_BIT
3873 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
3878 opnd
= IA64_OPND_NIL
;
3883 return bfd_reloc_ok
;
3885 /* Instruction relocations. */
3888 case R_IA64_TPREL14
:
3889 case R_IA64_DTPREL14
:
3890 opnd
= IA64_OPND_IMM14
;
3893 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
3894 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
3895 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
3896 case R_IA64_PCREL21B
:
3897 case R_IA64_PCREL21BI
:
3898 opnd
= IA64_OPND_TGT25c
;
3902 case R_IA64_GPREL22
:
3903 case R_IA64_LTOFF22
:
3904 case R_IA64_LTOFF22X
:
3905 case R_IA64_PLTOFF22
:
3906 case R_IA64_PCREL22
:
3907 case R_IA64_LTOFF_FPTR22
:
3908 case R_IA64_TPREL22
:
3909 case R_IA64_DTPREL22
:
3910 case R_IA64_LTOFF_TPREL22
:
3911 case R_IA64_LTOFF_DTPMOD22
:
3912 case R_IA64_LTOFF_DTPREL22
:
3913 opnd
= IA64_OPND_IMM22
;
3917 case R_IA64_GPREL64I
:
3918 case R_IA64_LTOFF64I
:
3919 case R_IA64_PLTOFF64I
:
3920 case R_IA64_PCREL64I
:
3921 case R_IA64_FPTR64I
:
3922 case R_IA64_LTOFF_FPTR64I
:
3923 case R_IA64_TPREL64I
:
3924 case R_IA64_DTPREL64I
:
3925 opnd
= IA64_OPND_IMMU64
;
3928 /* Data relocations. */
3930 case R_IA64_DIR32MSB
:
3931 case R_IA64_GPREL32MSB
:
3932 case R_IA64_FPTR32MSB
:
3933 case R_IA64_PCREL32MSB
:
3934 case R_IA64_LTOFF_FPTR32MSB
:
3935 case R_IA64_SEGREL32MSB
:
3936 case R_IA64_SECREL32MSB
:
3937 case R_IA64_LTV32MSB
:
3938 case R_IA64_DTPREL32MSB
:
3939 size
= 4; bigendian
= 1;
3942 case R_IA64_DIR32LSB
:
3943 case R_IA64_GPREL32LSB
:
3944 case R_IA64_FPTR32LSB
:
3945 case R_IA64_PCREL32LSB
:
3946 case R_IA64_LTOFF_FPTR32LSB
:
3947 case R_IA64_SEGREL32LSB
:
3948 case R_IA64_SECREL32LSB
:
3949 case R_IA64_LTV32LSB
:
3950 case R_IA64_DTPREL32LSB
:
3951 size
= 4; bigendian
= 0;
3954 case R_IA64_DIR64MSB
:
3955 case R_IA64_GPREL64MSB
:
3956 case R_IA64_PLTOFF64MSB
:
3957 case R_IA64_FPTR64MSB
:
3958 case R_IA64_PCREL64MSB
:
3959 case R_IA64_LTOFF_FPTR64MSB
:
3960 case R_IA64_SEGREL64MSB
:
3961 case R_IA64_SECREL64MSB
:
3962 case R_IA64_LTV64MSB
:
3963 case R_IA64_TPREL64MSB
:
3964 case R_IA64_DTPMOD64MSB
:
3965 case R_IA64_DTPREL64MSB
:
3966 size
= 8; bigendian
= 1;
3969 case R_IA64_DIR64LSB
:
3970 case R_IA64_GPREL64LSB
:
3971 case R_IA64_PLTOFF64LSB
:
3972 case R_IA64_FPTR64LSB
:
3973 case R_IA64_PCREL64LSB
:
3974 case R_IA64_LTOFF_FPTR64LSB
:
3975 case R_IA64_SEGREL64LSB
:
3976 case R_IA64_SECREL64LSB
:
3977 case R_IA64_LTV64LSB
:
3978 case R_IA64_TPREL64LSB
:
3979 case R_IA64_DTPMOD64LSB
:
3980 case R_IA64_DTPREL64LSB
:
3981 size
= 8; bigendian
= 0;
3984 /* Unsupported / Dynamic relocations. */
3986 return bfd_reloc_notsupported
;
3991 case IA64_OPND_IMMU64
:
3992 hit_addr
-= (long) hit_addr
& 0x3;
3993 t0
= bfd_getl64 (hit_addr
);
3994 t1
= bfd_getl64 (hit_addr
+ 8);
3996 /* tmpl/s: bits 0.. 5 in t0
3997 slot 0: bits 5..45 in t0
3998 slot 1: bits 46..63 in t0, bits 0..22 in t1
3999 slot 2: bits 23..63 in t1 */
4001 /* First, clear the bits that form the 64 bit constant. */
4002 t0
&= ~(0x3ffffLL
<< 46);
4004 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
4005 | (0x01fLL
<< 22) | (0x001LL
<< 21)
4006 | (0x001LL
<< 36)) << 23));
4008 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
4009 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
4010 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
4011 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
4012 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
4013 | (((val
>> 21) & 0x001) << 21) /* ic */
4014 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
4016 bfd_putl64 (t0
, hit_addr
);
4017 bfd_putl64 (t1
, hit_addr
+ 8);
4020 case IA64_OPND_TGT64
:
4021 hit_addr
-= (long) hit_addr
& 0x3;
4022 t0
= bfd_getl64 (hit_addr
);
4023 t1
= bfd_getl64 (hit_addr
+ 8);
4025 /* tmpl/s: bits 0.. 5 in t0
4026 slot 0: bits 5..45 in t0
4027 slot 1: bits 46..63 in t0, bits 0..22 in t1
4028 slot 2: bits 23..63 in t1 */
4030 /* First, clear the bits that form the 64 bit constant. */
4031 t0
&= ~(0x3ffffLL
<< 46);
4033 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
4036 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
4037 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
4038 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
4039 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
4041 bfd_putl64 (t0
, hit_addr
);
4042 bfd_putl64 (t1
, hit_addr
+ 8);
4046 switch ((long) hit_addr
& 0x3)
4048 case 0: shift
= 5; break;
4049 case 1: shift
= 14; hit_addr
+= 3; break;
4050 case 2: shift
= 23; hit_addr
+= 6; break;
4051 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
4053 dword
= bfd_getl64 (hit_addr
);
4054 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
4056 op
= elf64_ia64_operands
+ opnd
;
4057 err
= (*op
->insert
) (op
, val
, &insn
);
4059 return bfd_reloc_overflow
;
4061 dword
&= ~(0x1ffffffffffLL
<< shift
);
4062 dword
|= (insn
<< shift
);
4063 bfd_putl64 (dword
, hit_addr
);
4067 /* A data relocation. */
4070 bfd_putb32 (val
, hit_addr
);
4072 bfd_putb64 (val
, hit_addr
);
4075 bfd_putl32 (val
, hit_addr
);
4077 bfd_putl64 (val
, hit_addr
);
4081 return bfd_reloc_ok
;
4085 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
4088 struct bfd_link_info
*info
;
4096 Elf_Internal_Rela outrel
;
4099 BFD_ASSERT (dynindx
!= -1);
4100 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
4101 outrel
.r_addend
= addend
;
4102 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
4103 if (outrel
.r_offset
>= (bfd_vma
) -2)
4105 /* Run for the hills. We shouldn't be outputting a relocation
4106 for this. So do what everyone else does and output a no-op. */
4107 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
4108 outrel
.r_addend
= 0;
4109 outrel
.r_offset
= 0;
4112 outrel
.r_offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
4114 loc
= srel
->contents
;
4115 loc
+= srel
->reloc_count
++ * sizeof (ElfNN_External_Rela
);
4116 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
4117 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
<= srel
->size
);
4120 /* Store an entry for target address TARGET_ADDR in the linkage table
4121 and return the gp-relative address of the linkage table entry. */
4124 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
4126 struct bfd_link_info
*info
;
4127 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4131 unsigned int dyn_r_type
;
4133 struct elfNN_ia64_link_hash_table
*ia64_info
;
4138 ia64_info
= elfNN_ia64_hash_table (info
);
4139 got_sec
= ia64_info
->got_sec
;
4143 case R_IA64_TPREL64LSB
:
4144 done
= dyn_i
->tprel_done
;
4145 dyn_i
->tprel_done
= TRUE
;
4146 got_offset
= dyn_i
->tprel_offset
;
4148 case R_IA64_DTPMOD64LSB
:
4149 if (dyn_i
->dtpmod_offset
!= ia64_info
->self_dtpmod_offset
)
4151 done
= dyn_i
->dtpmod_done
;
4152 dyn_i
->dtpmod_done
= TRUE
;
4156 done
= ia64_info
->self_dtpmod_done
;
4157 ia64_info
->self_dtpmod_done
= TRUE
;
4160 got_offset
= dyn_i
->dtpmod_offset
;
4162 case R_IA64_DTPREL32LSB
:
4163 case R_IA64_DTPREL64LSB
:
4164 done
= dyn_i
->dtprel_done
;
4165 dyn_i
->dtprel_done
= TRUE
;
4166 got_offset
= dyn_i
->dtprel_offset
;
4169 done
= dyn_i
->got_done
;
4170 dyn_i
->got_done
= TRUE
;
4171 got_offset
= dyn_i
->got_offset
;
4175 BFD_ASSERT ((got_offset
& 7) == 0);
4179 /* Store the target address in the linkage table entry. */
4180 bfd_put_64 (abfd
, value
, got_sec
->contents
+ got_offset
);
4182 /* Install a dynamic relocation if needed. */
4185 || ELF_ST_VISIBILITY (dyn_i
->h
->other
) == STV_DEFAULT
4186 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
4187 && dyn_r_type
!= R_IA64_DTPREL32LSB
4188 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
4189 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
, dyn_r_type
)
4191 && (dyn_r_type
== R_IA64_FPTR32LSB
4192 || dyn_r_type
== R_IA64_FPTR64LSB
)))
4193 && (!dyn_i
->want_ltoff_fptr
4196 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
))
4199 && dyn_r_type
!= R_IA64_TPREL64LSB
4200 && dyn_r_type
!= R_IA64_DTPMOD64LSB
4201 && dyn_r_type
!= R_IA64_DTPREL32LSB
4202 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
4204 dyn_r_type
= R_IA64_RELNNLSB
;
4209 if (bfd_big_endian (abfd
))
4213 case R_IA64_REL32LSB
:
4214 dyn_r_type
= R_IA64_REL32MSB
;
4216 case R_IA64_DIR32LSB
:
4217 dyn_r_type
= R_IA64_DIR32MSB
;
4219 case R_IA64_FPTR32LSB
:
4220 dyn_r_type
= R_IA64_FPTR32MSB
;
4222 case R_IA64_DTPREL32LSB
:
4223 dyn_r_type
= R_IA64_DTPREL32MSB
;
4225 case R_IA64_REL64LSB
:
4226 dyn_r_type
= R_IA64_REL64MSB
;
4228 case R_IA64_DIR64LSB
:
4229 dyn_r_type
= R_IA64_DIR64MSB
;
4231 case R_IA64_FPTR64LSB
:
4232 dyn_r_type
= R_IA64_FPTR64MSB
;
4234 case R_IA64_TPREL64LSB
:
4235 dyn_r_type
= R_IA64_TPREL64MSB
;
4237 case R_IA64_DTPMOD64LSB
:
4238 dyn_r_type
= R_IA64_DTPMOD64MSB
;
4240 case R_IA64_DTPREL64LSB
:
4241 dyn_r_type
= R_IA64_DTPREL64MSB
;
4249 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
4250 ia64_info
->rel_got_sec
,
4251 got_offset
, dyn_r_type
,
4256 /* Return the address of the linkage table entry. */
4257 value
= (got_sec
->output_section
->vma
4258 + got_sec
->output_offset
4264 /* Fill in a function descriptor consisting of the function's code
4265 address and its global pointer. Return the descriptor's address. */
4268 set_fptr_entry (abfd
, info
, dyn_i
, value
)
4270 struct bfd_link_info
*info
;
4271 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4274 struct elfNN_ia64_link_hash_table
*ia64_info
;
4277 ia64_info
= elfNN_ia64_hash_table (info
);
4278 fptr_sec
= ia64_info
->fptr_sec
;
4280 if (!dyn_i
->fptr_done
)
4282 dyn_i
->fptr_done
= 1;
4284 /* Fill in the function descriptor. */
4285 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
4286 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
4287 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
4288 if (ia64_info
->rel_fptr_sec
)
4290 Elf_Internal_Rela outrel
;
4293 if (bfd_little_endian (abfd
))
4294 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_IPLTLSB
);
4296 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_IPLTMSB
);
4297 outrel
.r_addend
= value
;
4298 outrel
.r_offset
= (fptr_sec
->output_section
->vma
4299 + fptr_sec
->output_offset
4300 + dyn_i
->fptr_offset
);
4301 loc
= ia64_info
->rel_fptr_sec
->contents
;
4302 loc
+= ia64_info
->rel_fptr_sec
->reloc_count
++
4303 * sizeof (ElfNN_External_Rela
);
4304 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
4308 /* Return the descriptor's address. */
4309 value
= (fptr_sec
->output_section
->vma
4310 + fptr_sec
->output_offset
4311 + dyn_i
->fptr_offset
);
4316 /* Fill in a PLTOFF entry consisting of the function's code address
4317 and its global pointer. Return the descriptor's address. */
4320 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
4322 struct bfd_link_info
*info
;
4323 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4327 struct elfNN_ia64_link_hash_table
*ia64_info
;
4328 asection
*pltoff_sec
;
4330 ia64_info
= elfNN_ia64_hash_table (info
);
4331 pltoff_sec
= ia64_info
->pltoff_sec
;
4333 /* Don't do anything if this symbol uses a real PLT entry. In
4334 that case, we'll fill this in during finish_dynamic_symbol. */
4335 if ((! dyn_i
->want_plt
|| is_plt
)
4336 && !dyn_i
->pltoff_done
)
4338 bfd_vma gp
= _bfd_get_gp_value (abfd
);
4340 /* Fill in the function descriptor. */
4341 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
4342 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
4344 /* Install dynamic relocations if needed. */
4348 || ELF_ST_VISIBILITY (dyn_i
->h
->other
) == STV_DEFAULT
4349 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
))
4351 unsigned int dyn_r_type
;
4353 if (bfd_big_endian (abfd
))
4354 dyn_r_type
= R_IA64_RELNNMSB
;
4356 dyn_r_type
= R_IA64_RELNNLSB
;
4358 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
4359 ia64_info
->rel_pltoff_sec
,
4360 dyn_i
->pltoff_offset
,
4361 dyn_r_type
, 0, value
);
4362 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
4363 ia64_info
->rel_pltoff_sec
,
4364 dyn_i
->pltoff_offset
+ ARCH_SIZE
/ 8,
4368 dyn_i
->pltoff_done
= 1;
4371 /* Return the descriptor's address. */
4372 value
= (pltoff_sec
->output_section
->vma
4373 + pltoff_sec
->output_offset
4374 + dyn_i
->pltoff_offset
);
4379 /* Return the base VMA address which should be subtracted from real addresses
4380 when resolving @tprel() relocation.
4381 Main program TLS (whose template starts at PT_TLS p_vaddr)
4382 is assigned offset round(2 * size of pointer, PT_TLS p_align). */
4385 elfNN_ia64_tprel_base (info
)
4386 struct bfd_link_info
*info
;
4388 asection
*tls_sec
= elf_hash_table (info
)->tls_sec
;
4390 BFD_ASSERT (tls_sec
!= NULL
);
4391 return tls_sec
->vma
- align_power ((bfd_vma
) ARCH_SIZE
/ 4,
4392 tls_sec
->alignment_power
);
4395 /* Return the base VMA address which should be subtracted from real addresses
4396 when resolving @dtprel() relocation.
4397 This is PT_TLS segment p_vaddr. */
4400 elfNN_ia64_dtprel_base (info
)
4401 struct bfd_link_info
*info
;
4403 BFD_ASSERT (elf_hash_table (info
)->tls_sec
!= NULL
);
4404 return elf_hash_table (info
)->tls_sec
->vma
;
4407 /* Called through qsort to sort the .IA_64.unwind section during a
4408 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
4409 to the output bfd so we can do proper endianness frobbing. */
4411 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
4414 elfNN_ia64_unwind_entry_compare (a
, b
)
4420 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
4421 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
4423 return (av
< bv
? -1 : av
> bv
? 1 : 0);
4426 /* Make sure we've got ourselves a nice fat __gp value. */
4428 elfNN_ia64_choose_gp (abfd
, info
)
4430 struct bfd_link_info
*info
;
4432 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
4433 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
4434 struct elf_link_hash_entry
*gp
;
4437 struct elfNN_ia64_link_hash_table
*ia64_info
;
4439 ia64_info
= elfNN_ia64_hash_table (info
);
4441 /* Find the min and max vma of all sections marked short. Also collect
4442 min and max vma of any type, for use in selecting a nice gp. */
4443 for (os
= abfd
->sections
; os
; os
= os
->next
)
4447 if ((os
->flags
& SEC_ALLOC
) == 0)
4451 hi
= os
->vma
+ (os
->rawsize
? os
->rawsize
: os
->size
);
4459 if (os
->flags
& SEC_SMALL_DATA
)
4461 if (min_short_vma
> lo
)
4463 if (max_short_vma
< hi
)
4468 /* See if the user wants to force a value. */
4469 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
4473 && (gp
->root
.type
== bfd_link_hash_defined
4474 || gp
->root
.type
== bfd_link_hash_defweak
))
4476 asection
*gp_sec
= gp
->root
.u
.def
.section
;
4477 gp_val
= (gp
->root
.u
.def
.value
4478 + gp_sec
->output_section
->vma
4479 + gp_sec
->output_offset
);
4483 /* Pick a sensible value. */
4485 asection
*got_sec
= ia64_info
->got_sec
;
4487 /* Start with just the address of the .got. */
4489 gp_val
= got_sec
->output_section
->vma
;
4490 else if (max_short_vma
!= 0)
4491 gp_val
= min_short_vma
;
4492 else if (max_vma
- min_vma
< 0x200000)
4495 gp_val
= max_vma
- 0x200000 + 8;
4497 /* If it is possible to address the entire image, but we
4498 don't with the choice above, adjust. */
4499 if (max_vma
- min_vma
< 0x400000
4500 && (max_vma
- gp_val
>= 0x200000
4501 || gp_val
- min_vma
> 0x200000))
4502 gp_val
= min_vma
+ 0x200000;
4503 else if (max_short_vma
!= 0)
4505 /* If we don't cover all the short data, adjust. */
4506 if (max_short_vma
- gp_val
>= 0x200000)
4507 gp_val
= min_short_vma
+ 0x200000;
4509 /* If we're addressing stuff past the end, adjust back. */
4510 if (gp_val
> max_vma
)
4511 gp_val
= max_vma
- 0x200000 + 8;
4515 /* Validate whether all SHF_IA_64_SHORT sections are within
4516 range of the chosen GP. */
4518 if (max_short_vma
!= 0)
4520 if (max_short_vma
- min_short_vma
>= 0x400000)
4522 (*_bfd_error_handler
)
4523 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
4524 bfd_get_filename (abfd
),
4525 (unsigned long) (max_short_vma
- min_short_vma
));
4528 else if ((gp_val
> min_short_vma
4529 && gp_val
- min_short_vma
> 0x200000)
4530 || (gp_val
< max_short_vma
4531 && max_short_vma
- gp_val
>= 0x200000))
4533 (*_bfd_error_handler
)
4534 (_("%s: __gp does not cover short data segment"),
4535 bfd_get_filename (abfd
));
4540 _bfd_set_gp_value (abfd
, gp_val
);
4546 elfNN_ia64_final_link (abfd
, info
)
4548 struct bfd_link_info
*info
;
4550 struct elfNN_ia64_link_hash_table
*ia64_info
;
4551 asection
*unwind_output_sec
;
4553 ia64_info
= elfNN_ia64_hash_table (info
);
4555 /* Make sure we've got ourselves a nice fat __gp value. */
4556 if (!info
->relocatable
)
4559 struct elf_link_hash_entry
*gp
;
4561 /* We assume after gp is set, section size will only decrease. We
4562 need to adjust gp for it. */
4563 _bfd_set_gp_value (abfd
, 0);
4564 if (! elfNN_ia64_choose_gp (abfd
, info
))
4566 gp_val
= _bfd_get_gp_value (abfd
);
4568 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
4572 gp
->root
.type
= bfd_link_hash_defined
;
4573 gp
->root
.u
.def
.value
= gp_val
;
4574 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
4578 /* If we're producing a final executable, we need to sort the contents
4579 of the .IA_64.unwind section. Force this section to be relocated
4580 into memory rather than written immediately to the output file. */
4581 unwind_output_sec
= NULL
;
4582 if (!info
->relocatable
)
4584 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
4587 unwind_output_sec
= s
->output_section
;
4588 unwind_output_sec
->contents
4589 = bfd_malloc (unwind_output_sec
->size
);
4590 if (unwind_output_sec
->contents
== NULL
)
4595 /* Invoke the regular ELF backend linker to do all the work. */
4596 if (!bfd_elf_final_link (abfd
, info
))
4599 if (unwind_output_sec
)
4601 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
4602 qsort (unwind_output_sec
->contents
,
4603 (size_t) (unwind_output_sec
->size
/ 24),
4605 elfNN_ia64_unwind_entry_compare
);
4607 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
4608 unwind_output_sec
->contents
, (bfd_vma
) 0,
4609 unwind_output_sec
->size
))
4617 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
4618 contents
, relocs
, local_syms
, local_sections
)
4620 struct bfd_link_info
*info
;
4622 asection
*input_section
;
4624 Elf_Internal_Rela
*relocs
;
4625 Elf_Internal_Sym
*local_syms
;
4626 asection
**local_sections
;
4628 struct elfNN_ia64_link_hash_table
*ia64_info
;
4629 Elf_Internal_Shdr
*symtab_hdr
;
4630 Elf_Internal_Rela
*rel
;
4631 Elf_Internal_Rela
*relend
;
4633 bfd_boolean ret_val
= TRUE
; /* for non-fatal errors */
4636 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
4637 ia64_info
= elfNN_ia64_hash_table (info
);
4639 /* Infect various flags from the input section to the output section. */
4640 if (info
->relocatable
)
4644 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
4645 flags
&= SHF_IA_64_NORECOV
;
4647 elf_section_data(input_section
->output_section
)
4648 ->this_hdr
.sh_flags
|= flags
;
4651 gp_val
= _bfd_get_gp_value (output_bfd
);
4652 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, FALSE
);
4655 relend
= relocs
+ input_section
->reloc_count
;
4656 for (; rel
< relend
; ++rel
)
4658 struct elf_link_hash_entry
*h
;
4659 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4660 bfd_reloc_status_type r
;
4661 reloc_howto_type
*howto
;
4662 unsigned long r_symndx
;
4663 Elf_Internal_Sym
*sym
;
4664 unsigned int r_type
;
4668 bfd_boolean dynamic_symbol_p
;
4669 bfd_boolean undef_weak_ref
;
4671 r_type
= ELFNN_R_TYPE (rel
->r_info
);
4672 if (r_type
> R_IA64_MAX_RELOC_CODE
)
4674 (*_bfd_error_handler
)
4675 (_("%B: unknown relocation type %d"),
4676 input_bfd
, (int) r_type
);
4677 bfd_set_error (bfd_error_bad_value
);
4682 howto
= lookup_howto (r_type
);
4683 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4687 undef_weak_ref
= FALSE
;
4689 if (r_symndx
< symtab_hdr
->sh_info
)
4691 /* Reloc against local symbol. */
4693 sym
= local_syms
+ r_symndx
;
4694 sym_sec
= local_sections
[r_symndx
];
4696 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &msec
, rel
);
4697 if (!info
->relocatable
4698 && (sym_sec
->flags
& SEC_MERGE
) != 0
4699 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
4700 && sym_sec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
4702 struct elfNN_ia64_local_hash_entry
*loc_h
;
4704 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, FALSE
);
4705 if (loc_h
&& ! loc_h
->sec_merge_done
)
4707 struct elfNN_ia64_dyn_sym_info
*dynent
;
4710 for (count
= loc_h
->count
, dynent
= loc_h
->info
;
4716 _bfd_merged_section_offset (output_bfd
, &msec
,
4717 elf_section_data (msec
)->
4721 dynent
->addend
-= sym
->st_value
;
4722 dynent
->addend
+= msec
->output_section
->vma
4723 + msec
->output_offset
4724 - sym_sec
->output_section
->vma
4725 - sym_sec
->output_offset
;
4728 /* We may have introduced duplicated entries. We need
4729 to remove them properly. */
4730 count
= sort_dyn_sym_info (loc_h
->info
, loc_h
->count
);
4731 if (count
!= loc_h
->count
)
4733 loc_h
->count
= count
;
4734 loc_h
->sorted_count
= count
;
4737 loc_h
->sec_merge_done
= 1;
4743 bfd_boolean unresolved_reloc
;
4745 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
4747 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
4748 r_symndx
, symtab_hdr
, sym_hashes
,
4750 unresolved_reloc
, warned
);
4752 if (h
->root
.type
== bfd_link_hash_undefweak
)
4753 undef_weak_ref
= TRUE
;
4758 /* For relocs against symbols from removed linkonce sections,
4759 or sections discarded by a linker script, we just want the
4760 section contents zeroed. Avoid any special processing. */
4761 if (sym_sec
!= NULL
&& elf_discarded_section (sym_sec
))
4763 _bfd_clear_contents (howto
, input_bfd
, contents
+ rel
->r_offset
);
4769 if (info
->relocatable
)
4772 hit_addr
= contents
+ rel
->r_offset
;
4773 value
+= rel
->r_addend
;
4774 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
, r_type
);
4785 case R_IA64_DIR32MSB
:
4786 case R_IA64_DIR32LSB
:
4787 case R_IA64_DIR64MSB
:
4788 case R_IA64_DIR64LSB
:
4789 /* Install a dynamic relocation for this reloc. */
4790 if ((dynamic_symbol_p
|| info
->shared
)
4792 && (input_section
->flags
& SEC_ALLOC
) != 0)
4794 unsigned int dyn_r_type
;
4798 BFD_ASSERT (srel
!= NULL
);
4805 /* ??? People shouldn't be doing non-pic code in
4806 shared libraries nor dynamic executables. */
4807 (*_bfd_error_handler
)
4808 (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4810 h
? h
->root
.root
.string
4811 : bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4820 /* If we don't need dynamic symbol lookup, find a
4821 matching RELATIVE relocation. */
4822 dyn_r_type
= r_type
;
4823 if (dynamic_symbol_p
)
4825 dynindx
= h
->dynindx
;
4826 addend
= rel
->r_addend
;
4833 case R_IA64_DIR32MSB
:
4834 dyn_r_type
= R_IA64_REL32MSB
;
4836 case R_IA64_DIR32LSB
:
4837 dyn_r_type
= R_IA64_REL32LSB
;
4839 case R_IA64_DIR64MSB
:
4840 dyn_r_type
= R_IA64_REL64MSB
;
4842 case R_IA64_DIR64LSB
:
4843 dyn_r_type
= R_IA64_REL64LSB
;
4853 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4854 srel
, rel
->r_offset
, dyn_r_type
,
4859 case R_IA64_LTV32MSB
:
4860 case R_IA64_LTV32LSB
:
4861 case R_IA64_LTV64MSB
:
4862 case R_IA64_LTV64LSB
:
4863 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4866 case R_IA64_GPREL22
:
4867 case R_IA64_GPREL64I
:
4868 case R_IA64_GPREL32MSB
:
4869 case R_IA64_GPREL32LSB
:
4870 case R_IA64_GPREL64MSB
:
4871 case R_IA64_GPREL64LSB
:
4872 if (dynamic_symbol_p
)
4874 (*_bfd_error_handler
)
4875 (_("%B: @gprel relocation against dynamic symbol %s"),
4877 h
? h
->root
.root
.string
4878 : bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4884 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4887 case R_IA64_LTOFF22
:
4888 case R_IA64_LTOFF22X
:
4889 case R_IA64_LTOFF64I
:
4890 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4891 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
4892 rel
->r_addend
, value
, R_IA64_DIRNNLSB
);
4894 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4897 case R_IA64_PLTOFF22
:
4898 case R_IA64_PLTOFF64I
:
4899 case R_IA64_PLTOFF64MSB
:
4900 case R_IA64_PLTOFF64LSB
:
4901 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4902 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, FALSE
);
4904 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4907 case R_IA64_FPTR64I
:
4908 case R_IA64_FPTR32MSB
:
4909 case R_IA64_FPTR32LSB
:
4910 case R_IA64_FPTR64MSB
:
4911 case R_IA64_FPTR64LSB
:
4912 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4913 if (dyn_i
->want_fptr
)
4915 if (!undef_weak_ref
)
4916 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4918 if (!dyn_i
->want_fptr
|| info
->pie
)
4921 unsigned int dyn_r_type
= r_type
;
4922 bfd_vma addend
= rel
->r_addend
;
4924 /* Otherwise, we expect the dynamic linker to create
4927 if (dyn_i
->want_fptr
)
4929 if (r_type
== R_IA64_FPTR64I
)
4931 /* We can't represent this without a dynamic symbol.
4932 Adjust the relocation to be against an output
4933 section symbol, which are always present in the
4934 dynamic symbol table. */
4935 /* ??? People shouldn't be doing non-pic code in
4936 shared libraries. Hork. */
4937 (*_bfd_error_handler
)
4938 (_("%B: linking non-pic code in a position independent executable"),
4945 dyn_r_type
= r_type
+ R_IA64_RELNNLSB
- R_IA64_FPTRNNLSB
;
4949 if (h
->dynindx
!= -1)
4950 dynindx
= h
->dynindx
;
4952 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4953 (info
, h
->root
.u
.def
.section
->owner
,
4954 global_sym_index (h
)));
4959 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4960 (info
, input_bfd
, (long) r_symndx
));
4964 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4965 srel
, rel
->r_offset
, dyn_r_type
,
4969 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4972 case R_IA64_LTOFF_FPTR22
:
4973 case R_IA64_LTOFF_FPTR64I
:
4974 case R_IA64_LTOFF_FPTR32MSB
:
4975 case R_IA64_LTOFF_FPTR32LSB
:
4976 case R_IA64_LTOFF_FPTR64MSB
:
4977 case R_IA64_LTOFF_FPTR64LSB
:
4981 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4982 if (dyn_i
->want_fptr
)
4984 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1);
4985 if (!undef_weak_ref
)
4986 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4991 /* Otherwise, we expect the dynamic linker to create
4995 if (h
->dynindx
!= -1)
4996 dynindx
= h
->dynindx
;
4998 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4999 (info
, h
->root
.u
.def
.section
->owner
,
5000 global_sym_index (h
)));
5003 dynindx
= (_bfd_elf_link_lookup_local_dynindx
5004 (info
, input_bfd
, (long) r_symndx
));
5008 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
5009 rel
->r_addend
, value
, R_IA64_FPTRNNLSB
);
5011 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5015 case R_IA64_PCREL32MSB
:
5016 case R_IA64_PCREL32LSB
:
5017 case R_IA64_PCREL64MSB
:
5018 case R_IA64_PCREL64LSB
:
5019 /* Install a dynamic relocation for this reloc. */
5020 if (dynamic_symbol_p
&& r_symndx
!= 0)
5022 BFD_ASSERT (srel
!= NULL
);
5024 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
5025 srel
, rel
->r_offset
, r_type
,
5026 h
->dynindx
, rel
->r_addend
);
5030 case R_IA64_PCREL21B
:
5031 case R_IA64_PCREL60B
:
5032 /* We should have created a PLT entry for any dynamic symbol. */
5035 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
5037 if (dyn_i
&& dyn_i
->want_plt2
)
5039 /* Should have caught this earlier. */
5040 BFD_ASSERT (rel
->r_addend
== 0);
5042 value
= (ia64_info
->plt_sec
->output_section
->vma
5043 + ia64_info
->plt_sec
->output_offset
5044 + dyn_i
->plt2_offset
);
5048 /* Since there's no PLT entry, Validate that this is
5050 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
5052 /* If the symbol is undef_weak, we shouldn't be trying
5053 to call it. There's every chance that we'd wind up
5054 with an out-of-range fixup here. Don't bother setting
5055 any value at all. */
5061 case R_IA64_PCREL21BI
:
5062 case R_IA64_PCREL21F
:
5063 case R_IA64_PCREL21M
:
5064 case R_IA64_PCREL22
:
5065 case R_IA64_PCREL64I
:
5066 /* The PCREL21BI reloc is specifically not intended for use with
5067 dynamic relocs. PCREL21F and PCREL21M are used for speculation
5068 fixup code, and thus probably ought not be dynamic. The
5069 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
5070 if (dynamic_symbol_p
)
5074 if (r_type
== R_IA64_PCREL21BI
)
5075 msg
= _("%B: @internal branch to dynamic symbol %s");
5076 else if (r_type
== R_IA64_PCREL21F
|| r_type
== R_IA64_PCREL21M
)
5077 msg
= _("%B: speculation fixup to dynamic symbol %s");
5079 msg
= _("%B: @pcrel relocation against dynamic symbol %s");
5080 (*_bfd_error_handler
) (msg
, input_bfd
,
5081 h
? h
->root
.root
.string
5082 : bfd_elf_sym_name (input_bfd
,
5092 /* Make pc-relative. */
5093 value
-= (input_section
->output_section
->vma
5094 + input_section
->output_offset
5095 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
5096 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5099 case R_IA64_SEGREL32MSB
:
5100 case R_IA64_SEGREL32LSB
:
5101 case R_IA64_SEGREL64MSB
:
5102 case R_IA64_SEGREL64LSB
:
5104 struct elf_segment_map
*m
;
5105 Elf_Internal_Phdr
*p
;
5107 /* Find the segment that contains the output_section. */
5108 for (m
= elf_tdata (output_bfd
)->segment_map
,
5109 p
= elf_tdata (output_bfd
)->phdr
;
5114 for (i
= m
->count
- 1; i
>= 0; i
--)
5115 if (m
->sections
[i
] == input_section
->output_section
)
5123 r
= bfd_reloc_notsupported
;
5127 /* The VMA of the segment is the vaddr of the associated
5129 if (value
> p
->p_vaddr
)
5130 value
-= p
->p_vaddr
;
5133 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5138 case R_IA64_SECREL32MSB
:
5139 case R_IA64_SECREL32LSB
:
5140 case R_IA64_SECREL64MSB
:
5141 case R_IA64_SECREL64LSB
:
5142 /* Make output-section relative to section where the symbol
5143 is defined. PR 475 */
5145 value
-= sym_sec
->output_section
->vma
;
5146 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5149 case R_IA64_IPLTMSB
:
5150 case R_IA64_IPLTLSB
:
5151 /* Install a dynamic relocation for this reloc. */
5152 if ((dynamic_symbol_p
|| info
->shared
)
5153 && (input_section
->flags
& SEC_ALLOC
) != 0)
5155 BFD_ASSERT (srel
!= NULL
);
5157 /* If we don't need dynamic symbol lookup, install two
5158 RELATIVE relocations. */
5159 if (!dynamic_symbol_p
)
5161 unsigned int dyn_r_type
;
5163 if (r_type
== R_IA64_IPLTMSB
)
5164 dyn_r_type
= R_IA64_REL64MSB
;
5166 dyn_r_type
= R_IA64_REL64LSB
;
5168 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
5170 srel
, rel
->r_offset
,
5171 dyn_r_type
, 0, value
);
5172 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
5174 srel
, rel
->r_offset
+ 8,
5175 dyn_r_type
, 0, gp_val
);
5178 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
5179 srel
, rel
->r_offset
, r_type
,
5180 h
->dynindx
, rel
->r_addend
);
5183 if (r_type
== R_IA64_IPLTMSB
)
5184 r_type
= R_IA64_DIR64MSB
;
5186 r_type
= R_IA64_DIR64LSB
;
5187 elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5188 r
= elfNN_ia64_install_value (hit_addr
+ 8, gp_val
, r_type
);
5191 case R_IA64_TPREL14
:
5192 case R_IA64_TPREL22
:
5193 case R_IA64_TPREL64I
:
5194 value
-= elfNN_ia64_tprel_base (info
);
5195 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5198 case R_IA64_DTPREL14
:
5199 case R_IA64_DTPREL22
:
5200 case R_IA64_DTPREL64I
:
5201 case R_IA64_DTPREL32LSB
:
5202 case R_IA64_DTPREL32MSB
:
5203 case R_IA64_DTPREL64LSB
:
5204 case R_IA64_DTPREL64MSB
:
5205 value
-= elfNN_ia64_dtprel_base (info
);
5206 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5209 case R_IA64_LTOFF_TPREL22
:
5210 case R_IA64_LTOFF_DTPMOD22
:
5211 case R_IA64_LTOFF_DTPREL22
:
5214 long dynindx
= h
? h
->dynindx
: -1;
5215 bfd_vma r_addend
= rel
->r_addend
;
5220 case R_IA64_LTOFF_TPREL22
:
5221 if (!dynamic_symbol_p
)
5224 value
-= elfNN_ia64_tprel_base (info
);
5227 r_addend
+= value
- elfNN_ia64_dtprel_base (info
);
5231 got_r_type
= R_IA64_TPREL64LSB
;
5233 case R_IA64_LTOFF_DTPMOD22
:
5234 if (!dynamic_symbol_p
&& !info
->shared
)
5236 got_r_type
= R_IA64_DTPMOD64LSB
;
5238 case R_IA64_LTOFF_DTPREL22
:
5239 if (!dynamic_symbol_p
)
5240 value
-= elfNN_ia64_dtprel_base (info
);
5241 got_r_type
= R_IA64_DTPRELNNLSB
;
5244 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
5245 value
= set_got_entry (input_bfd
, info
, dyn_i
, dynindx
, r_addend
,
5248 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5253 r
= bfd_reloc_notsupported
;
5262 case bfd_reloc_undefined
:
5263 /* This can happen for global table relative relocs if
5264 __gp is undefined. This is a panic situation so we
5265 don't try to continue. */
5266 (*info
->callbacks
->undefined_symbol
)
5267 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
5270 case bfd_reloc_notsupported
:
5275 name
= h
->root
.root
.string
;
5277 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
5279 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
5281 input_section
, rel
->r_offset
))
5287 case bfd_reloc_dangerous
:
5288 case bfd_reloc_outofrange
:
5289 case bfd_reloc_overflow
:
5295 name
= h
->root
.root
.string
;
5297 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
5302 case R_IA64_PCREL21B
:
5303 case R_IA64_PCREL21BI
:
5304 case R_IA64_PCREL21M
:
5305 case R_IA64_PCREL21F
:
5306 if (is_elf_hash_table (info
->hash
))
5308 /* Relaxtion is always performed for ELF output.
5309 Overflow failures for those relocations mean
5310 that the section is too big to relax. */
5311 (*_bfd_error_handler
)
5312 (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
5313 input_bfd
, input_section
, howto
->name
, name
,
5314 rel
->r_offset
, input_section
->size
);
5318 if (!(*info
->callbacks
->reloc_overflow
) (info
,
5340 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
5342 struct bfd_link_info
*info
;
5343 struct elf_link_hash_entry
*h
;
5344 Elf_Internal_Sym
*sym
;
5346 struct elfNN_ia64_link_hash_table
*ia64_info
;
5347 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
5349 ia64_info
= elfNN_ia64_hash_table (info
);
5350 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
5352 /* Fill in the PLT data, if required. */
5353 if (dyn_i
&& dyn_i
->want_plt
)
5355 Elf_Internal_Rela outrel
;
5358 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
5360 gp_val
= _bfd_get_gp_value (output_bfd
);
5362 /* Initialize the minimal PLT entry. */
5364 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
5365 plt_sec
= ia64_info
->plt_sec
;
5366 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
5368 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
5369 elfNN_ia64_install_value (loc
, index
, R_IA64_IMM22
);
5370 elfNN_ia64_install_value (loc
+2, -dyn_i
->plt_offset
, R_IA64_PCREL21B
);
5372 plt_addr
= (plt_sec
->output_section
->vma
5373 + plt_sec
->output_offset
5374 + dyn_i
->plt_offset
);
5375 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, TRUE
);
5377 /* Initialize the FULL PLT entry, if needed. */
5378 if (dyn_i
->want_plt2
)
5380 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
5382 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
5383 elfNN_ia64_install_value (loc
, pltoff_addr
- gp_val
, R_IA64_IMM22
);
5385 /* Mark the symbol as undefined, rather than as defined in the
5386 plt section. Leave the value alone. */
5387 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
5388 first place. But perhaps elflink.c did some for us. */
5389 if (!h
->def_regular
)
5390 sym
->st_shndx
= SHN_UNDEF
;
5393 /* Create the dynamic relocation. */
5394 outrel
.r_offset
= pltoff_addr
;
5395 if (bfd_little_endian (output_bfd
))
5396 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
5398 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
5399 outrel
.r_addend
= 0;
5401 /* This is fun. In the .IA_64.pltoff section, we've got entries
5402 that correspond both to real PLT entries, and those that
5403 happened to resolve to local symbols but need to be created
5404 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
5405 relocations for the real PLT should come at the end of the
5406 section, so that they can be indexed by plt entry at runtime.
5408 We emitted all of the relocations for the non-PLT @pltoff
5409 entries during relocate_section. So we can consider the
5410 existing sec->reloc_count to be the base of the array of
5413 loc
= ia64_info
->rel_pltoff_sec
->contents
;
5414 loc
+= ((ia64_info
->rel_pltoff_sec
->reloc_count
+ index
)
5415 * sizeof (ElfNN_External_Rela
));
5416 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
5419 /* Mark some specially defined symbols as absolute. */
5420 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
5421 || h
== ia64_info
->root
.hgot
5422 || h
== ia64_info
->root
.hplt
)
5423 sym
->st_shndx
= SHN_ABS
;
5429 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
5431 struct bfd_link_info
*info
;
5433 struct elfNN_ia64_link_hash_table
*ia64_info
;
5436 ia64_info
= elfNN_ia64_hash_table (info
);
5437 dynobj
= ia64_info
->root
.dynobj
;
5439 if (elf_hash_table (info
)->dynamic_sections_created
)
5441 ElfNN_External_Dyn
*dyncon
, *dynconend
;
5442 asection
*sdyn
, *sgotplt
;
5445 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
5446 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
5447 BFD_ASSERT (sdyn
!= NULL
);
5448 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
5449 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
5451 gp_val
= _bfd_get_gp_value (abfd
);
5453 for (; dyncon
< dynconend
; dyncon
++)
5455 Elf_Internal_Dyn dyn
;
5457 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
5462 dyn
.d_un
.d_ptr
= gp_val
;
5466 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
5467 * sizeof (ElfNN_External_Rela
));
5471 /* See the comment above in finish_dynamic_symbol. */
5472 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
5473 + ia64_info
->rel_pltoff_sec
->output_offset
5474 + (ia64_info
->rel_pltoff_sec
->reloc_count
5475 * sizeof (ElfNN_External_Rela
)));
5478 case DT_IA_64_PLT_RESERVE
:
5479 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
5480 + sgotplt
->output_offset
);
5484 /* Do not have RELASZ include JMPREL. This makes things
5485 easier on ld.so. This is not what the rest of BFD set up. */
5486 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
5487 * sizeof (ElfNN_External_Rela
));
5491 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
5494 /* Initialize the PLT0 entry. */
5495 if (ia64_info
->plt_sec
)
5497 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
5500 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
5502 pltres
= (sgotplt
->output_section
->vma
5503 + sgotplt
->output_offset
5506 elfNN_ia64_install_value (loc
+1, pltres
, R_IA64_GPREL22
);
5513 /* ELF file flag handling: */
5515 /* Function to keep IA-64 specific file flags. */
5517 elfNN_ia64_set_private_flags (abfd
, flags
)
5521 BFD_ASSERT (!elf_flags_init (abfd
)
5522 || elf_elfheader (abfd
)->e_flags
== flags
);
5524 elf_elfheader (abfd
)->e_flags
= flags
;
5525 elf_flags_init (abfd
) = TRUE
;
5529 /* Merge backend specific data from an object file to the output
5530 object file when linking. */
5532 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
5537 bfd_boolean ok
= TRUE
;
5539 /* Don't even pretend to support mixed-format linking. */
5540 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
5541 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
5544 in_flags
= elf_elfheader (ibfd
)->e_flags
;
5545 out_flags
= elf_elfheader (obfd
)->e_flags
;
5547 if (! elf_flags_init (obfd
))
5549 elf_flags_init (obfd
) = TRUE
;
5550 elf_elfheader (obfd
)->e_flags
= in_flags
;
5552 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
5553 && bfd_get_arch_info (obfd
)->the_default
)
5555 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
5556 bfd_get_mach (ibfd
));
5562 /* Check flag compatibility. */
5563 if (in_flags
== out_flags
)
5566 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
5567 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
5568 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
5570 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
5572 (*_bfd_error_handler
)
5573 (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5576 bfd_set_error (bfd_error_bad_value
);
5579 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
5581 (*_bfd_error_handler
)
5582 (_("%B: linking big-endian files with little-endian files"),
5585 bfd_set_error (bfd_error_bad_value
);
5588 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
5590 (*_bfd_error_handler
)
5591 (_("%B: linking 64-bit files with 32-bit files"),
5594 bfd_set_error (bfd_error_bad_value
);
5597 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
5599 (*_bfd_error_handler
)
5600 (_("%B: linking constant-gp files with non-constant-gp files"),
5603 bfd_set_error (bfd_error_bad_value
);
5606 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
5607 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
5609 (*_bfd_error_handler
)
5610 (_("%B: linking auto-pic files with non-auto-pic files"),
5613 bfd_set_error (bfd_error_bad_value
);
5621 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
5625 FILE *file
= (FILE *) ptr
;
5626 flagword flags
= elf_elfheader (abfd
)->e_flags
;
5628 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
5630 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
5631 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
5632 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
5633 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
5634 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
5635 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
5636 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
5637 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
5638 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
5640 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
5644 static enum elf_reloc_type_class
5645 elfNN_ia64_reloc_type_class (rela
)
5646 const Elf_Internal_Rela
*rela
;
5648 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
5650 case R_IA64_REL32MSB
:
5651 case R_IA64_REL32LSB
:
5652 case R_IA64_REL64MSB
:
5653 case R_IA64_REL64LSB
:
5654 return reloc_class_relative
;
5655 case R_IA64_IPLTMSB
:
5656 case R_IA64_IPLTLSB
:
5657 return reloc_class_plt
;
5659 return reloc_class_copy
;
5661 return reloc_class_normal
;
5665 static const struct bfd_elf_special_section elfNN_ia64_special_sections
[] =
5667 { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_IA_64_SHORT
},
5668 { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_IA_64_SHORT
},
5669 { NULL
, 0, 0, 0, 0 }
5673 elfNN_ia64_object_p (bfd
*abfd
)
5676 asection
*group
, *unwi
, *unw
;
5679 char *unwi_name
, *unw_name
;
5682 if (abfd
->flags
& DYNAMIC
)
5685 /* Flags for fake group section. */
5686 flags
= (SEC_LINKER_CREATED
| SEC_GROUP
| SEC_LINK_ONCE
5689 /* We add a fake section group for each .gnu.linkonce.t.* section,
5690 which isn't in a section group, and its unwind sections. */
5691 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
5693 if (elf_sec_group (sec
) == NULL
5694 && ((sec
->flags
& (SEC_LINK_ONCE
| SEC_CODE
| SEC_GROUP
))
5695 == (SEC_LINK_ONCE
| SEC_CODE
))
5696 && CONST_STRNEQ (sec
->name
, ".gnu.linkonce.t."))
5698 name
= sec
->name
+ 16;
5700 amt
= strlen (name
) + sizeof (".gnu.linkonce.ia64unwi.");
5701 unwi_name
= bfd_alloc (abfd
, amt
);
5705 strcpy (stpcpy (unwi_name
, ".gnu.linkonce.ia64unwi."), name
);
5706 unwi
= bfd_get_section_by_name (abfd
, unwi_name
);
5708 amt
= strlen (name
) + sizeof (".gnu.linkonce.ia64unw.");
5709 unw_name
= bfd_alloc (abfd
, amt
);
5713 strcpy (stpcpy (unw_name
, ".gnu.linkonce.ia64unw."), name
);
5714 unw
= bfd_get_section_by_name (abfd
, unw_name
);
5716 /* We need to create a fake group section for it and its
5718 group
= bfd_make_section_anyway_with_flags (abfd
, name
,
5723 /* Move the fake group section to the beginning. */
5724 bfd_section_list_remove (abfd
, group
);
5725 bfd_section_list_prepend (abfd
, group
);
5727 elf_next_in_group (group
) = sec
;
5729 elf_group_name (sec
) = name
;
5730 elf_next_in_group (sec
) = sec
;
5731 elf_sec_group (sec
) = group
;
5735 elf_group_name (unwi
) = name
;
5736 elf_next_in_group (unwi
) = sec
;
5737 elf_next_in_group (sec
) = unwi
;
5738 elf_sec_group (unwi
) = group
;
5743 elf_group_name (unw
) = name
;
5746 elf_next_in_group (unw
) = elf_next_in_group (unwi
);
5747 elf_next_in_group (unwi
) = unw
;
5751 elf_next_in_group (unw
) = sec
;
5752 elf_next_in_group (sec
) = unw
;
5754 elf_sec_group (unw
) = group
;
5757 /* Fake SHT_GROUP section header. */
5758 elf_section_data (group
)->this_hdr
.bfd_section
= group
;
5759 elf_section_data (group
)->this_hdr
.sh_type
= SHT_GROUP
;
5766 elfNN_ia64_hpux_vec (const bfd_target
*vec
)
5768 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec
;
5769 return (vec
== & bfd_elfNN_ia64_hpux_big_vec
);
5773 elfNN_hpux_post_process_headers (abfd
, info
)
5775 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
5777 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
5779 i_ehdrp
->e_ident
[EI_OSABI
] = get_elf_backend_data (abfd
)->elf_osabi
;
5780 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 1;
5784 elfNN_hpux_backend_section_from_bfd_section (abfd
, sec
, retval
)
5785 bfd
*abfd ATTRIBUTE_UNUSED
;
5789 if (bfd_is_com_section (sec
))
5791 *retval
= SHN_IA_64_ANSI_COMMON
;
5798 elfNN_hpux_backend_symbol_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
5801 elf_symbol_type
*elfsym
= (elf_symbol_type
*) asym
;
5803 switch (elfsym
->internal_elf_sym
.st_shndx
)
5805 case SHN_IA_64_ANSI_COMMON
:
5806 asym
->section
= bfd_com_section_ptr
;
5807 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
5808 asym
->flags
&= ~BSF_GLOBAL
;
5814 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
5815 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
5816 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
5817 #define TARGET_BIG_NAME "elfNN-ia64-big"
5818 #define ELF_ARCH bfd_arch_ia64
5819 #define ELF_MACHINE_CODE EM_IA_64
5820 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
5821 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
5822 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
5823 #define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
5825 #define elf_backend_section_from_shdr \
5826 elfNN_ia64_section_from_shdr
5827 #define elf_backend_section_flags \
5828 elfNN_ia64_section_flags
5829 #define elf_backend_fake_sections \
5830 elfNN_ia64_fake_sections
5831 #define elf_backend_final_write_processing \
5832 elfNN_ia64_final_write_processing
5833 #define elf_backend_add_symbol_hook \
5834 elfNN_ia64_add_symbol_hook
5835 #define elf_backend_additional_program_headers \
5836 elfNN_ia64_additional_program_headers
5837 #define elf_backend_modify_segment_map \
5838 elfNN_ia64_modify_segment_map
5839 #define elf_backend_modify_program_headers \
5840 elfNN_ia64_modify_program_headers
5841 #define elf_info_to_howto \
5842 elfNN_ia64_info_to_howto
5844 #define bfd_elfNN_bfd_reloc_type_lookup \
5845 elfNN_ia64_reloc_type_lookup
5846 #define bfd_elfNN_bfd_reloc_name_lookup \
5847 elfNN_ia64_reloc_name_lookup
5848 #define bfd_elfNN_bfd_is_local_label_name \
5849 elfNN_ia64_is_local_label_name
5850 #define bfd_elfNN_bfd_relax_section \
5851 elfNN_ia64_relax_section
5853 #define elf_backend_object_p \
5856 /* Stuff for the BFD linker: */
5857 #define bfd_elfNN_bfd_link_hash_table_create \
5858 elfNN_ia64_hash_table_create
5859 #define bfd_elfNN_bfd_link_hash_table_free \
5860 elfNN_ia64_hash_table_free
5861 #define elf_backend_create_dynamic_sections \
5862 elfNN_ia64_create_dynamic_sections
5863 #define elf_backend_check_relocs \
5864 elfNN_ia64_check_relocs
5865 #define elf_backend_adjust_dynamic_symbol \
5866 elfNN_ia64_adjust_dynamic_symbol
5867 #define elf_backend_size_dynamic_sections \
5868 elfNN_ia64_size_dynamic_sections
5869 #define elf_backend_omit_section_dynsym \
5870 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
5871 #define elf_backend_relocate_section \
5872 elfNN_ia64_relocate_section
5873 #define elf_backend_finish_dynamic_symbol \
5874 elfNN_ia64_finish_dynamic_symbol
5875 #define elf_backend_finish_dynamic_sections \
5876 elfNN_ia64_finish_dynamic_sections
5877 #define bfd_elfNN_bfd_final_link \
5878 elfNN_ia64_final_link
5880 #define bfd_elfNN_bfd_merge_private_bfd_data \
5881 elfNN_ia64_merge_private_bfd_data
5882 #define bfd_elfNN_bfd_set_private_flags \
5883 elfNN_ia64_set_private_flags
5884 #define bfd_elfNN_bfd_print_private_bfd_data \
5885 elfNN_ia64_print_private_bfd_data
5887 #define elf_backend_plt_readonly 1
5888 #define elf_backend_want_plt_sym 0
5889 #define elf_backend_plt_alignment 5
5890 #define elf_backend_got_header_size 0
5891 #define elf_backend_want_got_plt 1
5892 #define elf_backend_may_use_rel_p 1
5893 #define elf_backend_may_use_rela_p 1
5894 #define elf_backend_default_use_rela_p 1
5895 #define elf_backend_want_dynbss 0
5896 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5897 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
5898 #define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
5899 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
5900 #define elf_backend_rela_normal 1
5901 #define elf_backend_special_sections elfNN_ia64_special_sections
5902 #define elf_backend_default_execstack 0
5904 /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5905 SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
5906 We don't want to flood users with so many error messages. We turn
5907 off the warning for now. It will be turned on later when the Intel
5908 compiler is fixed. */
5909 #define elf_backend_link_order_error_handler NULL
5911 #include "elfNN-target.h"
5913 /* HPUX-specific vectors. */
5915 #undef TARGET_LITTLE_SYM
5916 #undef TARGET_LITTLE_NAME
5917 #undef TARGET_BIG_SYM
5918 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
5919 #undef TARGET_BIG_NAME
5920 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
5922 /* These are HP-UX specific functions. */
5924 #undef elf_backend_post_process_headers
5925 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5927 #undef elf_backend_section_from_bfd_section
5928 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5930 #undef elf_backend_symbol_processing
5931 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5933 #undef elf_backend_want_p_paddr_set_to_zero
5934 #define elf_backend_want_p_paddr_set_to_zero 1
5936 #undef ELF_MAXPAGESIZE
5937 #define ELF_MAXPAGESIZE 0x1000 /* 4K */
5938 #undef ELF_COMMONPAGESIZE
5940 #define ELF_OSABI ELFOSABI_HPUX
5943 #define elfNN_bed elfNN_ia64_hpux_bed
5945 #include "elfNN-target.h"
5947 #undef elf_backend_want_p_paddr_set_to_zero