1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #include "opcode/ia64.h"
28 /* THE RULES for all the stuff the linker creates --
30 GOT Entries created in response to LTOFF or LTOFF_FPTR
31 relocations. Dynamic relocs created for dynamic
32 symbols in an application; REL relocs for locals
35 FPTR The canonical function descriptor. Created for local
36 symbols in applications. Descriptors for dynamic symbols
37 and local symbols in shared libraries are created by
38 ld.so. Thus there are no dynamic relocs against these
39 objects. The FPTR relocs for such _are_ passed through
40 to the dynamic relocation tables.
42 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
43 Requires the creation of a PLTOFF entry. This does not
44 require any dynamic relocations.
46 PLTOFF Created by PLTOFF relocations. For local symbols, this
47 is an alternate function descriptor, and in shared libraries
48 requires two REL relocations. Note that this cannot be
49 transformed into an FPTR relocation, since it must be in
50 range of the GP. For dynamic symbols, this is a function
51 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
53 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
54 does not reqire dynamic relocations. */
56 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
58 typedef struct bfd_hash_entry
*(*new_hash_entry_func
)
59 PARAMS ((struct bfd_hash_entry
*, struct bfd_hash_table
*, const char *));
61 /* In dynamically (linker-) created sections, we generally need to keep track
62 of the place a symbol or expression got allocated to. This is done via hash
63 tables that store entries of the following type. */
65 struct elfNN_ia64_dyn_sym_info
67 /* The addend for which this entry is relevant. */
70 /* Next addend in the list. */
71 struct elfNN_ia64_dyn_sym_info
*next
;
75 bfd_vma pltoff_offset
;
79 bfd_vma dtpmod_offset
;
80 bfd_vma dtprel_offset
;
82 /* The symbol table entry, if any, that this was derrived from. */
83 struct elf_link_hash_entry
*h
;
85 /* Used to count non-got, non-plt relocations for delayed sizing
86 of relocation sections. */
87 struct elfNN_ia64_dyn_reloc_entry
89 struct elfNN_ia64_dyn_reloc_entry
*next
;
95 /* True when the section contents have been updated. */
96 unsigned got_done
: 1;
97 unsigned fptr_done
: 1;
98 unsigned pltoff_done
: 1;
99 unsigned tprel_done
: 1;
100 unsigned dtpmod_done
: 1;
101 unsigned dtprel_done
: 1;
103 /* True for the different kinds of linker data we want created. */
104 unsigned want_got
: 1;
105 unsigned want_fptr
: 1;
106 unsigned want_ltoff_fptr
: 1;
107 unsigned want_plt
: 1;
108 unsigned want_plt2
: 1;
109 unsigned want_pltoff
: 1;
110 unsigned want_tprel
: 1;
111 unsigned want_dtpmod
: 1;
112 unsigned want_dtprel
: 1;
115 struct elfNN_ia64_local_hash_entry
117 struct bfd_hash_entry root
;
118 struct elfNN_ia64_dyn_sym_info
*info
;
120 /* True if this hash entry's addends was translated for
121 SHF_MERGE optimization. */
122 unsigned sec_merge_done
: 1;
125 struct elfNN_ia64_local_hash_table
127 struct bfd_hash_table root
;
128 /* No additional fields for now. */
131 struct elfNN_ia64_link_hash_entry
133 struct elf_link_hash_entry root
;
134 struct elfNN_ia64_dyn_sym_info
*info
;
137 struct elfNN_ia64_link_hash_table
139 /* The main hash table. */
140 struct elf_link_hash_table root
;
142 asection
*got_sec
; /* the linkage table section (or NULL) */
143 asection
*rel_got_sec
; /* dynamic relocation section for same */
144 asection
*fptr_sec
; /* function descriptor table (or NULL) */
145 asection
*plt_sec
; /* the primary plt section (or NULL) */
146 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
147 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
149 bfd_size_type minplt_entries
; /* number of minplt entries */
150 unsigned reltext
: 1; /* are there relocs against readonly sections? */
152 struct elfNN_ia64_local_hash_table loc_hash_table
;
155 #define elfNN_ia64_hash_table(p) \
156 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
158 static bfd_reloc_status_type elfNN_ia64_reloc
159 PARAMS ((bfd
*abfd
, arelent
*reloc
, asymbol
*sym
, PTR data
,
160 asection
*input_section
, bfd
*output_bfd
, char **error_message
));
161 static reloc_howto_type
* lookup_howto
162 PARAMS ((unsigned int rtype
));
163 static reloc_howto_type
*elfNN_ia64_reloc_type_lookup
164 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type bfd_code
));
165 static void elfNN_ia64_info_to_howto
166 PARAMS ((bfd
*abfd
, arelent
*bfd_reloc
, ElfNN_Internal_Rela
*elf_reloc
));
167 static boolean elfNN_ia64_relax_section
168 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
170 static boolean is_unwind_section_name
171 PARAMS ((bfd
*abfd
, const char *));
172 static boolean elfNN_ia64_section_from_shdr
173 PARAMS ((bfd
*, ElfNN_Internal_Shdr
*, const char *));
174 static boolean elfNN_ia64_section_flags
175 PARAMS ((flagword
*, ElfNN_Internal_Shdr
*));
176 static boolean elfNN_ia64_fake_sections
177 PARAMS ((bfd
*abfd
, ElfNN_Internal_Shdr
*hdr
, asection
*sec
));
178 static void elfNN_ia64_final_write_processing
179 PARAMS ((bfd
*abfd
, boolean linker
));
180 static boolean elfNN_ia64_add_symbol_hook
181 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
182 const char **namep
, flagword
*flagsp
, asection
**secp
,
184 static boolean elfNN_ia64_aix_vec
185 PARAMS ((const bfd_target
*vec
));
186 static boolean elfNN_ia64_aix_add_symbol_hook
187 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
188 const char **namep
, flagword
*flagsp
, asection
**secp
,
190 static boolean elfNN_ia64_aix_link_add_symbols
191 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
192 static int elfNN_ia64_additional_program_headers
193 PARAMS ((bfd
*abfd
));
194 static boolean elfNN_ia64_modify_segment_map
196 static boolean elfNN_ia64_is_local_label_name
197 PARAMS ((bfd
*abfd
, const char *name
));
198 static boolean elfNN_ia64_dynamic_symbol_p
199 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
));
200 static boolean elfNN_ia64_local_hash_table_init
201 PARAMS ((struct elfNN_ia64_local_hash_table
*ht
, bfd
*abfd
,
202 new_hash_entry_func
new));
203 static struct bfd_hash_entry
*elfNN_ia64_new_loc_hash_entry
204 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
205 const char *string
));
206 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
207 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
208 const char *string
));
209 static void elfNN_ia64_hash_copy_indirect
210 PARAMS ((struct elf_link_hash_entry
*, struct elf_link_hash_entry
*));
211 static void elfNN_ia64_hash_hide_symbol
212 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*, boolean
));
213 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
214 PARAMS ((bfd
*abfd
));
215 static struct elfNN_ia64_local_hash_entry
*elfNN_ia64_local_hash_lookup
216 PARAMS ((struct elfNN_ia64_local_hash_table
*table
, const char *string
,
217 boolean create
, boolean copy
));
218 static boolean elfNN_ia64_global_dyn_sym_thunk
219 PARAMS ((struct bfd_hash_entry
*, PTR
));
220 static boolean elfNN_ia64_local_dyn_sym_thunk
221 PARAMS ((struct bfd_hash_entry
*, PTR
));
222 static void elfNN_ia64_dyn_sym_traverse
223 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
224 boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
226 static boolean elfNN_ia64_create_dynamic_sections
227 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
228 static struct elfNN_ia64_local_hash_entry
* get_local_sym_hash
229 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
230 bfd
*abfd
, const Elf_Internal_Rela
*rel
, boolean create
));
231 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
232 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
233 struct elf_link_hash_entry
*h
,
234 bfd
*abfd
, const Elf_Internal_Rela
*rel
, boolean create
));
235 static asection
*get_got
236 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
237 struct elfNN_ia64_link_hash_table
*ia64_info
));
238 static asection
*get_fptr
239 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
240 struct elfNN_ia64_link_hash_table
*ia64_info
));
241 static asection
*get_pltoff
242 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
243 struct elfNN_ia64_link_hash_table
*ia64_info
));
244 static asection
*get_reloc_section
245 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
246 asection
*sec
, boolean create
));
247 static boolean count_dyn_reloc
248 PARAMS ((bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
249 asection
*srel
, int type
));
250 static boolean elfNN_ia64_check_relocs
251 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
252 const Elf_Internal_Rela
*relocs
));
253 static boolean elfNN_ia64_adjust_dynamic_symbol
254 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
255 static long global_sym_index
256 PARAMS ((struct elf_link_hash_entry
*h
));
257 static boolean allocate_fptr
258 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
259 static boolean allocate_global_data_got
260 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
261 static boolean allocate_global_fptr_got
262 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
263 static boolean allocate_local_got
264 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
265 static boolean allocate_pltoff_entries
266 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
267 static boolean allocate_plt_entries
268 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
269 static boolean allocate_plt2_entries
270 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
271 static boolean allocate_dynrel_entries
272 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
273 static boolean elfNN_ia64_size_dynamic_sections
274 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
275 static bfd_reloc_status_type elfNN_ia64_install_value
276 PARAMS ((bfd
*abfd
, bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
277 static void elfNN_ia64_install_dyn_reloc
278 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
279 asection
*srel
, bfd_vma offset
, unsigned int type
,
280 long dynindx
, bfd_vma addend
));
281 static bfd_vma set_got_entry
282 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
283 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
284 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
285 static bfd_vma set_fptr_entry
286 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
287 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
289 static bfd_vma set_pltoff_entry
290 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
291 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
292 bfd_vma value
, boolean
));
293 static bfd_vma elfNN_ia64_tprel_base
294 PARAMS ((struct bfd_link_info
*info
));
295 static bfd_vma elfNN_ia64_dtprel_base
296 PARAMS ((struct bfd_link_info
*info
));
297 static int elfNN_ia64_unwind_entry_compare
298 PARAMS ((const PTR
, const PTR
));
299 static boolean elfNN_ia64_final_link
300 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
301 static boolean elfNN_ia64_relocate_section
302 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
303 asection
*input_section
, bfd_byte
*contents
,
304 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
305 asection
**local_sections
));
306 static boolean elfNN_ia64_finish_dynamic_symbol
307 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
308 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
309 static boolean elfNN_ia64_finish_dynamic_sections
310 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
311 static boolean elfNN_ia64_set_private_flags
312 PARAMS ((bfd
*abfd
, flagword flags
));
313 static boolean elfNN_ia64_merge_private_bfd_data
314 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
315 static boolean elfNN_ia64_print_private_bfd_data
316 PARAMS ((bfd
*abfd
, PTR ptr
));
317 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
318 PARAMS ((const Elf_Internal_Rela
*));
319 static boolean elfNN_ia64_hpux_vec
320 PARAMS ((const bfd_target
*vec
));
321 static void elfNN_hpux_post_process_headers
322 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
323 boolean elfNN_hpux_backend_section_from_bfd_section
324 PARAMS ((bfd
*abfd
, asection
*sec
, int *retval
));
326 /* ia64-specific relocation. */
328 /* Perform a relocation. Not much to do here as all the hard work is
329 done in elfNN_ia64_final_link_relocate. */
330 static bfd_reloc_status_type
331 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
332 output_bfd
, error_message
)
333 bfd
*abfd ATTRIBUTE_UNUSED
;
335 asymbol
*sym ATTRIBUTE_UNUSED
;
336 PTR data ATTRIBUTE_UNUSED
;
337 asection
*input_section
;
339 char **error_message
;
343 reloc
->address
+= input_section
->output_offset
;
346 *error_message
= "Unsupported call to elfNN_ia64_reloc";
347 return bfd_reloc_notsupported
;
350 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
351 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
352 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
354 /* This table has to be sorted according to increasing number of the
356 static reloc_howto_type ia64_howto_table
[] =
358 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, false, true),
360 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, false, true),
361 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, false, true),
362 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, false, true),
363 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, false, true),
364 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, false, true),
365 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, false, true),
366 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, false, true),
368 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, false, true),
369 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, false, true),
370 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, false, true),
371 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, false, true),
372 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, false, true),
373 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, false, true),
375 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, false, true),
376 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, false, true),
378 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, false, true),
379 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, false, true),
380 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, false, true),
381 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, false, true),
383 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, false, true),
384 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, false, true),
385 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, false, true),
386 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, false, true),
387 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, false, true),
389 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, true, true),
390 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, true, true),
391 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, true, true),
392 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, true, true),
393 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, true, true),
394 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, true, true),
395 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, true, true),
396 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, true, true),
398 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, false, true),
399 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, false, true),
400 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, false, true),
401 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, false, true),
402 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, false, true),
403 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, false, true),
405 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, false, true),
406 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, false, true),
407 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, false, true),
408 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, false, true),
410 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, false, true),
411 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, false, true),
412 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, false, true),
413 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, false, true),
415 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, false, true),
416 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, false, true),
417 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, false, true),
418 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, false, true),
420 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, false, true),
421 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, false, true),
422 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, false, true),
423 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, false, true),
425 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, true, true),
426 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, true, true),
427 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, true, true),
429 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, false, true),
430 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, false, true),
431 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, false, true),
432 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, false, true),
433 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, false, true),
435 IA64_HOWTO (R_IA64_TPREL14
, "TPREL14", 0, false, false),
436 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, false, false),
437 IA64_HOWTO (R_IA64_TPREL64I
, "TPREL64I", 0, false, false),
438 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, false, false),
439 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, false, false),
440 IA64_HOWTO (R_IA64_LTOFF_TPREL22
, "LTOFF_TPREL22", 0, false, false),
442 IA64_HOWTO (R_IA64_DTPMOD64MSB
, "TPREL64MSB", 8, false, false),
443 IA64_HOWTO (R_IA64_DTPMOD64LSB
, "TPREL64LSB", 8, false, false),
444 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22
, "LTOFF_DTPMOD22", 0, false, false),
446 IA64_HOWTO (R_IA64_DTPREL14
, "DTPREL14", 0, false, false),
447 IA64_HOWTO (R_IA64_DTPREL22
, "DTPREL22", 0, false, false),
448 IA64_HOWTO (R_IA64_DTPREL64I
, "DTPREL64I", 0, false, false),
449 IA64_HOWTO (R_IA64_DTPREL32MSB
, "DTPREL32MSB", 4, false, false),
450 IA64_HOWTO (R_IA64_DTPREL32LSB
, "DTPREL32LSB", 4, false, false),
451 IA64_HOWTO (R_IA64_DTPREL64MSB
, "DTPREL64MSB", 8, false, false),
452 IA64_HOWTO (R_IA64_DTPREL64LSB
, "DTPREL64LSB", 8, false, false),
453 IA64_HOWTO (R_IA64_LTOFF_DTPREL22
, "LTOFF_DTPREL22", 0, false, false),
456 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
458 /* Given a BFD reloc type, return the matching HOWTO structure. */
460 static reloc_howto_type
*
464 static int inited
= 0;
471 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
472 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
473 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
476 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
477 i
= elf_code_to_howto_index
[rtype
];
478 if (i
>= NELEMS (ia64_howto_table
))
480 return ia64_howto_table
+ i
;
483 static reloc_howto_type
*
484 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
485 bfd
*abfd ATTRIBUTE_UNUSED
;
486 bfd_reloc_code_real_type bfd_code
;
492 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
494 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
495 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
496 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
498 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
499 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
500 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
501 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
503 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
504 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
505 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
506 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
507 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
508 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
510 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
511 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
513 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
514 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
515 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
516 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
517 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
518 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
519 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
520 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
521 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
523 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
524 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
525 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
526 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
527 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
528 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
529 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
530 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
531 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
532 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
533 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
535 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
536 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
537 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
538 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
539 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
540 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
542 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
543 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
544 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
545 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
547 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
548 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
549 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
550 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
552 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
553 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
554 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
555 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
557 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
558 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
559 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
560 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
562 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
563 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
564 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
565 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
566 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
568 case BFD_RELOC_IA64_TPREL14
: rtype
= R_IA64_TPREL14
; break;
569 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
570 case BFD_RELOC_IA64_TPREL64I
: rtype
= R_IA64_TPREL64I
; break;
571 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
572 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
573 case BFD_RELOC_IA64_LTOFF_TPREL22
: rtype
= R_IA64_LTOFF_TPREL22
; break;
575 case BFD_RELOC_IA64_DTPMOD64MSB
: rtype
= R_IA64_DTPMOD64MSB
; break;
576 case BFD_RELOC_IA64_DTPMOD64LSB
: rtype
= R_IA64_DTPMOD64LSB
; break;
577 case BFD_RELOC_IA64_LTOFF_DTPMOD22
: rtype
= R_IA64_LTOFF_DTPMOD22
; break;
579 case BFD_RELOC_IA64_DTPREL14
: rtype
= R_IA64_DTPREL14
; break;
580 case BFD_RELOC_IA64_DTPREL22
: rtype
= R_IA64_DTPREL22
; break;
581 case BFD_RELOC_IA64_DTPREL64I
: rtype
= R_IA64_DTPREL64I
; break;
582 case BFD_RELOC_IA64_DTPREL32MSB
: rtype
= R_IA64_DTPREL32MSB
; break;
583 case BFD_RELOC_IA64_DTPREL32LSB
: rtype
= R_IA64_DTPREL32LSB
; break;
584 case BFD_RELOC_IA64_DTPREL64MSB
: rtype
= R_IA64_DTPREL64MSB
; break;
585 case BFD_RELOC_IA64_DTPREL64LSB
: rtype
= R_IA64_DTPREL64LSB
; break;
586 case BFD_RELOC_IA64_LTOFF_DTPREL22
: rtype
= R_IA64_LTOFF_DTPREL22
; break;
590 return lookup_howto (rtype
);
593 /* Given a ELF reloc, return the matching HOWTO structure. */
596 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
597 bfd
*abfd ATTRIBUTE_UNUSED
;
599 ElfNN_Internal_Rela
*elf_reloc
;
602 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
605 #define PLT_HEADER_SIZE (3 * 16)
606 #define PLT_MIN_ENTRY_SIZE (1 * 16)
607 #define PLT_FULL_ENTRY_SIZE (2 * 16)
608 #define PLT_RESERVED_WORDS 3
610 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
612 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
613 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
614 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
615 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
616 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
617 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
618 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
619 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
620 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
623 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
625 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
626 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
627 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
630 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
632 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
633 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
634 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
635 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
636 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
637 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
640 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
641 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
642 #define DYNAMIC_INTERPRETER(abfd) \
643 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
645 /* Select out of range branch fixup type. Note that Itanium does
646 not support brl, and so it gets emulated by the kernel. */
649 static const bfd_byte oor_brl
[16] =
651 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
653 0x00, 0x00, 0x00, 0xc0
656 static const bfd_byte oor_ip
[48] =
658 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
659 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
660 0x01, 0x00, 0x00, 0x60,
661 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
662 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
663 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
664 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
665 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
666 0x60, 0x00, 0x80, 0x00 /* br b6;; */
669 /* These functions do relaxation for IA-64 ELF.
671 This is primarily to support branches to targets out of range;
672 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
675 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
678 struct bfd_link_info
*link_info
;
683 struct one_fixup
*next
;
689 Elf_Internal_Shdr
*symtab_hdr
;
690 Elf_Internal_Rela
*internal_relocs
;
691 Elf_Internal_Rela
*irel
, *irelend
;
693 Elf_Internal_Sym
*isymbuf
= NULL
;
694 struct elfNN_ia64_link_hash_table
*ia64_info
;
695 struct one_fixup
*fixups
= NULL
;
696 boolean changed_contents
= false;
697 boolean changed_relocs
= false;
699 /* Assume we're not going to change any sizes, and we'll only need
703 /* Nothing to do if there are no relocations. */
704 if ((sec
->flags
& SEC_RELOC
) == 0
705 || sec
->reloc_count
== 0)
708 /* If this is the first time we have been called for this section,
709 initialize the cooked size. */
710 if (sec
->_cooked_size
== 0)
711 sec
->_cooked_size
= sec
->_raw_size
;
713 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
715 /* Load the relocations for this section. */
716 internal_relocs
= (_bfd_elfNN_link_read_relocs
717 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
718 link_info
->keep_memory
));
719 if (internal_relocs
== NULL
)
722 ia64_info
= elfNN_ia64_hash_table (link_info
);
723 irelend
= internal_relocs
+ sec
->reloc_count
;
725 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
726 if (ELFNN_R_TYPE (irel
->r_info
) == (int) R_IA64_PCREL21B
)
729 /* No branch-type relocations. */
732 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
733 free (internal_relocs
);
737 /* Get the section contents. */
738 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
739 contents
= elf_section_data (sec
)->this_hdr
.contents
;
742 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
743 if (contents
== NULL
)
746 if (! bfd_get_section_contents (abfd
, sec
, contents
,
747 (file_ptr
) 0, sec
->_raw_size
))
751 for (; irel
< irelend
; irel
++)
753 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
758 if (ELFNN_R_TYPE (irel
->r_info
) != (int) R_IA64_PCREL21B
)
761 /* Get the value of the symbol referred to by the reloc. */
762 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
764 /* A local symbol. */
765 Elf_Internal_Sym
*isym
;
767 /* Read this BFD's local symbols. */
770 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
772 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
773 symtab_hdr
->sh_info
, 0,
779 isym
= isymbuf
+ ELF64_R_SYM (irel
->r_info
);
780 if (isym
->st_shndx
== SHN_UNDEF
)
781 continue; /* We can't do anthing with undefined symbols. */
782 else if (isym
->st_shndx
== SHN_ABS
)
783 tsec
= bfd_abs_section_ptr
;
784 else if (isym
->st_shndx
== SHN_COMMON
)
785 tsec
= bfd_com_section_ptr
;
786 else if (isym
->st_shndx
== SHN_IA_64_ANSI_COMMON
)
787 tsec
= bfd_com_section_ptr
;
789 tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
791 toff
= isym
->st_value
;
796 struct elf_link_hash_entry
*h
;
797 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
799 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
800 h
= elf_sym_hashes (abfd
)[indx
];
801 BFD_ASSERT (h
!= NULL
);
803 while (h
->root
.type
== bfd_link_hash_indirect
804 || h
->root
.type
== bfd_link_hash_warning
)
805 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
807 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, false);
809 /* For branches to dynamic symbols, we're interested instead
810 in a branch to the PLT entry. */
811 if (dyn_i
&& dyn_i
->want_plt2
)
813 tsec
= ia64_info
->plt_sec
;
814 toff
= dyn_i
->plt2_offset
;
818 /* We can't do anthing with undefined symbols. */
819 if (h
->root
.type
== bfd_link_hash_undefined
820 || h
->root
.type
== bfd_link_hash_undefweak
)
823 tsec
= h
->root
.u
.def
.section
;
824 toff
= h
->root
.u
.def
.value
;
828 symaddr
= (tsec
->output_section
->vma
829 + tsec
->output_offset
833 roff
= irel
->r_offset
;
834 reladdr
= (sec
->output_section
->vma
836 + roff
) & (bfd_vma
) -4;
838 /* If the branch is in range, no need to do anything. */
839 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
840 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
843 /* If the branch and target are in the same section, you've
844 got one honking big section and we can't help you. You'll
845 get an error message later. */
849 /* Look for an existing fixup to this address. */
850 for (f
= fixups
; f
; f
= f
->next
)
851 if (f
->tsec
== tsec
&& f
->toff
== toff
)
856 /* Two alternatives: If it's a branch to a PLT entry, we can
857 make a copy of the FULL_PLT entry. Otherwise, we'll have
858 to use a `brl' insn to get where we're going. */
862 if (tsec
== ia64_info
->plt_sec
)
863 size
= sizeof (plt_full_entry
);
867 size
= sizeof (oor_brl
);
869 size
= sizeof (oor_ip
);
873 /* Resize the current section to make room for the new branch. */
874 trampoff
= (sec
->_cooked_size
+ 15) & (bfd_vma
) -16;
875 amt
= trampoff
+ size
;
876 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
877 if (contents
== NULL
)
879 sec
->_cooked_size
= amt
;
881 if (tsec
== ia64_info
->plt_sec
)
883 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
885 /* Hijack the old relocation for use as the PLTOFF reloc. */
886 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
888 irel
->r_offset
= trampoff
;
893 memcpy (contents
+ trampoff
, oor_brl
, size
);
894 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
896 irel
->r_offset
= trampoff
+ 2;
898 memcpy (contents
+ trampoff
, oor_ip
, size
);
899 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
901 irel
->r_addend
-= 16;
902 irel
->r_offset
= trampoff
+ 2;
906 /* Record the fixup so we don't do it again this section. */
907 f
= (struct one_fixup
*) bfd_malloc ((bfd_size_type
) sizeof (*f
));
911 f
->trampoff
= trampoff
;
916 /* Nop out the reloc, since we're finalizing things here. */
917 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
920 /* Fix up the existing branch to hit the trampoline. Hope like
921 hell this doesn't overflow too. */
922 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
923 f
->trampoff
- (roff
& (bfd_vma
) -4),
924 R_IA64_PCREL21B
) != bfd_reloc_ok
)
927 changed_contents
= true;
928 changed_relocs
= true;
931 /* Clean up and go home. */
934 struct one_fixup
*f
= fixups
;
935 fixups
= fixups
->next
;
940 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
942 if (! link_info
->keep_memory
)
946 /* Cache the symbols for elf_link_input_bfd. */
947 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
952 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
954 if (!changed_contents
&& !link_info
->keep_memory
)
958 /* Cache the section contents for elf_link_input_bfd. */
959 elf_section_data (sec
)->this_hdr
.contents
= contents
;
963 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
966 free (internal_relocs
);
968 elf_section_data (sec
)->relocs
= internal_relocs
;
971 *again
= changed_contents
|| changed_relocs
;
975 if (isymbuf
!= NULL
&& (unsigned char *) isymbuf
!= symtab_hdr
->contents
)
978 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
980 if (internal_relocs
!= NULL
981 && elf_section_data (sec
)->relocs
!= internal_relocs
)
982 free (internal_relocs
);
986 /* Return true if NAME is an unwind table section name. */
988 static inline boolean
989 is_unwind_section_name (abfd
, name
)
993 size_t len1
, len2
, len3
;
995 if (elfNN_ia64_hpux_vec (abfd
->xvec
)
996 && !strcmp (name
, ELF_STRING_ia64_unwind_hdr
))
999 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1000 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
1001 len3
= sizeof (ELF_STRING_ia64_unwind_once
) - 1;
1002 return ((strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
1003 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0)
1004 || strncmp (name
, ELF_STRING_ia64_unwind_once
, len3
) == 0);
1007 /* Handle an IA-64 specific section when reading an object file. This
1008 is called when elfcode.h finds a section with an unknown type. */
1011 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
1013 ElfNN_Internal_Shdr
*hdr
;
1018 /* There ought to be a place to keep ELF backend specific flags, but
1019 at the moment there isn't one. We just keep track of the
1020 sections by their name, instead. Fortunately, the ABI gives
1021 suggested names for all the MIPS specific sections, so we will
1022 probably get away with this. */
1023 switch (hdr
->sh_type
)
1025 case SHT_IA_64_UNWIND
:
1026 case SHT_IA_64_HP_OPT_ANOT
:
1030 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1038 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
1040 newsect
= hdr
->bfd_section
;
1045 /* Convert IA-64 specific section flags to bfd internal section flags. */
1047 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1051 elfNN_ia64_section_flags (flags
, hdr
)
1053 ElfNN_Internal_Shdr
*hdr
;
1055 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1056 *flags
|= SEC_SMALL_DATA
;
1061 /* Set the correct type for an IA-64 ELF section. We do this by the
1062 section name, which is a hack, but ought to work. */
1065 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1066 bfd
*abfd ATTRIBUTE_UNUSED
;
1067 ElfNN_Internal_Shdr
*hdr
;
1070 register const char *name
;
1072 name
= bfd_get_section_name (abfd
, sec
);
1074 if (is_unwind_section_name (abfd
, name
))
1076 /* We don't have the sections numbered at this point, so sh_info
1077 is set later, in elfNN_ia64_final_write_processing. */
1078 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1079 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1081 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1082 hdr
->sh_type
= SHT_IA_64_EXT
;
1083 else if (strcmp (name
, ".HP.opt_annot") == 0)
1084 hdr
->sh_type
= SHT_IA_64_HP_OPT_ANOT
;
1085 else if (strcmp (name
, ".reloc") == 0)
1086 /* This is an ugly, but unfortunately necessary hack that is
1087 needed when producing EFI binaries on IA-64. It tells
1088 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1089 containing ELF relocation info. We need this hack in order to
1090 be able to generate ELF binaries that can be translated into
1091 EFI applications (which are essentially COFF objects). Those
1092 files contain a COFF ".reloc" section inside an ELFNN object,
1093 which would normally cause BFD to segfault because it would
1094 attempt to interpret this section as containing relocation
1095 entries for section "oc". With this hack enabled, ".reloc"
1096 will be treated as a normal data section, which will avoid the
1097 segfault. However, you won't be able to create an ELFNN binary
1098 with a section named "oc" that needs relocations, but that's
1099 the kind of ugly side-effects you get when detecting section
1100 types based on their names... In practice, this limitation is
1101 unlikely to bite. */
1102 hdr
->sh_type
= SHT_PROGBITS
;
1104 if (sec
->flags
& SEC_SMALL_DATA
)
1105 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1110 /* The final processing done just before writing out an IA-64 ELF
1114 elfNN_ia64_final_write_processing (abfd
, linker
)
1116 boolean linker ATTRIBUTE_UNUSED
;
1118 Elf_Internal_Shdr
*hdr
;
1120 asection
*text_sect
, *s
;
1123 for (s
= abfd
->sections
; s
; s
= s
->next
)
1125 hdr
= &elf_section_data (s
)->this_hdr
;
1126 switch (hdr
->sh_type
)
1128 case SHT_IA_64_UNWIND
:
1129 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1131 sname
= bfd_get_section_name (abfd
, s
);
1132 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1133 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1137 if (sname
[0] == '\0')
1138 /* .IA_64.unwind -> .text */
1139 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1141 /* .IA_64.unwindFOO -> FOO */
1142 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1145 && (len
= sizeof (ELF_STRING_ia64_unwind_once
) - 1,
1146 strncmp (sname
, ELF_STRING_ia64_unwind_once
, len
)) == 0)
1148 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1149 size_t len2
= sizeof (".gnu.linkonce.t.") - 1;
1150 char *once_name
= bfd_malloc (len2
+ strlen (sname
+ len
) + 1);
1152 if (once_name
!= NULL
)
1154 memcpy (once_name
, ".gnu.linkonce.t.", len2
);
1155 strcpy (once_name
+ len2
, sname
+ len
);
1156 text_sect
= bfd_get_section_by_name (abfd
, once_name
);
1160 /* Should only happen if we run out of memory, in
1161 which case we're probably toast anyway. Try to
1162 cope by finding the section the slow way. */
1163 for (text_sect
= abfd
->sections
;
1165 text_sect
= text_sect
->next
)
1167 if (strncmp (bfd_section_name (abfd
, text_sect
),
1168 ".gnu.linkonce.t.", len2
) == 0
1169 && strcmp (bfd_section_name (abfd
, text_sect
) + len2
,
1175 /* last resort: fall back on .text */
1176 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1180 /* The IA-64 processor-specific ABI requires setting
1181 sh_link to the unwind section, whereas HP-UX requires
1182 sh_info to do so. For maximum compatibility, we'll
1183 set both for now... */
1184 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1185 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1192 /* Hook called by the linker routine which adds symbols from an object
1193 file. We use it to put .comm items in .sbss, and not .bss. */
1196 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1198 struct bfd_link_info
*info
;
1199 const Elf_Internal_Sym
*sym
;
1200 const char **namep ATTRIBUTE_UNUSED
;
1201 flagword
*flagsp ATTRIBUTE_UNUSED
;
1205 if (sym
->st_shndx
== SHN_COMMON
1206 && !info
->relocateable
1207 && sym
->st_size
<= elf_gp_size (abfd
))
1209 /* Common symbols less than or equal to -G nn bytes are
1210 automatically put into .sbss. */
1212 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1216 scomm
= bfd_make_section (abfd
, ".scommon");
1218 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1220 | SEC_LINKER_CREATED
)))
1225 *valp
= sym
->st_size
;
1232 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1234 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1235 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1237 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1238 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1241 /* Hook called by the linker routine which adds symbols from an object
1242 file. We use it to handle OS-specific symbols. */
1245 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1247 struct bfd_link_info
*info
;
1248 const Elf_Internal_Sym
*sym
;
1254 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1256 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1257 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1258 no one else should use it b/c it is undocumented. */
1259 struct elf_link_hash_entry
*h
;
1261 h
= elf_link_hash_lookup (elf_hash_table (info
), *namep
,
1262 false, false, false);
1265 struct elf_backend_data
*bed
;
1266 struct elfNN_ia64_link_hash_table
*ia64_info
;
1268 bed
= get_elf_backend_data (abfd
);
1269 ia64_info
= elfNN_ia64_hash_table (info
);
1271 if (!(_bfd_generic_link_add_one_symbol
1272 (info
, abfd
, *namep
, BSF_GLOBAL
,
1273 bfd_get_section_by_name (abfd
, ".bss"),
1274 bed
->got_symbol_offset
, (const char *) NULL
, false,
1275 bed
->collect
, (struct bfd_link_hash_entry
**) &h
)))
1278 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1279 h
->type
= STT_OBJECT
;
1281 if (! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1287 else if (sym
->st_shndx
== SHN_LOOS
)
1291 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1292 is only relevant when compiling code for extended system calls.
1293 Replace the "special" section with .text, if possible.
1294 Note that these symbols are always assumed to be in .text. */
1295 for (i
= 1; i
< elf_numsections (abfd
); i
++)
1297 asection
* sec
= bfd_section_from_elf_index (abfd
, i
);
1299 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1307 *secp
= bfd_abs_section_ptr
;
1309 *valp
= sym
->st_size
;
1315 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1316 namep
, flagsp
, secp
, valp
);
1321 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1323 struct bfd_link_info
*info
;
1325 /* Make sure dynamic sections are always created. */
1326 if (! elf_hash_table (info
)->dynamic_sections_created
1327 && abfd
->xvec
== info
->hash
->creator
)
1329 if (! bfd_elfNN_link_create_dynamic_sections (abfd
, info
))
1333 /* Now do the standard call. */
1334 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1337 /* Return the number of additional phdrs we will need. */
1340 elfNN_ia64_additional_program_headers (abfd
)
1346 /* See if we need a PT_IA_64_ARCHEXT segment. */
1347 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1348 if (s
&& (s
->flags
& SEC_LOAD
))
1351 /* Count how many PT_IA_64_UNWIND segments we need. */
1352 for (s
= abfd
->sections
; s
; s
= s
->next
)
1353 if (is_unwind_section_name (abfd
, s
->name
) && (s
->flags
& SEC_LOAD
))
1360 elfNN_ia64_modify_segment_map (abfd
)
1363 struct elf_segment_map
*m
, **pm
;
1364 Elf_Internal_Shdr
*hdr
;
1367 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1368 all PT_LOAD segments. */
1369 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1370 if (s
&& (s
->flags
& SEC_LOAD
))
1372 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1373 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1377 m
= ((struct elf_segment_map
*)
1378 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1382 m
->p_type
= PT_IA_64_ARCHEXT
;
1386 /* We want to put it after the PHDR and INTERP segments. */
1387 pm
= &elf_tdata (abfd
)->segment_map
;
1389 && ((*pm
)->p_type
== PT_PHDR
1390 || (*pm
)->p_type
== PT_INTERP
))
1398 /* Install PT_IA_64_UNWIND segments, if needed. */
1399 for (s
= abfd
->sections
; s
; s
= s
->next
)
1401 hdr
= &elf_section_data (s
)->this_hdr
;
1402 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1405 if (s
&& (s
->flags
& SEC_LOAD
))
1407 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1408 if (m
->p_type
== PT_IA_64_UNWIND
)
1412 /* Look through all sections in the unwind segment
1413 for a match since there may be multiple sections
1415 for (i
= m
->count
- 1; i
>= 0; --i
)
1416 if (m
->sections
[i
] == s
)
1425 m
= ((struct elf_segment_map
*)
1426 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1430 m
->p_type
= PT_IA_64_UNWIND
;
1435 /* We want to put it last. */
1436 pm
= &elf_tdata (abfd
)->segment_map
;
1444 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1445 the input sections for each output section in the segment and testing
1446 for SHF_IA_64_NORECOV on each. */
1447 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1448 if (m
->p_type
== PT_LOAD
)
1451 for (i
= m
->count
- 1; i
>= 0; --i
)
1453 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1456 if (order
->type
== bfd_indirect_link_order
)
1458 asection
*is
= order
->u
.indirect
.section
;
1459 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1460 if (flags
& SHF_IA_64_NORECOV
)
1462 m
->p_flags
|= PF_IA_64_NORECOV
;
1466 order
= order
->next
;
1475 /* According to the Tahoe assembler spec, all labels starting with a
1479 elfNN_ia64_is_local_label_name (abfd
, name
)
1480 bfd
*abfd ATTRIBUTE_UNUSED
;
1483 return name
[0] == '.';
1486 /* Should we do dynamic things to this symbol? */
1489 elfNN_ia64_dynamic_symbol_p (h
, info
)
1490 struct elf_link_hash_entry
*h
;
1491 struct bfd_link_info
*info
;
1496 while (h
->root
.type
== bfd_link_hash_indirect
1497 || h
->root
.type
== bfd_link_hash_warning
)
1498 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1500 if (h
->dynindx
== -1)
1502 switch (ELF_ST_VISIBILITY (h
->other
))
1511 if (h
->root
.type
== bfd_link_hash_undefweak
1512 || h
->root
.type
== bfd_link_hash_defweak
)
1515 if ((info
->shared
&& (!info
->symbolic
|| info
->allow_shlib_undefined
))
1516 || ((h
->elf_link_hash_flags
1517 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1518 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1525 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1526 struct elfNN_ia64_local_hash_table
*ht
;
1527 bfd
*abfd ATTRIBUTE_UNUSED
;
1528 new_hash_entry_func
new;
1530 memset (ht
, 0, sizeof (*ht
));
1531 return bfd_hash_table_init (&ht
->root
, new);
1534 static struct bfd_hash_entry
*
1535 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1536 struct bfd_hash_entry
*entry
;
1537 struct bfd_hash_table
*table
;
1540 struct elfNN_ia64_local_hash_entry
*ret
;
1541 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1543 /* Allocate the structure if it has not already been allocated by a
1546 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1551 /* Initialize our local data. All zeros, and definitely easier
1552 than setting a handful of bit fields. */
1553 memset (ret
, 0, sizeof (*ret
));
1555 /* Call the allocation method of the superclass. */
1556 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1557 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1559 return (struct bfd_hash_entry
*) ret
;
1562 static struct bfd_hash_entry
*
1563 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1564 struct bfd_hash_entry
*entry
;
1565 struct bfd_hash_table
*table
;
1568 struct elfNN_ia64_link_hash_entry
*ret
;
1569 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1571 /* Allocate the structure if it has not already been allocated by a
1574 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1579 /* Initialize our local data. All zeros, and definitely easier
1580 than setting a handful of bit fields. */
1581 memset (ret
, 0, sizeof (*ret
));
1583 /* Call the allocation method of the superclass. */
1584 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1585 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1588 return (struct bfd_hash_entry
*) ret
;
1592 elfNN_ia64_hash_copy_indirect (xdir
, xind
)
1593 struct elf_link_hash_entry
*xdir
, *xind
;
1595 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1597 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1598 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1600 /* Copy down any references that we may have already seen to the
1601 symbol which just became indirect. */
1603 dir
->root
.elf_link_hash_flags
|=
1604 (ind
->root
.elf_link_hash_flags
1605 & (ELF_LINK_HASH_REF_DYNAMIC
1606 | ELF_LINK_HASH_REF_REGULAR
1607 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1609 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1612 /* Copy over the got and plt data. This would have been done
1615 if (dir
->info
== NULL
)
1617 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1619 dir
->info
= dyn_i
= ind
->info
;
1622 /* Fix up the dyn_sym_info pointers to the global symbol. */
1623 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1624 dyn_i
->h
= &dir
->root
;
1626 BFD_ASSERT (ind
->info
== NULL
);
1628 /* Copy over the dynindx. */
1630 if (dir
->root
.dynindx
== -1)
1632 dir
->root
.dynindx
= ind
->root
.dynindx
;
1633 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1634 ind
->root
.dynindx
= -1;
1635 ind
->root
.dynstr_index
= 0;
1637 BFD_ASSERT (ind
->root
.dynindx
== -1);
1641 elfNN_ia64_hash_hide_symbol (info
, xh
, force_local
)
1642 struct bfd_link_info
*info
;
1643 struct elf_link_hash_entry
*xh
;
1644 boolean force_local
;
1646 struct elfNN_ia64_link_hash_entry
*h
;
1647 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1649 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1651 _bfd_elf_link_hash_hide_symbol (info
, &h
->root
, force_local
);
1653 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1654 dyn_i
->want_plt2
= 0;
1657 /* Create the derived linker hash table. The IA-64 ELF port uses this
1658 derived hash table to keep information specific to the IA-64 ElF
1659 linker (without using static variables). */
1661 static struct bfd_link_hash_table
*
1662 elfNN_ia64_hash_table_create (abfd
)
1665 struct elfNN_ia64_link_hash_table
*ret
;
1667 ret
= bfd_zalloc (abfd
, (bfd_size_type
) sizeof (*ret
));
1670 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1671 elfNN_ia64_new_elf_hash_entry
))
1673 bfd_release (abfd
, ret
);
1677 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1678 elfNN_ia64_new_loc_hash_entry
))
1680 return &ret
->root
.root
;
1683 /* Look up an entry in a Alpha ELF linker hash table. */
1685 static INLINE
struct elfNN_ia64_local_hash_entry
*
1686 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1687 struct elfNN_ia64_local_hash_table
*table
;
1689 boolean create
, copy
;
1691 return ((struct elfNN_ia64_local_hash_entry
*)
1692 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1695 /* Traverse both local and global hash tables. */
1697 struct elfNN_ia64_dyn_sym_traverse_data
1699 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1704 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1705 struct bfd_hash_entry
*xentry
;
1708 struct elfNN_ia64_link_hash_entry
*entry
1709 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1710 struct elfNN_ia64_dyn_sym_traverse_data
*data
1711 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1712 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1714 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
1715 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
1717 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1718 if (! (*data
->func
) (dyn_i
, data
->data
))
1724 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1725 struct bfd_hash_entry
*xentry
;
1728 struct elfNN_ia64_local_hash_entry
*entry
1729 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1730 struct elfNN_ia64_dyn_sym_traverse_data
*data
1731 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1732 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1734 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1735 if (! (*data
->func
) (dyn_i
, data
->data
))
1741 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1742 struct elfNN_ia64_link_hash_table
*ia64_info
;
1743 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1746 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1751 elf_link_hash_traverse (&ia64_info
->root
,
1752 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1753 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1754 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1758 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1760 struct bfd_link_info
*info
;
1762 struct elfNN_ia64_link_hash_table
*ia64_info
;
1765 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1768 ia64_info
= elfNN_ia64_hash_table (info
);
1770 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1771 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1774 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1775 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1778 if (!get_pltoff (abfd
, info
, ia64_info
))
1781 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1783 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1786 | SEC_LINKER_CREATED
1788 || !bfd_set_section_alignment (abfd
, s
, 3))
1790 ia64_info
->rel_pltoff_sec
= s
;
1792 s
= bfd_make_section(abfd
, ".rela.got");
1794 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1797 | SEC_LINKER_CREATED
1799 || !bfd_set_section_alignment (abfd
, s
, 3))
1801 ia64_info
->rel_got_sec
= s
;
1806 /* Find and/or create a hash entry for local symbol. */
1807 static struct elfNN_ia64_local_hash_entry
*
1808 get_local_sym_hash (ia64_info
, abfd
, rel
, create
)
1809 struct elfNN_ia64_link_hash_table
*ia64_info
;
1811 const Elf_Internal_Rela
*rel
;
1816 struct elfNN_ia64_local_hash_entry
*ret
;
1818 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1819 name describes what was once anonymous memory. */
1821 len
= sizeof (void*)*2 + 1 + sizeof (bfd_vma
)*4 + 1 + 1;
1822 len
+= 10; /* %p slop */
1824 addr_name
= bfd_malloc (len
);
1825 if (addr_name
== NULL
)
1827 sprintf (addr_name
, "%p:%lx",
1828 (void *) abfd
, (unsigned long) ELFNN_R_SYM (rel
->r_info
));
1830 /* Collect the canonical entry data for this address. */
1831 ret
= elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1832 addr_name
, create
, create
);
1837 /* Find and/or create a descriptor for dynamic symbol info. This will
1838 vary based on global or local symbol, and the addend to the reloc. */
1840 static struct elfNN_ia64_dyn_sym_info
*
1841 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1842 struct elfNN_ia64_link_hash_table
*ia64_info
;
1843 struct elf_link_hash_entry
*h
;
1845 const Elf_Internal_Rela
*rel
;
1848 struct elfNN_ia64_dyn_sym_info
**pp
;
1849 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1850 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1853 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1856 struct elfNN_ia64_local_hash_entry
*loc_h
;
1858 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
1864 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
1867 if (dyn_i
== NULL
&& create
)
1869 dyn_i
= ((struct elfNN_ia64_dyn_sym_info
*)
1870 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *dyn_i
));
1872 dyn_i
->addend
= addend
;
1879 get_got (abfd
, info
, ia64_info
)
1881 struct bfd_link_info
*info
;
1882 struct elfNN_ia64_link_hash_table
*ia64_info
;
1887 got
= ia64_info
->got_sec
;
1892 dynobj
= ia64_info
->root
.dynobj
;
1894 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1895 if (!_bfd_elf_create_got_section (dynobj
, info
))
1898 got
= bfd_get_section_by_name (dynobj
, ".got");
1900 ia64_info
->got_sec
= got
;
1902 flags
= bfd_get_section_flags (abfd
, got
);
1903 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
1909 /* Create function descriptor section (.opd). This section is called .opd
1910 because it contains "official prodecure descriptors". The "official"
1911 refers to the fact that these descriptors are used when taking the address
1912 of a procedure, thus ensuring a unique address for each procedure. */
1915 get_fptr (abfd
, info
, ia64_info
)
1917 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1918 struct elfNN_ia64_link_hash_table
*ia64_info
;
1923 fptr
= ia64_info
->fptr_sec
;
1926 dynobj
= ia64_info
->root
.dynobj
;
1928 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1930 fptr
= bfd_make_section (dynobj
, ".opd");
1932 || !bfd_set_section_flags (dynobj
, fptr
,
1938 | SEC_LINKER_CREATED
))
1939 || !bfd_set_section_alignment (abfd
, fptr
, 4))
1945 ia64_info
->fptr_sec
= fptr
;
1952 get_pltoff (abfd
, info
, ia64_info
)
1954 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1955 struct elfNN_ia64_link_hash_table
*ia64_info
;
1960 pltoff
= ia64_info
->pltoff_sec
;
1963 dynobj
= ia64_info
->root
.dynobj
;
1965 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1967 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
1969 || !bfd_set_section_flags (dynobj
, pltoff
,
1975 | SEC_LINKER_CREATED
))
1976 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
1982 ia64_info
->pltoff_sec
= pltoff
;
1989 get_reloc_section (abfd
, ia64_info
, sec
, create
)
1991 struct elfNN_ia64_link_hash_table
*ia64_info
;
1995 const char *srel_name
;
1999 srel_name
= (bfd_elf_string_from_elf_section
2000 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
2001 elf_section_data(sec
)->rel_hdr
.sh_name
));
2002 if (srel_name
== NULL
)
2005 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
2006 && strcmp (bfd_get_section_name (abfd
, sec
),
2008 || (strncmp (srel_name
, ".rel", 4) == 0
2009 && strcmp (bfd_get_section_name (abfd
, sec
),
2010 srel_name
+4) == 0));
2012 dynobj
= ia64_info
->root
.dynobj
;
2014 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2016 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
2017 if (srel
== NULL
&& create
)
2019 srel
= bfd_make_section (dynobj
, srel_name
);
2021 || !bfd_set_section_flags (dynobj
, srel
,
2026 | SEC_LINKER_CREATED
2028 || !bfd_set_section_alignment (dynobj
, srel
, 3))
2032 if (sec
->flags
& SEC_READONLY
)
2033 ia64_info
->reltext
= 1;
2039 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
2041 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2045 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2047 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2048 if (rent
->srel
== srel
&& rent
->type
== type
)
2053 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
2054 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
2058 rent
->next
= dyn_i
->reloc_entries
;
2062 dyn_i
->reloc_entries
= rent
;
2070 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
2072 struct bfd_link_info
*info
;
2074 const Elf_Internal_Rela
*relocs
;
2076 struct elfNN_ia64_link_hash_table
*ia64_info
;
2077 const Elf_Internal_Rela
*relend
;
2078 Elf_Internal_Shdr
*symtab_hdr
;
2079 const Elf_Internal_Rela
*rel
;
2080 asection
*got
, *fptr
, *srel
;
2082 if (info
->relocateable
)
2085 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2086 ia64_info
= elfNN_ia64_hash_table (info
);
2088 got
= fptr
= srel
= NULL
;
2090 relend
= relocs
+ sec
->reloc_count
;
2091 for (rel
= relocs
; rel
< relend
; ++rel
)
2100 NEED_LTOFF_FPTR
= 64,
2106 struct elf_link_hash_entry
*h
= NULL
;
2107 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2108 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2110 boolean maybe_dynamic
;
2111 int dynrel_type
= R_IA64_NONE
;
2113 if (r_symndx
>= symtab_hdr
->sh_info
)
2115 /* We're dealing with a global symbol -- find its hash entry
2116 and mark it as being referenced. */
2117 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2118 h
= elf_sym_hashes (abfd
)[indx
];
2119 while (h
->root
.type
== bfd_link_hash_indirect
2120 || h
->root
.type
== bfd_link_hash_warning
)
2121 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2123 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
2126 /* We can only get preliminary data on whether a symbol is
2127 locally or externally defined, as not all of the input files
2128 have yet been processed. Do something with what we know, as
2129 this may help reduce memory usage and processing time later. */
2130 maybe_dynamic
= false;
2131 if (h
&& ((info
->shared
2132 && (!info
->symbolic
|| info
->allow_shlib_undefined
))
2133 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
2134 || h
->root
.type
== bfd_link_hash_defweak
2135 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2136 maybe_dynamic
= true;
2139 switch (ELFNN_R_TYPE (rel
->r_info
))
2141 case R_IA64_TPREL64MSB
:
2142 case R_IA64_TPREL64LSB
:
2143 if (info
->shared
|| maybe_dynamic
)
2144 need_entry
= NEED_DYNREL
;
2145 dynrel_type
= R_IA64_TPREL64LSB
;
2147 info
->flags
|= DF_STATIC_TLS
;
2150 case R_IA64_LTOFF_TPREL22
:
2151 need_entry
= NEED_TPREL
;
2153 info
->flags
|= DF_STATIC_TLS
;
2156 case R_IA64_DTPREL64MSB
:
2157 case R_IA64_DTPREL64LSB
:
2158 if (info
->shared
|| maybe_dynamic
)
2159 need_entry
= NEED_DYNREL
;
2160 dynrel_type
= R_IA64_DTPREL64LSB
;
2163 case R_IA64_LTOFF_DTPREL22
:
2164 need_entry
= NEED_DTPREL
;
2167 case R_IA64_DTPMOD64MSB
:
2168 case R_IA64_DTPMOD64LSB
:
2169 if (info
->shared
|| maybe_dynamic
)
2170 need_entry
= NEED_DYNREL
;
2171 dynrel_type
= R_IA64_DTPMOD64LSB
;
2174 case R_IA64_LTOFF_DTPMOD22
:
2175 need_entry
= NEED_DTPMOD
;
2178 case R_IA64_LTOFF_FPTR22
:
2179 case R_IA64_LTOFF_FPTR64I
:
2180 case R_IA64_LTOFF_FPTR32MSB
:
2181 case R_IA64_LTOFF_FPTR32LSB
:
2182 case R_IA64_LTOFF_FPTR64MSB
:
2183 case R_IA64_LTOFF_FPTR64LSB
:
2184 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2187 case R_IA64_FPTR64I
:
2188 case R_IA64_FPTR32MSB
:
2189 case R_IA64_FPTR32LSB
:
2190 case R_IA64_FPTR64MSB
:
2191 case R_IA64_FPTR64LSB
:
2192 if (info
->shared
|| h
|| elfNN_ia64_aix_vec (abfd
->xvec
))
2193 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2195 need_entry
= NEED_FPTR
;
2196 dynrel_type
= R_IA64_FPTR64LSB
;
2199 case R_IA64_LTOFF22
:
2200 case R_IA64_LTOFF22X
:
2201 case R_IA64_LTOFF64I
:
2202 need_entry
= NEED_GOT
;
2205 case R_IA64_PLTOFF22
:
2206 case R_IA64_PLTOFF64I
:
2207 case R_IA64_PLTOFF64MSB
:
2208 case R_IA64_PLTOFF64LSB
:
2209 need_entry
= NEED_PLTOFF
;
2213 need_entry
|= NEED_MIN_PLT
;
2217 (*info
->callbacks
->warning
)
2218 (info
, _("@pltoff reloc against local symbol"), 0,
2219 abfd
, 0, (bfd_vma
) 0);
2223 case R_IA64_PCREL21B
:
2224 case R_IA64_PCREL60B
:
2225 /* Depending on where this symbol is defined, we may or may not
2226 need a full plt entry. Only skip if we know we'll not need
2227 the entry -- static or symbolic, and the symbol definition
2228 has already been seen. */
2229 if (maybe_dynamic
&& rel
->r_addend
== 0)
2230 need_entry
= NEED_FULL_PLT
;
2236 case R_IA64_DIR32MSB
:
2237 case R_IA64_DIR32LSB
:
2238 case R_IA64_DIR64MSB
:
2239 case R_IA64_DIR64LSB
:
2240 /* Shared objects will always need at least a REL relocation. */
2241 if (info
->shared
|| maybe_dynamic
2242 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2243 && (!h
|| strcmp (h
->root
.root
.string
,
2244 "__GLOB_DATA_PTR") != 0)))
2245 need_entry
= NEED_DYNREL
;
2246 dynrel_type
= R_IA64_DIR64LSB
;
2249 case R_IA64_IPLTMSB
:
2250 case R_IA64_IPLTLSB
:
2251 /* Shared objects will always need at least a REL relocation. */
2252 if (info
->shared
|| maybe_dynamic
)
2253 need_entry
= NEED_DYNREL
;
2254 dynrel_type
= R_IA64_IPLTLSB
;
2257 case R_IA64_PCREL22
:
2258 case R_IA64_PCREL64I
:
2259 case R_IA64_PCREL32MSB
:
2260 case R_IA64_PCREL32LSB
:
2261 case R_IA64_PCREL64MSB
:
2262 case R_IA64_PCREL64LSB
:
2264 need_entry
= NEED_DYNREL
;
2265 dynrel_type
= R_IA64_PCREL64LSB
;
2272 if ((need_entry
& NEED_FPTR
) != 0
2275 (*info
->callbacks
->warning
)
2276 (info
, _("non-zero addend in @fptr reloc"), 0,
2277 abfd
, 0, (bfd_vma
) 0);
2280 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, true);
2282 /* Record whether or not this is a local symbol. */
2285 /* Create what's needed. */
2286 if (need_entry
& (NEED_GOT
| NEED_TPREL
| NEED_DTPMOD
| NEED_DTPREL
))
2290 got
= get_got (abfd
, info
, ia64_info
);
2294 if (need_entry
& NEED_GOT
)
2295 dyn_i
->want_got
= 1;
2296 if (need_entry
& NEED_TPREL
)
2297 dyn_i
->want_tprel
= 1;
2298 if (need_entry
& NEED_DTPMOD
)
2299 dyn_i
->want_dtpmod
= 1;
2300 if (need_entry
& NEED_DTPREL
)
2301 dyn_i
->want_dtprel
= 1;
2303 if (need_entry
& NEED_FPTR
)
2307 fptr
= get_fptr (abfd
, info
, ia64_info
);
2312 /* FPTRs for shared libraries are allocated by the dynamic
2313 linker. Make sure this local symbol will appear in the
2314 dynamic symbol table. */
2315 if (!h
&& (info
->shared
2316 /* AIX also needs one */
2317 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2319 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2320 (info
, abfd
, (long) r_symndx
)))
2324 dyn_i
->want_fptr
= 1;
2326 if (need_entry
& NEED_LTOFF_FPTR
)
2327 dyn_i
->want_ltoff_fptr
= 1;
2328 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2330 if (!ia64_info
->root
.dynobj
)
2331 ia64_info
->root
.dynobj
= abfd
;
2332 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2333 dyn_i
->want_plt
= 1;
2335 if (need_entry
& NEED_FULL_PLT
)
2336 dyn_i
->want_plt2
= 1;
2337 if (need_entry
& NEED_PLTOFF
)
2338 dyn_i
->want_pltoff
= 1;
2339 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2343 srel
= get_reloc_section (abfd
, ia64_info
, sec
, true);
2347 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2355 struct elfNN_ia64_allocate_data
2357 struct bfd_link_info
*info
;
2361 /* For cleanliness, and potentially faster dynamic loading, allocate
2362 external GOT entries first. */
2365 allocate_global_data_got (dyn_i
, data
)
2366 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2369 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2372 && ! dyn_i
->want_fptr
2373 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2374 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2375 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2376 "__GLOB_DATA_PTR") != 0))))
2378 dyn_i
->got_offset
= x
->ofs
;
2381 if (dyn_i
->want_tprel
)
2383 dyn_i
->tprel_offset
= x
->ofs
;
2386 if (dyn_i
->want_dtpmod
)
2388 dyn_i
->dtpmod_offset
= x
->ofs
;
2391 if (dyn_i
->want_dtprel
)
2393 dyn_i
->dtprel_offset
= x
->ofs
;
2399 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2402 allocate_global_fptr_got (dyn_i
, data
)
2403 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2406 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2410 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2411 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2413 dyn_i
->got_offset
= x
->ofs
;
2419 /* Lastly, allocate all the GOT entries for local data. */
2422 allocate_local_got (dyn_i
, data
)
2423 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2426 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2429 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2430 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2432 dyn_i
->got_offset
= x
->ofs
;
2438 /* Search for the index of a global symbol in it's defining object file. */
2441 global_sym_index (h
)
2442 struct elf_link_hash_entry
*h
;
2444 struct elf_link_hash_entry
**p
;
2447 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2448 || h
->root
.type
== bfd_link_hash_defweak
);
2450 obj
= h
->root
.u
.def
.section
->owner
;
2451 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2454 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2457 /* Allocate function descriptors. We can do these for every function
2458 in a main executable that is not exported. */
2461 allocate_fptr (dyn_i
, data
)
2462 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2465 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2467 if (dyn_i
->want_fptr
)
2469 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2472 while (h
->root
.type
== bfd_link_hash_indirect
2473 || h
->root
.type
== bfd_link_hash_warning
)
2474 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2477 /* AIX needs an FPTR in this case. */
2478 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2480 || h
->root
.type
== bfd_link_hash_defined
2481 || h
->root
.type
== bfd_link_hash_defweak
)))
2483 if (h
&& h
->dynindx
== -1)
2485 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2486 || (h
->root
.type
== bfd_link_hash_defweak
));
2488 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2489 (x
->info
, h
->root
.u
.def
.section
->owner
,
2490 global_sym_index (h
)))
2494 dyn_i
->want_fptr
= 0;
2496 else if (h
== NULL
|| h
->dynindx
== -1)
2498 dyn_i
->fptr_offset
= x
->ofs
;
2502 dyn_i
->want_fptr
= 0;
2507 /* Allocate all the minimal PLT entries. */
2510 allocate_plt_entries (dyn_i
, data
)
2511 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2514 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2516 if (dyn_i
->want_plt
)
2518 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2521 while (h
->root
.type
== bfd_link_hash_indirect
2522 || h
->root
.type
== bfd_link_hash_warning
)
2523 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2525 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2526 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2528 bfd_size_type offset
= x
->ofs
;
2530 offset
= PLT_HEADER_SIZE
;
2531 dyn_i
->plt_offset
= offset
;
2532 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2534 dyn_i
->want_pltoff
= 1;
2538 dyn_i
->want_plt
= 0;
2539 dyn_i
->want_plt2
= 0;
2545 /* Allocate all the full PLT entries. */
2548 allocate_plt2_entries (dyn_i
, data
)
2549 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2552 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2554 if (dyn_i
->want_plt2
)
2556 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2557 bfd_size_type ofs
= x
->ofs
;
2559 dyn_i
->plt2_offset
= ofs
;
2560 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2562 while (h
->root
.type
== bfd_link_hash_indirect
2563 || h
->root
.type
== bfd_link_hash_warning
)
2564 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2565 dyn_i
->h
->plt
.offset
= ofs
;
2570 /* Allocate all the PLTOFF entries requested by relocations and
2571 plt entries. We can't share space with allocated FPTR entries,
2572 because the latter are not necessarily addressable by the GP.
2573 ??? Relaxation might be able to determine that they are. */
2576 allocate_pltoff_entries (dyn_i
, data
)
2577 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2580 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2582 if (dyn_i
->want_pltoff
)
2584 dyn_i
->pltoff_offset
= x
->ofs
;
2590 /* Allocate dynamic relocations for those symbols that turned out
2594 allocate_dynrel_entries (dyn_i
, data
)
2595 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2598 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2599 struct elfNN_ia64_link_hash_table
*ia64_info
;
2600 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2601 boolean dynamic_symbol
, shared
;
2603 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2604 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2605 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2606 /* Don't allocate an entry for __GLOB_DATA_PTR */
2607 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2608 "__GLOB_DATA_PTR") != 0));
2609 shared
= x
->info
->shared
;
2611 /* Take care of the normal data relocations. */
2613 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2615 int count
= rent
->count
;
2619 case R_IA64_FPTR64LSB
:
2620 /* Allocate one iff !want_fptr, which by this point will
2621 be true only if we're actually allocating one statically
2622 in the main executable. */
2623 if (dyn_i
->want_fptr
)
2626 case R_IA64_PCREL64LSB
:
2627 if (!dynamic_symbol
)
2630 case R_IA64_DIR64LSB
:
2631 if (!dynamic_symbol
&& !shared
)
2634 case R_IA64_IPLTLSB
:
2635 if (!dynamic_symbol
&& !shared
)
2637 /* Use two REL relocations for IPLT relocations
2638 against local symbols. */
2639 if (!dynamic_symbol
)
2642 case R_IA64_TPREL64LSB
:
2643 case R_IA64_DTPREL64LSB
:
2644 case R_IA64_DTPMOD64LSB
:
2649 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2652 /* Take care of the GOT and PLT relocations. */
2654 if (((dynamic_symbol
|| shared
) && dyn_i
->want_got
)
2655 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2656 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2657 if ((dynamic_symbol
|| shared
) && dyn_i
->want_tprel
)
2658 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2659 if ((dynamic_symbol
|| shared
) && dyn_i
->want_dtpmod
)
2660 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2661 if (dynamic_symbol
&& dyn_i
->want_dtprel
)
2662 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2664 if (dyn_i
->want_pltoff
)
2666 bfd_size_type t
= 0;
2668 /* Dynamic symbols get one IPLT relocation. Local symbols in
2669 shared libraries get two REL relocations. Local symbols in
2670 main applications get nothing. */
2672 t
= sizeof (ElfNN_External_Rela
);
2674 t
= 2 * sizeof (ElfNN_External_Rela
);
2676 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2683 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2684 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2685 struct elf_link_hash_entry
*h
;
2687 /* ??? Undefined symbols with PLT entries should be re-defined
2688 to be the PLT entry. */
2690 /* If this is a weak symbol, and there is a real definition, the
2691 processor independent code will have arranged for us to see the
2692 real definition first, and we can just use the same value. */
2693 if (h
->weakdef
!= NULL
)
2695 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2696 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2697 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2698 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2702 /* If this is a reference to a symbol defined by a dynamic object which
2703 is not a function, we might allocate the symbol in our .dynbss section
2704 and allocate a COPY dynamic relocation.
2706 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2713 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2715 struct bfd_link_info
*info
;
2717 struct elfNN_ia64_allocate_data data
;
2718 struct elfNN_ia64_link_hash_table
*ia64_info
;
2721 boolean relplt
= false;
2723 dynobj
= elf_hash_table(info
)->dynobj
;
2724 ia64_info
= elfNN_ia64_hash_table (info
);
2725 BFD_ASSERT(dynobj
!= NULL
);
2728 /* Set the contents of the .interp section to the interpreter. */
2729 if (ia64_info
->root
.dynamic_sections_created
2732 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2733 BFD_ASSERT (sec
!= NULL
);
2734 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2735 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2738 /* Allocate the GOT entries. */
2740 if (ia64_info
->got_sec
)
2743 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2744 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2745 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2746 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2749 /* Allocate the FPTR entries. */
2751 if (ia64_info
->fptr_sec
)
2754 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2755 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2758 /* Now that we've seen all of the input files, we can decide which
2759 symbols need plt entries. Allocate the minimal PLT entries first.
2760 We do this even though dynamic_sections_created may be false, because
2761 this has the side-effect of clearing want_plt and want_plt2. */
2764 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2766 ia64_info
->minplt_entries
= 0;
2769 ia64_info
->minplt_entries
2770 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2773 /* Align the pointer for the plt2 entries. */
2774 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
2776 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2779 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2781 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2783 /* If we've got a .plt, we need some extra memory for the dynamic
2784 linker. We stuff these in .got.plt. */
2785 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2786 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2789 /* Allocate the PLTOFF entries. */
2791 if (ia64_info
->pltoff_sec
)
2794 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2795 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2798 if (ia64_info
->root
.dynamic_sections_created
)
2800 /* Allocate space for the dynamic relocations that turned out to be
2803 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2806 /* We have now determined the sizes of the various dynamic sections.
2807 Allocate memory for them. */
2808 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2812 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2815 /* If we don't need this section, strip it from the output file.
2816 There were several sections primarily related to dynamic
2817 linking that must be create before the linker maps input
2818 sections to output sections. The linker does that before
2819 bfd_elf_size_dynamic_sections is called, and it is that
2820 function which decides whether anything needs to go into
2823 strip
= (sec
->_raw_size
== 0);
2825 if (sec
== ia64_info
->got_sec
)
2827 else if (sec
== ia64_info
->rel_got_sec
)
2830 ia64_info
->rel_got_sec
= NULL
;
2832 /* We use the reloc_count field as a counter if we need to
2833 copy relocs into the output file. */
2834 sec
->reloc_count
= 0;
2836 else if (sec
== ia64_info
->fptr_sec
)
2839 ia64_info
->fptr_sec
= NULL
;
2841 else if (sec
== ia64_info
->plt_sec
)
2844 ia64_info
->plt_sec
= NULL
;
2846 else if (sec
== ia64_info
->pltoff_sec
)
2849 ia64_info
->pltoff_sec
= NULL
;
2851 else if (sec
== ia64_info
->rel_pltoff_sec
)
2854 ia64_info
->rel_pltoff_sec
= NULL
;
2858 /* We use the reloc_count field as a counter if we need to
2859 copy relocs into the output file. */
2860 sec
->reloc_count
= 0;
2867 /* It's OK to base decisions on the section name, because none
2868 of the dynobj section names depend upon the input files. */
2869 name
= bfd_get_section_name (dynobj
, sec
);
2871 if (strcmp (name
, ".got.plt") == 0)
2873 else if (strncmp (name
, ".rel", 4) == 0)
2877 /* We use the reloc_count field as a counter if we need to
2878 copy relocs into the output file. */
2879 sec
->reloc_count
= 0;
2887 _bfd_strip_section_from_output (info
, sec
);
2890 /* Allocate memory for the section contents. */
2891 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->_raw_size
);
2892 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
2897 if (elf_hash_table (info
)->dynamic_sections_created
)
2899 /* Add some entries to the .dynamic section. We fill in the values
2900 later (in finish_dynamic_sections) but we must add the entries now
2901 so that we get the correct size for the .dynamic section. */
2905 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2907 #define add_dynamic_entry(TAG, VAL) \
2908 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
2910 if (!add_dynamic_entry (DT_DEBUG
, 0))
2914 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
2916 if (!add_dynamic_entry (DT_PLTGOT
, 0))
2921 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
2922 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
2923 || !add_dynamic_entry (DT_JMPREL
, 0))
2927 if (!add_dynamic_entry (DT_RELA
, 0)
2928 || !add_dynamic_entry (DT_RELASZ
, 0)
2929 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
2932 if (ia64_info
->reltext
)
2934 if (!add_dynamic_entry (DT_TEXTREL
, 0))
2936 info
->flags
|= DF_TEXTREL
;
2940 /* ??? Perhaps force __gp local. */
2945 static bfd_reloc_status_type
2946 elfNN_ia64_install_value (abfd
, hit_addr
, v
, r_type
)
2950 unsigned int r_type
;
2952 const struct ia64_operand
*op
;
2953 int bigendian
= 0, shift
= 0;
2954 bfd_vma t0
, t1
, insn
, dword
;
2955 enum ia64_opnd opnd
;
2958 #ifdef BFD_HOST_U_64_BIT
2959 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
2964 opnd
= IA64_OPND_NIL
;
2969 return bfd_reloc_ok
;
2971 /* Instruction relocations. */
2974 case R_IA64_TPREL14
:
2975 case R_IA64_DTPREL14
:
2976 opnd
= IA64_OPND_IMM14
;
2979 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
2980 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
2981 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
2982 case R_IA64_PCREL21B
:
2983 case R_IA64_PCREL21BI
:
2984 opnd
= IA64_OPND_TGT25c
;
2988 case R_IA64_GPREL22
:
2989 case R_IA64_LTOFF22
:
2990 case R_IA64_LTOFF22X
:
2991 case R_IA64_PLTOFF22
:
2992 case R_IA64_PCREL22
:
2993 case R_IA64_LTOFF_FPTR22
:
2994 case R_IA64_TPREL22
:
2995 case R_IA64_DTPREL22
:
2996 case R_IA64_LTOFF_TPREL22
:
2997 case R_IA64_LTOFF_DTPMOD22
:
2998 case R_IA64_LTOFF_DTPREL22
:
2999 opnd
= IA64_OPND_IMM22
;
3003 case R_IA64_GPREL64I
:
3004 case R_IA64_LTOFF64I
:
3005 case R_IA64_PLTOFF64I
:
3006 case R_IA64_PCREL64I
:
3007 case R_IA64_FPTR64I
:
3008 case R_IA64_LTOFF_FPTR64I
:
3009 case R_IA64_TPREL64I
:
3010 case R_IA64_DTPREL64I
:
3011 opnd
= IA64_OPND_IMMU64
;
3014 /* Data relocations. */
3016 case R_IA64_DIR32MSB
:
3017 case R_IA64_GPREL32MSB
:
3018 case R_IA64_FPTR32MSB
:
3019 case R_IA64_PCREL32MSB
:
3020 case R_IA64_LTOFF_FPTR32MSB
:
3021 case R_IA64_SEGREL32MSB
:
3022 case R_IA64_SECREL32MSB
:
3023 case R_IA64_LTV32MSB
:
3024 case R_IA64_DTPREL32MSB
:
3025 size
= 4; bigendian
= 1;
3028 case R_IA64_DIR32LSB
:
3029 case R_IA64_GPREL32LSB
:
3030 case R_IA64_FPTR32LSB
:
3031 case R_IA64_PCREL32LSB
:
3032 case R_IA64_LTOFF_FPTR32LSB
:
3033 case R_IA64_SEGREL32LSB
:
3034 case R_IA64_SECREL32LSB
:
3035 case R_IA64_LTV32LSB
:
3036 case R_IA64_DTPREL32LSB
:
3037 size
= 4; bigendian
= 0;
3040 case R_IA64_DIR64MSB
:
3041 case R_IA64_GPREL64MSB
:
3042 case R_IA64_PLTOFF64MSB
:
3043 case R_IA64_FPTR64MSB
:
3044 case R_IA64_PCREL64MSB
:
3045 case R_IA64_LTOFF_FPTR64MSB
:
3046 case R_IA64_SEGREL64MSB
:
3047 case R_IA64_SECREL64MSB
:
3048 case R_IA64_LTV64MSB
:
3049 case R_IA64_TPREL64MSB
:
3050 case R_IA64_DTPMOD64MSB
:
3051 case R_IA64_DTPREL64MSB
:
3052 size
= 8; bigendian
= 1;
3055 case R_IA64_DIR64LSB
:
3056 case R_IA64_GPREL64LSB
:
3057 case R_IA64_PLTOFF64LSB
:
3058 case R_IA64_FPTR64LSB
:
3059 case R_IA64_PCREL64LSB
:
3060 case R_IA64_LTOFF_FPTR64LSB
:
3061 case R_IA64_SEGREL64LSB
:
3062 case R_IA64_SECREL64LSB
:
3063 case R_IA64_LTV64LSB
:
3064 case R_IA64_TPREL64LSB
:
3065 case R_IA64_DTPMOD64LSB
:
3066 case R_IA64_DTPREL64LSB
:
3067 size
= 8; bigendian
= 0;
3070 /* Unsupported / Dynamic relocations. */
3072 return bfd_reloc_notsupported
;
3077 case IA64_OPND_IMMU64
:
3078 hit_addr
-= (long) hit_addr
& 0x3;
3079 t0
= bfd_get_64 (abfd
, hit_addr
);
3080 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
3082 /* tmpl/s: bits 0.. 5 in t0
3083 slot 0: bits 5..45 in t0
3084 slot 1: bits 46..63 in t0, bits 0..22 in t1
3085 slot 2: bits 23..63 in t1 */
3087 /* First, clear the bits that form the 64 bit constant. */
3088 t0
&= ~(0x3ffffLL
<< 46);
3090 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
3091 | (0x01fLL
<< 22) | (0x001LL
<< 21)
3092 | (0x001LL
<< 36)) << 23));
3094 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
3095 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
3096 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
3097 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
3098 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
3099 | (((val
>> 21) & 0x001) << 21) /* ic */
3100 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
3102 bfd_put_64 (abfd
, t0
, hit_addr
);
3103 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3106 case IA64_OPND_TGT64
:
3107 hit_addr
-= (long) hit_addr
& 0x3;
3108 t0
= bfd_get_64 (abfd
, hit_addr
);
3109 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
3111 /* tmpl/s: bits 0.. 5 in t0
3112 slot 0: bits 5..45 in t0
3113 slot 1: bits 46..63 in t0, bits 0..22 in t1
3114 slot 2: bits 23..63 in t1 */
3116 /* First, clear the bits that form the 64 bit constant. */
3117 t0
&= ~(0x3ffffLL
<< 46);
3119 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
3122 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
3123 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
3124 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
3125 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
3127 bfd_put_64 (abfd
, t0
, hit_addr
);
3128 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3132 switch ((long) hit_addr
& 0x3)
3134 case 0: shift
= 5; break;
3135 case 1: shift
= 14; hit_addr
+= 3; break;
3136 case 2: shift
= 23; hit_addr
+= 6; break;
3137 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
3139 dword
= bfd_get_64 (abfd
, hit_addr
);
3140 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
3142 op
= elf64_ia64_operands
+ opnd
;
3143 err
= (*op
->insert
) (op
, val
, (ia64_insn
*)& insn
);
3145 return bfd_reloc_overflow
;
3147 dword
&= ~(0x1ffffffffffLL
<< shift
);
3148 dword
|= (insn
<< shift
);
3149 bfd_put_64 (abfd
, dword
, hit_addr
);
3153 /* A data relocation. */
3156 bfd_putb32 (val
, hit_addr
);
3158 bfd_putb64 (val
, hit_addr
);
3161 bfd_putl32 (val
, hit_addr
);
3163 bfd_putl64 (val
, hit_addr
);
3167 return bfd_reloc_ok
;
3171 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
3174 struct bfd_link_info
*info
;
3182 Elf_Internal_Rela outrel
;
3184 offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3186 BFD_ASSERT (dynindx
!= -1);
3187 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3188 outrel
.r_addend
= addend
;
3189 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3190 if ((outrel
.r_offset
| 1) == (bfd_vma
) -1)
3192 /* Run for the hills. We shouldn't be outputting a relocation
3193 for this. So do what everyone else does and output a no-op. */
3194 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3195 outrel
.r_addend
= 0;
3196 outrel
.r_offset
= 0;
3199 bfd_elfNN_swap_reloca_out (abfd
, &outrel
,
3200 ((ElfNN_External_Rela
*) srel
->contents
3201 + srel
->reloc_count
++));
3202 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3203 <= srel
->_cooked_size
);
3206 /* Store an entry for target address TARGET_ADDR in the linkage table
3207 and return the gp-relative address of the linkage table entry. */
3210 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3212 struct bfd_link_info
*info
;
3213 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3217 unsigned int dyn_r_type
;
3219 struct elfNN_ia64_link_hash_table
*ia64_info
;
3224 ia64_info
= elfNN_ia64_hash_table (info
);
3225 got_sec
= ia64_info
->got_sec
;
3229 case R_IA64_TPREL64LSB
:
3230 done
= dyn_i
->tprel_done
;
3231 dyn_i
->tprel_done
= true;
3232 got_offset
= dyn_i
->tprel_offset
;
3234 case R_IA64_DTPMOD64LSB
:
3235 done
= dyn_i
->dtpmod_done
;
3236 dyn_i
->dtpmod_done
= true;
3237 got_offset
= dyn_i
->dtpmod_offset
;
3239 case R_IA64_DTPREL64LSB
:
3240 done
= dyn_i
->dtprel_done
;
3241 dyn_i
->dtprel_done
= true;
3242 got_offset
= dyn_i
->dtprel_offset
;
3245 done
= dyn_i
->got_done
;
3246 dyn_i
->got_done
= true;
3247 got_offset
= dyn_i
->got_offset
;
3251 BFD_ASSERT ((got_offset
& 7) == 0);
3255 /* Store the target address in the linkage table entry. */
3256 bfd_put_64 (abfd
, value
, got_sec
->contents
+ got_offset
);
3258 /* Install a dynamic relocation if needed. */
3259 if ((info
->shared
&& dyn_r_type
!= R_IA64_DTPREL64LSB
)
3260 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3261 || elfNN_ia64_aix_vec (abfd
->xvec
)
3262 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3265 && dyn_r_type
!= R_IA64_TPREL64LSB
3266 && dyn_r_type
!= R_IA64_DTPMOD64LSB
3267 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
3269 dyn_r_type
= R_IA64_REL64LSB
;
3274 if (bfd_big_endian (abfd
))
3278 case R_IA64_REL64LSB
:
3279 dyn_r_type
= R_IA64_REL64MSB
;
3281 case R_IA64_DIR64LSB
:
3282 dyn_r_type
= R_IA64_DIR64MSB
;
3284 case R_IA64_FPTR64LSB
:
3285 dyn_r_type
= R_IA64_FPTR64MSB
;
3287 case R_IA64_TPREL64LSB
:
3288 dyn_r_type
= R_IA64_TPREL64MSB
;
3290 case R_IA64_DTPMOD64LSB
:
3291 dyn_r_type
= R_IA64_DTPMOD64MSB
;
3293 case R_IA64_DTPREL64LSB
:
3294 dyn_r_type
= R_IA64_DTPREL64MSB
;
3302 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3303 ia64_info
->rel_got_sec
,
3304 got_offset
, dyn_r_type
,
3309 /* Return the address of the linkage table entry. */
3310 value
= (got_sec
->output_section
->vma
3311 + got_sec
->output_offset
3317 /* Fill in a function descriptor consisting of the function's code
3318 address and its global pointer. Return the descriptor's address. */
3321 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3323 struct bfd_link_info
*info
;
3324 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3327 struct elfNN_ia64_link_hash_table
*ia64_info
;
3330 ia64_info
= elfNN_ia64_hash_table (info
);
3331 fptr_sec
= ia64_info
->fptr_sec
;
3333 if (!dyn_i
->fptr_done
)
3335 dyn_i
->fptr_done
= 1;
3337 /* Fill in the function descriptor. */
3338 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3339 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3340 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3343 /* Return the descriptor's address. */
3344 value
= (fptr_sec
->output_section
->vma
3345 + fptr_sec
->output_offset
3346 + dyn_i
->fptr_offset
);
3351 /* Fill in a PLTOFF entry consisting of the function's code address
3352 and its global pointer. Return the descriptor's address. */
3355 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3357 struct bfd_link_info
*info
;
3358 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3362 struct elfNN_ia64_link_hash_table
*ia64_info
;
3363 asection
*pltoff_sec
;
3365 ia64_info
= elfNN_ia64_hash_table (info
);
3366 pltoff_sec
= ia64_info
->pltoff_sec
;
3368 /* Don't do anything if this symbol uses a real PLT entry. In
3369 that case, we'll fill this in during finish_dynamic_symbol. */
3370 if ((! dyn_i
->want_plt
|| is_plt
)
3371 && !dyn_i
->pltoff_done
)
3373 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3375 /* Fill in the function descriptor. */
3376 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3377 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3379 /* Install dynamic relocations if needed. */
3380 if (!is_plt
&& info
->shared
)
3382 unsigned int dyn_r_type
;
3384 if (bfd_big_endian (abfd
))
3385 dyn_r_type
= R_IA64_REL64MSB
;
3387 dyn_r_type
= R_IA64_REL64LSB
;
3389 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3390 ia64_info
->rel_pltoff_sec
,
3391 dyn_i
->pltoff_offset
,
3392 dyn_r_type
, 0, value
);
3393 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3394 ia64_info
->rel_pltoff_sec
,
3395 dyn_i
->pltoff_offset
+ 8,
3399 dyn_i
->pltoff_done
= 1;
3402 /* Return the descriptor's address. */
3403 value
= (pltoff_sec
->output_section
->vma
3404 + pltoff_sec
->output_offset
3405 + dyn_i
->pltoff_offset
);
3410 /* Return the base VMA address which should be subtracted from real addresses
3411 when resolving @tprel() relocation.
3412 Main program TLS (whose template starts at PT_TLS p_vaddr)
3413 is assigned offset round(16, PT_TLS p_align). */
3416 elfNN_ia64_tprel_base (info
)
3417 struct bfd_link_info
*info
;
3419 struct elf_link_tls_segment
*tls_segment
3420 = elf_hash_table (info
)->tls_segment
;
3422 BFD_ASSERT (tls_segment
!= NULL
);
3423 return (tls_segment
->start
3424 - align_power ((bfd_vma
) 16, tls_segment
->align
));
3427 /* Return the base VMA address which should be subtracted from real addresses
3428 when resolving @dtprel() relocation.
3429 This is PT_TLS segment p_vaddr. */
3432 elfNN_ia64_dtprel_base (info
)
3433 struct bfd_link_info
*info
;
3435 BFD_ASSERT (elf_hash_table (info
)->tls_segment
!= NULL
);
3436 return elf_hash_table (info
)->tls_segment
->start
;
3439 /* Called through qsort to sort the .IA_64.unwind section during a
3440 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3441 to the output bfd so we can do proper endianness frobbing. */
3443 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3446 elfNN_ia64_unwind_entry_compare (a
, b
)
3452 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3453 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3455 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3459 elfNN_ia64_final_link (abfd
, info
)
3461 struct bfd_link_info
*info
;
3463 struct elfNN_ia64_link_hash_table
*ia64_info
;
3464 asection
*unwind_output_sec
;
3466 ia64_info
= elfNN_ia64_hash_table (info
);
3468 /* Make sure we've got ourselves a nice fat __gp value. */
3469 if (!info
->relocateable
)
3471 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3472 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3473 struct elf_link_hash_entry
*gp
;
3477 /* Find the min and max vma of all sections marked short. Also
3478 collect min and max vma of any type, for use in selecting a
3480 for (os
= abfd
->sections
; os
; os
= os
->next
)
3484 if ((os
->flags
& SEC_ALLOC
) == 0)
3488 hi
= os
->vma
+ os
->_raw_size
;
3496 if (os
->flags
& SEC_SMALL_DATA
)
3498 if (min_short_vma
> lo
)
3500 if (max_short_vma
< hi
)
3505 /* See if the user wants to force a value. */
3506 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", false,
3510 && (gp
->root
.type
== bfd_link_hash_defined
3511 || gp
->root
.type
== bfd_link_hash_defweak
))
3513 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3514 gp_val
= (gp
->root
.u
.def
.value
3515 + gp_sec
->output_section
->vma
3516 + gp_sec
->output_offset
);
3520 /* Pick a sensible value. */
3522 asection
*got_sec
= ia64_info
->got_sec
;
3524 /* Start with just the address of the .got. */
3526 gp_val
= got_sec
->output_section
->vma
;
3527 else if (max_short_vma
!= 0)
3528 gp_val
= min_short_vma
;
3532 /* If it is possible to address the entire image, but we
3533 don't with the choice above, adjust. */
3534 if (max_vma
- min_vma
< 0x400000
3535 && max_vma
- gp_val
<= 0x200000
3536 && gp_val
- min_vma
> 0x200000)
3537 gp_val
= min_vma
+ 0x200000;
3538 else if (max_short_vma
!= 0)
3540 /* If we don't cover all the short data, adjust. */
3541 if (max_short_vma
- gp_val
>= 0x200000)
3542 gp_val
= min_short_vma
+ 0x200000;
3544 /* If we're addressing stuff past the end, adjust back. */
3545 if (gp_val
> max_vma
)
3546 gp_val
= max_vma
- 0x200000 + 8;
3550 /* Validate whether all SHF_IA_64_SHORT sections are within
3551 range of the chosen GP. */
3553 if (max_short_vma
!= 0)
3555 if (max_short_vma
- min_short_vma
>= 0x400000)
3557 (*_bfd_error_handler
)
3558 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3559 bfd_get_filename (abfd
),
3560 (unsigned long) (max_short_vma
- min_short_vma
));
3563 else if ((gp_val
> min_short_vma
3564 && gp_val
- min_short_vma
> 0x200000)
3565 || (gp_val
< max_short_vma
3566 && max_short_vma
- gp_val
>= 0x200000))
3568 (*_bfd_error_handler
)
3569 (_("%s: __gp does not cover short data segment"),
3570 bfd_get_filename (abfd
));
3575 _bfd_set_gp_value (abfd
, gp_val
);
3579 gp
->root
.type
= bfd_link_hash_defined
;
3580 gp
->root
.u
.def
.value
= gp_val
;
3581 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3585 /* If we're producing a final executable, we need to sort the contents
3586 of the .IA_64.unwind section. Force this section to be relocated
3587 into memory rather than written immediately to the output file. */
3588 unwind_output_sec
= NULL
;
3589 if (!info
->relocateable
)
3591 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3594 unwind_output_sec
= s
->output_section
;
3595 unwind_output_sec
->contents
3596 = bfd_malloc (unwind_output_sec
->_raw_size
);
3597 if (unwind_output_sec
->contents
== NULL
)
3602 /* Invoke the regular ELF backend linker to do all the work. */
3603 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3606 if (unwind_output_sec
)
3608 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3609 qsort (unwind_output_sec
->contents
,
3610 (size_t) (unwind_output_sec
->_raw_size
/ 24),
3612 elfNN_ia64_unwind_entry_compare
);
3614 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3615 unwind_output_sec
->contents
, (bfd_vma
) 0,
3616 unwind_output_sec
->_raw_size
))
3624 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3625 contents
, relocs
, local_syms
, local_sections
)
3627 struct bfd_link_info
*info
;
3629 asection
*input_section
;
3631 Elf_Internal_Rela
*relocs
;
3632 Elf_Internal_Sym
*local_syms
;
3633 asection
**local_sections
;
3635 struct elfNN_ia64_link_hash_table
*ia64_info
;
3636 Elf_Internal_Shdr
*symtab_hdr
;
3637 Elf_Internal_Rela
*rel
;
3638 Elf_Internal_Rela
*relend
;
3640 boolean ret_val
= true; /* for non-fatal errors */
3643 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3644 ia64_info
= elfNN_ia64_hash_table (info
);
3646 /* Infect various flags from the input section to the output section. */
3647 if (info
->relocateable
)
3651 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3652 flags
&= SHF_IA_64_NORECOV
;
3654 elf_section_data(input_section
->output_section
)
3655 ->this_hdr
.sh_flags
|= flags
;
3659 gp_val
= _bfd_get_gp_value (output_bfd
);
3660 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, false);
3663 relend
= relocs
+ input_section
->reloc_count
;
3664 for (; rel
< relend
; ++rel
)
3666 struct elf_link_hash_entry
*h
;
3667 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3668 bfd_reloc_status_type r
;
3669 reloc_howto_type
*howto
;
3670 unsigned long r_symndx
;
3671 Elf_Internal_Sym
*sym
;
3672 unsigned int r_type
;
3676 boolean dynamic_symbol_p
;
3677 boolean undef_weak_ref
;
3679 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3680 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3682 (*_bfd_error_handler
)
3683 (_("%s: unknown relocation type %d"),
3684 bfd_archive_filename (input_bfd
), (int)r_type
);
3685 bfd_set_error (bfd_error_bad_value
);
3690 howto
= lookup_howto (r_type
);
3691 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3695 undef_weak_ref
= false;
3697 if (r_symndx
< symtab_hdr
->sh_info
)
3699 /* Reloc against local symbol. */
3700 sym
= local_syms
+ r_symndx
;
3701 sym_sec
= local_sections
[r_symndx
];
3702 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, sym_sec
, rel
);
3703 if ((sym_sec
->flags
& SEC_MERGE
)
3704 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
3705 && (elf_section_data (sym_sec
)->sec_info_type
3706 == ELF_INFO_TYPE_MERGE
))
3708 struct elfNN_ia64_local_hash_entry
*loc_h
;
3710 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, false);
3711 if (loc_h
&& ! loc_h
->sec_merge_done
)
3713 struct elfNN_ia64_dyn_sym_info
*dynent
;
3716 for (dynent
= loc_h
->info
; dynent
; dynent
= dynent
->next
)
3720 _bfd_merged_section_offset (output_bfd
, &msec
,
3721 elf_section_data (msec
)->
3726 dynent
->addend
-= sym
->st_value
;
3727 dynent
->addend
+= msec
->output_section
->vma
3728 + msec
->output_offset
3729 - sym_sec
->output_section
->vma
3730 - sym_sec
->output_offset
;
3732 loc_h
->sec_merge_done
= 1;
3740 /* Reloc against global symbol. */
3741 indx
= r_symndx
- symtab_hdr
->sh_info
;
3742 h
= elf_sym_hashes (input_bfd
)[indx
];
3743 while (h
->root
.type
== bfd_link_hash_indirect
3744 || h
->root
.type
== bfd_link_hash_warning
)
3745 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3748 if (h
->root
.type
== bfd_link_hash_defined
3749 || h
->root
.type
== bfd_link_hash_defweak
)
3751 sym_sec
= h
->root
.u
.def
.section
;
3753 /* Detect the cases that sym_sec->output_section is
3754 expected to be NULL -- all cases in which the symbol
3755 is defined in another shared module. This includes
3756 PLT relocs for which we've created a PLT entry and
3757 other relocs for which we're prepared to create
3758 dynamic relocations. */
3759 /* ??? Just accept it NULL and continue. */
3761 if (sym_sec
->output_section
!= NULL
)
3763 value
= (h
->root
.u
.def
.value
3764 + sym_sec
->output_section
->vma
3765 + sym_sec
->output_offset
);
3768 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3769 undef_weak_ref
= true;
3770 else if (info
->shared
3771 && (!info
->symbolic
|| info
->allow_shlib_undefined
)
3772 && !info
->no_undefined
3773 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3777 if (! ((*info
->callbacks
->undefined_symbol
)
3778 (info
, h
->root
.root
.string
, input_bfd
,
3779 input_section
, rel
->r_offset
,
3780 (!info
->shared
|| info
->no_undefined
3781 || ELF_ST_VISIBILITY (h
->other
)))))
3788 hit_addr
= contents
+ rel
->r_offset
;
3789 value
+= rel
->r_addend
;
3790 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3801 case R_IA64_DIR32MSB
:
3802 case R_IA64_DIR32LSB
:
3803 case R_IA64_DIR64MSB
:
3804 case R_IA64_DIR64LSB
:
3805 /* Install a dynamic relocation for this reloc. */
3806 if ((dynamic_symbol_p
|| info
->shared
3807 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
3808 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3809 && (!h
|| strcmp (h
->root
.root
.string
,
3810 "__GLOB_DATA_PTR") != 0)))
3812 && (input_section
->flags
& SEC_ALLOC
) != 0)
3814 unsigned int dyn_r_type
;
3818 BFD_ASSERT (srel
!= NULL
);
3820 /* If we don't need dynamic symbol lookup, find a
3821 matching RELATIVE relocation. */
3822 dyn_r_type
= r_type
;
3823 if (dynamic_symbol_p
)
3825 dynindx
= h
->dynindx
;
3826 addend
= rel
->r_addend
;
3833 case R_IA64_DIR32MSB
:
3834 dyn_r_type
= R_IA64_REL32MSB
;
3836 case R_IA64_DIR32LSB
:
3837 dyn_r_type
= R_IA64_REL32LSB
;
3839 case R_IA64_DIR64MSB
:
3840 dyn_r_type
= R_IA64_REL64MSB
;
3842 case R_IA64_DIR64LSB
:
3843 dyn_r_type
= R_IA64_REL64LSB
;
3847 /* We can't represent this without a dynamic symbol.
3848 Adjust the relocation to be against an output
3849 section symbol, which are always present in the
3850 dynamic symbol table. */
3851 /* ??? People shouldn't be doing non-pic code in
3852 shared libraries. Hork. */
3853 (*_bfd_error_handler
)
3854 (_("%s: linking non-pic code in a shared library"),
3855 bfd_archive_filename (input_bfd
));
3863 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
3864 rel
->r_addend
= value
;
3865 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3866 srel
, rel
->r_offset
, dyn_r_type
,
3871 case R_IA64_LTV32MSB
:
3872 case R_IA64_LTV32LSB
:
3873 case R_IA64_LTV64MSB
:
3874 case R_IA64_LTV64LSB
:
3875 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3878 case R_IA64_GPREL22
:
3879 case R_IA64_GPREL64I
:
3880 case R_IA64_GPREL32MSB
:
3881 case R_IA64_GPREL32LSB
:
3882 case R_IA64_GPREL64MSB
:
3883 case R_IA64_GPREL64LSB
:
3884 if (dynamic_symbol_p
)
3886 (*_bfd_error_handler
)
3887 (_("%s: @gprel relocation against dynamic symbol %s"),
3888 bfd_archive_filename (input_bfd
), h
->root
.root
.string
);
3893 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3896 case R_IA64_LTOFF22
:
3897 case R_IA64_LTOFF22X
:
3898 case R_IA64_LTOFF64I
:
3899 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3900 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
3901 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
3903 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3906 case R_IA64_PLTOFF22
:
3907 case R_IA64_PLTOFF64I
:
3908 case R_IA64_PLTOFF64MSB
:
3909 case R_IA64_PLTOFF64LSB
:
3910 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3911 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, false);
3913 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3916 case R_IA64_FPTR64I
:
3917 case R_IA64_FPTR32MSB
:
3918 case R_IA64_FPTR32LSB
:
3919 case R_IA64_FPTR64MSB
:
3920 case R_IA64_FPTR64LSB
:
3921 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3922 if (dyn_i
->want_fptr
)
3924 if (!undef_weak_ref
)
3925 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3931 /* Otherwise, we expect the dynamic linker to create
3936 if (h
->dynindx
!= -1)
3937 dynindx
= h
->dynindx
;
3939 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3940 (info
, h
->root
.u
.def
.section
->owner
,
3941 global_sym_index (h
)));
3945 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3946 (info
, input_bfd
, (long) r_symndx
));
3949 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3950 srel
, rel
->r_offset
, r_type
,
3951 dynindx
, rel
->r_addend
);
3955 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3958 case R_IA64_LTOFF_FPTR22
:
3959 case R_IA64_LTOFF_FPTR64I
:
3960 case R_IA64_LTOFF_FPTR32MSB
:
3961 case R_IA64_LTOFF_FPTR32LSB
:
3962 case R_IA64_LTOFF_FPTR64MSB
:
3963 case R_IA64_LTOFF_FPTR64LSB
:
3967 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3968 if (dyn_i
->want_fptr
)
3970 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
3971 if (!undef_weak_ref
)
3972 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3977 /* Otherwise, we expect the dynamic linker to create
3981 if (h
->dynindx
!= -1)
3982 dynindx
= h
->dynindx
;
3984 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3985 (info
, h
->root
.u
.def
.section
->owner
,
3986 global_sym_index (h
)));
3989 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3990 (info
, input_bfd
, (long) r_symndx
));
3994 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
3995 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
3997 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4001 case R_IA64_PCREL32MSB
:
4002 case R_IA64_PCREL32LSB
:
4003 case R_IA64_PCREL64MSB
:
4004 case R_IA64_PCREL64LSB
:
4005 /* Install a dynamic relocation for this reloc. */
4006 if ((dynamic_symbol_p
4007 || elfNN_ia64_aix_vec (info
->hash
->creator
))
4010 BFD_ASSERT (srel
!= NULL
);
4012 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4013 srel
, rel
->r_offset
, r_type
,
4014 h
->dynindx
, rel
->r_addend
);
4018 case R_IA64_PCREL21BI
:
4019 case R_IA64_PCREL21F
:
4020 case R_IA64_PCREL21M
:
4021 /* ??? These two are only used for speculation fixup code.
4022 They should never be dynamic. */
4023 if (dynamic_symbol_p
)
4025 (*_bfd_error_handler
)
4026 (_("%s: dynamic relocation against speculation fixup"),
4027 bfd_archive_filename (input_bfd
));
4033 (*_bfd_error_handler
)
4034 (_("%s: speculation fixup against undefined weak symbol"),
4035 bfd_archive_filename (input_bfd
));
4041 case R_IA64_PCREL21B
:
4042 case R_IA64_PCREL60B
:
4043 /* We should have created a PLT entry for any dynamic symbol. */
4046 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
4048 if (dyn_i
&& dyn_i
->want_plt2
)
4050 /* Should have caught this earlier. */
4051 BFD_ASSERT (rel
->r_addend
== 0);
4053 value
= (ia64_info
->plt_sec
->output_section
->vma
4054 + ia64_info
->plt_sec
->output_offset
4055 + dyn_i
->plt2_offset
);
4059 /* Since there's no PLT entry, Validate that this is
4061 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
4063 /* If the symbol is undef_weak, we shouldn't be trying
4064 to call it. There's every chance that we'd wind up
4065 with an out-of-range fixup here. Don't bother setting
4066 any value at all. */
4072 case R_IA64_PCREL22
:
4073 case R_IA64_PCREL64I
:
4075 /* Make pc-relative. */
4076 value
-= (input_section
->output_section
->vma
4077 + input_section
->output_offset
4078 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
4079 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4082 case R_IA64_SEGREL32MSB
:
4083 case R_IA64_SEGREL32LSB
:
4084 case R_IA64_SEGREL64MSB
:
4085 case R_IA64_SEGREL64LSB
:
4088 /* If the input section was discarded from the output, then
4094 struct elf_segment_map
*m
;
4095 Elf_Internal_Phdr
*p
;
4097 /* Find the segment that contains the output_section. */
4098 for (m
= elf_tdata (output_bfd
)->segment_map
,
4099 p
= elf_tdata (output_bfd
)->phdr
;
4104 for (i
= m
->count
- 1; i
>= 0; i
--)
4105 if (m
->sections
[i
] == sym_sec
->output_section
)
4113 r
= bfd_reloc_notsupported
;
4117 /* The VMA of the segment is the vaddr of the associated
4119 if (value
> p
->p_vaddr
)
4120 value
-= p
->p_vaddr
;
4123 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
4129 case R_IA64_SECREL32MSB
:
4130 case R_IA64_SECREL32LSB
:
4131 case R_IA64_SECREL64MSB
:
4132 case R_IA64_SECREL64LSB
:
4133 /* Make output-section relative. */
4134 if (value
> input_section
->output_section
->vma
)
4135 value
-= input_section
->output_section
->vma
;
4138 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4141 case R_IA64_IPLTMSB
:
4142 case R_IA64_IPLTLSB
:
4143 /* Install a dynamic relocation for this reloc. */
4144 if ((dynamic_symbol_p
|| info
->shared
)
4145 && (input_section
->flags
& SEC_ALLOC
) != 0)
4147 BFD_ASSERT (srel
!= NULL
);
4149 /* If we don't need dynamic symbol lookup, install two
4150 RELATIVE relocations. */
4151 if (! dynamic_symbol_p
)
4153 unsigned int dyn_r_type
;
4155 if (r_type
== R_IA64_IPLTMSB
)
4156 dyn_r_type
= R_IA64_REL64MSB
;
4158 dyn_r_type
= R_IA64_REL64LSB
;
4160 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4162 srel
, rel
->r_offset
,
4163 dyn_r_type
, 0, value
);
4164 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4166 srel
, rel
->r_offset
+ 8,
4167 dyn_r_type
, 0, gp_val
);
4170 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4171 srel
, rel
->r_offset
, r_type
,
4172 h
->dynindx
, rel
->r_addend
);
4175 if (r_type
== R_IA64_IPLTMSB
)
4176 r_type
= R_IA64_DIR64MSB
;
4178 r_type
= R_IA64_DIR64LSB
;
4179 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4180 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
4184 case R_IA64_TPREL14
:
4185 case R_IA64_TPREL22
:
4186 case R_IA64_TPREL64I
:
4187 value
-= elfNN_ia64_tprel_base (info
);
4188 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4191 case R_IA64_DTPREL14
:
4192 case R_IA64_DTPREL22
:
4193 case R_IA64_DTPREL64I
:
4194 value
-= elfNN_ia64_dtprel_base (info
);
4195 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4198 case R_IA64_LTOFF_TPREL22
:
4199 case R_IA64_LTOFF_DTPMOD22
:
4200 case R_IA64_LTOFF_DTPREL22
:
4207 case R_IA64_LTOFF_TPREL22
:
4208 if (!dynamic_symbol_p
&& !info
->shared
)
4209 value
-= elfNN_ia64_tprel_base (info
);
4210 got_r_type
= R_IA64_TPREL64LSB
;
4212 case R_IA64_LTOFF_DTPMOD22
:
4213 if (!dynamic_symbol_p
&& !info
->shared
)
4215 got_r_type
= R_IA64_DTPMOD64LSB
;
4217 case R_IA64_LTOFF_DTPREL22
:
4218 if (!dynamic_symbol_p
)
4219 value
-= elfNN_ia64_dtprel_base (info
);
4220 got_r_type
= R_IA64_DTPREL64LSB
;
4223 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
4224 value
= set_got_entry (input_bfd
, info
, dyn_i
,
4225 (h
? h
->dynindx
: -1), rel
->r_addend
,
4228 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
4234 r
= bfd_reloc_notsupported
;
4243 case bfd_reloc_undefined
:
4244 /* This can happen for global table relative relocs if
4245 __gp is undefined. This is a panic situation so we
4246 don't try to continue. */
4247 (*info
->callbacks
->undefined_symbol
)
4248 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
4251 case bfd_reloc_notsupported
:
4256 name
= h
->root
.root
.string
;
4259 name
= bfd_elf_string_from_elf_section (input_bfd
,
4260 symtab_hdr
->sh_link
,
4265 name
= bfd_section_name (input_bfd
, input_section
);
4267 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
4269 input_section
, rel
->r_offset
))
4275 case bfd_reloc_dangerous
:
4276 case bfd_reloc_outofrange
:
4277 case bfd_reloc_overflow
:
4283 name
= h
->root
.root
.string
;
4286 name
= bfd_elf_string_from_elf_section (input_bfd
,
4287 symtab_hdr
->sh_link
,
4292 name
= bfd_section_name (input_bfd
, input_section
);
4294 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
4311 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
4313 struct bfd_link_info
*info
;
4314 struct elf_link_hash_entry
*h
;
4315 Elf_Internal_Sym
*sym
;
4317 struct elfNN_ia64_link_hash_table
*ia64_info
;
4318 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4320 ia64_info
= elfNN_ia64_hash_table (info
);
4321 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
4323 /* Fill in the PLT data, if required. */
4324 if (dyn_i
&& dyn_i
->want_plt
)
4326 Elf_Internal_Rela outrel
;
4329 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
4330 ElfNN_External_Rela
*rel
;
4332 gp_val
= _bfd_get_gp_value (output_bfd
);
4334 /* Initialize the minimal PLT entry. */
4336 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4337 plt_sec
= ia64_info
->plt_sec
;
4338 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4340 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4341 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4342 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4345 plt_addr
= (plt_sec
->output_section
->vma
4346 + plt_sec
->output_offset
4347 + dyn_i
->plt_offset
);
4348 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, true);
4350 /* Initialize the FULL PLT entry, if needed. */
4351 if (dyn_i
->want_plt2
)
4353 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4355 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4356 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4359 /* Mark the symbol as undefined, rather than as defined in the
4360 plt section. Leave the value alone. */
4361 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4362 first place. But perhaps elflink.h did some for us. */
4363 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4364 sym
->st_shndx
= SHN_UNDEF
;
4367 /* Create the dynamic relocation. */
4368 outrel
.r_offset
= pltoff_addr
;
4369 if (bfd_little_endian (output_bfd
))
4370 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4372 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4373 outrel
.r_addend
= 0;
4375 /* This is fun. In the .IA_64.pltoff section, we've got entries
4376 that correspond both to real PLT entries, and those that
4377 happened to resolve to local symbols but need to be created
4378 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4379 relocations for the real PLT should come at the end of the
4380 section, so that they can be indexed by plt entry at runtime.
4382 We emitted all of the relocations for the non-PLT @pltoff
4383 entries during relocate_section. So we can consider the
4384 existing sec->reloc_count to be the base of the array of
4387 rel
= (ElfNN_External_Rela
*)ia64_info
->rel_pltoff_sec
->contents
;
4388 rel
+= ia64_info
->rel_pltoff_sec
->reloc_count
;
4390 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, rel
+ index
);
4393 /* Mark some specially defined symbols as absolute. */
4394 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4395 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4396 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4397 sym
->st_shndx
= SHN_ABS
;
4403 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4405 struct bfd_link_info
*info
;
4407 struct elfNN_ia64_link_hash_table
*ia64_info
;
4410 ia64_info
= elfNN_ia64_hash_table (info
);
4411 dynobj
= ia64_info
->root
.dynobj
;
4413 if (elf_hash_table (info
)->dynamic_sections_created
)
4415 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4416 asection
*sdyn
, *sgotplt
;
4419 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4420 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4421 BFD_ASSERT (sdyn
!= NULL
);
4422 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4423 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4425 gp_val
= _bfd_get_gp_value (abfd
);
4427 for (; dyncon
< dynconend
; dyncon
++)
4429 Elf_Internal_Dyn dyn
;
4431 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4436 dyn
.d_un
.d_ptr
= gp_val
;
4440 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4441 * sizeof (ElfNN_External_Rela
));
4445 /* See the comment above in finish_dynamic_symbol. */
4446 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4447 + ia64_info
->rel_pltoff_sec
->output_offset
4448 + (ia64_info
->rel_pltoff_sec
->reloc_count
4449 * sizeof (ElfNN_External_Rela
)));
4452 case DT_IA_64_PLT_RESERVE
:
4453 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4454 + sgotplt
->output_offset
);
4458 /* Do not have RELASZ include JMPREL. This makes things
4459 easier on ld.so. This is not what the rest of BFD set up. */
4460 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4461 * sizeof (ElfNN_External_Rela
));
4465 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4468 /* Initialize the PLT0 entry */
4469 if (ia64_info
->plt_sec
)
4471 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4474 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4476 pltres
= (sgotplt
->output_section
->vma
4477 + sgotplt
->output_offset
4480 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4487 /* ELF file flag handling: */
4489 /* Function to keep IA-64 specific file flags. */
4491 elfNN_ia64_set_private_flags (abfd
, flags
)
4495 BFD_ASSERT (!elf_flags_init (abfd
)
4496 || elf_elfheader (abfd
)->e_flags
== flags
);
4498 elf_elfheader (abfd
)->e_flags
= flags
;
4499 elf_flags_init (abfd
) = true;
4503 /* Merge backend specific data from an object file to the output
4504 object file when linking. */
4506 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4513 /* Don't even pretend to support mixed-format linking. */
4514 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4515 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4518 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4519 out_flags
= elf_elfheader (obfd
)->e_flags
;
4521 if (! elf_flags_init (obfd
))
4523 elf_flags_init (obfd
) = true;
4524 elf_elfheader (obfd
)->e_flags
= in_flags
;
4526 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4527 && bfd_get_arch_info (obfd
)->the_default
)
4529 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4530 bfd_get_mach (ibfd
));
4536 /* Check flag compatibility. */
4537 if (in_flags
== out_flags
)
4540 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4541 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4542 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4544 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4546 (*_bfd_error_handler
)
4547 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4548 bfd_archive_filename (ibfd
));
4550 bfd_set_error (bfd_error_bad_value
);
4553 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4555 (*_bfd_error_handler
)
4556 (_("%s: linking big-endian files with little-endian files"),
4557 bfd_archive_filename (ibfd
));
4559 bfd_set_error (bfd_error_bad_value
);
4562 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4564 (*_bfd_error_handler
)
4565 (_("%s: linking 64-bit files with 32-bit files"),
4566 bfd_archive_filename (ibfd
));
4568 bfd_set_error (bfd_error_bad_value
);
4571 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4573 (*_bfd_error_handler
)
4574 (_("%s: linking constant-gp files with non-constant-gp files"),
4575 bfd_archive_filename (ibfd
));
4577 bfd_set_error (bfd_error_bad_value
);
4580 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4581 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4583 (*_bfd_error_handler
)
4584 (_("%s: linking auto-pic files with non-auto-pic files"),
4585 bfd_archive_filename (ibfd
));
4587 bfd_set_error (bfd_error_bad_value
);
4595 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4599 FILE *file
= (FILE *) ptr
;
4600 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4602 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4604 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4605 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4606 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4607 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4608 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4609 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4610 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4611 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4612 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4614 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4618 static enum elf_reloc_type_class
4619 elfNN_ia64_reloc_type_class (rela
)
4620 const Elf_Internal_Rela
*rela
;
4622 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
4624 case R_IA64_REL32MSB
:
4625 case R_IA64_REL32LSB
:
4626 case R_IA64_REL64MSB
:
4627 case R_IA64_REL64LSB
:
4628 return reloc_class_relative
;
4629 case R_IA64_IPLTMSB
:
4630 case R_IA64_IPLTLSB
:
4631 return reloc_class_plt
;
4633 return reloc_class_copy
;
4635 return reloc_class_normal
;
4640 elfNN_ia64_hpux_vec (const bfd_target
*vec
)
4642 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec
;
4643 return (vec
== & bfd_elfNN_ia64_hpux_big_vec
);
4647 elfNN_hpux_post_process_headers (abfd
, info
)
4649 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
4651 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
4653 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_HPUX
;
4654 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 1;
4658 elfNN_hpux_backend_section_from_bfd_section (abfd
, sec
, retval
)
4659 bfd
*abfd ATTRIBUTE_UNUSED
;
4663 if (bfd_is_com_section (sec
))
4665 *retval
= SHN_IA_64_ANSI_COMMON
;
4671 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4672 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4673 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4674 #define TARGET_BIG_NAME "elfNN-ia64-big"
4675 #define ELF_ARCH bfd_arch_ia64
4676 #define ELF_MACHINE_CODE EM_IA_64
4677 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4678 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4679 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4681 #define elf_backend_section_from_shdr \
4682 elfNN_ia64_section_from_shdr
4683 #define elf_backend_section_flags \
4684 elfNN_ia64_section_flags
4685 #define elf_backend_fake_sections \
4686 elfNN_ia64_fake_sections
4687 #define elf_backend_final_write_processing \
4688 elfNN_ia64_final_write_processing
4689 #define elf_backend_add_symbol_hook \
4690 elfNN_ia64_add_symbol_hook
4691 #define elf_backend_additional_program_headers \
4692 elfNN_ia64_additional_program_headers
4693 #define elf_backend_modify_segment_map \
4694 elfNN_ia64_modify_segment_map
4695 #define elf_info_to_howto \
4696 elfNN_ia64_info_to_howto
4698 #define bfd_elfNN_bfd_reloc_type_lookup \
4699 elfNN_ia64_reloc_type_lookup
4700 #define bfd_elfNN_bfd_is_local_label_name \
4701 elfNN_ia64_is_local_label_name
4702 #define bfd_elfNN_bfd_relax_section \
4703 elfNN_ia64_relax_section
4705 /* Stuff for the BFD linker: */
4706 #define bfd_elfNN_bfd_link_hash_table_create \
4707 elfNN_ia64_hash_table_create
4708 #define elf_backend_create_dynamic_sections \
4709 elfNN_ia64_create_dynamic_sections
4710 #define elf_backend_check_relocs \
4711 elfNN_ia64_check_relocs
4712 #define elf_backend_adjust_dynamic_symbol \
4713 elfNN_ia64_adjust_dynamic_symbol
4714 #define elf_backend_size_dynamic_sections \
4715 elfNN_ia64_size_dynamic_sections
4716 #define elf_backend_relocate_section \
4717 elfNN_ia64_relocate_section
4718 #define elf_backend_finish_dynamic_symbol \
4719 elfNN_ia64_finish_dynamic_symbol
4720 #define elf_backend_finish_dynamic_sections \
4721 elfNN_ia64_finish_dynamic_sections
4722 #define bfd_elfNN_bfd_final_link \
4723 elfNN_ia64_final_link
4725 #define bfd_elfNN_bfd_merge_private_bfd_data \
4726 elfNN_ia64_merge_private_bfd_data
4727 #define bfd_elfNN_bfd_set_private_flags \
4728 elfNN_ia64_set_private_flags
4729 #define bfd_elfNN_bfd_print_private_bfd_data \
4730 elfNN_ia64_print_private_bfd_data
4732 #define elf_backend_plt_readonly 1
4733 #define elf_backend_want_plt_sym 0
4734 #define elf_backend_plt_alignment 5
4735 #define elf_backend_got_header_size 0
4736 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4737 #define elf_backend_want_got_plt 1
4738 #define elf_backend_may_use_rel_p 1
4739 #define elf_backend_may_use_rela_p 1
4740 #define elf_backend_default_use_rela_p 1
4741 #define elf_backend_want_dynbss 0
4742 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4743 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4744 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4745 #define elf_backend_rela_normal 1
4747 #include "elfNN-target.h"
4749 /* AIX-specific vectors. */
4751 #undef TARGET_LITTLE_SYM
4752 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4753 #undef TARGET_LITTLE_NAME
4754 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4755 #undef TARGET_BIG_SYM
4756 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4757 #undef TARGET_BIG_NAME
4758 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4760 #undef elf_backend_add_symbol_hook
4761 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4763 #undef bfd_elfNN_bfd_link_add_symbols
4764 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4766 #define elfNN_bed elfNN_ia64_aix_bed
4768 #include "elfNN-target.h"
4770 /* HPUX-specific vectors. */
4772 #undef TARGET_LITTLE_SYM
4773 #undef TARGET_LITTLE_NAME
4774 #undef TARGET_BIG_SYM
4775 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4776 #undef TARGET_BIG_NAME
4777 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4779 /* We need to undo the AIX specific functions. */
4781 #undef elf_backend_add_symbol_hook
4782 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
4784 #undef bfd_elfNN_bfd_link_add_symbols
4785 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
4787 /* These are HP-UX specific functions. */
4789 #undef elf_backend_post_process_headers
4790 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4792 #undef elf_backend_section_from_bfd_section
4793 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4795 #undef elf_backend_want_p_paddr_set_to_zero
4796 #define elf_backend_want_p_paddr_set_to_zero 1
4798 #undef ELF_MAXPAGESIZE
4799 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4802 #define elfNN_bed elfNN_ia64_hpux_bed
4804 #include "elfNN-target.h"
4806 #undef elf_backend_want_p_paddr_set_to_zero