1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003 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_gotx : 1;
106 unsigned want_fptr : 1;
107 unsigned want_ltoff_fptr : 1;
108 unsigned want_plt : 1;
109 unsigned want_plt2 : 1;
110 unsigned want_pltoff : 1;
111 unsigned want_tprel : 1;
112 unsigned want_dtpmod : 1;
113 unsigned want_dtprel : 1;
116 struct elfNN_ia64_local_hash_entry
118 struct bfd_hash_entry root;
119 struct elfNN_ia64_dyn_sym_info *info;
121 /* TRUE if this hash entry's addends was translated for
122 SHF_MERGE optimization. */
123 unsigned sec_merge_done : 1;
126 struct elfNN_ia64_local_hash_table
128 struct bfd_hash_table root;
129 /* No additional fields for now. */
132 struct elfNN_ia64_link_hash_entry
134 struct elf_link_hash_entry root;
135 struct elfNN_ia64_dyn_sym_info *info;
138 struct elfNN_ia64_link_hash_table
140 /* The main hash table. */
141 struct elf_link_hash_table root;
143 asection *got_sec; /* the linkage table section (or NULL) */
144 asection *rel_got_sec; /* dynamic relocation section for same */
145 asection *fptr_sec; /* function descriptor table (or NULL) */
146 asection *plt_sec; /* the primary plt section (or NULL) */
147 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
148 asection *rel_pltoff_sec; /* dynamic relocation section for same */
150 bfd_size_type minplt_entries; /* number of minplt entries */
151 unsigned reltext : 1; /* are there relocs against readonly sections? */
152 unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
153 bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry */
155 struct elfNN_ia64_local_hash_table loc_hash_table;
158 struct elfNN_ia64_allocate_data
160 struct bfd_link_info *info;
164 #define elfNN_ia64_hash_table(p) \
165 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
167 static bfd_reloc_status_type elfNN_ia64_reloc
168 PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
169 asection *input_section, bfd *output_bfd, char **error_message));
170 static reloc_howto_type * lookup_howto
171 PARAMS ((unsigned int rtype));
172 static reloc_howto_type *elfNN_ia64_reloc_type_lookup
173 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
174 static void elfNN_ia64_info_to_howto
175 PARAMS ((bfd *abfd, arelent *bfd_reloc, Elf_Internal_Rela *elf_reloc));
176 static bfd_boolean elfNN_ia64_relax_section
177 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
178 bfd_boolean *again));
179 static void elfNN_ia64_relax_ldxmov
180 PARAMS((bfd *abfd, bfd_byte *contents, bfd_vma off));
181 static bfd_boolean is_unwind_section_name
182 PARAMS ((bfd *abfd, const char *));
183 static bfd_boolean elfNN_ia64_section_from_shdr
184 PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
185 static bfd_boolean elfNN_ia64_section_flags
186 PARAMS ((flagword *, Elf_Internal_Shdr *));
187 static bfd_boolean elfNN_ia64_fake_sections
188 PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec));
189 static void elfNN_ia64_final_write_processing
190 PARAMS ((bfd *abfd, bfd_boolean linker));
191 static bfd_boolean elfNN_ia64_add_symbol_hook
192 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
193 const char **namep, flagword *flagsp, asection **secp,
195 static bfd_boolean elfNN_ia64_aix_vec
196 PARAMS ((const bfd_target *vec));
197 static bfd_boolean elfNN_ia64_aix_add_symbol_hook
198 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
199 const char **namep, flagword *flagsp, asection **secp,
201 static bfd_boolean elfNN_ia64_aix_link_add_symbols
202 PARAMS ((bfd *abfd, struct bfd_link_info *info));
203 static int elfNN_ia64_additional_program_headers
204 PARAMS ((bfd *abfd));
205 static bfd_boolean elfNN_ia64_modify_segment_map
207 static bfd_boolean elfNN_ia64_is_local_label_name
208 PARAMS ((bfd *abfd, const char *name));
209 static bfd_boolean elfNN_ia64_dynamic_symbol_p
210 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
211 static bfd_boolean elfNN_ia64_local_hash_table_init
212 PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
213 new_hash_entry_func new));
214 static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
215 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
216 const char *string));
217 static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
218 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
219 const char *string));
220 static void elfNN_ia64_hash_copy_indirect
221 PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
222 struct elf_link_hash_entry *));
223 static void elfNN_ia64_hash_hide_symbol
224 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
225 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
226 PARAMS ((bfd *abfd));
227 static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
228 PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
229 bfd_boolean create, bfd_boolean copy));
230 static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
231 PARAMS ((struct bfd_hash_entry *, PTR));
232 static bfd_boolean elfNN_ia64_local_dyn_sym_thunk
233 PARAMS ((struct bfd_hash_entry *, PTR));
234 static void elfNN_ia64_dyn_sym_traverse
235 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
236 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
238 static bfd_boolean elfNN_ia64_create_dynamic_sections
239 PARAMS ((bfd *abfd, struct bfd_link_info *info));
240 static struct elfNN_ia64_local_hash_entry * get_local_sym_hash
241 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
242 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
243 static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
244 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
245 struct elf_link_hash_entry *h,
246 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
247 static asection *get_got
248 PARAMS ((bfd *abfd, struct bfd_link_info *info,
249 struct elfNN_ia64_link_hash_table *ia64_info));
250 static asection *get_fptr
251 PARAMS ((bfd *abfd, struct bfd_link_info *info,
252 struct elfNN_ia64_link_hash_table *ia64_info));
253 static asection *get_pltoff
254 PARAMS ((bfd *abfd, struct bfd_link_info *info,
255 struct elfNN_ia64_link_hash_table *ia64_info));
256 static asection *get_reloc_section
257 PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
258 asection *sec, bfd_boolean create));
259 static bfd_boolean count_dyn_reloc
260 PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
261 asection *srel, int type));
262 static bfd_boolean elfNN_ia64_check_relocs
263 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
264 const Elf_Internal_Rela *relocs));
265 static bfd_boolean elfNN_ia64_adjust_dynamic_symbol
266 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
267 static long global_sym_index
268 PARAMS ((struct elf_link_hash_entry *h));
269 static bfd_boolean allocate_fptr
270 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
271 static bfd_boolean allocate_global_data_got
272 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
273 static bfd_boolean allocate_global_fptr_got
274 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
275 static bfd_boolean allocate_local_got
276 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
277 static bfd_boolean allocate_pltoff_entries
278 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
279 static bfd_boolean allocate_plt_entries
280 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
281 static bfd_boolean allocate_plt2_entries
282 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
283 static bfd_boolean allocate_dynrel_entries
284 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
285 static bfd_boolean elfNN_ia64_size_dynamic_sections
286 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
287 static bfd_reloc_status_type elfNN_ia64_install_value
288 PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
289 static void elfNN_ia64_install_dyn_reloc
290 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
291 asection *srel, bfd_vma offset, unsigned int type,
292 long dynindx, bfd_vma addend));
293 static bfd_vma set_got_entry
294 PARAMS ((bfd *abfd, struct bfd_link_info *info,
295 struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
296 bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
297 static bfd_vma set_fptr_entry
298 PARAMS ((bfd *abfd, struct bfd_link_info *info,
299 struct elfNN_ia64_dyn_sym_info *dyn_i,
301 static bfd_vma set_pltoff_entry
302 PARAMS ((bfd *abfd, struct bfd_link_info *info,
303 struct elfNN_ia64_dyn_sym_info *dyn_i,
304 bfd_vma value, bfd_boolean));
305 static bfd_vma elfNN_ia64_tprel_base
306 PARAMS ((struct bfd_link_info *info));
307 static bfd_vma elfNN_ia64_dtprel_base
308 PARAMS ((struct bfd_link_info *info));
309 static int elfNN_ia64_unwind_entry_compare
310 PARAMS ((const PTR, const PTR));
311 static bfd_boolean elfNN_ia64_choose_gp
312 PARAMS ((bfd *abfd, struct bfd_link_info *info));
313 static bfd_boolean elfNN_ia64_final_link
314 PARAMS ((bfd *abfd, struct bfd_link_info *info));
315 static bfd_boolean elfNN_ia64_relocate_section
316 PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
317 asection *input_section, bfd_byte *contents,
318 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
319 asection **local_sections));
320 static bfd_boolean elfNN_ia64_finish_dynamic_symbol
321 PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
322 struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
323 static bfd_boolean elfNN_ia64_finish_dynamic_sections
324 PARAMS ((bfd *abfd, struct bfd_link_info *info));
325 static bfd_boolean elfNN_ia64_set_private_flags
326 PARAMS ((bfd *abfd, flagword flags));
327 static bfd_boolean elfNN_ia64_merge_private_bfd_data
328 PARAMS ((bfd *ibfd, bfd *obfd));
329 static bfd_boolean elfNN_ia64_print_private_bfd_data
330 PARAMS ((bfd *abfd, PTR ptr));
331 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
332 PARAMS ((const Elf_Internal_Rela *));
333 static bfd_boolean elfNN_ia64_hpux_vec
334 PARAMS ((const bfd_target *vec));
335 static void elfNN_hpux_post_process_headers
336 PARAMS ((bfd *abfd, struct bfd_link_info *info));
337 bfd_boolean elfNN_hpux_backend_section_from_bfd_section
338 PARAMS ((bfd *abfd, asection *sec, int *retval));
340 /* ia64-specific relocation. */
342 /* Perform a relocation. Not much to do here as all the hard work is
343 done in elfNN_ia64_final_link_relocate. */
344 static bfd_reloc_status_type
345 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
346 output_bfd, error_message)
347 bfd *abfd ATTRIBUTE_UNUSED;
349 asymbol *sym ATTRIBUTE_UNUSED;
350 PTR data ATTRIBUTE_UNUSED;
351 asection *input_section;
353 char **error_message;
357 reloc->address += input_section->output_offset;
360 *error_message = "Unsupported call to elfNN_ia64_reloc";
361 return bfd_reloc_notsupported;
364 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
365 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
366 elfNN_ia64_reloc, NAME, FALSE, 0, 0, IN)
368 /* This table has to be sorted according to increasing number of the
370 static reloc_howto_type ia64_howto_table[] =
372 IA64_HOWTO (R_IA64_NONE, "NONE", 0, FALSE, TRUE),
374 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, FALSE, TRUE),
375 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, FALSE, TRUE),
376 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, FALSE, TRUE),
377 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, FALSE, TRUE),
378 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, FALSE, TRUE),
379 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, FALSE, TRUE),
380 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, FALSE, TRUE),
382 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, FALSE, TRUE),
383 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, FALSE, TRUE),
384 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, FALSE, TRUE),
385 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, FALSE, TRUE),
386 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, FALSE, TRUE),
387 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, FALSE, TRUE),
389 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, FALSE, TRUE),
390 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, FALSE, TRUE),
392 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, FALSE, TRUE),
393 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, FALSE, TRUE),
394 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, FALSE, TRUE),
395 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, FALSE, TRUE),
397 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, FALSE, TRUE),
398 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, FALSE, TRUE),
399 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, FALSE, TRUE),
400 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, FALSE, TRUE),
401 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, FALSE, TRUE),
403 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, TRUE, TRUE),
404 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, TRUE, TRUE),
405 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, TRUE, TRUE),
406 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, TRUE, TRUE),
407 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, TRUE, TRUE),
408 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, TRUE, TRUE),
409 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, TRUE, TRUE),
410 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, TRUE, TRUE),
412 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, FALSE, TRUE),
413 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, FALSE, TRUE),
414 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, FALSE, TRUE),
415 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, FALSE, TRUE),
416 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, FALSE, TRUE),
417 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, FALSE, TRUE),
419 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, FALSE, TRUE),
420 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, FALSE, TRUE),
421 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, FALSE, TRUE),
422 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, FALSE, TRUE),
424 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, FALSE, TRUE),
425 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, FALSE, TRUE),
426 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, FALSE, TRUE),
427 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, FALSE, TRUE),
429 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, FALSE, TRUE),
430 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, FALSE, TRUE),
431 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, FALSE, TRUE),
432 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, FALSE, TRUE),
434 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, FALSE, TRUE),
435 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, FALSE, TRUE),
436 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, FALSE, TRUE),
437 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, FALSE, TRUE),
439 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, TRUE, TRUE),
440 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, TRUE, TRUE),
441 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, TRUE, TRUE),
443 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, FALSE, TRUE),
444 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, FALSE, TRUE),
445 IA64_HOWTO (R_IA64_COPY, "COPY", 4, FALSE, TRUE),
446 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, FALSE, TRUE),
447 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, FALSE, TRUE),
449 IA64_HOWTO (R_IA64_TPREL14, "TPREL14", 0, FALSE, FALSE),
450 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, FALSE, FALSE),
451 IA64_HOWTO (R_IA64_TPREL64I, "TPREL64I", 0, FALSE, FALSE),
452 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 8, FALSE, FALSE),
453 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 8, FALSE, FALSE),
454 IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, FALSE, FALSE),
456 IA64_HOWTO (R_IA64_DTPMOD64MSB, "TPREL64MSB", 8, FALSE, FALSE),
457 IA64_HOWTO (R_IA64_DTPMOD64LSB, "TPREL64LSB", 8, FALSE, FALSE),
458 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
460 IA64_HOWTO (R_IA64_DTPREL14, "DTPREL14", 0, FALSE, FALSE),
461 IA64_HOWTO (R_IA64_DTPREL22, "DTPREL22", 0, FALSE, FALSE),
462 IA64_HOWTO (R_IA64_DTPREL64I, "DTPREL64I", 0, FALSE, FALSE),
463 IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 4, FALSE, FALSE),
464 IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 4, FALSE, FALSE),
465 IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 8, FALSE, FALSE),
466 IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 8, FALSE, FALSE),
467 IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
470 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
472 /* Given a BFD reloc type, return the matching HOWTO structure. */
474 static reloc_howto_type *
478 static int inited = 0;
485 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
486 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
487 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
490 BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
491 i = elf_code_to_howto_index[rtype];
492 if (i >= NELEMS (ia64_howto_table))
494 return ia64_howto_table + i;
497 static reloc_howto_type*
498 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
499 bfd *abfd ATTRIBUTE_UNUSED;
500 bfd_reloc_code_real_type bfd_code;
506 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
508 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
509 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
510 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
512 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
513 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
514 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
515 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
517 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
518 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
519 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
520 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
521 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
522 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
524 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
525 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
527 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
528 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
529 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
530 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
531 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
532 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
533 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
534 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
535 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
537 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
538 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
539 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
540 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
541 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
542 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
543 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
544 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
545 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
546 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
547 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
549 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
550 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
551 case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
552 case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
553 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
554 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
556 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
557 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
558 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
559 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
561 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
562 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
563 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
564 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
566 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
567 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
568 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
569 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
571 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
572 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
573 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
574 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
576 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
577 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
578 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
579 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
580 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
582 case BFD_RELOC_IA64_TPREL14: rtype = R_IA64_TPREL14; break;
583 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
584 case BFD_RELOC_IA64_TPREL64I: rtype = R_IA64_TPREL64I; break;
585 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
586 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
587 case BFD_RELOC_IA64_LTOFF_TPREL22: rtype = R_IA64_LTOFF_TPREL22; break;
589 case BFD_RELOC_IA64_DTPMOD64MSB: rtype = R_IA64_DTPMOD64MSB; break;
590 case BFD_RELOC_IA64_DTPMOD64LSB: rtype = R_IA64_DTPMOD64LSB; break;
591 case BFD_RELOC_IA64_LTOFF_DTPMOD22: rtype = R_IA64_LTOFF_DTPMOD22; break;
593 case BFD_RELOC_IA64_DTPREL14: rtype = R_IA64_DTPREL14; break;
594 case BFD_RELOC_IA64_DTPREL22: rtype = R_IA64_DTPREL22; break;
595 case BFD_RELOC_IA64_DTPREL64I: rtype = R_IA64_DTPREL64I; break;
596 case BFD_RELOC_IA64_DTPREL32MSB: rtype = R_IA64_DTPREL32MSB; break;
597 case BFD_RELOC_IA64_DTPREL32LSB: rtype = R_IA64_DTPREL32LSB; break;
598 case BFD_RELOC_IA64_DTPREL64MSB: rtype = R_IA64_DTPREL64MSB; break;
599 case BFD_RELOC_IA64_DTPREL64LSB: rtype = R_IA64_DTPREL64LSB; break;
600 case BFD_RELOC_IA64_LTOFF_DTPREL22: rtype = R_IA64_LTOFF_DTPREL22; break;
604 return lookup_howto (rtype);
607 /* Given a ELF reloc, return the matching HOWTO structure. */
610 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
611 bfd *abfd ATTRIBUTE_UNUSED;
613 Elf_Internal_Rela *elf_reloc;
616 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
619 #define PLT_HEADER_SIZE (3 * 16)
620 #define PLT_MIN_ENTRY_SIZE (1 * 16)
621 #define PLT_FULL_ENTRY_SIZE (2 * 16)
622 #define PLT_RESERVED_WORDS 3
624 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
626 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
627 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
628 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
629 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
630 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
631 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
632 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
633 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
634 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
637 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
639 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
640 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
641 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
644 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
646 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
647 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
648 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
649 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
650 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
651 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
654 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
655 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
656 #define DYNAMIC_INTERPRETER(abfd) \
657 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
659 static const bfd_byte oor_brl[16] =
661 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
663 0x00, 0x00, 0x00, 0xc0
666 /* These functions do relaxation for IA-64 ELF. */
669 elfNN_ia64_relax_section (abfd, sec, link_info, again)
672 struct bfd_link_info *link_info;
677 struct one_fixup *next;
683 Elf_Internal_Shdr *symtab_hdr;
684 Elf_Internal_Rela *internal_relocs;
685 Elf_Internal_Rela *irel, *irelend;
687 Elf_Internal_Sym *isymbuf = NULL;
688 struct elfNN_ia64_link_hash_table *ia64_info;
689 struct one_fixup *fixups = NULL;
690 bfd_boolean changed_contents = FALSE;
691 bfd_boolean changed_relocs = FALSE;
692 bfd_boolean changed_got = FALSE;
695 /* Assume we're not going to change any sizes, and we'll only need
699 /* Nothing to do if there are no relocations. */
700 if ((sec->flags & SEC_RELOC) == 0
701 || sec->reloc_count == 0)
704 /* If this is the first time we have been called for this section,
705 initialize the cooked size. */
706 if (sec->_cooked_size == 0)
707 sec->_cooked_size = sec->_raw_size;
709 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
711 /* Load the relocations for this section. */
712 internal_relocs = (_bfd_elfNN_link_read_relocs
713 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
714 link_info->keep_memory));
715 if (internal_relocs == NULL)
718 ia64_info = elfNN_ia64_hash_table (link_info);
719 irelend = internal_relocs + sec->reloc_count;
721 /* Get the section contents. */
722 if (elf_section_data (sec)->this_hdr.contents != NULL)
723 contents = elf_section_data (sec)->this_hdr.contents;
726 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
727 if (contents == NULL)
730 if (! bfd_get_section_contents (abfd, sec, contents,
731 (file_ptr) 0, sec->_raw_size))
735 for (irel = internal_relocs; irel < irelend; irel++)
737 unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
738 bfd_vma symaddr, reladdr, trampoff, toff, roff;
742 bfd_boolean is_branch;
743 struct elfNN_ia64_dyn_sym_info *dyn_i;
747 case R_IA64_PCREL21B:
748 case R_IA64_PCREL21BI:
749 case R_IA64_PCREL21M:
750 case R_IA64_PCREL21F:
754 case R_IA64_LTOFF22X:
763 /* Get the value of the symbol referred to by the reloc. */
764 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
766 /* A local symbol. */
767 Elf_Internal_Sym *isym;
769 /* Read this BFD's local symbols. */
772 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
774 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
775 symtab_hdr->sh_info, 0,
781 isym = isymbuf + ELF64_R_SYM (irel->r_info);
782 if (isym->st_shndx == SHN_UNDEF)
783 continue; /* We can't do anthing with undefined symbols. */
784 else if (isym->st_shndx == SHN_ABS)
785 tsec = bfd_abs_section_ptr;
786 else if (isym->st_shndx == SHN_COMMON)
787 tsec = bfd_com_section_ptr;
788 else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
789 tsec = bfd_com_section_ptr;
791 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
793 toff = isym->st_value;
794 dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
799 struct elf_link_hash_entry *h;
801 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
802 h = elf_sym_hashes (abfd)[indx];
803 BFD_ASSERT (h != NULL);
805 while (h->root.type == bfd_link_hash_indirect
806 || h->root.type == bfd_link_hash_warning)
807 h = (struct elf_link_hash_entry *) h->root.u.i.link;
809 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
811 /* For branches to dynamic symbols, we're interested instead
812 in a branch to the PLT entry. */
813 if (is_branch && dyn_i && dyn_i->want_plt2)
815 /* Internal branches shouldn't be sent to the PLT.
816 Leave this for now and we'll give an error later. */
817 if (r_type != R_IA64_PCREL21B)
820 tsec = ia64_info->plt_sec;
821 toff = dyn_i->plt2_offset;
824 /* Can't do anything else with dynamic symbols. */
825 else if (elfNN_ia64_dynamic_symbol_p (h, link_info))
830 /* We can't do anthing with undefined symbols. */
831 if (h->root.type == bfd_link_hash_undefined
832 || h->root.type == bfd_link_hash_undefweak)
835 tsec = h->root.u.def.section;
836 toff = h->root.u.def.value;
840 symaddr = (tsec->output_section->vma
841 + tsec->output_offset
845 roff = irel->r_offset;
849 reladdr = (sec->output_section->vma
851 + roff) & (bfd_vma) -4;
853 /* If the branch is in range, no need to do anything. */
854 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
855 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
858 /* If the branch and target are in the same section, you've
859 got one honking big section and we can't help you. You'll
860 get an error message later. */
864 /* Look for an existing fixup to this address. */
865 for (f = fixups; f ; f = f->next)
866 if (f->tsec == tsec && f->toff == toff)
871 /* Two alternatives: If it's a branch to a PLT entry, we can
872 make a copy of the FULL_PLT entry. Otherwise, we'll have
873 to use a `brl' insn to get where we're going. */
877 if (tsec == ia64_info->plt_sec)
878 size = sizeof (plt_full_entry);
881 size = sizeof (oor_brl);
884 /* Resize the current section to make room for the new branch. */
885 trampoff = (sec->_cooked_size + 15) & (bfd_vma) -16;
886 amt = trampoff + size;
887 contents = (bfd_byte *) bfd_realloc (contents, amt);
888 if (contents == NULL)
890 sec->_cooked_size = amt;
892 if (tsec == ia64_info->plt_sec)
894 memcpy (contents + trampoff, plt_full_entry, size);
896 /* Hijack the old relocation for use as the PLTOFF reloc. */
897 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
899 irel->r_offset = trampoff;
903 memcpy (contents + trampoff, oor_brl, size);
904 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
906 irel->r_offset = trampoff + 2;
909 /* Record the fixup so we don't do it again this section. */
910 f = (struct one_fixup *)
911 bfd_malloc ((bfd_size_type) sizeof (*f));
915 f->trampoff = trampoff;
920 /* Nop out the reloc, since we're finalizing things here. */
921 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
924 /* Fix up the existing branch to hit the trampoline. Hope like
925 hell this doesn't overflow too. */
926 if (elfNN_ia64_install_value (abfd, contents + roff,
927 f->trampoff - (roff & (bfd_vma) -4),
928 r_type) != bfd_reloc_ok)
931 changed_contents = TRUE;
932 changed_relocs = TRUE;
939 bfd *obfd = sec->output_section->owner;
940 gp = _bfd_get_gp_value (obfd);
943 if (!elfNN_ia64_choose_gp (obfd, link_info))
945 gp = _bfd_get_gp_value (obfd);
949 /* If the data is out of range, do nothing. */
950 if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
951 ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
954 if (r_type == R_IA64_LTOFF22X)
956 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
958 changed_relocs = TRUE;
959 if (dyn_i->want_gotx)
961 dyn_i->want_gotx = 0;
962 changed_got |= !dyn_i->want_got;
967 elfNN_ia64_relax_ldxmov (abfd, contents, roff);
968 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
969 changed_contents = TRUE;
970 changed_relocs = TRUE;
975 /* ??? If we created fixups, this may push the code segment large
976 enough that the data segment moves, which will change the GP.
977 Reset the GP so that we re-calculate next round. We need to
978 do this at the _beginning_ of the next round; now will not do. */
980 /* Clean up and go home. */
983 struct one_fixup *f = fixups;
984 fixups = fixups->next;
989 && symtab_hdr->contents != (unsigned char *) isymbuf)
991 if (! link_info->keep_memory)
995 /* Cache the symbols for elf_link_input_bfd. */
996 symtab_hdr->contents = (unsigned char *) isymbuf;
1000 if (contents != NULL
1001 && elf_section_data (sec)->this_hdr.contents != contents)
1003 if (!changed_contents && !link_info->keep_memory)
1007 /* Cache the section contents for elf_link_input_bfd. */
1008 elf_section_data (sec)->this_hdr.contents = contents;
1012 if (elf_section_data (sec)->relocs != internal_relocs)
1014 if (!changed_relocs)
1015 free (internal_relocs);
1017 elf_section_data (sec)->relocs = internal_relocs;
1022 struct elfNN_ia64_allocate_data data;
1023 data.info = link_info;
1026 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
1027 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
1028 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
1029 ia64_info->got_sec->_raw_size = data.ofs;
1030 ia64_info->got_sec->_cooked_size = data.ofs;
1032 /* ??? Resize .rela.got too. */
1035 *again = changed_contents || changed_relocs;
1039 if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
1041 if (contents != NULL
1042 && elf_section_data (sec)->this_hdr.contents != contents)
1044 if (internal_relocs != NULL
1045 && elf_section_data (sec)->relocs != internal_relocs)
1046 free (internal_relocs);
1051 elfNN_ia64_relax_ldxmov (abfd, contents, off)
1057 bfd_vma dword, insn;
1059 switch ((int)off & 0x3)
1061 case 0: shift = 5; break;
1062 case 1: shift = 14; off += 3; break;
1063 case 2: shift = 23; off += 6; break;
1068 dword = bfd_get_64 (abfd, contents + off);
1069 insn = (dword >> shift) & 0x1ffffffffffLL;
1071 r1 = (insn >> 6) & 127;
1072 r3 = (insn >> 20) & 127;
1074 insn = 0x8000000; /* nop */
1076 insn = (insn & 0x7f01fff) | 0x10800000000LL; /* (qp) mov r1 = r3 */
1078 dword &= ~(0x1ffffffffffLL << shift);
1079 dword |= (insn << shift);
1080 bfd_put_64 (abfd, dword, contents + off);
1083 /* Return TRUE if NAME is an unwind table section name. */
1085 static inline bfd_boolean
1086 is_unwind_section_name (abfd, name)
1090 size_t len1, len2, len3;
1092 if (elfNN_ia64_hpux_vec (abfd->xvec)
1093 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
1096 len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
1097 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
1098 len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
1099 return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
1100 && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
1101 || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
1104 /* Handle an IA-64 specific section when reading an object file. This
1105 is called when elfcode.h finds a section with an unknown type. */
1108 elfNN_ia64_section_from_shdr (abfd, hdr, name)
1110 Elf_Internal_Shdr *hdr;
1115 /* There ought to be a place to keep ELF backend specific flags, but
1116 at the moment there isn't one. We just keep track of the
1117 sections by their name, instead. Fortunately, the ABI gives
1118 suggested names for all the MIPS specific sections, so we will
1119 probably get away with this. */
1120 switch (hdr->sh_type)
1122 case SHT_IA_64_UNWIND:
1123 case SHT_IA_64_HP_OPT_ANOT:
1127 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1135 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
1137 newsect = hdr->bfd_section;
1142 /* Convert IA-64 specific section flags to bfd internal section flags. */
1144 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1148 elfNN_ia64_section_flags (flags, hdr)
1150 Elf_Internal_Shdr *hdr;
1152 if (hdr->sh_flags & SHF_IA_64_SHORT)
1153 *flags |= SEC_SMALL_DATA;
1158 /* Set the correct type for an IA-64 ELF section. We do this by the
1159 section name, which is a hack, but ought to work. */
1162 elfNN_ia64_fake_sections (abfd, hdr, sec)
1163 bfd *abfd ATTRIBUTE_UNUSED;
1164 Elf_Internal_Shdr *hdr;
1167 register const char *name;
1169 name = bfd_get_section_name (abfd, sec);
1171 if (is_unwind_section_name (abfd, name))
1173 /* We don't have the sections numbered at this point, so sh_info
1174 is set later, in elfNN_ia64_final_write_processing. */
1175 hdr->sh_type = SHT_IA_64_UNWIND;
1176 hdr->sh_flags |= SHF_LINK_ORDER;
1178 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1179 hdr->sh_type = SHT_IA_64_EXT;
1180 else if (strcmp (name, ".HP.opt_annot") == 0)
1181 hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
1182 else if (strcmp (name, ".reloc") == 0)
1183 /* This is an ugly, but unfortunately necessary hack that is
1184 needed when producing EFI binaries on IA-64. It tells
1185 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1186 containing ELF relocation info. We need this hack in order to
1187 be able to generate ELF binaries that can be translated into
1188 EFI applications (which are essentially COFF objects). Those
1189 files contain a COFF ".reloc" section inside an ELFNN object,
1190 which would normally cause BFD to segfault because it would
1191 attempt to interpret this section as containing relocation
1192 entries for section "oc". With this hack enabled, ".reloc"
1193 will be treated as a normal data section, which will avoid the
1194 segfault. However, you won't be able to create an ELFNN binary
1195 with a section named "oc" that needs relocations, but that's
1196 the kind of ugly side-effects you get when detecting section
1197 types based on their names... In practice, this limitation is
1198 unlikely to bite. */
1199 hdr->sh_type = SHT_PROGBITS;
1201 if (sec->flags & SEC_SMALL_DATA)
1202 hdr->sh_flags |= SHF_IA_64_SHORT;
1207 /* The final processing done just before writing out an IA-64 ELF
1211 elfNN_ia64_final_write_processing (abfd, linker)
1213 bfd_boolean linker ATTRIBUTE_UNUSED;
1215 Elf_Internal_Shdr *hdr;
1217 asection *text_sect, *s;
1220 for (s = abfd->sections; s; s = s->next)
1222 hdr = &elf_section_data (s)->this_hdr;
1223 switch (hdr->sh_type)
1225 case SHT_IA_64_UNWIND:
1226 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1228 sname = bfd_get_section_name (abfd, s);
1229 len = sizeof (ELF_STRING_ia64_unwind) - 1;
1230 if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0)
1234 if (sname[0] == '\0')
1235 /* .IA_64.unwind -> .text */
1236 text_sect = bfd_get_section_by_name (abfd, ".text");
1238 /* .IA_64.unwindFOO -> FOO */
1239 text_sect = bfd_get_section_by_name (abfd, sname);
1242 && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
1243 strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
1245 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1246 size_t len2 = sizeof (".gnu.linkonce.t.") - 1;
1247 char *once_name = bfd_malloc (len2 + strlen (sname + len) + 1);
1249 if (once_name != NULL)
1251 memcpy (once_name, ".gnu.linkonce.t.", len2);
1252 strcpy (once_name + len2, sname + len);
1253 text_sect = bfd_get_section_by_name (abfd, once_name);
1257 /* Should only happen if we run out of memory, in
1258 which case we're probably toast anyway. Try to
1259 cope by finding the section the slow way. */
1260 for (text_sect = abfd->sections;
1262 text_sect = text_sect->next)
1264 if (strncmp (bfd_section_name (abfd, text_sect),
1265 ".gnu.linkonce.t.", len2) == 0
1266 && strcmp (bfd_section_name (abfd, text_sect) + len2,
1272 /* last resort: fall back on .text */
1273 text_sect = bfd_get_section_by_name (abfd, ".text");
1277 /* The IA-64 processor-specific ABI requires setting
1278 sh_link to the unwind section, whereas HP-UX requires
1279 sh_info to do so. For maximum compatibility, we'll
1280 set both for now... */
1281 hdr->sh_link = elf_section_data (text_sect)->this_idx;
1282 hdr->sh_info = elf_section_data (text_sect)->this_idx;
1288 if (! elf_flags_init (abfd))
1290 unsigned long flags = 0;
1292 if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
1293 flags |= EF_IA_64_BE;
1294 if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
1295 flags |= EF_IA_64_ABI64;
1297 elf_elfheader(abfd)->e_flags = flags;
1298 elf_flags_init (abfd) = TRUE;
1302 /* Hook called by the linker routine which adds symbols from an object
1303 file. We use it to put .comm items in .sbss, and not .bss. */
1306 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1308 struct bfd_link_info *info;
1309 const Elf_Internal_Sym *sym;
1310 const char **namep ATTRIBUTE_UNUSED;
1311 flagword *flagsp ATTRIBUTE_UNUSED;
1315 if (sym->st_shndx == SHN_COMMON
1316 && !info->relocateable
1317 && sym->st_size <= elf_gp_size (abfd))
1319 /* Common symbols less than or equal to -G nn bytes are
1320 automatically put into .sbss. */
1322 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1326 scomm = bfd_make_section (abfd, ".scommon");
1328 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1330 | SEC_LINKER_CREATED)))
1335 *valp = sym->st_size;
1342 elfNN_ia64_aix_vec (const bfd_target *vec)
1344 extern const bfd_target bfd_elfNN_ia64_aix_little_vec;
1345 extern const bfd_target bfd_elfNN_ia64_aix_big_vec;
1347 return (/**/vec == & bfd_elfNN_ia64_aix_little_vec
1348 || vec == & bfd_elfNN_ia64_aix_big_vec);
1351 /* Hook called by the linker routine which adds symbols from an object
1352 file. We use it to handle OS-specific symbols. */
1355 elfNN_ia64_aix_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1357 struct bfd_link_info *info;
1358 const Elf_Internal_Sym *sym;
1364 if (strcmp (*namep, "__GLOB_DATA_PTR") == 0)
1366 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1367 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1368 no one else should use it b/c it is undocumented. */
1369 struct elf_link_hash_entry *h;
1371 h = elf_link_hash_lookup (elf_hash_table (info), *namep,
1372 FALSE, FALSE, FALSE);
1375 struct elf_backend_data *bed;
1376 struct elfNN_ia64_link_hash_table *ia64_info;
1377 struct bfd_link_hash_entry *bh = NULL;
1379 bed = get_elf_backend_data (abfd);
1380 ia64_info = elfNN_ia64_hash_table (info);
1382 if (!(_bfd_generic_link_add_one_symbol
1383 (info, abfd, *namep, BSF_GLOBAL,
1384 bfd_get_section_by_name (abfd, ".bss"),
1385 bed->got_symbol_offset, (const char *) NULL, FALSE,
1386 bed->collect, &bh)))
1389 h = (struct elf_link_hash_entry *) bh;
1390 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1391 h->type = STT_OBJECT;
1393 if (! _bfd_elf_link_record_dynamic_symbol (info, h))
1399 else if (sym->st_shndx == SHN_LOOS)
1403 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1404 is only relevant when compiling code for extended system calls.
1405 Replace the "special" section with .text, if possible.
1406 Note that these symbols are always assumed to be in .text. */
1407 for (i = 1; i < elf_numsections (abfd); i++)
1409 asection * sec = bfd_section_from_elf_index (abfd, i);
1411 if (sec && strcmp (sec->name, ".text") == 0)
1419 *secp = bfd_abs_section_ptr;
1421 *valp = sym->st_size;
1427 return elfNN_ia64_add_symbol_hook (abfd, info, sym,
1428 namep, flagsp, secp, valp);
1433 elfNN_ia64_aix_link_add_symbols (abfd, info)
1435 struct bfd_link_info *info;
1437 /* Make sure dynamic sections are always created. */
1438 if (! elf_hash_table (info)->dynamic_sections_created
1439 && abfd->xvec == info->hash->creator)
1441 if (! bfd_elfNN_link_create_dynamic_sections (abfd, info))
1445 /* Now do the standard call. */
1446 return bfd_elfNN_bfd_link_add_symbols (abfd, info);
1449 /* Return the number of additional phdrs we will need. */
1452 elfNN_ia64_additional_program_headers (abfd)
1458 /* See if we need a PT_IA_64_ARCHEXT segment. */
1459 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1460 if (s && (s->flags & SEC_LOAD))
1463 /* Count how many PT_IA_64_UNWIND segments we need. */
1464 for (s = abfd->sections; s; s = s->next)
1465 if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1472 elfNN_ia64_modify_segment_map (abfd)
1475 struct elf_segment_map *m, **pm;
1476 Elf_Internal_Shdr *hdr;
1479 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1480 all PT_LOAD segments. */
1481 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1482 if (s && (s->flags & SEC_LOAD))
1484 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1485 if (m->p_type == PT_IA_64_ARCHEXT)
1489 m = ((struct elf_segment_map *)
1490 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1494 m->p_type = PT_IA_64_ARCHEXT;
1498 /* We want to put it after the PHDR and INTERP segments. */
1499 pm = &elf_tdata (abfd)->segment_map;
1501 && ((*pm)->p_type == PT_PHDR
1502 || (*pm)->p_type == PT_INTERP))
1510 /* Install PT_IA_64_UNWIND segments, if needed. */
1511 for (s = abfd->sections; s; s = s->next)
1513 hdr = &elf_section_data (s)->this_hdr;
1514 if (hdr->sh_type != SHT_IA_64_UNWIND)
1517 if (s && (s->flags & SEC_LOAD))
1519 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1520 if (m->p_type == PT_IA_64_UNWIND)
1524 /* Look through all sections in the unwind segment
1525 for a match since there may be multiple sections
1527 for (i = m->count - 1; i >= 0; --i)
1528 if (m->sections[i] == s)
1537 m = ((struct elf_segment_map *)
1538 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1542 m->p_type = PT_IA_64_UNWIND;
1547 /* We want to put it last. */
1548 pm = &elf_tdata (abfd)->segment_map;
1556 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1557 the input sections for each output section in the segment and testing
1558 for SHF_IA_64_NORECOV on each. */
1559 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1560 if (m->p_type == PT_LOAD)
1563 for (i = m->count - 1; i >= 0; --i)
1565 struct bfd_link_order *order = m->sections[i]->link_order_head;
1568 if (order->type == bfd_indirect_link_order)
1570 asection *is = order->u.indirect.section;
1571 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1572 if (flags & SHF_IA_64_NORECOV)
1574 m->p_flags |= PF_IA_64_NORECOV;
1578 order = order->next;
1587 /* According to the Tahoe assembler spec, all labels starting with a
1591 elfNN_ia64_is_local_label_name (abfd, name)
1592 bfd *abfd ATTRIBUTE_UNUSED;
1595 return name[0] == '.';
1598 /* Should we do dynamic things to this symbol? */
1601 elfNN_ia64_dynamic_symbol_p (h, info)
1602 struct elf_link_hash_entry *h;
1603 struct bfd_link_info *info;
1608 while (h->root.type == bfd_link_hash_indirect
1609 || h->root.type == bfd_link_hash_warning)
1610 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1612 if (h->dynindx == -1)
1614 switch (ELF_ST_VISIBILITY (h->other))
1623 if (h->root.type == bfd_link_hash_undefweak
1624 || h->root.type == bfd_link_hash_defweak)
1627 if ((info->shared && (!info->symbolic || info->allow_shlib_undefined))
1628 || ((h->elf_link_hash_flags
1629 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1630 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1637 elfNN_ia64_local_hash_table_init (ht, abfd, new)
1638 struct elfNN_ia64_local_hash_table *ht;
1639 bfd *abfd ATTRIBUTE_UNUSED;
1640 new_hash_entry_func new;
1642 memset (ht, 0, sizeof (*ht));
1643 return bfd_hash_table_init (&ht->root, new);
1646 static struct bfd_hash_entry*
1647 elfNN_ia64_new_loc_hash_entry (entry, table, string)
1648 struct bfd_hash_entry *entry;
1649 struct bfd_hash_table *table;
1652 struct elfNN_ia64_local_hash_entry *ret;
1653 ret = (struct elfNN_ia64_local_hash_entry *) entry;
1655 /* Allocate the structure if it has not already been allocated by a
1658 ret = bfd_hash_allocate (table, sizeof (*ret));
1663 /* Initialize our local data. All zeros, and definitely easier
1664 than setting a handful of bit fields. */
1665 memset (ret, 0, sizeof (*ret));
1667 /* Call the allocation method of the superclass. */
1668 ret = ((struct elfNN_ia64_local_hash_entry *)
1669 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1671 return (struct bfd_hash_entry *) ret;
1674 static struct bfd_hash_entry*
1675 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1676 struct bfd_hash_entry *entry;
1677 struct bfd_hash_table *table;
1680 struct elfNN_ia64_link_hash_entry *ret;
1681 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1683 /* Allocate the structure if it has not already been allocated by a
1686 ret = bfd_hash_allocate (table, sizeof (*ret));
1691 /* Initialize our local data. All zeros, and definitely easier
1692 than setting a handful of bit fields. */
1693 memset (ret, 0, sizeof (*ret));
1695 /* Call the allocation method of the superclass. */
1696 ret = ((struct elfNN_ia64_link_hash_entry *)
1697 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1700 return (struct bfd_hash_entry *) ret;
1704 elfNN_ia64_hash_copy_indirect (bed, xdir, xind)
1705 struct elf_backend_data *bed ATTRIBUTE_UNUSED;
1706 struct elf_link_hash_entry *xdir, *xind;
1708 struct elfNN_ia64_link_hash_entry *dir, *ind;
1710 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1711 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1713 /* Copy down any references that we may have already seen to the
1714 symbol which just became indirect. */
1716 dir->root.elf_link_hash_flags |=
1717 (ind->root.elf_link_hash_flags
1718 & (ELF_LINK_HASH_REF_DYNAMIC
1719 | ELF_LINK_HASH_REF_REGULAR
1720 | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1722 if (ind->root.root.type != bfd_link_hash_indirect)
1725 /* Copy over the got and plt data. This would have been done
1728 if (dir->info == NULL)
1730 struct elfNN_ia64_dyn_sym_info *dyn_i;
1732 dir->info = dyn_i = ind->info;
1735 /* Fix up the dyn_sym_info pointers to the global symbol. */
1736 for (; dyn_i; dyn_i = dyn_i->next)
1737 dyn_i->h = &dir->root;
1739 BFD_ASSERT (ind->info == NULL);
1741 /* Copy over the dynindx. */
1743 if (dir->root.dynindx == -1)
1745 dir->root.dynindx = ind->root.dynindx;
1746 dir->root.dynstr_index = ind->root.dynstr_index;
1747 ind->root.dynindx = -1;
1748 ind->root.dynstr_index = 0;
1750 BFD_ASSERT (ind->root.dynindx == -1);
1754 elfNN_ia64_hash_hide_symbol (info, xh, force_local)
1755 struct bfd_link_info *info;
1756 struct elf_link_hash_entry *xh;
1757 bfd_boolean force_local;
1759 struct elfNN_ia64_link_hash_entry *h;
1760 struct elfNN_ia64_dyn_sym_info *dyn_i;
1762 h = (struct elfNN_ia64_link_hash_entry *)xh;
1764 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1766 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1767 dyn_i->want_plt2 = 0;
1770 /* Create the derived linker hash table. The IA-64 ELF port uses this
1771 derived hash table to keep information specific to the IA-64 ElF
1772 linker (without using static variables). */
1774 static struct bfd_link_hash_table*
1775 elfNN_ia64_hash_table_create (abfd)
1778 struct elfNN_ia64_link_hash_table *ret;
1780 ret = bfd_zalloc (abfd, (bfd_size_type) sizeof (*ret));
1783 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1784 elfNN_ia64_new_elf_hash_entry))
1786 bfd_release (abfd, ret);
1790 if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1791 elfNN_ia64_new_loc_hash_entry))
1793 return &ret->root.root;
1796 /* Look up an entry in a Alpha ELF linker hash table. */
1798 static INLINE struct elfNN_ia64_local_hash_entry *
1799 elfNN_ia64_local_hash_lookup(table, string, create, copy)
1800 struct elfNN_ia64_local_hash_table *table;
1802 bfd_boolean create, copy;
1804 return ((struct elfNN_ia64_local_hash_entry *)
1805 bfd_hash_lookup (&table->root, string, create, copy));
1808 /* Traverse both local and global hash tables. */
1810 struct elfNN_ia64_dyn_sym_traverse_data
1812 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1817 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1818 struct bfd_hash_entry *xentry;
1821 struct elfNN_ia64_link_hash_entry *entry
1822 = (struct elfNN_ia64_link_hash_entry *) xentry;
1823 struct elfNN_ia64_dyn_sym_traverse_data *data
1824 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1825 struct elfNN_ia64_dyn_sym_info *dyn_i;
1827 if (entry->root.root.type == bfd_link_hash_warning)
1828 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1830 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1831 if (! (*data->func) (dyn_i, data->data))
1837 elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1838 struct bfd_hash_entry *xentry;
1841 struct elfNN_ia64_local_hash_entry *entry
1842 = (struct elfNN_ia64_local_hash_entry *) xentry;
1843 struct elfNN_ia64_dyn_sym_traverse_data *data
1844 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1845 struct elfNN_ia64_dyn_sym_info *dyn_i;
1847 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1848 if (! (*data->func) (dyn_i, data->data))
1854 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1855 struct elfNN_ia64_link_hash_table *ia64_info;
1856 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1859 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1864 elf_link_hash_traverse (&ia64_info->root,
1865 elfNN_ia64_global_dyn_sym_thunk, &xdata);
1866 bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1867 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1871 elfNN_ia64_create_dynamic_sections (abfd, info)
1873 struct bfd_link_info *info;
1875 struct elfNN_ia64_link_hash_table *ia64_info;
1878 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1881 ia64_info = elfNN_ia64_hash_table (info);
1883 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1884 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1887 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1888 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1891 if (!get_pltoff (abfd, info, ia64_info))
1894 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1896 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1899 | SEC_LINKER_CREATED
1901 || !bfd_set_section_alignment (abfd, s, 3))
1903 ia64_info->rel_pltoff_sec = s;
1905 s = bfd_make_section(abfd, ".rela.got");
1907 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1910 | SEC_LINKER_CREATED
1912 || !bfd_set_section_alignment (abfd, s, 3))
1914 ia64_info->rel_got_sec = s;
1919 /* Find and/or create a hash entry for local symbol. */
1920 static struct elfNN_ia64_local_hash_entry *
1921 get_local_sym_hash (ia64_info, abfd, rel, create)
1922 struct elfNN_ia64_link_hash_table *ia64_info;
1924 const Elf_Internal_Rela *rel;
1927 struct elfNN_ia64_local_hash_entry *ret;
1928 asection *sec = abfd->sections;
1929 char addr_name [34];
1931 BFD_ASSERT ((sizeof (sec->id)*2 + 1 + sizeof (unsigned long)*2 + 1) <= 34);
1934 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1935 name describes what was once anonymous memory. */
1937 sprintf (addr_name, "%x:%lx",
1938 sec->id, (unsigned long) ELFNN_R_SYM (rel->r_info));
1940 /* Collect the canonical entry data for this address. */
1941 ret = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1942 addr_name, create, create);
1946 /* Find and/or create a descriptor for dynamic symbol info. This will
1947 vary based on global or local symbol, and the addend to the reloc. */
1949 static struct elfNN_ia64_dyn_sym_info *
1950 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1951 struct elfNN_ia64_link_hash_table *ia64_info;
1952 struct elf_link_hash_entry *h;
1954 const Elf_Internal_Rela *rel;
1957 struct elfNN_ia64_dyn_sym_info **pp;
1958 struct elfNN_ia64_dyn_sym_info *dyn_i;
1959 bfd_vma addend = rel ? rel->r_addend : 0;
1962 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1965 struct elfNN_ia64_local_hash_entry *loc_h;
1967 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1970 BFD_ASSERT (!create);
1977 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1980 if (dyn_i == NULL && create)
1982 dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
1983 bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
1985 dyn_i->addend = addend;
1992 get_got (abfd, info, ia64_info)
1994 struct bfd_link_info *info;
1995 struct elfNN_ia64_link_hash_table *ia64_info;
2000 got = ia64_info->got_sec;
2005 dynobj = ia64_info->root.dynobj;
2007 ia64_info->root.dynobj = dynobj = abfd;
2008 if (!_bfd_elf_create_got_section (dynobj, info))
2011 got = bfd_get_section_by_name (dynobj, ".got");
2013 ia64_info->got_sec = got;
2015 flags = bfd_get_section_flags (abfd, got);
2016 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2022 /* Create function descriptor section (.opd). This section is called .opd
2023 because it contains "official prodecure descriptors". The "official"
2024 refers to the fact that these descriptors are used when taking the address
2025 of a procedure, thus ensuring a unique address for each procedure. */
2028 get_fptr (abfd, info, ia64_info)
2030 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2031 struct elfNN_ia64_link_hash_table *ia64_info;
2036 fptr = ia64_info->fptr_sec;
2039 dynobj = ia64_info->root.dynobj;
2041 ia64_info->root.dynobj = dynobj = abfd;
2043 fptr = bfd_make_section (dynobj, ".opd");
2045 || !bfd_set_section_flags (dynobj, fptr,
2051 | SEC_LINKER_CREATED))
2052 || !bfd_set_section_alignment (abfd, fptr, 4))
2058 ia64_info->fptr_sec = fptr;
2065 get_pltoff (abfd, info, ia64_info)
2067 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2068 struct elfNN_ia64_link_hash_table *ia64_info;
2073 pltoff = ia64_info->pltoff_sec;
2076 dynobj = ia64_info->root.dynobj;
2078 ia64_info->root.dynobj = dynobj = abfd;
2080 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
2082 || !bfd_set_section_flags (dynobj, pltoff,
2088 | SEC_LINKER_CREATED))
2089 || !bfd_set_section_alignment (abfd, pltoff, 4))
2095 ia64_info->pltoff_sec = pltoff;
2102 get_reloc_section (abfd, ia64_info, sec, create)
2104 struct elfNN_ia64_link_hash_table *ia64_info;
2108 const char *srel_name;
2112 srel_name = (bfd_elf_string_from_elf_section
2113 (abfd, elf_elfheader(abfd)->e_shstrndx,
2114 elf_section_data(sec)->rel_hdr.sh_name));
2115 if (srel_name == NULL)
2118 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2119 && strcmp (bfd_get_section_name (abfd, sec),
2121 || (strncmp (srel_name, ".rel", 4) == 0
2122 && strcmp (bfd_get_section_name (abfd, sec),
2123 srel_name+4) == 0));
2125 dynobj = ia64_info->root.dynobj;
2127 ia64_info->root.dynobj = dynobj = abfd;
2129 srel = bfd_get_section_by_name (dynobj, srel_name);
2130 if (srel == NULL && create)
2132 srel = bfd_make_section (dynobj, srel_name);
2134 || !bfd_set_section_flags (dynobj, srel,
2139 | SEC_LINKER_CREATED
2141 || !bfd_set_section_alignment (dynobj, srel, 3))
2145 if (sec->flags & SEC_READONLY)
2146 ia64_info->reltext = 1;
2152 count_dyn_reloc (abfd, dyn_i, srel, type)
2154 struct elfNN_ia64_dyn_sym_info *dyn_i;
2158 struct elfNN_ia64_dyn_reloc_entry *rent;
2160 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2161 if (rent->srel == srel && rent->type == type)
2166 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2167 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2171 rent->next = dyn_i->reloc_entries;
2175 dyn_i->reloc_entries = rent;
2183 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2185 struct bfd_link_info *info;
2187 const Elf_Internal_Rela *relocs;
2189 struct elfNN_ia64_link_hash_table *ia64_info;
2190 const Elf_Internal_Rela *relend;
2191 Elf_Internal_Shdr *symtab_hdr;
2192 const Elf_Internal_Rela *rel;
2193 asection *got, *fptr, *srel;
2195 if (info->relocateable)
2198 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2199 ia64_info = elfNN_ia64_hash_table (info);
2201 got = fptr = srel = NULL;
2203 relend = relocs + sec->reloc_count;
2204 for (rel = relocs; rel < relend; ++rel)
2214 NEED_LTOFF_FPTR = 128,
2220 struct elf_link_hash_entry *h = NULL;
2221 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2222 struct elfNN_ia64_dyn_sym_info *dyn_i;
2224 bfd_boolean maybe_dynamic;
2225 int dynrel_type = R_IA64_NONE;
2227 if (r_symndx >= symtab_hdr->sh_info)
2229 /* We're dealing with a global symbol -- find its hash entry
2230 and mark it as being referenced. */
2231 long indx = r_symndx - symtab_hdr->sh_info;
2232 h = elf_sym_hashes (abfd)[indx];
2233 while (h->root.type == bfd_link_hash_indirect
2234 || h->root.type == bfd_link_hash_warning)
2235 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2237 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2240 /* We can only get preliminary data on whether a symbol is
2241 locally or externally defined, as not all of the input files
2242 have yet been processed. Do something with what we know, as
2243 this may help reduce memory usage and processing time later. */
2244 maybe_dynamic = FALSE;
2245 if (h && ((info->shared
2246 && (!info->symbolic || info->allow_shlib_undefined))
2247 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
2248 || h->root.type == bfd_link_hash_defweak
2249 || elfNN_ia64_aix_vec (abfd->xvec)))
2250 maybe_dynamic = TRUE;
2253 switch (ELFNN_R_TYPE (rel->r_info))
2255 case R_IA64_TPREL64MSB:
2256 case R_IA64_TPREL64LSB:
2257 if (info->shared || maybe_dynamic)
2258 need_entry = NEED_DYNREL;
2259 dynrel_type = R_IA64_TPREL64LSB;
2261 info->flags |= DF_STATIC_TLS;
2264 case R_IA64_LTOFF_TPREL22:
2265 need_entry = NEED_TPREL;
2267 info->flags |= DF_STATIC_TLS;
2270 case R_IA64_DTPREL64MSB:
2271 case R_IA64_DTPREL64LSB:
2272 if (info->shared || maybe_dynamic)
2273 need_entry = NEED_DYNREL;
2274 dynrel_type = R_IA64_DTPREL64LSB;
2277 case R_IA64_LTOFF_DTPREL22:
2278 need_entry = NEED_DTPREL;
2281 case R_IA64_DTPMOD64MSB:
2282 case R_IA64_DTPMOD64LSB:
2283 if (info->shared || maybe_dynamic)
2284 need_entry = NEED_DYNREL;
2285 dynrel_type = R_IA64_DTPMOD64LSB;
2288 case R_IA64_LTOFF_DTPMOD22:
2289 need_entry = NEED_DTPMOD;
2292 case R_IA64_LTOFF_FPTR22:
2293 case R_IA64_LTOFF_FPTR64I:
2294 case R_IA64_LTOFF_FPTR32MSB:
2295 case R_IA64_LTOFF_FPTR32LSB:
2296 case R_IA64_LTOFF_FPTR64MSB:
2297 case R_IA64_LTOFF_FPTR64LSB:
2298 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2301 case R_IA64_FPTR64I:
2302 case R_IA64_FPTR32MSB:
2303 case R_IA64_FPTR32LSB:
2304 case R_IA64_FPTR64MSB:
2305 case R_IA64_FPTR64LSB:
2306 if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
2307 need_entry = NEED_FPTR | NEED_DYNREL;
2309 need_entry = NEED_FPTR;
2310 dynrel_type = R_IA64_FPTR64LSB;
2313 case R_IA64_LTOFF22:
2314 case R_IA64_LTOFF64I:
2315 need_entry = NEED_GOT;
2318 case R_IA64_LTOFF22X:
2319 need_entry = NEED_GOTX;
2322 case R_IA64_PLTOFF22:
2323 case R_IA64_PLTOFF64I:
2324 case R_IA64_PLTOFF64MSB:
2325 case R_IA64_PLTOFF64LSB:
2326 need_entry = NEED_PLTOFF;
2330 need_entry |= NEED_MIN_PLT;
2334 (*info->callbacks->warning)
2335 (info, _("@pltoff reloc against local symbol"), 0,
2336 abfd, 0, (bfd_vma) 0);
2340 case R_IA64_PCREL21B:
2341 case R_IA64_PCREL60B:
2342 /* Depending on where this symbol is defined, we may or may not
2343 need a full plt entry. Only skip if we know we'll not need
2344 the entry -- static or symbolic, and the symbol definition
2345 has already been seen. */
2346 if (maybe_dynamic && rel->r_addend == 0)
2347 need_entry = NEED_FULL_PLT;
2353 case R_IA64_DIR32MSB:
2354 case R_IA64_DIR32LSB:
2355 case R_IA64_DIR64MSB:
2356 case R_IA64_DIR64LSB:
2357 /* Shared objects will always need at least a REL relocation. */
2358 if (info->shared || maybe_dynamic
2359 || (elfNN_ia64_aix_vec (abfd->xvec)
2360 && (!h || strcmp (h->root.root.string,
2361 "__GLOB_DATA_PTR") != 0)))
2362 need_entry = NEED_DYNREL;
2363 dynrel_type = R_IA64_DIR64LSB;
2366 case R_IA64_IPLTMSB:
2367 case R_IA64_IPLTLSB:
2368 /* Shared objects will always need at least a REL relocation. */
2369 if (info->shared || maybe_dynamic)
2370 need_entry = NEED_DYNREL;
2371 dynrel_type = R_IA64_IPLTLSB;
2374 case R_IA64_PCREL22:
2375 case R_IA64_PCREL64I:
2376 case R_IA64_PCREL32MSB:
2377 case R_IA64_PCREL32LSB:
2378 case R_IA64_PCREL64MSB:
2379 case R_IA64_PCREL64LSB:
2381 need_entry = NEED_DYNREL;
2382 dynrel_type = R_IA64_PCREL64LSB;
2389 if ((need_entry & NEED_FPTR) != 0
2392 (*info->callbacks->warning)
2393 (info, _("non-zero addend in @fptr reloc"), 0,
2394 abfd, 0, (bfd_vma) 0);
2397 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE);
2399 /* Record whether or not this is a local symbol. */
2402 /* Create what's needed. */
2403 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2404 | NEED_DTPMOD | NEED_DTPREL))
2408 got = get_got (abfd, info, ia64_info);
2412 if (need_entry & NEED_GOT)
2413 dyn_i->want_got = 1;
2414 if (need_entry & NEED_GOTX)
2415 dyn_i->want_gotx = 1;
2416 if (need_entry & NEED_TPREL)
2417 dyn_i->want_tprel = 1;
2418 if (need_entry & NEED_DTPMOD)
2419 dyn_i->want_dtpmod = 1;
2420 if (need_entry & NEED_DTPREL)
2421 dyn_i->want_dtprel = 1;
2423 if (need_entry & NEED_FPTR)
2427 fptr = get_fptr (abfd, info, ia64_info);
2432 /* FPTRs for shared libraries are allocated by the dynamic
2433 linker. Make sure this local symbol will appear in the
2434 dynamic symbol table. */
2435 if (!h && (info->shared
2436 /* AIX also needs one */
2437 || elfNN_ia64_aix_vec (abfd->xvec)))
2439 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2440 (info, abfd, (long) r_symndx)))
2444 dyn_i->want_fptr = 1;
2446 if (need_entry & NEED_LTOFF_FPTR)
2447 dyn_i->want_ltoff_fptr = 1;
2448 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2450 if (!ia64_info->root.dynobj)
2451 ia64_info->root.dynobj = abfd;
2452 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2453 dyn_i->want_plt = 1;
2455 if (need_entry & NEED_FULL_PLT)
2456 dyn_i->want_plt2 = 1;
2457 if (need_entry & NEED_PLTOFF)
2458 dyn_i->want_pltoff = 1;
2459 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2463 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
2467 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2475 /* For cleanliness, and potentially faster dynamic loading, allocate
2476 external GOT entries first. */
2479 allocate_global_data_got (dyn_i, data)
2480 struct elfNN_ia64_dyn_sym_info *dyn_i;
2483 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2485 if ((dyn_i->want_got || dyn_i->want_gotx)
2486 && ! dyn_i->want_fptr
2487 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2488 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2489 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2490 "__GLOB_DATA_PTR") != 0))))
2492 dyn_i->got_offset = x->ofs;
2495 if (dyn_i->want_tprel)
2497 dyn_i->tprel_offset = x->ofs;
2500 if (dyn_i->want_dtpmod)
2502 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
2504 dyn_i->dtpmod_offset = x->ofs;
2509 struct elfNN_ia64_link_hash_table *ia64_info;
2511 ia64_info = elfNN_ia64_hash_table (x->info);
2512 if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
2514 ia64_info->self_dtpmod_offset = x->ofs;
2517 dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
2520 if (dyn_i->want_dtprel)
2522 dyn_i->dtprel_offset = x->ofs;
2528 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2531 allocate_global_fptr_got (dyn_i, data)
2532 struct elfNN_ia64_dyn_sym_info *dyn_i;
2535 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2539 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2540 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2542 dyn_i->got_offset = x->ofs;
2548 /* Lastly, allocate all the GOT entries for local data. */
2551 allocate_local_got (dyn_i, data)
2552 struct elfNN_ia64_dyn_sym_info *dyn_i;
2555 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2557 if ((dyn_i->want_got || dyn_i->want_gotx)
2558 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2559 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2561 dyn_i->got_offset = x->ofs;
2567 /* Search for the index of a global symbol in it's defining object file. */
2570 global_sym_index (h)
2571 struct elf_link_hash_entry *h;
2573 struct elf_link_hash_entry **p;
2576 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2577 || h->root.type == bfd_link_hash_defweak);
2579 obj = h->root.u.def.section->owner;
2580 for (p = elf_sym_hashes (obj); *p != h; ++p)
2583 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2586 /* Allocate function descriptors. We can do these for every function
2587 in a main executable that is not exported. */
2590 allocate_fptr (dyn_i, data)
2591 struct elfNN_ia64_dyn_sym_info *dyn_i;
2594 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2596 if (dyn_i->want_fptr)
2598 struct elf_link_hash_entry *h = dyn_i->h;
2601 while (h->root.type == bfd_link_hash_indirect
2602 || h->root.type == bfd_link_hash_warning)
2603 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2606 /* AIX needs an FPTR in this case. */
2607 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2609 || h->root.type == bfd_link_hash_defined
2610 || h->root.type == bfd_link_hash_defweak)))
2612 if (h && h->dynindx == -1)
2614 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2615 || (h->root.type == bfd_link_hash_defweak));
2617 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2618 (x->info, h->root.u.def.section->owner,
2619 global_sym_index (h)))
2623 dyn_i->want_fptr = 0;
2625 else if (h == NULL || h->dynindx == -1)
2627 dyn_i->fptr_offset = x->ofs;
2631 dyn_i->want_fptr = 0;
2636 /* Allocate all the minimal PLT entries. */
2639 allocate_plt_entries (dyn_i, data)
2640 struct elfNN_ia64_dyn_sym_info *dyn_i;
2643 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2645 if (dyn_i->want_plt)
2647 struct elf_link_hash_entry *h = dyn_i->h;
2650 while (h->root.type == bfd_link_hash_indirect
2651 || h->root.type == bfd_link_hash_warning)
2652 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2654 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2655 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2657 bfd_size_type offset = x->ofs;
2659 offset = PLT_HEADER_SIZE;
2660 dyn_i->plt_offset = offset;
2661 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2663 dyn_i->want_pltoff = 1;
2667 dyn_i->want_plt = 0;
2668 dyn_i->want_plt2 = 0;
2674 /* Allocate all the full PLT entries. */
2677 allocate_plt2_entries (dyn_i, data)
2678 struct elfNN_ia64_dyn_sym_info *dyn_i;
2681 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2683 if (dyn_i->want_plt2)
2685 struct elf_link_hash_entry *h = dyn_i->h;
2686 bfd_size_type ofs = x->ofs;
2688 dyn_i->plt2_offset = ofs;
2689 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2691 while (h->root.type == bfd_link_hash_indirect
2692 || h->root.type == bfd_link_hash_warning)
2693 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2694 dyn_i->h->plt.offset = ofs;
2699 /* Allocate all the PLTOFF entries requested by relocations and
2700 plt entries. We can't share space with allocated FPTR entries,
2701 because the latter are not necessarily addressable by the GP.
2702 ??? Relaxation might be able to determine that they are. */
2705 allocate_pltoff_entries (dyn_i, data)
2706 struct elfNN_ia64_dyn_sym_info *dyn_i;
2709 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2711 if (dyn_i->want_pltoff)
2713 dyn_i->pltoff_offset = x->ofs;
2719 /* Allocate dynamic relocations for those symbols that turned out
2723 allocate_dynrel_entries (dyn_i, data)
2724 struct elfNN_ia64_dyn_sym_info *dyn_i;
2727 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2728 struct elfNN_ia64_link_hash_table *ia64_info;
2729 struct elfNN_ia64_dyn_reloc_entry *rent;
2730 bfd_boolean dynamic_symbol, shared;
2732 ia64_info = elfNN_ia64_hash_table (x->info);
2733 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2734 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2735 /* Don't allocate an entry for __GLOB_DATA_PTR */
2736 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2737 "__GLOB_DATA_PTR") != 0));
2738 shared = x->info->shared;
2740 /* Take care of the normal data relocations. */
2742 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2744 int count = rent->count;
2748 case R_IA64_FPTR64LSB:
2749 /* Allocate one iff !want_fptr, which by this point will
2750 be true only if we're actually allocating one statically
2751 in the main executable. */
2752 if (dyn_i->want_fptr)
2755 case R_IA64_PCREL64LSB:
2756 if (!dynamic_symbol)
2759 case R_IA64_DIR64LSB:
2760 if (!dynamic_symbol && !shared)
2763 case R_IA64_IPLTLSB:
2764 if (!dynamic_symbol && !shared)
2766 /* Use two REL relocations for IPLT relocations
2767 against local symbols. */
2768 if (!dynamic_symbol)
2771 case R_IA64_TPREL64LSB:
2772 case R_IA64_DTPREL64LSB:
2773 case R_IA64_DTPMOD64LSB:
2778 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2781 /* Take care of the GOT and PLT relocations. */
2783 if (((dynamic_symbol || shared) && (dyn_i->want_got || dyn_i->want_gotx))
2784 || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2785 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2786 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2787 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2788 if (dynamic_symbol && dyn_i->want_dtpmod)
2789 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2790 if (dynamic_symbol && dyn_i->want_dtprel)
2791 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2793 if (dyn_i->want_pltoff)
2795 bfd_size_type t = 0;
2797 /* Dynamic symbols get one IPLT relocation. Local symbols in
2798 shared libraries get two REL relocations. Local symbols in
2799 main applications get nothing. */
2801 t = sizeof (ElfNN_External_Rela);
2803 t = 2 * sizeof (ElfNN_External_Rela);
2805 ia64_info->rel_pltoff_sec->_raw_size += t;
2812 elfNN_ia64_adjust_dynamic_symbol (info, h)
2813 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2814 struct elf_link_hash_entry *h;
2816 /* ??? Undefined symbols with PLT entries should be re-defined
2817 to be the PLT entry. */
2819 /* If this is a weak symbol, and there is a real definition, the
2820 processor independent code will have arranged for us to see the
2821 real definition first, and we can just use the same value. */
2822 if (h->weakdef != NULL)
2824 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2825 || h->weakdef->root.type == bfd_link_hash_defweak);
2826 h->root.u.def.section = h->weakdef->root.u.def.section;
2827 h->root.u.def.value = h->weakdef->root.u.def.value;
2831 /* If this is a reference to a symbol defined by a dynamic object which
2832 is not a function, we might allocate the symbol in our .dynbss section
2833 and allocate a COPY dynamic relocation.
2835 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2842 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2844 struct bfd_link_info *info;
2846 struct elfNN_ia64_allocate_data data;
2847 struct elfNN_ia64_link_hash_table *ia64_info;
2850 bfd_boolean relplt = FALSE;
2852 dynobj = elf_hash_table(info)->dynobj;
2853 ia64_info = elfNN_ia64_hash_table (info);
2854 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
2855 BFD_ASSERT(dynobj != NULL);
2858 /* Set the contents of the .interp section to the interpreter. */
2859 if (ia64_info->root.dynamic_sections_created
2862 sec = bfd_get_section_by_name (dynobj, ".interp");
2863 BFD_ASSERT (sec != NULL);
2864 sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd);
2865 sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1;
2868 /* Allocate the GOT entries. */
2870 if (ia64_info->got_sec)
2873 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2874 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2875 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2876 ia64_info->got_sec->_raw_size = data.ofs;
2879 /* Allocate the FPTR entries. */
2881 if (ia64_info->fptr_sec)
2884 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2885 ia64_info->fptr_sec->_raw_size = data.ofs;
2888 /* Now that we've seen all of the input files, we can decide which
2889 symbols need plt entries. Allocate the minimal PLT entries first.
2890 We do this even though dynamic_sections_created may be FALSE, because
2891 this has the side-effect of clearing want_plt and want_plt2. */
2894 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2896 ia64_info->minplt_entries = 0;
2899 ia64_info->minplt_entries
2900 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2903 /* Align the pointer for the plt2 entries. */
2904 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2906 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2909 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2911 ia64_info->plt_sec->_raw_size = data.ofs;
2913 /* If we've got a .plt, we need some extra memory for the dynamic
2914 linker. We stuff these in .got.plt. */
2915 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2916 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2919 /* Allocate the PLTOFF entries. */
2921 if (ia64_info->pltoff_sec)
2924 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2925 ia64_info->pltoff_sec->_raw_size = data.ofs;
2928 if (ia64_info->root.dynamic_sections_created)
2930 /* Allocate space for the dynamic relocations that turned out to be
2933 if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
2934 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2935 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2938 /* We have now determined the sizes of the various dynamic sections.
2939 Allocate memory for them. */
2940 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2944 if (!(sec->flags & SEC_LINKER_CREATED))
2947 /* If we don't need this section, strip it from the output file.
2948 There were several sections primarily related to dynamic
2949 linking that must be create before the linker maps input
2950 sections to output sections. The linker does that before
2951 bfd_elf_size_dynamic_sections is called, and it is that
2952 function which decides whether anything needs to go into
2955 strip = (sec->_raw_size == 0);
2957 if (sec == ia64_info->got_sec)
2959 else if (sec == ia64_info->rel_got_sec)
2962 ia64_info->rel_got_sec = NULL;
2964 /* We use the reloc_count field as a counter if we need to
2965 copy relocs into the output file. */
2966 sec->reloc_count = 0;
2968 else if (sec == ia64_info->fptr_sec)
2971 ia64_info->fptr_sec = NULL;
2973 else if (sec == ia64_info->plt_sec)
2976 ia64_info->plt_sec = NULL;
2978 else if (sec == ia64_info->pltoff_sec)
2981 ia64_info->pltoff_sec = NULL;
2983 else if (sec == ia64_info->rel_pltoff_sec)
2986 ia64_info->rel_pltoff_sec = NULL;
2990 /* We use the reloc_count field as a counter if we need to
2991 copy relocs into the output file. */
2992 sec->reloc_count = 0;
2999 /* It's OK to base decisions on the section name, because none
3000 of the dynobj section names depend upon the input files. */
3001 name = bfd_get_section_name (dynobj, sec);
3003 if (strcmp (name, ".got.plt") == 0)
3005 else if (strncmp (name, ".rel", 4) == 0)
3009 /* We use the reloc_count field as a counter if we need to
3010 copy relocs into the output file. */
3011 sec->reloc_count = 0;
3019 _bfd_strip_section_from_output (info, sec);
3022 /* Allocate memory for the section contents. */
3023 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
3024 if (sec->contents == NULL && sec->_raw_size != 0)
3029 if (elf_hash_table (info)->dynamic_sections_created)
3031 /* Add some entries to the .dynamic section. We fill in the values
3032 later (in finish_dynamic_sections) but we must add the entries now
3033 so that we get the correct size for the .dynamic section. */
3037 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3039 #define add_dynamic_entry(TAG, VAL) \
3040 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
3042 if (!add_dynamic_entry (DT_DEBUG, 0))
3046 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3048 if (!add_dynamic_entry (DT_PLTGOT, 0))
3053 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3054 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3055 || !add_dynamic_entry (DT_JMPREL, 0))
3059 if (!add_dynamic_entry (DT_RELA, 0)
3060 || !add_dynamic_entry (DT_RELASZ, 0)
3061 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3064 if (ia64_info->reltext)
3066 if (!add_dynamic_entry (DT_TEXTREL, 0))
3068 info->flags |= DF_TEXTREL;
3072 /* ??? Perhaps force __gp local. */
3077 static bfd_reloc_status_type
3078 elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
3082 unsigned int r_type;
3084 const struct ia64_operand *op;
3085 int bigendian = 0, shift = 0;
3086 bfd_vma t0, t1, insn, dword;
3087 enum ia64_opnd opnd;
3090 #ifdef BFD_HOST_U_64_BIT
3091 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3096 opnd = IA64_OPND_NIL;
3101 return bfd_reloc_ok;
3103 /* Instruction relocations. */
3106 case R_IA64_TPREL14:
3107 case R_IA64_DTPREL14:
3108 opnd = IA64_OPND_IMM14;
3111 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
3112 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
3113 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
3114 case R_IA64_PCREL21B:
3115 case R_IA64_PCREL21BI:
3116 opnd = IA64_OPND_TGT25c;
3120 case R_IA64_GPREL22:
3121 case R_IA64_LTOFF22:
3122 case R_IA64_LTOFF22X:
3123 case R_IA64_PLTOFF22:
3124 case R_IA64_PCREL22:
3125 case R_IA64_LTOFF_FPTR22:
3126 case R_IA64_TPREL22:
3127 case R_IA64_DTPREL22:
3128 case R_IA64_LTOFF_TPREL22:
3129 case R_IA64_LTOFF_DTPMOD22:
3130 case R_IA64_LTOFF_DTPREL22:
3131 opnd = IA64_OPND_IMM22;
3135 case R_IA64_GPREL64I:
3136 case R_IA64_LTOFF64I:
3137 case R_IA64_PLTOFF64I:
3138 case R_IA64_PCREL64I:
3139 case R_IA64_FPTR64I:
3140 case R_IA64_LTOFF_FPTR64I:
3141 case R_IA64_TPREL64I:
3142 case R_IA64_DTPREL64I:
3143 opnd = IA64_OPND_IMMU64;
3146 /* Data relocations. */
3148 case R_IA64_DIR32MSB:
3149 case R_IA64_GPREL32MSB:
3150 case R_IA64_FPTR32MSB:
3151 case R_IA64_PCREL32MSB:
3152 case R_IA64_LTOFF_FPTR32MSB:
3153 case R_IA64_SEGREL32MSB:
3154 case R_IA64_SECREL32MSB:
3155 case R_IA64_LTV32MSB:
3156 case R_IA64_DTPREL32MSB:
3157 size = 4; bigendian = 1;
3160 case R_IA64_DIR32LSB:
3161 case R_IA64_GPREL32LSB:
3162 case R_IA64_FPTR32LSB:
3163 case R_IA64_PCREL32LSB:
3164 case R_IA64_LTOFF_FPTR32LSB:
3165 case R_IA64_SEGREL32LSB:
3166 case R_IA64_SECREL32LSB:
3167 case R_IA64_LTV32LSB:
3168 case R_IA64_DTPREL32LSB:
3169 size = 4; bigendian = 0;
3172 case R_IA64_DIR64MSB:
3173 case R_IA64_GPREL64MSB:
3174 case R_IA64_PLTOFF64MSB:
3175 case R_IA64_FPTR64MSB:
3176 case R_IA64_PCREL64MSB:
3177 case R_IA64_LTOFF_FPTR64MSB:
3178 case R_IA64_SEGREL64MSB:
3179 case R_IA64_SECREL64MSB:
3180 case R_IA64_LTV64MSB:
3181 case R_IA64_TPREL64MSB:
3182 case R_IA64_DTPMOD64MSB:
3183 case R_IA64_DTPREL64MSB:
3184 size = 8; bigendian = 1;
3187 case R_IA64_DIR64LSB:
3188 case R_IA64_GPREL64LSB:
3189 case R_IA64_PLTOFF64LSB:
3190 case R_IA64_FPTR64LSB:
3191 case R_IA64_PCREL64LSB:
3192 case R_IA64_LTOFF_FPTR64LSB:
3193 case R_IA64_SEGREL64LSB:
3194 case R_IA64_SECREL64LSB:
3195 case R_IA64_LTV64LSB:
3196 case R_IA64_TPREL64LSB:
3197 case R_IA64_DTPMOD64LSB:
3198 case R_IA64_DTPREL64LSB:
3199 size = 8; bigendian = 0;
3202 /* Unsupported / Dynamic relocations. */
3204 return bfd_reloc_notsupported;
3209 case IA64_OPND_IMMU64:
3210 hit_addr -= (long) hit_addr & 0x3;
3211 t0 = bfd_get_64 (abfd, hit_addr);
3212 t1 = bfd_get_64 (abfd, hit_addr + 8);
3214 /* tmpl/s: bits 0.. 5 in t0
3215 slot 0: bits 5..45 in t0
3216 slot 1: bits 46..63 in t0, bits 0..22 in t1
3217 slot 2: bits 23..63 in t1 */
3219 /* First, clear the bits that form the 64 bit constant. */
3220 t0 &= ~(0x3ffffLL << 46);
3222 | (( (0x07fLL << 13) | (0x1ffLL << 27)
3223 | (0x01fLL << 22) | (0x001LL << 21)
3224 | (0x001LL << 36)) << 23));
3226 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
3227 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
3228 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
3229 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
3230 | (((val >> 16) & 0x01f) << 22) /* imm5c */
3231 | (((val >> 21) & 0x001) << 21) /* ic */
3232 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
3234 bfd_put_64 (abfd, t0, hit_addr);
3235 bfd_put_64 (abfd, t1, hit_addr + 8);
3238 case IA64_OPND_TGT64:
3239 hit_addr -= (long) hit_addr & 0x3;
3240 t0 = bfd_get_64 (abfd, hit_addr);
3241 t1 = bfd_get_64 (abfd, hit_addr + 8);
3243 /* tmpl/s: bits 0.. 5 in t0
3244 slot 0: bits 5..45 in t0
3245 slot 1: bits 46..63 in t0, bits 0..22 in t1
3246 slot 2: bits 23..63 in t1 */
3248 /* First, clear the bits that form the 64 bit constant. */
3249 t0 &= ~(0x3ffffLL << 46);
3251 | ((1LL << 36 | 0xfffffLL << 13) << 23));
3254 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
3255 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
3256 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
3257 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
3259 bfd_put_64 (abfd, t0, hit_addr);
3260 bfd_put_64 (abfd, t1, hit_addr + 8);
3264 switch ((long) hit_addr & 0x3)
3266 case 0: shift = 5; break;
3267 case 1: shift = 14; hit_addr += 3; break;
3268 case 2: shift = 23; hit_addr += 6; break;
3269 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
3271 dword = bfd_get_64 (abfd, hit_addr);
3272 insn = (dword >> shift) & 0x1ffffffffffLL;
3274 op = elf64_ia64_operands + opnd;
3275 err = (*op->insert) (op, val, (ia64_insn *)& insn);
3277 return bfd_reloc_overflow;
3279 dword &= ~(0x1ffffffffffLL << shift);
3280 dword |= (insn << shift);
3281 bfd_put_64 (abfd, dword, hit_addr);
3285 /* A data relocation. */
3288 bfd_putb32 (val, hit_addr);
3290 bfd_putb64 (val, hit_addr);
3293 bfd_putl32 (val, hit_addr);
3295 bfd_putl64 (val, hit_addr);
3299 return bfd_reloc_ok;
3303 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3306 struct bfd_link_info *info;
3314 Elf_Internal_Rela outrel;
3317 BFD_ASSERT (dynindx != -1);
3318 outrel.r_info = ELFNN_R_INFO (dynindx, type);
3319 outrel.r_addend = addend;
3320 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3321 if (outrel.r_offset >= (bfd_vma) -2)
3323 /* Run for the hills. We shouldn't be outputting a relocation
3324 for this. So do what everyone else does and output a no-op. */
3325 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3326 outrel.r_addend = 0;
3327 outrel.r_offset = 0;
3330 outrel.r_offset += sec->output_section->vma + sec->output_offset;
3332 loc = srel->contents;
3333 loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3334 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3335 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3336 <= srel->_cooked_size);
3339 /* Store an entry for target address TARGET_ADDR in the linkage table
3340 and return the gp-relative address of the linkage table entry. */
3343 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3345 struct bfd_link_info *info;
3346 struct elfNN_ia64_dyn_sym_info *dyn_i;
3350 unsigned int dyn_r_type;
3352 struct elfNN_ia64_link_hash_table *ia64_info;
3357 ia64_info = elfNN_ia64_hash_table (info);
3358 got_sec = ia64_info->got_sec;
3362 case R_IA64_TPREL64LSB:
3363 done = dyn_i->tprel_done;
3364 dyn_i->tprel_done = TRUE;
3365 got_offset = dyn_i->tprel_offset;
3367 case R_IA64_DTPMOD64LSB:
3368 if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3370 done = dyn_i->dtpmod_done;
3371 dyn_i->dtpmod_done = TRUE;
3375 done = ia64_info->self_dtpmod_done;
3376 ia64_info->self_dtpmod_done = TRUE;
3379 got_offset = dyn_i->dtpmod_offset;
3381 case R_IA64_DTPREL64LSB:
3382 done = dyn_i->dtprel_done;
3383 dyn_i->dtprel_done = TRUE;
3384 got_offset = dyn_i->dtprel_offset;
3387 done = dyn_i->got_done;
3388 dyn_i->got_done = TRUE;
3389 got_offset = dyn_i->got_offset;
3393 BFD_ASSERT ((got_offset & 7) == 0);
3397 /* Store the target address in the linkage table entry. */
3398 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3400 /* Install a dynamic relocation if needed. */
3401 if ((info->shared && dyn_r_type != R_IA64_DTPREL64LSB)
3402 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
3403 || elfNN_ia64_aix_vec (abfd->xvec)
3404 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3407 && dyn_r_type != R_IA64_TPREL64LSB
3408 && dyn_r_type != R_IA64_DTPMOD64LSB
3409 && dyn_r_type != R_IA64_DTPREL64LSB)
3411 dyn_r_type = R_IA64_REL64LSB;
3416 if (bfd_big_endian (abfd))
3420 case R_IA64_REL64LSB:
3421 dyn_r_type = R_IA64_REL64MSB;
3423 case R_IA64_DIR64LSB:
3424 dyn_r_type = R_IA64_DIR64MSB;
3426 case R_IA64_FPTR64LSB:
3427 dyn_r_type = R_IA64_FPTR64MSB;
3429 case R_IA64_TPREL64LSB:
3430 dyn_r_type = R_IA64_TPREL64MSB;
3432 case R_IA64_DTPMOD64LSB:
3433 dyn_r_type = R_IA64_DTPMOD64MSB;
3435 case R_IA64_DTPREL64LSB:
3436 dyn_r_type = R_IA64_DTPREL64MSB;
3444 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3445 ia64_info->rel_got_sec,
3446 got_offset, dyn_r_type,
3451 /* Return the address of the linkage table entry. */
3452 value = (got_sec->output_section->vma
3453 + got_sec->output_offset
3459 /* Fill in a function descriptor consisting of the function's code
3460 address and its global pointer. Return the descriptor's address. */
3463 set_fptr_entry (abfd, info, dyn_i, value)
3465 struct bfd_link_info *info;
3466 struct elfNN_ia64_dyn_sym_info *dyn_i;
3469 struct elfNN_ia64_link_hash_table *ia64_info;
3472 ia64_info = elfNN_ia64_hash_table (info);
3473 fptr_sec = ia64_info->fptr_sec;
3475 if (!dyn_i->fptr_done)
3477 dyn_i->fptr_done = 1;
3479 /* Fill in the function descriptor. */
3480 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3481 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3482 fptr_sec->contents + dyn_i->fptr_offset + 8);
3485 /* Return the descriptor's address. */
3486 value = (fptr_sec->output_section->vma
3487 + fptr_sec->output_offset
3488 + dyn_i->fptr_offset);
3493 /* Fill in a PLTOFF entry consisting of the function's code address
3494 and its global pointer. Return the descriptor's address. */
3497 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3499 struct bfd_link_info *info;
3500 struct elfNN_ia64_dyn_sym_info *dyn_i;
3504 struct elfNN_ia64_link_hash_table *ia64_info;
3505 asection *pltoff_sec;
3507 ia64_info = elfNN_ia64_hash_table (info);
3508 pltoff_sec = ia64_info->pltoff_sec;
3510 /* Don't do anything if this symbol uses a real PLT entry. In
3511 that case, we'll fill this in during finish_dynamic_symbol. */
3512 if ((! dyn_i->want_plt || is_plt)
3513 && !dyn_i->pltoff_done)
3515 bfd_vma gp = _bfd_get_gp_value (abfd);
3517 /* Fill in the function descriptor. */
3518 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3519 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3521 /* Install dynamic relocations if needed. */
3522 if (!is_plt && info->shared)
3524 unsigned int dyn_r_type;
3526 if (bfd_big_endian (abfd))
3527 dyn_r_type = R_IA64_REL64MSB;
3529 dyn_r_type = R_IA64_REL64LSB;
3531 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3532 ia64_info->rel_pltoff_sec,
3533 dyn_i->pltoff_offset,
3534 dyn_r_type, 0, value);
3535 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3536 ia64_info->rel_pltoff_sec,
3537 dyn_i->pltoff_offset + 8,
3541 dyn_i->pltoff_done = 1;
3544 /* Return the descriptor's address. */
3545 value = (pltoff_sec->output_section->vma
3546 + pltoff_sec->output_offset
3547 + dyn_i->pltoff_offset);
3552 /* Return the base VMA address which should be subtracted from real addresses
3553 when resolving @tprel() relocation.
3554 Main program TLS (whose template starts at PT_TLS p_vaddr)
3555 is assigned offset round(16, PT_TLS p_align). */
3558 elfNN_ia64_tprel_base (info)
3559 struct bfd_link_info *info;
3561 struct elf_link_tls_segment *tls_segment
3562 = elf_hash_table (info)->tls_segment;
3564 BFD_ASSERT (tls_segment != NULL);
3565 return (tls_segment->start
3566 - align_power ((bfd_vma) 16, tls_segment->align));
3569 /* Return the base VMA address which should be subtracted from real addresses
3570 when resolving @dtprel() relocation.
3571 This is PT_TLS segment p_vaddr. */
3574 elfNN_ia64_dtprel_base (info)
3575 struct bfd_link_info *info;
3577 BFD_ASSERT (elf_hash_table (info)->tls_segment != NULL);
3578 return elf_hash_table (info)->tls_segment->start;
3581 /* Called through qsort to sort the .IA_64.unwind section during a
3582 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3583 to the output bfd so we can do proper endianness frobbing. */
3585 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3588 elfNN_ia64_unwind_entry_compare (a, b)
3594 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3595 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3597 return (av < bv ? -1 : av > bv ? 1 : 0);
3600 /* Make sure we've got ourselves a nice fat __gp value. */
3602 elfNN_ia64_choose_gp (abfd, info)
3604 struct bfd_link_info *info;
3606 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3607 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3608 struct elf_link_hash_entry *gp;
3611 struct elfNN_ia64_link_hash_table *ia64_info;
3613 ia64_info = elfNN_ia64_hash_table (info);
3615 /* Find the min and max vma of all sections marked short. Also collect
3616 min and max vma of any type, for use in selecting a nice gp. */
3617 for (os = abfd->sections; os ; os = os->next)
3621 if ((os->flags & SEC_ALLOC) == 0)
3625 hi = os->vma + os->_raw_size;
3633 if (os->flags & SEC_SMALL_DATA)
3635 if (min_short_vma > lo)
3637 if (max_short_vma < hi)
3642 /* See if the user wants to force a value. */
3643 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3647 && (gp->root.type == bfd_link_hash_defined
3648 || gp->root.type == bfd_link_hash_defweak))
3650 asection *gp_sec = gp->root.u.def.section;
3651 gp_val = (gp->root.u.def.value
3652 + gp_sec->output_section->vma
3653 + gp_sec->output_offset);
3657 /* Pick a sensible value. */
3659 asection *got_sec = ia64_info->got_sec;
3661 /* Start with just the address of the .got. */
3663 gp_val = got_sec->output_section->vma;
3664 else if (max_short_vma != 0)
3665 gp_val = min_short_vma;
3669 /* If it is possible to address the entire image, but we
3670 don't with the choice above, adjust. */
3671 if (max_vma - min_vma < 0x400000
3672 && max_vma - gp_val <= 0x200000
3673 && gp_val - min_vma > 0x200000)
3674 gp_val = min_vma + 0x200000;
3675 else if (max_short_vma != 0)
3677 /* If we don't cover all the short data, adjust. */
3678 if (max_short_vma - gp_val >= 0x200000)
3679 gp_val = min_short_vma + 0x200000;
3681 /* If we're addressing stuff past the end, adjust back. */
3682 if (gp_val > max_vma)
3683 gp_val = max_vma - 0x200000 + 8;
3687 /* Validate whether all SHF_IA_64_SHORT sections are within
3688 range of the chosen GP. */
3690 if (max_short_vma != 0)
3692 if (max_short_vma - min_short_vma >= 0x400000)
3694 (*_bfd_error_handler)
3695 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3696 bfd_get_filename (abfd),
3697 (unsigned long) (max_short_vma - min_short_vma));
3700 else if ((gp_val > min_short_vma
3701 && gp_val - min_short_vma > 0x200000)
3702 || (gp_val < max_short_vma
3703 && max_short_vma - gp_val >= 0x200000))
3705 (*_bfd_error_handler)
3706 (_("%s: __gp does not cover short data segment"),
3707 bfd_get_filename (abfd));
3712 _bfd_set_gp_value (abfd, gp_val);
3718 elfNN_ia64_final_link (abfd, info)
3720 struct bfd_link_info *info;
3722 struct elfNN_ia64_link_hash_table *ia64_info;
3723 asection *unwind_output_sec;
3725 ia64_info = elfNN_ia64_hash_table (info);
3727 /* Make sure we've got ourselves a nice fat __gp value. */
3728 if (!info->relocateable)
3730 bfd_vma gp_val = _bfd_get_gp_value (abfd);
3731 struct elf_link_hash_entry *gp;
3735 if (! elfNN_ia64_choose_gp (abfd, info))
3737 gp_val = _bfd_get_gp_value (abfd);
3740 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3744 gp->root.type = bfd_link_hash_defined;
3745 gp->root.u.def.value = gp_val;
3746 gp->root.u.def.section = bfd_abs_section_ptr;
3750 /* If we're producing a final executable, we need to sort the contents
3751 of the .IA_64.unwind section. Force this section to be relocated
3752 into memory rather than written immediately to the output file. */
3753 unwind_output_sec = NULL;
3754 if (!info->relocateable)
3756 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3759 unwind_output_sec = s->output_section;
3760 unwind_output_sec->contents
3761 = bfd_malloc (unwind_output_sec->_raw_size);
3762 if (unwind_output_sec->contents == NULL)
3767 /* Invoke the regular ELF backend linker to do all the work. */
3768 if (!bfd_elfNN_bfd_final_link (abfd, info))
3771 if (unwind_output_sec)
3773 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3774 qsort (unwind_output_sec->contents,
3775 (size_t) (unwind_output_sec->_raw_size / 24),
3777 elfNN_ia64_unwind_entry_compare);
3779 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3780 unwind_output_sec->contents, (bfd_vma) 0,
3781 unwind_output_sec->_raw_size))
3789 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3790 contents, relocs, local_syms, local_sections)
3792 struct bfd_link_info *info;
3794 asection *input_section;
3796 Elf_Internal_Rela *relocs;
3797 Elf_Internal_Sym *local_syms;
3798 asection **local_sections;
3800 struct elfNN_ia64_link_hash_table *ia64_info;
3801 Elf_Internal_Shdr *symtab_hdr;
3802 Elf_Internal_Rela *rel;
3803 Elf_Internal_Rela *relend;
3805 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
3808 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3809 ia64_info = elfNN_ia64_hash_table (info);
3811 /* Infect various flags from the input section to the output section. */
3812 if (info->relocateable)
3816 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3817 flags &= SHF_IA_64_NORECOV;
3819 elf_section_data(input_section->output_section)
3820 ->this_hdr.sh_flags |= flags;
3824 gp_val = _bfd_get_gp_value (output_bfd);
3825 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
3828 relend = relocs + input_section->reloc_count;
3829 for (; rel < relend; ++rel)
3831 struct elf_link_hash_entry *h;
3832 struct elfNN_ia64_dyn_sym_info *dyn_i;
3833 bfd_reloc_status_type r;
3834 reloc_howto_type *howto;
3835 unsigned long r_symndx;
3836 Elf_Internal_Sym *sym;
3837 unsigned int r_type;
3841 bfd_boolean dynamic_symbol_p;
3842 bfd_boolean undef_weak_ref;
3844 r_type = ELFNN_R_TYPE (rel->r_info);
3845 if (r_type > R_IA64_MAX_RELOC_CODE)
3847 (*_bfd_error_handler)
3848 (_("%s: unknown relocation type %d"),
3849 bfd_archive_filename (input_bfd), (int)r_type);
3850 bfd_set_error (bfd_error_bad_value);
3855 howto = lookup_howto (r_type);
3856 r_symndx = ELFNN_R_SYM (rel->r_info);
3860 undef_weak_ref = FALSE;
3862 if (r_symndx < symtab_hdr->sh_info)
3864 /* Reloc against local symbol. */
3865 sym = local_syms + r_symndx;
3866 sym_sec = local_sections[r_symndx];
3867 value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel);
3868 if ((sym_sec->flags & SEC_MERGE)
3869 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3870 && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
3872 struct elfNN_ia64_local_hash_entry *loc_h;
3874 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
3875 if (loc_h && ! loc_h->sec_merge_done)
3877 struct elfNN_ia64_dyn_sym_info *dynent;
3880 for (dynent = loc_h->info; dynent; dynent = dynent->next)
3884 _bfd_merged_section_offset (output_bfd, &msec,
3885 elf_section_data (msec)->
3890 dynent->addend -= sym->st_value;
3891 dynent->addend += msec->output_section->vma
3892 + msec->output_offset
3893 - sym_sec->output_section->vma
3894 - sym_sec->output_offset;
3896 loc_h->sec_merge_done = 1;
3904 /* Reloc against global symbol. */
3905 indx = r_symndx - symtab_hdr->sh_info;
3906 h = elf_sym_hashes (input_bfd)[indx];
3907 while (h->root.type == bfd_link_hash_indirect
3908 || h->root.type == bfd_link_hash_warning)
3909 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3912 if (h->root.type == bfd_link_hash_defined
3913 || h->root.type == bfd_link_hash_defweak)
3915 sym_sec = h->root.u.def.section;
3917 /* Detect the cases that sym_sec->output_section is
3918 expected to be NULL -- all cases in which the symbol
3919 is defined in another shared module. This includes
3920 PLT relocs for which we've created a PLT entry and
3921 other relocs for which we're prepared to create
3922 dynamic relocations. */
3923 /* ??? Just accept it NULL and continue. */
3925 if (sym_sec->output_section != NULL)
3927 value = (h->root.u.def.value
3928 + sym_sec->output_section->vma
3929 + sym_sec->output_offset);
3932 else if (h->root.type == bfd_link_hash_undefweak)
3933 undef_weak_ref = TRUE;
3934 else if (info->shared
3935 && !info->no_undefined
3936 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3940 if (! ((*info->callbacks->undefined_symbol)
3941 (info, h->root.root.string, input_bfd,
3942 input_section, rel->r_offset,
3943 (!info->shared || info->no_undefined
3944 || ELF_ST_VISIBILITY (h->other)))))
3951 hit_addr = contents + rel->r_offset;
3952 value += rel->r_addend;
3953 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3964 case R_IA64_DIR32MSB:
3965 case R_IA64_DIR32LSB:
3966 case R_IA64_DIR64MSB:
3967 case R_IA64_DIR64LSB:
3968 /* Install a dynamic relocation for this reloc. */
3969 if ((dynamic_symbol_p || info->shared
3970 || (elfNN_ia64_aix_vec (info->hash->creator)
3971 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3972 && (!h || strcmp (h->root.root.string,
3973 "__GLOB_DATA_PTR") != 0)))
3975 && (input_section->flags & SEC_ALLOC) != 0)
3977 unsigned int dyn_r_type;
3981 BFD_ASSERT (srel != NULL);
3983 /* If we don't need dynamic symbol lookup, find a
3984 matching RELATIVE relocation. */
3985 dyn_r_type = r_type;
3986 if (dynamic_symbol_p)
3988 dynindx = h->dynindx;
3989 addend = rel->r_addend;
3996 case R_IA64_DIR32MSB:
3997 dyn_r_type = R_IA64_REL32MSB;
3999 case R_IA64_DIR32LSB:
4000 dyn_r_type = R_IA64_REL32LSB;
4002 case R_IA64_DIR64MSB:
4003 dyn_r_type = R_IA64_REL64MSB;
4005 case R_IA64_DIR64LSB:
4006 dyn_r_type = R_IA64_REL64LSB;
4010 /* We can't represent this without a dynamic symbol.
4011 Adjust the relocation to be against an output
4012 section symbol, which are always present in the
4013 dynamic symbol table. */
4014 /* ??? People shouldn't be doing non-pic code in
4015 shared libraries. Hork. */
4016 (*_bfd_error_handler)
4017 (_("%s: linking non-pic code in a shared library"),
4018 bfd_archive_filename (input_bfd));
4026 if (elfNN_ia64_aix_vec (info->hash->creator))
4027 rel->r_addend = value;
4028 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4029 srel, rel->r_offset, dyn_r_type,
4034 case R_IA64_LTV32MSB:
4035 case R_IA64_LTV32LSB:
4036 case R_IA64_LTV64MSB:
4037 case R_IA64_LTV64LSB:
4038 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4041 case R_IA64_GPREL22:
4042 case R_IA64_GPREL64I:
4043 case R_IA64_GPREL32MSB:
4044 case R_IA64_GPREL32LSB:
4045 case R_IA64_GPREL64MSB:
4046 case R_IA64_GPREL64LSB:
4047 if (dynamic_symbol_p)
4049 (*_bfd_error_handler)
4050 (_("%s: @gprel relocation against dynamic symbol %s"),
4051 bfd_archive_filename (input_bfd), h->root.root.string);
4056 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4059 case R_IA64_LTOFF22:
4060 case R_IA64_LTOFF22X:
4061 case R_IA64_LTOFF64I:
4062 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4063 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4064 rel->r_addend, value, R_IA64_DIR64LSB);
4066 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4069 case R_IA64_PLTOFF22:
4070 case R_IA64_PLTOFF64I:
4071 case R_IA64_PLTOFF64MSB:
4072 case R_IA64_PLTOFF64LSB:
4073 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4074 value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4076 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4079 case R_IA64_FPTR64I:
4080 case R_IA64_FPTR32MSB:
4081 case R_IA64_FPTR32LSB:
4082 case R_IA64_FPTR64MSB:
4083 case R_IA64_FPTR64LSB:
4084 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4085 if (dyn_i->want_fptr)
4087 if (!undef_weak_ref)
4088 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4094 /* Otherwise, we expect the dynamic linker to create
4099 if (h->dynindx != -1)
4100 dynindx = h->dynindx;
4102 dynindx = (_bfd_elf_link_lookup_local_dynindx
4103 (info, h->root.u.def.section->owner,
4104 global_sym_index (h)));
4108 dynindx = (_bfd_elf_link_lookup_local_dynindx
4109 (info, input_bfd, (long) r_symndx));
4112 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4113 srel, rel->r_offset, r_type,
4114 dynindx, rel->r_addend);
4118 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4121 case R_IA64_LTOFF_FPTR22:
4122 case R_IA64_LTOFF_FPTR64I:
4123 case R_IA64_LTOFF_FPTR32MSB:
4124 case R_IA64_LTOFF_FPTR32LSB:
4125 case R_IA64_LTOFF_FPTR64MSB:
4126 case R_IA64_LTOFF_FPTR64LSB:
4130 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4131 if (dyn_i->want_fptr)
4133 BFD_ASSERT (h == NULL || h->dynindx == -1)
4134 if (!undef_weak_ref)
4135 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4140 /* Otherwise, we expect the dynamic linker to create
4144 if (h->dynindx != -1)
4145 dynindx = h->dynindx;
4147 dynindx = (_bfd_elf_link_lookup_local_dynindx
4148 (info, h->root.u.def.section->owner,
4149 global_sym_index (h)));
4152 dynindx = (_bfd_elf_link_lookup_local_dynindx
4153 (info, input_bfd, (long) r_symndx));
4157 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4158 rel->r_addend, value, R_IA64_FPTR64LSB);
4160 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4164 case R_IA64_PCREL32MSB:
4165 case R_IA64_PCREL32LSB:
4166 case R_IA64_PCREL64MSB:
4167 case R_IA64_PCREL64LSB:
4168 /* Install a dynamic relocation for this reloc. */
4169 if ((dynamic_symbol_p
4170 || elfNN_ia64_aix_vec (info->hash->creator))
4173 BFD_ASSERT (srel != NULL);
4175 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4176 srel, rel->r_offset, r_type,
4177 h->dynindx, rel->r_addend);
4181 case R_IA64_PCREL21B:
4182 case R_IA64_PCREL60B:
4183 /* We should have created a PLT entry for any dynamic symbol. */
4186 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4188 if (dyn_i && dyn_i->want_plt2)
4190 /* Should have caught this earlier. */
4191 BFD_ASSERT (rel->r_addend == 0);
4193 value = (ia64_info->plt_sec->output_section->vma
4194 + ia64_info->plt_sec->output_offset
4195 + dyn_i->plt2_offset);
4199 /* Since there's no PLT entry, Validate that this is
4201 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4203 /* If the symbol is undef_weak, we shouldn't be trying
4204 to call it. There's every chance that we'd wind up
4205 with an out-of-range fixup here. Don't bother setting
4206 any value at all. */
4212 case R_IA64_PCREL21BI:
4213 case R_IA64_PCREL21F:
4214 case R_IA64_PCREL21M:
4215 case R_IA64_PCREL22:
4216 case R_IA64_PCREL64I:
4217 /* The PCREL21BI reloc is specifically not intended for use with
4218 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4219 fixup code, and thus probably ought not be dynamic. The
4220 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4221 if (dynamic_symbol_p)
4225 if (r_type == R_IA64_PCREL21BI)
4226 msg = _("%s: @internal branch to dynamic symbol %s");
4227 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4228 msg = _("%s: speculation fixup to dynamic symbol %s");
4230 msg = _("%s: @pcrel relocation against dynamic symbol %s");
4231 (*_bfd_error_handler) (msg, bfd_archive_filename (input_bfd),
4232 h->root.root.string);
4239 /* Make pc-relative. */
4240 value -= (input_section->output_section->vma
4241 + input_section->output_offset
4242 + rel->r_offset) & ~ (bfd_vma) 0x3;
4243 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4246 case R_IA64_SEGREL32MSB:
4247 case R_IA64_SEGREL32LSB:
4248 case R_IA64_SEGREL64MSB:
4249 case R_IA64_SEGREL64LSB:
4252 /* If the input section was discarded from the output, then
4258 struct elf_segment_map *m;
4259 Elf_Internal_Phdr *p;
4261 /* Find the segment that contains the output_section. */
4262 for (m = elf_tdata (output_bfd)->segment_map,
4263 p = elf_tdata (output_bfd)->phdr;
4268 for (i = m->count - 1; i >= 0; i--)
4269 if (m->sections[i] == sym_sec->output_section)
4277 r = bfd_reloc_notsupported;
4281 /* The VMA of the segment is the vaddr of the associated
4283 if (value > p->p_vaddr)
4284 value -= p->p_vaddr;
4287 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4293 case R_IA64_SECREL32MSB:
4294 case R_IA64_SECREL32LSB:
4295 case R_IA64_SECREL64MSB:
4296 case R_IA64_SECREL64LSB:
4297 /* Make output-section relative. */
4298 if (value > input_section->output_section->vma)
4299 value -= input_section->output_section->vma;
4302 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4305 case R_IA64_IPLTMSB:
4306 case R_IA64_IPLTLSB:
4307 /* Install a dynamic relocation for this reloc. */
4308 if ((dynamic_symbol_p || info->shared)
4309 && (input_section->flags & SEC_ALLOC) != 0)
4311 BFD_ASSERT (srel != NULL);
4313 /* If we don't need dynamic symbol lookup, install two
4314 RELATIVE relocations. */
4315 if (! dynamic_symbol_p)
4317 unsigned int dyn_r_type;
4319 if (r_type == R_IA64_IPLTMSB)
4320 dyn_r_type = R_IA64_REL64MSB;
4322 dyn_r_type = R_IA64_REL64LSB;
4324 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4326 srel, rel->r_offset,
4327 dyn_r_type, 0, value);
4328 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4330 srel, rel->r_offset + 8,
4331 dyn_r_type, 0, gp_val);
4334 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4335 srel, rel->r_offset, r_type,
4336 h->dynindx, rel->r_addend);
4339 if (r_type == R_IA64_IPLTMSB)
4340 r_type = R_IA64_DIR64MSB;
4342 r_type = R_IA64_DIR64LSB;
4343 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4344 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
4348 case R_IA64_TPREL14:
4349 case R_IA64_TPREL22:
4350 case R_IA64_TPREL64I:
4351 value -= elfNN_ia64_tprel_base (info);
4352 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4355 case R_IA64_DTPREL14:
4356 case R_IA64_DTPREL22:
4357 case R_IA64_DTPREL64I:
4358 case R_IA64_DTPREL64LSB:
4359 case R_IA64_DTPREL64MSB:
4360 value -= elfNN_ia64_dtprel_base (info);
4361 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4364 case R_IA64_LTOFF_TPREL22:
4365 case R_IA64_LTOFF_DTPMOD22:
4366 case R_IA64_LTOFF_DTPREL22:
4369 long dynindx = h ? h->dynindx : -1;
4370 bfd_vma r_addend = rel->r_addend;
4375 case R_IA64_LTOFF_TPREL22:
4376 if (!dynamic_symbol_p)
4379 value -= elfNN_ia64_tprel_base (info);
4382 r_addend += value - elfNN_ia64_dtprel_base (info);
4386 got_r_type = R_IA64_TPREL64LSB;
4388 case R_IA64_LTOFF_DTPMOD22:
4389 if (!dynamic_symbol_p && !info->shared)
4391 got_r_type = R_IA64_DTPMOD64LSB;
4393 case R_IA64_LTOFF_DTPREL22:
4394 if (!dynamic_symbol_p)
4395 value -= elfNN_ia64_dtprel_base (info);
4396 got_r_type = R_IA64_DTPREL64LSB;
4399 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4400 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
4403 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4409 r = bfd_reloc_notsupported;
4418 case bfd_reloc_undefined:
4419 /* This can happen for global table relative relocs if
4420 __gp is undefined. This is a panic situation so we
4421 don't try to continue. */
4422 (*info->callbacks->undefined_symbol)
4423 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4426 case bfd_reloc_notsupported:
4431 name = h->root.root.string;
4434 name = bfd_elf_string_from_elf_section (input_bfd,
4435 symtab_hdr->sh_link,
4440 name = bfd_section_name (input_bfd, input_section);
4442 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4444 input_section, rel->r_offset))
4450 case bfd_reloc_dangerous:
4451 case bfd_reloc_outofrange:
4452 case bfd_reloc_overflow:
4458 name = h->root.root.string;
4461 name = bfd_elf_string_from_elf_section (input_bfd,
4462 symtab_hdr->sh_link,
4467 name = bfd_section_name (input_bfd, input_section);
4469 if (!(*info->callbacks->reloc_overflow) (info, name,
4486 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4488 struct bfd_link_info *info;
4489 struct elf_link_hash_entry *h;
4490 Elf_Internal_Sym *sym;
4492 struct elfNN_ia64_link_hash_table *ia64_info;
4493 struct elfNN_ia64_dyn_sym_info *dyn_i;
4495 ia64_info = elfNN_ia64_hash_table (info);
4496 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4498 /* Fill in the PLT data, if required. */
4499 if (dyn_i && dyn_i->want_plt)
4501 Elf_Internal_Rela outrel;
4504 bfd_vma plt_addr, pltoff_addr, gp_val, index;
4506 gp_val = _bfd_get_gp_value (output_bfd);
4508 /* Initialize the minimal PLT entry. */
4510 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4511 plt_sec = ia64_info->plt_sec;
4512 loc = plt_sec->contents + dyn_i->plt_offset;
4514 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4515 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4516 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4519 plt_addr = (plt_sec->output_section->vma
4520 + plt_sec->output_offset
4521 + dyn_i->plt_offset);
4522 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
4524 /* Initialize the FULL PLT entry, if needed. */
4525 if (dyn_i->want_plt2)
4527 loc = plt_sec->contents + dyn_i->plt2_offset;
4529 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4530 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4533 /* Mark the symbol as undefined, rather than as defined in the
4534 plt section. Leave the value alone. */
4535 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4536 first place. But perhaps elflink.h did some for us. */
4537 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4538 sym->st_shndx = SHN_UNDEF;
4541 /* Create the dynamic relocation. */
4542 outrel.r_offset = pltoff_addr;
4543 if (bfd_little_endian (output_bfd))
4544 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4546 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4547 outrel.r_addend = 0;
4549 /* This is fun. In the .IA_64.pltoff section, we've got entries
4550 that correspond both to real PLT entries, and those that
4551 happened to resolve to local symbols but need to be created
4552 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4553 relocations for the real PLT should come at the end of the
4554 section, so that they can be indexed by plt entry at runtime.
4556 We emitted all of the relocations for the non-PLT @pltoff
4557 entries during relocate_section. So we can consider the
4558 existing sec->reloc_count to be the base of the array of
4561 loc = ia64_info->rel_pltoff_sec->contents;
4562 loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
4563 * sizeof (Elf64_External_Rela));
4564 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4567 /* Mark some specially defined symbols as absolute. */
4568 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4569 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4570 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4571 sym->st_shndx = SHN_ABS;
4577 elfNN_ia64_finish_dynamic_sections (abfd, info)
4579 struct bfd_link_info *info;
4581 struct elfNN_ia64_link_hash_table *ia64_info;
4584 ia64_info = elfNN_ia64_hash_table (info);
4585 dynobj = ia64_info->root.dynobj;
4587 if (elf_hash_table (info)->dynamic_sections_created)
4589 ElfNN_External_Dyn *dyncon, *dynconend;
4590 asection *sdyn, *sgotplt;
4593 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4594 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4595 BFD_ASSERT (sdyn != NULL);
4596 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4597 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4599 gp_val = _bfd_get_gp_value (abfd);
4601 for (; dyncon < dynconend; dyncon++)
4603 Elf_Internal_Dyn dyn;
4605 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4610 dyn.d_un.d_ptr = gp_val;
4614 dyn.d_un.d_val = (ia64_info->minplt_entries
4615 * sizeof (ElfNN_External_Rela));
4619 /* See the comment above in finish_dynamic_symbol. */
4620 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4621 + ia64_info->rel_pltoff_sec->output_offset
4622 + (ia64_info->rel_pltoff_sec->reloc_count
4623 * sizeof (ElfNN_External_Rela)));
4626 case DT_IA_64_PLT_RESERVE:
4627 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4628 + sgotplt->output_offset);
4632 /* Do not have RELASZ include JMPREL. This makes things
4633 easier on ld.so. This is not what the rest of BFD set up. */
4634 dyn.d_un.d_val -= (ia64_info->minplt_entries
4635 * sizeof (ElfNN_External_Rela));
4639 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4642 /* Initialize the PLT0 entry. */
4643 if (ia64_info->plt_sec)
4645 bfd_byte *loc = ia64_info->plt_sec->contents;
4648 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4650 pltres = (sgotplt->output_section->vma
4651 + sgotplt->output_offset
4654 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4661 /* ELF file flag handling: */
4663 /* Function to keep IA-64 specific file flags. */
4665 elfNN_ia64_set_private_flags (abfd, flags)
4669 BFD_ASSERT (!elf_flags_init (abfd)
4670 || elf_elfheader (abfd)->e_flags == flags);
4672 elf_elfheader (abfd)->e_flags = flags;
4673 elf_flags_init (abfd) = TRUE;
4677 /* Merge backend specific data from an object file to the output
4678 object file when linking. */
4680 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4685 bfd_boolean ok = TRUE;
4687 /* Don't even pretend to support mixed-format linking. */
4688 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4689 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4692 in_flags = elf_elfheader (ibfd)->e_flags;
4693 out_flags = elf_elfheader (obfd)->e_flags;
4695 if (! elf_flags_init (obfd))
4697 elf_flags_init (obfd) = TRUE;
4698 elf_elfheader (obfd)->e_flags = in_flags;
4700 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4701 && bfd_get_arch_info (obfd)->the_default)
4703 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4704 bfd_get_mach (ibfd));
4710 /* Check flag compatibility. */
4711 if (in_flags == out_flags)
4714 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4715 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4716 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4718 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4720 (*_bfd_error_handler)
4721 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4722 bfd_archive_filename (ibfd));
4724 bfd_set_error (bfd_error_bad_value);
4727 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4729 (*_bfd_error_handler)
4730 (_("%s: linking big-endian files with little-endian files"),
4731 bfd_archive_filename (ibfd));
4733 bfd_set_error (bfd_error_bad_value);
4736 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4738 (*_bfd_error_handler)
4739 (_("%s: linking 64-bit files with 32-bit files"),
4740 bfd_archive_filename (ibfd));
4742 bfd_set_error (bfd_error_bad_value);
4745 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4747 (*_bfd_error_handler)
4748 (_("%s: linking constant-gp files with non-constant-gp files"),
4749 bfd_archive_filename (ibfd));
4751 bfd_set_error (bfd_error_bad_value);
4754 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4755 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4757 (*_bfd_error_handler)
4758 (_("%s: linking auto-pic files with non-auto-pic files"),
4759 bfd_archive_filename (ibfd));
4761 bfd_set_error (bfd_error_bad_value);
4769 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4773 FILE *file = (FILE *) ptr;
4774 flagword flags = elf_elfheader (abfd)->e_flags;
4776 BFD_ASSERT (abfd != NULL && ptr != NULL);
4778 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4779 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4780 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4781 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4782 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4783 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4784 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4785 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4786 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4788 _bfd_elf_print_private_bfd_data (abfd, ptr);
4792 static enum elf_reloc_type_class
4793 elfNN_ia64_reloc_type_class (rela)
4794 const Elf_Internal_Rela *rela;
4796 switch ((int) ELFNN_R_TYPE (rela->r_info))
4798 case R_IA64_REL32MSB:
4799 case R_IA64_REL32LSB:
4800 case R_IA64_REL64MSB:
4801 case R_IA64_REL64LSB:
4802 return reloc_class_relative;
4803 case R_IA64_IPLTMSB:
4804 case R_IA64_IPLTLSB:
4805 return reloc_class_plt;
4807 return reloc_class_copy;
4809 return reloc_class_normal;
4814 elfNN_ia64_hpux_vec (const bfd_target *vec)
4816 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4817 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4821 elfNN_hpux_post_process_headers (abfd, info)
4823 struct bfd_link_info *info ATTRIBUTE_UNUSED;
4825 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4827 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4828 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4832 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
4833 bfd *abfd ATTRIBUTE_UNUSED;
4837 if (bfd_is_com_section (sec))
4839 *retval = SHN_IA_64_ANSI_COMMON;
4845 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4846 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4847 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4848 #define TARGET_BIG_NAME "elfNN-ia64-big"
4849 #define ELF_ARCH bfd_arch_ia64
4850 #define ELF_MACHINE_CODE EM_IA_64
4851 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4852 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4853 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4855 #define elf_backend_section_from_shdr \
4856 elfNN_ia64_section_from_shdr
4857 #define elf_backend_section_flags \
4858 elfNN_ia64_section_flags
4859 #define elf_backend_fake_sections \
4860 elfNN_ia64_fake_sections
4861 #define elf_backend_final_write_processing \
4862 elfNN_ia64_final_write_processing
4863 #define elf_backend_add_symbol_hook \
4864 elfNN_ia64_add_symbol_hook
4865 #define elf_backend_additional_program_headers \
4866 elfNN_ia64_additional_program_headers
4867 #define elf_backend_modify_segment_map \
4868 elfNN_ia64_modify_segment_map
4869 #define elf_info_to_howto \
4870 elfNN_ia64_info_to_howto
4872 #define bfd_elfNN_bfd_reloc_type_lookup \
4873 elfNN_ia64_reloc_type_lookup
4874 #define bfd_elfNN_bfd_is_local_label_name \
4875 elfNN_ia64_is_local_label_name
4876 #define bfd_elfNN_bfd_relax_section \
4877 elfNN_ia64_relax_section
4879 /* Stuff for the BFD linker: */
4880 #define bfd_elfNN_bfd_link_hash_table_create \
4881 elfNN_ia64_hash_table_create
4882 #define elf_backend_create_dynamic_sections \
4883 elfNN_ia64_create_dynamic_sections
4884 #define elf_backend_check_relocs \
4885 elfNN_ia64_check_relocs
4886 #define elf_backend_adjust_dynamic_symbol \
4887 elfNN_ia64_adjust_dynamic_symbol
4888 #define elf_backend_size_dynamic_sections \
4889 elfNN_ia64_size_dynamic_sections
4890 #define elf_backend_relocate_section \
4891 elfNN_ia64_relocate_section
4892 #define elf_backend_finish_dynamic_symbol \
4893 elfNN_ia64_finish_dynamic_symbol
4894 #define elf_backend_finish_dynamic_sections \
4895 elfNN_ia64_finish_dynamic_sections
4896 #define bfd_elfNN_bfd_final_link \
4897 elfNN_ia64_final_link
4899 #define bfd_elfNN_bfd_merge_private_bfd_data \
4900 elfNN_ia64_merge_private_bfd_data
4901 #define bfd_elfNN_bfd_set_private_flags \
4902 elfNN_ia64_set_private_flags
4903 #define bfd_elfNN_bfd_print_private_bfd_data \
4904 elfNN_ia64_print_private_bfd_data
4906 #define elf_backend_plt_readonly 1
4907 #define elf_backend_want_plt_sym 0
4908 #define elf_backend_plt_alignment 5
4909 #define elf_backend_got_header_size 0
4910 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4911 #define elf_backend_want_got_plt 1
4912 #define elf_backend_may_use_rel_p 1
4913 #define elf_backend_may_use_rela_p 1
4914 #define elf_backend_default_use_rela_p 1
4915 #define elf_backend_want_dynbss 0
4916 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4917 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4918 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4919 #define elf_backend_rela_normal 1
4921 #include "elfNN-target.h"
4923 /* AIX-specific vectors. */
4925 #undef TARGET_LITTLE_SYM
4926 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4927 #undef TARGET_LITTLE_NAME
4928 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4929 #undef TARGET_BIG_SYM
4930 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4931 #undef TARGET_BIG_NAME
4932 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4934 #undef elf_backend_add_symbol_hook
4935 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4937 #undef bfd_elfNN_bfd_link_add_symbols
4938 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4940 #define elfNN_bed elfNN_ia64_aix_bed
4942 #include "elfNN-target.h"
4944 /* HPUX-specific vectors. */
4946 #undef TARGET_LITTLE_SYM
4947 #undef TARGET_LITTLE_NAME
4948 #undef TARGET_BIG_SYM
4949 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4950 #undef TARGET_BIG_NAME
4951 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4953 /* We need to undo the AIX specific functions. */
4955 #undef elf_backend_add_symbol_hook
4956 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
4958 #undef bfd_elfNN_bfd_link_add_symbols
4959 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
4961 /* These are HP-UX specific functions. */
4963 #undef elf_backend_post_process_headers
4964 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4966 #undef elf_backend_section_from_bfd_section
4967 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4969 #undef elf_backend_want_p_paddr_set_to_zero
4970 #define elf_backend_want_p_paddr_set_to_zero 1
4972 #undef ELF_MAXPAGESIZE
4973 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4976 #define elfNN_bed elfNN_ia64_hpux_bed
4978 #include "elfNN-target.h"
4980 #undef elf_backend_want_p_paddr_set_to_zero