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);
1973 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1976 if (dyn_i == NULL && create)
1978 dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
1979 bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
1981 dyn_i->addend = addend;
1988 get_got (abfd, info, ia64_info)
1990 struct bfd_link_info *info;
1991 struct elfNN_ia64_link_hash_table *ia64_info;
1996 got = ia64_info->got_sec;
2001 dynobj = ia64_info->root.dynobj;
2003 ia64_info->root.dynobj = dynobj = abfd;
2004 if (!_bfd_elf_create_got_section (dynobj, info))
2007 got = bfd_get_section_by_name (dynobj, ".got");
2009 ia64_info->got_sec = got;
2011 flags = bfd_get_section_flags (abfd, got);
2012 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2018 /* Create function descriptor section (.opd). This section is called .opd
2019 because it contains "official prodecure descriptors". The "official"
2020 refers to the fact that these descriptors are used when taking the address
2021 of a procedure, thus ensuring a unique address for each procedure. */
2024 get_fptr (abfd, info, ia64_info)
2026 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2027 struct elfNN_ia64_link_hash_table *ia64_info;
2032 fptr = ia64_info->fptr_sec;
2035 dynobj = ia64_info->root.dynobj;
2037 ia64_info->root.dynobj = dynobj = abfd;
2039 fptr = bfd_make_section (dynobj, ".opd");
2041 || !bfd_set_section_flags (dynobj, fptr,
2047 | SEC_LINKER_CREATED))
2048 || !bfd_set_section_alignment (abfd, fptr, 4))
2054 ia64_info->fptr_sec = fptr;
2061 get_pltoff (abfd, info, ia64_info)
2063 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2064 struct elfNN_ia64_link_hash_table *ia64_info;
2069 pltoff = ia64_info->pltoff_sec;
2072 dynobj = ia64_info->root.dynobj;
2074 ia64_info->root.dynobj = dynobj = abfd;
2076 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
2078 || !bfd_set_section_flags (dynobj, pltoff,
2084 | SEC_LINKER_CREATED))
2085 || !bfd_set_section_alignment (abfd, pltoff, 4))
2091 ia64_info->pltoff_sec = pltoff;
2098 get_reloc_section (abfd, ia64_info, sec, create)
2100 struct elfNN_ia64_link_hash_table *ia64_info;
2104 const char *srel_name;
2108 srel_name = (bfd_elf_string_from_elf_section
2109 (abfd, elf_elfheader(abfd)->e_shstrndx,
2110 elf_section_data(sec)->rel_hdr.sh_name));
2111 if (srel_name == NULL)
2114 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2115 && strcmp (bfd_get_section_name (abfd, sec),
2117 || (strncmp (srel_name, ".rel", 4) == 0
2118 && strcmp (bfd_get_section_name (abfd, sec),
2119 srel_name+4) == 0));
2121 dynobj = ia64_info->root.dynobj;
2123 ia64_info->root.dynobj = dynobj = abfd;
2125 srel = bfd_get_section_by_name (dynobj, srel_name);
2126 if (srel == NULL && create)
2128 srel = bfd_make_section (dynobj, srel_name);
2130 || !bfd_set_section_flags (dynobj, srel,
2135 | SEC_LINKER_CREATED
2137 || !bfd_set_section_alignment (dynobj, srel, 3))
2141 if (sec->flags & SEC_READONLY)
2142 ia64_info->reltext = 1;
2148 count_dyn_reloc (abfd, dyn_i, srel, type)
2150 struct elfNN_ia64_dyn_sym_info *dyn_i;
2154 struct elfNN_ia64_dyn_reloc_entry *rent;
2156 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2157 if (rent->srel == srel && rent->type == type)
2162 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2163 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2167 rent->next = dyn_i->reloc_entries;
2171 dyn_i->reloc_entries = rent;
2179 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2181 struct bfd_link_info *info;
2183 const Elf_Internal_Rela *relocs;
2185 struct elfNN_ia64_link_hash_table *ia64_info;
2186 const Elf_Internal_Rela *relend;
2187 Elf_Internal_Shdr *symtab_hdr;
2188 const Elf_Internal_Rela *rel;
2189 asection *got, *fptr, *srel;
2191 if (info->relocateable)
2194 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2195 ia64_info = elfNN_ia64_hash_table (info);
2197 got = fptr = srel = NULL;
2199 relend = relocs + sec->reloc_count;
2200 for (rel = relocs; rel < relend; ++rel)
2210 NEED_LTOFF_FPTR = 128,
2216 struct elf_link_hash_entry *h = NULL;
2217 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2218 struct elfNN_ia64_dyn_sym_info *dyn_i;
2220 bfd_boolean maybe_dynamic;
2221 int dynrel_type = R_IA64_NONE;
2223 if (r_symndx >= symtab_hdr->sh_info)
2225 /* We're dealing with a global symbol -- find its hash entry
2226 and mark it as being referenced. */
2227 long indx = r_symndx - symtab_hdr->sh_info;
2228 h = elf_sym_hashes (abfd)[indx];
2229 while (h->root.type == bfd_link_hash_indirect
2230 || h->root.type == bfd_link_hash_warning)
2231 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2233 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2236 /* We can only get preliminary data on whether a symbol is
2237 locally or externally defined, as not all of the input files
2238 have yet been processed. Do something with what we know, as
2239 this may help reduce memory usage and processing time later. */
2240 maybe_dynamic = FALSE;
2241 if (h && ((info->shared
2242 && (!info->symbolic || info->allow_shlib_undefined))
2243 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
2244 || h->root.type == bfd_link_hash_defweak
2245 || elfNN_ia64_aix_vec (abfd->xvec)))
2246 maybe_dynamic = TRUE;
2249 switch (ELFNN_R_TYPE (rel->r_info))
2251 case R_IA64_TPREL64MSB:
2252 case R_IA64_TPREL64LSB:
2253 if (info->shared || maybe_dynamic)
2254 need_entry = NEED_DYNREL;
2255 dynrel_type = R_IA64_TPREL64LSB;
2257 info->flags |= DF_STATIC_TLS;
2260 case R_IA64_LTOFF_TPREL22:
2261 need_entry = NEED_TPREL;
2263 info->flags |= DF_STATIC_TLS;
2266 case R_IA64_DTPREL64MSB:
2267 case R_IA64_DTPREL64LSB:
2268 if (info->shared || maybe_dynamic)
2269 need_entry = NEED_DYNREL;
2270 dynrel_type = R_IA64_DTPREL64LSB;
2273 case R_IA64_LTOFF_DTPREL22:
2274 need_entry = NEED_DTPREL;
2277 case R_IA64_DTPMOD64MSB:
2278 case R_IA64_DTPMOD64LSB:
2279 if (info->shared || maybe_dynamic)
2280 need_entry = NEED_DYNREL;
2281 dynrel_type = R_IA64_DTPMOD64LSB;
2284 case R_IA64_LTOFF_DTPMOD22:
2285 need_entry = NEED_DTPMOD;
2288 case R_IA64_LTOFF_FPTR22:
2289 case R_IA64_LTOFF_FPTR64I:
2290 case R_IA64_LTOFF_FPTR32MSB:
2291 case R_IA64_LTOFF_FPTR32LSB:
2292 case R_IA64_LTOFF_FPTR64MSB:
2293 case R_IA64_LTOFF_FPTR64LSB:
2294 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2297 case R_IA64_FPTR64I:
2298 case R_IA64_FPTR32MSB:
2299 case R_IA64_FPTR32LSB:
2300 case R_IA64_FPTR64MSB:
2301 case R_IA64_FPTR64LSB:
2302 if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
2303 need_entry = NEED_FPTR | NEED_DYNREL;
2305 need_entry = NEED_FPTR;
2306 dynrel_type = R_IA64_FPTR64LSB;
2309 case R_IA64_LTOFF22:
2310 case R_IA64_LTOFF64I:
2311 need_entry = NEED_GOT;
2314 case R_IA64_LTOFF22X:
2315 need_entry = NEED_GOTX;
2318 case R_IA64_PLTOFF22:
2319 case R_IA64_PLTOFF64I:
2320 case R_IA64_PLTOFF64MSB:
2321 case R_IA64_PLTOFF64LSB:
2322 need_entry = NEED_PLTOFF;
2326 need_entry |= NEED_MIN_PLT;
2330 (*info->callbacks->warning)
2331 (info, _("@pltoff reloc against local symbol"), 0,
2332 abfd, 0, (bfd_vma) 0);
2336 case R_IA64_PCREL21B:
2337 case R_IA64_PCREL60B:
2338 /* Depending on where this symbol is defined, we may or may not
2339 need a full plt entry. Only skip if we know we'll not need
2340 the entry -- static or symbolic, and the symbol definition
2341 has already been seen. */
2342 if (maybe_dynamic && rel->r_addend == 0)
2343 need_entry = NEED_FULL_PLT;
2349 case R_IA64_DIR32MSB:
2350 case R_IA64_DIR32LSB:
2351 case R_IA64_DIR64MSB:
2352 case R_IA64_DIR64LSB:
2353 /* Shared objects will always need at least a REL relocation. */
2354 if (info->shared || maybe_dynamic
2355 || (elfNN_ia64_aix_vec (abfd->xvec)
2356 && (!h || strcmp (h->root.root.string,
2357 "__GLOB_DATA_PTR") != 0)))
2358 need_entry = NEED_DYNREL;
2359 dynrel_type = R_IA64_DIR64LSB;
2362 case R_IA64_IPLTMSB:
2363 case R_IA64_IPLTLSB:
2364 /* Shared objects will always need at least a REL relocation. */
2365 if (info->shared || maybe_dynamic)
2366 need_entry = NEED_DYNREL;
2367 dynrel_type = R_IA64_IPLTLSB;
2370 case R_IA64_PCREL22:
2371 case R_IA64_PCREL64I:
2372 case R_IA64_PCREL32MSB:
2373 case R_IA64_PCREL32LSB:
2374 case R_IA64_PCREL64MSB:
2375 case R_IA64_PCREL64LSB:
2377 need_entry = NEED_DYNREL;
2378 dynrel_type = R_IA64_PCREL64LSB;
2385 if ((need_entry & NEED_FPTR) != 0
2388 (*info->callbacks->warning)
2389 (info, _("non-zero addend in @fptr reloc"), 0,
2390 abfd, 0, (bfd_vma) 0);
2393 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE);
2395 /* Record whether or not this is a local symbol. */
2398 /* Create what's needed. */
2399 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2400 | NEED_DTPMOD | NEED_DTPREL))
2404 got = get_got (abfd, info, ia64_info);
2408 if (need_entry & NEED_GOT)
2409 dyn_i->want_got = 1;
2410 if (need_entry & NEED_GOTX)
2411 dyn_i->want_gotx = 1;
2412 if (need_entry & NEED_TPREL)
2413 dyn_i->want_tprel = 1;
2414 if (need_entry & NEED_DTPMOD)
2415 dyn_i->want_dtpmod = 1;
2416 if (need_entry & NEED_DTPREL)
2417 dyn_i->want_dtprel = 1;
2419 if (need_entry & NEED_FPTR)
2423 fptr = get_fptr (abfd, info, ia64_info);
2428 /* FPTRs for shared libraries are allocated by the dynamic
2429 linker. Make sure this local symbol will appear in the
2430 dynamic symbol table. */
2431 if (!h && (info->shared
2432 /* AIX also needs one */
2433 || elfNN_ia64_aix_vec (abfd->xvec)))
2435 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2436 (info, abfd, (long) r_symndx)))
2440 dyn_i->want_fptr = 1;
2442 if (need_entry & NEED_LTOFF_FPTR)
2443 dyn_i->want_ltoff_fptr = 1;
2444 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2446 if (!ia64_info->root.dynobj)
2447 ia64_info->root.dynobj = abfd;
2448 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2449 dyn_i->want_plt = 1;
2451 if (need_entry & NEED_FULL_PLT)
2452 dyn_i->want_plt2 = 1;
2453 if (need_entry & NEED_PLTOFF)
2454 dyn_i->want_pltoff = 1;
2455 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2459 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
2463 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2471 /* For cleanliness, and potentially faster dynamic loading, allocate
2472 external GOT entries first. */
2475 allocate_global_data_got (dyn_i, data)
2476 struct elfNN_ia64_dyn_sym_info *dyn_i;
2479 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2481 if ((dyn_i->want_got || dyn_i->want_gotx)
2482 && ! dyn_i->want_fptr
2483 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2484 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2485 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2486 "__GLOB_DATA_PTR") != 0))))
2488 dyn_i->got_offset = x->ofs;
2491 if (dyn_i->want_tprel)
2493 dyn_i->tprel_offset = x->ofs;
2496 if (dyn_i->want_dtpmod)
2498 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
2500 dyn_i->dtpmod_offset = x->ofs;
2505 struct elfNN_ia64_link_hash_table *ia64_info;
2507 ia64_info = elfNN_ia64_hash_table (x->info);
2508 if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
2510 ia64_info->self_dtpmod_offset = x->ofs;
2513 dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
2516 if (dyn_i->want_dtprel)
2518 dyn_i->dtprel_offset = x->ofs;
2524 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2527 allocate_global_fptr_got (dyn_i, data)
2528 struct elfNN_ia64_dyn_sym_info *dyn_i;
2531 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2535 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2536 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2538 dyn_i->got_offset = x->ofs;
2544 /* Lastly, allocate all the GOT entries for local data. */
2547 allocate_local_got (dyn_i, data)
2548 struct elfNN_ia64_dyn_sym_info *dyn_i;
2551 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2553 if ((dyn_i->want_got || dyn_i->want_gotx)
2554 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2555 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2557 dyn_i->got_offset = x->ofs;
2563 /* Search for the index of a global symbol in it's defining object file. */
2566 global_sym_index (h)
2567 struct elf_link_hash_entry *h;
2569 struct elf_link_hash_entry **p;
2572 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2573 || h->root.type == bfd_link_hash_defweak);
2575 obj = h->root.u.def.section->owner;
2576 for (p = elf_sym_hashes (obj); *p != h; ++p)
2579 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2582 /* Allocate function descriptors. We can do these for every function
2583 in a main executable that is not exported. */
2586 allocate_fptr (dyn_i, data)
2587 struct elfNN_ia64_dyn_sym_info *dyn_i;
2590 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2592 if (dyn_i->want_fptr)
2594 struct elf_link_hash_entry *h = dyn_i->h;
2597 while (h->root.type == bfd_link_hash_indirect
2598 || h->root.type == bfd_link_hash_warning)
2599 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2602 /* AIX needs an FPTR in this case. */
2603 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2605 || h->root.type == bfd_link_hash_defined
2606 || h->root.type == bfd_link_hash_defweak)))
2608 if (h && h->dynindx == -1)
2610 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2611 || (h->root.type == bfd_link_hash_defweak));
2613 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2614 (x->info, h->root.u.def.section->owner,
2615 global_sym_index (h)))
2619 dyn_i->want_fptr = 0;
2621 else if (h == NULL || h->dynindx == -1)
2623 dyn_i->fptr_offset = x->ofs;
2627 dyn_i->want_fptr = 0;
2632 /* Allocate all the minimal PLT entries. */
2635 allocate_plt_entries (dyn_i, data)
2636 struct elfNN_ia64_dyn_sym_info *dyn_i;
2639 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2641 if (dyn_i->want_plt)
2643 struct elf_link_hash_entry *h = dyn_i->h;
2646 while (h->root.type == bfd_link_hash_indirect
2647 || h->root.type == bfd_link_hash_warning)
2648 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2650 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2651 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2653 bfd_size_type offset = x->ofs;
2655 offset = PLT_HEADER_SIZE;
2656 dyn_i->plt_offset = offset;
2657 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2659 dyn_i->want_pltoff = 1;
2663 dyn_i->want_plt = 0;
2664 dyn_i->want_plt2 = 0;
2670 /* Allocate all the full PLT entries. */
2673 allocate_plt2_entries (dyn_i, data)
2674 struct elfNN_ia64_dyn_sym_info *dyn_i;
2677 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2679 if (dyn_i->want_plt2)
2681 struct elf_link_hash_entry *h = dyn_i->h;
2682 bfd_size_type ofs = x->ofs;
2684 dyn_i->plt2_offset = ofs;
2685 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2687 while (h->root.type == bfd_link_hash_indirect
2688 || h->root.type == bfd_link_hash_warning)
2689 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2690 dyn_i->h->plt.offset = ofs;
2695 /* Allocate all the PLTOFF entries requested by relocations and
2696 plt entries. We can't share space with allocated FPTR entries,
2697 because the latter are not necessarily addressable by the GP.
2698 ??? Relaxation might be able to determine that they are. */
2701 allocate_pltoff_entries (dyn_i, data)
2702 struct elfNN_ia64_dyn_sym_info *dyn_i;
2705 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2707 if (dyn_i->want_pltoff)
2709 dyn_i->pltoff_offset = x->ofs;
2715 /* Allocate dynamic relocations for those symbols that turned out
2719 allocate_dynrel_entries (dyn_i, data)
2720 struct elfNN_ia64_dyn_sym_info *dyn_i;
2723 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2724 struct elfNN_ia64_link_hash_table *ia64_info;
2725 struct elfNN_ia64_dyn_reloc_entry *rent;
2726 bfd_boolean dynamic_symbol, shared;
2728 ia64_info = elfNN_ia64_hash_table (x->info);
2729 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2730 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2731 /* Don't allocate an entry for __GLOB_DATA_PTR */
2732 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2733 "__GLOB_DATA_PTR") != 0));
2734 shared = x->info->shared;
2736 /* Take care of the normal data relocations. */
2738 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2740 int count = rent->count;
2744 case R_IA64_FPTR64LSB:
2745 /* Allocate one iff !want_fptr, which by this point will
2746 be true only if we're actually allocating one statically
2747 in the main executable. */
2748 if (dyn_i->want_fptr)
2751 case R_IA64_PCREL64LSB:
2752 if (!dynamic_symbol)
2755 case R_IA64_DIR64LSB:
2756 if (!dynamic_symbol && !shared)
2759 case R_IA64_IPLTLSB:
2760 if (!dynamic_symbol && !shared)
2762 /* Use two REL relocations for IPLT relocations
2763 against local symbols. */
2764 if (!dynamic_symbol)
2767 case R_IA64_TPREL64LSB:
2768 case R_IA64_DTPREL64LSB:
2769 case R_IA64_DTPMOD64LSB:
2774 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2777 /* Take care of the GOT and PLT relocations. */
2779 if (((dynamic_symbol || shared) && (dyn_i->want_got || dyn_i->want_gotx))
2780 || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2781 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2782 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2783 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2784 if (dynamic_symbol && dyn_i->want_dtpmod)
2785 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2786 if (dynamic_symbol && dyn_i->want_dtprel)
2787 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2789 if (dyn_i->want_pltoff)
2791 bfd_size_type t = 0;
2793 /* Dynamic symbols get one IPLT relocation. Local symbols in
2794 shared libraries get two REL relocations. Local symbols in
2795 main applications get nothing. */
2797 t = sizeof (ElfNN_External_Rela);
2799 t = 2 * sizeof (ElfNN_External_Rela);
2801 ia64_info->rel_pltoff_sec->_raw_size += t;
2808 elfNN_ia64_adjust_dynamic_symbol (info, h)
2809 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2810 struct elf_link_hash_entry *h;
2812 /* ??? Undefined symbols with PLT entries should be re-defined
2813 to be the PLT entry. */
2815 /* If this is a weak symbol, and there is a real definition, the
2816 processor independent code will have arranged for us to see the
2817 real definition first, and we can just use the same value. */
2818 if (h->weakdef != NULL)
2820 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2821 || h->weakdef->root.type == bfd_link_hash_defweak);
2822 h->root.u.def.section = h->weakdef->root.u.def.section;
2823 h->root.u.def.value = h->weakdef->root.u.def.value;
2827 /* If this is a reference to a symbol defined by a dynamic object which
2828 is not a function, we might allocate the symbol in our .dynbss section
2829 and allocate a COPY dynamic relocation.
2831 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2838 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2840 struct bfd_link_info *info;
2842 struct elfNN_ia64_allocate_data data;
2843 struct elfNN_ia64_link_hash_table *ia64_info;
2846 bfd_boolean relplt = FALSE;
2848 dynobj = elf_hash_table(info)->dynobj;
2849 ia64_info = elfNN_ia64_hash_table (info);
2850 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
2851 BFD_ASSERT(dynobj != NULL);
2854 /* Set the contents of the .interp section to the interpreter. */
2855 if (ia64_info->root.dynamic_sections_created
2858 sec = bfd_get_section_by_name (dynobj, ".interp");
2859 BFD_ASSERT (sec != NULL);
2860 sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd);
2861 sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1;
2864 /* Allocate the GOT entries. */
2866 if (ia64_info->got_sec)
2869 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2870 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2871 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2872 ia64_info->got_sec->_raw_size = data.ofs;
2875 /* Allocate the FPTR entries. */
2877 if (ia64_info->fptr_sec)
2880 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2881 ia64_info->fptr_sec->_raw_size = data.ofs;
2884 /* Now that we've seen all of the input files, we can decide which
2885 symbols need plt entries. Allocate the minimal PLT entries first.
2886 We do this even though dynamic_sections_created may be FALSE, because
2887 this has the side-effect of clearing want_plt and want_plt2. */
2890 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2892 ia64_info->minplt_entries = 0;
2895 ia64_info->minplt_entries
2896 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2899 /* Align the pointer for the plt2 entries. */
2900 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2902 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2905 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2907 ia64_info->plt_sec->_raw_size = data.ofs;
2909 /* If we've got a .plt, we need some extra memory for the dynamic
2910 linker. We stuff these in .got.plt. */
2911 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2912 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2915 /* Allocate the PLTOFF entries. */
2917 if (ia64_info->pltoff_sec)
2920 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2921 ia64_info->pltoff_sec->_raw_size = data.ofs;
2924 if (ia64_info->root.dynamic_sections_created)
2926 /* Allocate space for the dynamic relocations that turned out to be
2929 if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
2930 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2931 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2934 /* We have now determined the sizes of the various dynamic sections.
2935 Allocate memory for them. */
2936 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2940 if (!(sec->flags & SEC_LINKER_CREATED))
2943 /* If we don't need this section, strip it from the output file.
2944 There were several sections primarily related to dynamic
2945 linking that must be create before the linker maps input
2946 sections to output sections. The linker does that before
2947 bfd_elf_size_dynamic_sections is called, and it is that
2948 function which decides whether anything needs to go into
2951 strip = (sec->_raw_size == 0);
2953 if (sec == ia64_info->got_sec)
2955 else if (sec == ia64_info->rel_got_sec)
2958 ia64_info->rel_got_sec = NULL;
2960 /* We use the reloc_count field as a counter if we need to
2961 copy relocs into the output file. */
2962 sec->reloc_count = 0;
2964 else if (sec == ia64_info->fptr_sec)
2967 ia64_info->fptr_sec = NULL;
2969 else if (sec == ia64_info->plt_sec)
2972 ia64_info->plt_sec = NULL;
2974 else if (sec == ia64_info->pltoff_sec)
2977 ia64_info->pltoff_sec = NULL;
2979 else if (sec == ia64_info->rel_pltoff_sec)
2982 ia64_info->rel_pltoff_sec = NULL;
2986 /* We use the reloc_count field as a counter if we need to
2987 copy relocs into the output file. */
2988 sec->reloc_count = 0;
2995 /* It's OK to base decisions on the section name, because none
2996 of the dynobj section names depend upon the input files. */
2997 name = bfd_get_section_name (dynobj, sec);
2999 if (strcmp (name, ".got.plt") == 0)
3001 else if (strncmp (name, ".rel", 4) == 0)
3005 /* We use the reloc_count field as a counter if we need to
3006 copy relocs into the output file. */
3007 sec->reloc_count = 0;
3015 _bfd_strip_section_from_output (info, sec);
3018 /* Allocate memory for the section contents. */
3019 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
3020 if (sec->contents == NULL && sec->_raw_size != 0)
3025 if (elf_hash_table (info)->dynamic_sections_created)
3027 /* Add some entries to the .dynamic section. We fill in the values
3028 later (in finish_dynamic_sections) but we must add the entries now
3029 so that we get the correct size for the .dynamic section. */
3033 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3035 #define add_dynamic_entry(TAG, VAL) \
3036 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
3038 if (!add_dynamic_entry (DT_DEBUG, 0))
3042 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3044 if (!add_dynamic_entry (DT_PLTGOT, 0))
3049 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3050 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3051 || !add_dynamic_entry (DT_JMPREL, 0))
3055 if (!add_dynamic_entry (DT_RELA, 0)
3056 || !add_dynamic_entry (DT_RELASZ, 0)
3057 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3060 if (ia64_info->reltext)
3062 if (!add_dynamic_entry (DT_TEXTREL, 0))
3064 info->flags |= DF_TEXTREL;
3068 /* ??? Perhaps force __gp local. */
3073 static bfd_reloc_status_type
3074 elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
3078 unsigned int r_type;
3080 const struct ia64_operand *op;
3081 int bigendian = 0, shift = 0;
3082 bfd_vma t0, t1, insn, dword;
3083 enum ia64_opnd opnd;
3086 #ifdef BFD_HOST_U_64_BIT
3087 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3092 opnd = IA64_OPND_NIL;
3097 return bfd_reloc_ok;
3099 /* Instruction relocations. */
3102 case R_IA64_TPREL14:
3103 case R_IA64_DTPREL14:
3104 opnd = IA64_OPND_IMM14;
3107 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
3108 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
3109 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
3110 case R_IA64_PCREL21B:
3111 case R_IA64_PCREL21BI:
3112 opnd = IA64_OPND_TGT25c;
3116 case R_IA64_GPREL22:
3117 case R_IA64_LTOFF22:
3118 case R_IA64_LTOFF22X:
3119 case R_IA64_PLTOFF22:
3120 case R_IA64_PCREL22:
3121 case R_IA64_LTOFF_FPTR22:
3122 case R_IA64_TPREL22:
3123 case R_IA64_DTPREL22:
3124 case R_IA64_LTOFF_TPREL22:
3125 case R_IA64_LTOFF_DTPMOD22:
3126 case R_IA64_LTOFF_DTPREL22:
3127 opnd = IA64_OPND_IMM22;
3131 case R_IA64_GPREL64I:
3132 case R_IA64_LTOFF64I:
3133 case R_IA64_PLTOFF64I:
3134 case R_IA64_PCREL64I:
3135 case R_IA64_FPTR64I:
3136 case R_IA64_LTOFF_FPTR64I:
3137 case R_IA64_TPREL64I:
3138 case R_IA64_DTPREL64I:
3139 opnd = IA64_OPND_IMMU64;
3142 /* Data relocations. */
3144 case R_IA64_DIR32MSB:
3145 case R_IA64_GPREL32MSB:
3146 case R_IA64_FPTR32MSB:
3147 case R_IA64_PCREL32MSB:
3148 case R_IA64_LTOFF_FPTR32MSB:
3149 case R_IA64_SEGREL32MSB:
3150 case R_IA64_SECREL32MSB:
3151 case R_IA64_LTV32MSB:
3152 case R_IA64_DTPREL32MSB:
3153 size = 4; bigendian = 1;
3156 case R_IA64_DIR32LSB:
3157 case R_IA64_GPREL32LSB:
3158 case R_IA64_FPTR32LSB:
3159 case R_IA64_PCREL32LSB:
3160 case R_IA64_LTOFF_FPTR32LSB:
3161 case R_IA64_SEGREL32LSB:
3162 case R_IA64_SECREL32LSB:
3163 case R_IA64_LTV32LSB:
3164 case R_IA64_DTPREL32LSB:
3165 size = 4; bigendian = 0;
3168 case R_IA64_DIR64MSB:
3169 case R_IA64_GPREL64MSB:
3170 case R_IA64_PLTOFF64MSB:
3171 case R_IA64_FPTR64MSB:
3172 case R_IA64_PCREL64MSB:
3173 case R_IA64_LTOFF_FPTR64MSB:
3174 case R_IA64_SEGREL64MSB:
3175 case R_IA64_SECREL64MSB:
3176 case R_IA64_LTV64MSB:
3177 case R_IA64_TPREL64MSB:
3178 case R_IA64_DTPMOD64MSB:
3179 case R_IA64_DTPREL64MSB:
3180 size = 8; bigendian = 1;
3183 case R_IA64_DIR64LSB:
3184 case R_IA64_GPREL64LSB:
3185 case R_IA64_PLTOFF64LSB:
3186 case R_IA64_FPTR64LSB:
3187 case R_IA64_PCREL64LSB:
3188 case R_IA64_LTOFF_FPTR64LSB:
3189 case R_IA64_SEGREL64LSB:
3190 case R_IA64_SECREL64LSB:
3191 case R_IA64_LTV64LSB:
3192 case R_IA64_TPREL64LSB:
3193 case R_IA64_DTPMOD64LSB:
3194 case R_IA64_DTPREL64LSB:
3195 size = 8; bigendian = 0;
3198 /* Unsupported / Dynamic relocations. */
3200 return bfd_reloc_notsupported;
3205 case IA64_OPND_IMMU64:
3206 hit_addr -= (long) hit_addr & 0x3;
3207 t0 = bfd_get_64 (abfd, hit_addr);
3208 t1 = bfd_get_64 (abfd, hit_addr + 8);
3210 /* tmpl/s: bits 0.. 5 in t0
3211 slot 0: bits 5..45 in t0
3212 slot 1: bits 46..63 in t0, bits 0..22 in t1
3213 slot 2: bits 23..63 in t1 */
3215 /* First, clear the bits that form the 64 bit constant. */
3216 t0 &= ~(0x3ffffLL << 46);
3218 | (( (0x07fLL << 13) | (0x1ffLL << 27)
3219 | (0x01fLL << 22) | (0x001LL << 21)
3220 | (0x001LL << 36)) << 23));
3222 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
3223 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
3224 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
3225 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
3226 | (((val >> 16) & 0x01f) << 22) /* imm5c */
3227 | (((val >> 21) & 0x001) << 21) /* ic */
3228 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
3230 bfd_put_64 (abfd, t0, hit_addr);
3231 bfd_put_64 (abfd, t1, hit_addr + 8);
3234 case IA64_OPND_TGT64:
3235 hit_addr -= (long) hit_addr & 0x3;
3236 t0 = bfd_get_64 (abfd, hit_addr);
3237 t1 = bfd_get_64 (abfd, hit_addr + 8);
3239 /* tmpl/s: bits 0.. 5 in t0
3240 slot 0: bits 5..45 in t0
3241 slot 1: bits 46..63 in t0, bits 0..22 in t1
3242 slot 2: bits 23..63 in t1 */
3244 /* First, clear the bits that form the 64 bit constant. */
3245 t0 &= ~(0x3ffffLL << 46);
3247 | ((1LL << 36 | 0xfffffLL << 13) << 23));
3250 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
3251 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
3252 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
3253 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
3255 bfd_put_64 (abfd, t0, hit_addr);
3256 bfd_put_64 (abfd, t1, hit_addr + 8);
3260 switch ((long) hit_addr & 0x3)
3262 case 0: shift = 5; break;
3263 case 1: shift = 14; hit_addr += 3; break;
3264 case 2: shift = 23; hit_addr += 6; break;
3265 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
3267 dword = bfd_get_64 (abfd, hit_addr);
3268 insn = (dword >> shift) & 0x1ffffffffffLL;
3270 op = elf64_ia64_operands + opnd;
3271 err = (*op->insert) (op, val, (ia64_insn *)& insn);
3273 return bfd_reloc_overflow;
3275 dword &= ~(0x1ffffffffffLL << shift);
3276 dword |= (insn << shift);
3277 bfd_put_64 (abfd, dword, hit_addr);
3281 /* A data relocation. */
3284 bfd_putb32 (val, hit_addr);
3286 bfd_putb64 (val, hit_addr);
3289 bfd_putl32 (val, hit_addr);
3291 bfd_putl64 (val, hit_addr);
3295 return bfd_reloc_ok;
3299 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3302 struct bfd_link_info *info;
3310 Elf_Internal_Rela outrel;
3313 BFD_ASSERT (dynindx != -1);
3314 outrel.r_info = ELFNN_R_INFO (dynindx, type);
3315 outrel.r_addend = addend;
3316 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3317 if (outrel.r_offset >= (bfd_vma) -2)
3319 /* Run for the hills. We shouldn't be outputting a relocation
3320 for this. So do what everyone else does and output a no-op. */
3321 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3322 outrel.r_addend = 0;
3323 outrel.r_offset = 0;
3326 outrel.r_offset += sec->output_section->vma + sec->output_offset;
3328 loc = srel->contents;
3329 loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3330 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3331 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3332 <= srel->_cooked_size);
3335 /* Store an entry for target address TARGET_ADDR in the linkage table
3336 and return the gp-relative address of the linkage table entry. */
3339 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3341 struct bfd_link_info *info;
3342 struct elfNN_ia64_dyn_sym_info *dyn_i;
3346 unsigned int dyn_r_type;
3348 struct elfNN_ia64_link_hash_table *ia64_info;
3353 ia64_info = elfNN_ia64_hash_table (info);
3354 got_sec = ia64_info->got_sec;
3358 case R_IA64_TPREL64LSB:
3359 done = dyn_i->tprel_done;
3360 dyn_i->tprel_done = TRUE;
3361 got_offset = dyn_i->tprel_offset;
3363 case R_IA64_DTPMOD64LSB:
3364 if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3366 done = dyn_i->dtpmod_done;
3367 dyn_i->dtpmod_done = TRUE;
3371 done = ia64_info->self_dtpmod_done;
3372 ia64_info->self_dtpmod_done = TRUE;
3375 got_offset = dyn_i->dtpmod_offset;
3377 case R_IA64_DTPREL64LSB:
3378 done = dyn_i->dtprel_done;
3379 dyn_i->dtprel_done = TRUE;
3380 got_offset = dyn_i->dtprel_offset;
3383 done = dyn_i->got_done;
3384 dyn_i->got_done = TRUE;
3385 got_offset = dyn_i->got_offset;
3389 BFD_ASSERT ((got_offset & 7) == 0);
3393 /* Store the target address in the linkage table entry. */
3394 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3396 /* Install a dynamic relocation if needed. */
3397 if ((info->shared && dyn_r_type != R_IA64_DTPREL64LSB)
3398 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
3399 || elfNN_ia64_aix_vec (abfd->xvec)
3400 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3403 && dyn_r_type != R_IA64_TPREL64LSB
3404 && dyn_r_type != R_IA64_DTPMOD64LSB
3405 && dyn_r_type != R_IA64_DTPREL64LSB)
3407 dyn_r_type = R_IA64_REL64LSB;
3412 if (bfd_big_endian (abfd))
3416 case R_IA64_REL64LSB:
3417 dyn_r_type = R_IA64_REL64MSB;
3419 case R_IA64_DIR64LSB:
3420 dyn_r_type = R_IA64_DIR64MSB;
3422 case R_IA64_FPTR64LSB:
3423 dyn_r_type = R_IA64_FPTR64MSB;
3425 case R_IA64_TPREL64LSB:
3426 dyn_r_type = R_IA64_TPREL64MSB;
3428 case R_IA64_DTPMOD64LSB:
3429 dyn_r_type = R_IA64_DTPMOD64MSB;
3431 case R_IA64_DTPREL64LSB:
3432 dyn_r_type = R_IA64_DTPREL64MSB;
3440 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3441 ia64_info->rel_got_sec,
3442 got_offset, dyn_r_type,
3447 /* Return the address of the linkage table entry. */
3448 value = (got_sec->output_section->vma
3449 + got_sec->output_offset
3455 /* Fill in a function descriptor consisting of the function's code
3456 address and its global pointer. Return the descriptor's address. */
3459 set_fptr_entry (abfd, info, dyn_i, value)
3461 struct bfd_link_info *info;
3462 struct elfNN_ia64_dyn_sym_info *dyn_i;
3465 struct elfNN_ia64_link_hash_table *ia64_info;
3468 ia64_info = elfNN_ia64_hash_table (info);
3469 fptr_sec = ia64_info->fptr_sec;
3471 if (!dyn_i->fptr_done)
3473 dyn_i->fptr_done = 1;
3475 /* Fill in the function descriptor. */
3476 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3477 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3478 fptr_sec->contents + dyn_i->fptr_offset + 8);
3481 /* Return the descriptor's address. */
3482 value = (fptr_sec->output_section->vma
3483 + fptr_sec->output_offset
3484 + dyn_i->fptr_offset);
3489 /* Fill in a PLTOFF entry consisting of the function's code address
3490 and its global pointer. Return the descriptor's address. */
3493 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3495 struct bfd_link_info *info;
3496 struct elfNN_ia64_dyn_sym_info *dyn_i;
3500 struct elfNN_ia64_link_hash_table *ia64_info;
3501 asection *pltoff_sec;
3503 ia64_info = elfNN_ia64_hash_table (info);
3504 pltoff_sec = ia64_info->pltoff_sec;
3506 /* Don't do anything if this symbol uses a real PLT entry. In
3507 that case, we'll fill this in during finish_dynamic_symbol. */
3508 if ((! dyn_i->want_plt || is_plt)
3509 && !dyn_i->pltoff_done)
3511 bfd_vma gp = _bfd_get_gp_value (abfd);
3513 /* Fill in the function descriptor. */
3514 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3515 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3517 /* Install dynamic relocations if needed. */
3518 if (!is_plt && info->shared)
3520 unsigned int dyn_r_type;
3522 if (bfd_big_endian (abfd))
3523 dyn_r_type = R_IA64_REL64MSB;
3525 dyn_r_type = R_IA64_REL64LSB;
3527 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3528 ia64_info->rel_pltoff_sec,
3529 dyn_i->pltoff_offset,
3530 dyn_r_type, 0, value);
3531 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3532 ia64_info->rel_pltoff_sec,
3533 dyn_i->pltoff_offset + 8,
3537 dyn_i->pltoff_done = 1;
3540 /* Return the descriptor's address. */
3541 value = (pltoff_sec->output_section->vma
3542 + pltoff_sec->output_offset
3543 + dyn_i->pltoff_offset);
3548 /* Return the base VMA address which should be subtracted from real addresses
3549 when resolving @tprel() relocation.
3550 Main program TLS (whose template starts at PT_TLS p_vaddr)
3551 is assigned offset round(16, PT_TLS p_align). */
3554 elfNN_ia64_tprel_base (info)
3555 struct bfd_link_info *info;
3557 struct elf_link_tls_segment *tls_segment
3558 = elf_hash_table (info)->tls_segment;
3560 BFD_ASSERT (tls_segment != NULL);
3561 return (tls_segment->start
3562 - align_power ((bfd_vma) 16, tls_segment->align));
3565 /* Return the base VMA address which should be subtracted from real addresses
3566 when resolving @dtprel() relocation.
3567 This is PT_TLS segment p_vaddr. */
3570 elfNN_ia64_dtprel_base (info)
3571 struct bfd_link_info *info;
3573 BFD_ASSERT (elf_hash_table (info)->tls_segment != NULL);
3574 return elf_hash_table (info)->tls_segment->start;
3577 /* Called through qsort to sort the .IA_64.unwind section during a
3578 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3579 to the output bfd so we can do proper endianness frobbing. */
3581 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3584 elfNN_ia64_unwind_entry_compare (a, b)
3590 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3591 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3593 return (av < bv ? -1 : av > bv ? 1 : 0);
3596 /* Make sure we've got ourselves a nice fat __gp value. */
3598 elfNN_ia64_choose_gp (abfd, info)
3600 struct bfd_link_info *info;
3602 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3603 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3604 struct elf_link_hash_entry *gp;
3607 struct elfNN_ia64_link_hash_table *ia64_info;
3609 ia64_info = elfNN_ia64_hash_table (info);
3611 /* Find the min and max vma of all sections marked short. Also collect
3612 min and max vma of any type, for use in selecting a nice gp. */
3613 for (os = abfd->sections; os ; os = os->next)
3617 if ((os->flags & SEC_ALLOC) == 0)
3621 hi = os->vma + os->_raw_size;
3629 if (os->flags & SEC_SMALL_DATA)
3631 if (min_short_vma > lo)
3633 if (max_short_vma < hi)
3638 /* See if the user wants to force a value. */
3639 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3643 && (gp->root.type == bfd_link_hash_defined
3644 || gp->root.type == bfd_link_hash_defweak))
3646 asection *gp_sec = gp->root.u.def.section;
3647 gp_val = (gp->root.u.def.value
3648 + gp_sec->output_section->vma
3649 + gp_sec->output_offset);
3653 /* Pick a sensible value. */
3655 asection *got_sec = ia64_info->got_sec;
3657 /* Start with just the address of the .got. */
3659 gp_val = got_sec->output_section->vma;
3660 else if (max_short_vma != 0)
3661 gp_val = min_short_vma;
3665 /* If it is possible to address the entire image, but we
3666 don't with the choice above, adjust. */
3667 if (max_vma - min_vma < 0x400000
3668 && max_vma - gp_val <= 0x200000
3669 && gp_val - min_vma > 0x200000)
3670 gp_val = min_vma + 0x200000;
3671 else if (max_short_vma != 0)
3673 /* If we don't cover all the short data, adjust. */
3674 if (max_short_vma - gp_val >= 0x200000)
3675 gp_val = min_short_vma + 0x200000;
3677 /* If we're addressing stuff past the end, adjust back. */
3678 if (gp_val > max_vma)
3679 gp_val = max_vma - 0x200000 + 8;
3683 /* Validate whether all SHF_IA_64_SHORT sections are within
3684 range of the chosen GP. */
3686 if (max_short_vma != 0)
3688 if (max_short_vma - min_short_vma >= 0x400000)
3690 (*_bfd_error_handler)
3691 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3692 bfd_get_filename (abfd),
3693 (unsigned long) (max_short_vma - min_short_vma));
3696 else if ((gp_val > min_short_vma
3697 && gp_val - min_short_vma > 0x200000)
3698 || (gp_val < max_short_vma
3699 && max_short_vma - gp_val >= 0x200000))
3701 (*_bfd_error_handler)
3702 (_("%s: __gp does not cover short data segment"),
3703 bfd_get_filename (abfd));
3708 _bfd_set_gp_value (abfd, gp_val);
3714 elfNN_ia64_final_link (abfd, info)
3716 struct bfd_link_info *info;
3718 struct elfNN_ia64_link_hash_table *ia64_info;
3719 asection *unwind_output_sec;
3721 ia64_info = elfNN_ia64_hash_table (info);
3723 /* Make sure we've got ourselves a nice fat __gp value. */
3724 if (!info->relocateable)
3726 bfd_vma gp_val = _bfd_get_gp_value (abfd);
3727 struct elf_link_hash_entry *gp;
3731 if (! elfNN_ia64_choose_gp (abfd, info))
3733 gp_val = _bfd_get_gp_value (abfd);
3736 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3740 gp->root.type = bfd_link_hash_defined;
3741 gp->root.u.def.value = gp_val;
3742 gp->root.u.def.section = bfd_abs_section_ptr;
3746 /* If we're producing a final executable, we need to sort the contents
3747 of the .IA_64.unwind section. Force this section to be relocated
3748 into memory rather than written immediately to the output file. */
3749 unwind_output_sec = NULL;
3750 if (!info->relocateable)
3752 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3755 unwind_output_sec = s->output_section;
3756 unwind_output_sec->contents
3757 = bfd_malloc (unwind_output_sec->_raw_size);
3758 if (unwind_output_sec->contents == NULL)
3763 /* Invoke the regular ELF backend linker to do all the work. */
3764 if (!bfd_elfNN_bfd_final_link (abfd, info))
3767 if (unwind_output_sec)
3769 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3770 qsort (unwind_output_sec->contents,
3771 (size_t) (unwind_output_sec->_raw_size / 24),
3773 elfNN_ia64_unwind_entry_compare);
3775 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3776 unwind_output_sec->contents, (bfd_vma) 0,
3777 unwind_output_sec->_raw_size))
3785 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3786 contents, relocs, local_syms, local_sections)
3788 struct bfd_link_info *info;
3790 asection *input_section;
3792 Elf_Internal_Rela *relocs;
3793 Elf_Internal_Sym *local_syms;
3794 asection **local_sections;
3796 struct elfNN_ia64_link_hash_table *ia64_info;
3797 Elf_Internal_Shdr *symtab_hdr;
3798 Elf_Internal_Rela *rel;
3799 Elf_Internal_Rela *relend;
3801 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
3804 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3805 ia64_info = elfNN_ia64_hash_table (info);
3807 /* Infect various flags from the input section to the output section. */
3808 if (info->relocateable)
3812 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3813 flags &= SHF_IA_64_NORECOV;
3815 elf_section_data(input_section->output_section)
3816 ->this_hdr.sh_flags |= flags;
3820 gp_val = _bfd_get_gp_value (output_bfd);
3821 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
3824 relend = relocs + input_section->reloc_count;
3825 for (; rel < relend; ++rel)
3827 struct elf_link_hash_entry *h;
3828 struct elfNN_ia64_dyn_sym_info *dyn_i;
3829 bfd_reloc_status_type r;
3830 reloc_howto_type *howto;
3831 unsigned long r_symndx;
3832 Elf_Internal_Sym *sym;
3833 unsigned int r_type;
3837 bfd_boolean dynamic_symbol_p;
3838 bfd_boolean undef_weak_ref;
3840 r_type = ELFNN_R_TYPE (rel->r_info);
3841 if (r_type > R_IA64_MAX_RELOC_CODE)
3843 (*_bfd_error_handler)
3844 (_("%s: unknown relocation type %d"),
3845 bfd_archive_filename (input_bfd), (int)r_type);
3846 bfd_set_error (bfd_error_bad_value);
3851 howto = lookup_howto (r_type);
3852 r_symndx = ELFNN_R_SYM (rel->r_info);
3856 undef_weak_ref = FALSE;
3858 if (r_symndx < symtab_hdr->sh_info)
3860 /* Reloc against local symbol. */
3861 sym = local_syms + r_symndx;
3862 sym_sec = local_sections[r_symndx];
3863 value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel);
3864 if ((sym_sec->flags & SEC_MERGE)
3865 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3866 && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
3868 struct elfNN_ia64_local_hash_entry *loc_h;
3870 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
3871 if (loc_h && ! loc_h->sec_merge_done)
3873 struct elfNN_ia64_dyn_sym_info *dynent;
3876 for (dynent = loc_h->info; dynent; dynent = dynent->next)
3880 _bfd_merged_section_offset (output_bfd, &msec,
3881 elf_section_data (msec)->
3886 dynent->addend -= sym->st_value;
3887 dynent->addend += msec->output_section->vma
3888 + msec->output_offset
3889 - sym_sec->output_section->vma
3890 - sym_sec->output_offset;
3892 loc_h->sec_merge_done = 1;
3900 /* Reloc against global symbol. */
3901 indx = r_symndx - symtab_hdr->sh_info;
3902 h = elf_sym_hashes (input_bfd)[indx];
3903 while (h->root.type == bfd_link_hash_indirect
3904 || h->root.type == bfd_link_hash_warning)
3905 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3908 if (h->root.type == bfd_link_hash_defined
3909 || h->root.type == bfd_link_hash_defweak)
3911 sym_sec = h->root.u.def.section;
3913 /* Detect the cases that sym_sec->output_section is
3914 expected to be NULL -- all cases in which the symbol
3915 is defined in another shared module. This includes
3916 PLT relocs for which we've created a PLT entry and
3917 other relocs for which we're prepared to create
3918 dynamic relocations. */
3919 /* ??? Just accept it NULL and continue. */
3921 if (sym_sec->output_section != NULL)
3923 value = (h->root.u.def.value
3924 + sym_sec->output_section->vma
3925 + sym_sec->output_offset);
3928 else if (h->root.type == bfd_link_hash_undefweak)
3929 undef_weak_ref = TRUE;
3930 else if (info->shared
3931 && !info->no_undefined
3932 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3936 if (! ((*info->callbacks->undefined_symbol)
3937 (info, h->root.root.string, input_bfd,
3938 input_section, rel->r_offset,
3939 (!info->shared || info->no_undefined
3940 || ELF_ST_VISIBILITY (h->other)))))
3947 hit_addr = contents + rel->r_offset;
3948 value += rel->r_addend;
3949 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3960 case R_IA64_DIR32MSB:
3961 case R_IA64_DIR32LSB:
3962 case R_IA64_DIR64MSB:
3963 case R_IA64_DIR64LSB:
3964 /* Install a dynamic relocation for this reloc. */
3965 if ((dynamic_symbol_p || info->shared
3966 || (elfNN_ia64_aix_vec (info->hash->creator)
3967 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3968 && (!h || strcmp (h->root.root.string,
3969 "__GLOB_DATA_PTR") != 0)))
3971 && (input_section->flags & SEC_ALLOC) != 0)
3973 unsigned int dyn_r_type;
3977 BFD_ASSERT (srel != NULL);
3979 /* If we don't need dynamic symbol lookup, find a
3980 matching RELATIVE relocation. */
3981 dyn_r_type = r_type;
3982 if (dynamic_symbol_p)
3984 dynindx = h->dynindx;
3985 addend = rel->r_addend;
3992 case R_IA64_DIR32MSB:
3993 dyn_r_type = R_IA64_REL32MSB;
3995 case R_IA64_DIR32LSB:
3996 dyn_r_type = R_IA64_REL32LSB;
3998 case R_IA64_DIR64MSB:
3999 dyn_r_type = R_IA64_REL64MSB;
4001 case R_IA64_DIR64LSB:
4002 dyn_r_type = R_IA64_REL64LSB;
4006 /* We can't represent this without a dynamic symbol.
4007 Adjust the relocation to be against an output
4008 section symbol, which are always present in the
4009 dynamic symbol table. */
4010 /* ??? People shouldn't be doing non-pic code in
4011 shared libraries. Hork. */
4012 (*_bfd_error_handler)
4013 (_("%s: linking non-pic code in a shared library"),
4014 bfd_archive_filename (input_bfd));
4022 if (elfNN_ia64_aix_vec (info->hash->creator))
4023 rel->r_addend = value;
4024 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4025 srel, rel->r_offset, dyn_r_type,
4030 case R_IA64_LTV32MSB:
4031 case R_IA64_LTV32LSB:
4032 case R_IA64_LTV64MSB:
4033 case R_IA64_LTV64LSB:
4034 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4037 case R_IA64_GPREL22:
4038 case R_IA64_GPREL64I:
4039 case R_IA64_GPREL32MSB:
4040 case R_IA64_GPREL32LSB:
4041 case R_IA64_GPREL64MSB:
4042 case R_IA64_GPREL64LSB:
4043 if (dynamic_symbol_p)
4045 (*_bfd_error_handler)
4046 (_("%s: @gprel relocation against dynamic symbol %s"),
4047 bfd_archive_filename (input_bfd), h->root.root.string);
4052 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4055 case R_IA64_LTOFF22:
4056 case R_IA64_LTOFF22X:
4057 case R_IA64_LTOFF64I:
4058 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4059 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4060 rel->r_addend, value, R_IA64_DIR64LSB);
4062 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4065 case R_IA64_PLTOFF22:
4066 case R_IA64_PLTOFF64I:
4067 case R_IA64_PLTOFF64MSB:
4068 case R_IA64_PLTOFF64LSB:
4069 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4070 value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4072 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4075 case R_IA64_FPTR64I:
4076 case R_IA64_FPTR32MSB:
4077 case R_IA64_FPTR32LSB:
4078 case R_IA64_FPTR64MSB:
4079 case R_IA64_FPTR64LSB:
4080 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4081 if (dyn_i->want_fptr)
4083 if (!undef_weak_ref)
4084 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4090 /* Otherwise, we expect the dynamic linker to create
4095 if (h->dynindx != -1)
4096 dynindx = h->dynindx;
4098 dynindx = (_bfd_elf_link_lookup_local_dynindx
4099 (info, h->root.u.def.section->owner,
4100 global_sym_index (h)));
4104 dynindx = (_bfd_elf_link_lookup_local_dynindx
4105 (info, input_bfd, (long) r_symndx));
4108 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4109 srel, rel->r_offset, r_type,
4110 dynindx, rel->r_addend);
4114 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4117 case R_IA64_LTOFF_FPTR22:
4118 case R_IA64_LTOFF_FPTR64I:
4119 case R_IA64_LTOFF_FPTR32MSB:
4120 case R_IA64_LTOFF_FPTR32LSB:
4121 case R_IA64_LTOFF_FPTR64MSB:
4122 case R_IA64_LTOFF_FPTR64LSB:
4126 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4127 if (dyn_i->want_fptr)
4129 BFD_ASSERT (h == NULL || h->dynindx == -1)
4130 if (!undef_weak_ref)
4131 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4136 /* Otherwise, we expect the dynamic linker to create
4140 if (h->dynindx != -1)
4141 dynindx = h->dynindx;
4143 dynindx = (_bfd_elf_link_lookup_local_dynindx
4144 (info, h->root.u.def.section->owner,
4145 global_sym_index (h)));
4148 dynindx = (_bfd_elf_link_lookup_local_dynindx
4149 (info, input_bfd, (long) r_symndx));
4153 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4154 rel->r_addend, value, R_IA64_FPTR64LSB);
4156 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4160 case R_IA64_PCREL32MSB:
4161 case R_IA64_PCREL32LSB:
4162 case R_IA64_PCREL64MSB:
4163 case R_IA64_PCREL64LSB:
4164 /* Install a dynamic relocation for this reloc. */
4165 if ((dynamic_symbol_p
4166 || elfNN_ia64_aix_vec (info->hash->creator))
4169 BFD_ASSERT (srel != NULL);
4171 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4172 srel, rel->r_offset, r_type,
4173 h->dynindx, rel->r_addend);
4177 case R_IA64_PCREL21B:
4178 case R_IA64_PCREL60B:
4179 /* We should have created a PLT entry for any dynamic symbol. */
4182 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4184 if (dyn_i && dyn_i->want_plt2)
4186 /* Should have caught this earlier. */
4187 BFD_ASSERT (rel->r_addend == 0);
4189 value = (ia64_info->plt_sec->output_section->vma
4190 + ia64_info->plt_sec->output_offset
4191 + dyn_i->plt2_offset);
4195 /* Since there's no PLT entry, Validate that this is
4197 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4199 /* If the symbol is undef_weak, we shouldn't be trying
4200 to call it. There's every chance that we'd wind up
4201 with an out-of-range fixup here. Don't bother setting
4202 any value at all. */
4208 case R_IA64_PCREL21BI:
4209 case R_IA64_PCREL21F:
4210 case R_IA64_PCREL21M:
4211 case R_IA64_PCREL22:
4212 case R_IA64_PCREL64I:
4213 /* The PCREL21BI reloc is specifically not intended for use with
4214 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4215 fixup code, and thus probably ought not be dynamic. The
4216 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4217 if (dynamic_symbol_p)
4221 if (r_type == R_IA64_PCREL21BI)
4222 msg = _("%s: @internal branch to dynamic symbol %s");
4223 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4224 msg = _("%s: speculation fixup to dynamic symbol %s");
4226 msg = _("%s: @pcrel relocation against dynamic symbol %s");
4227 (*_bfd_error_handler) (msg, bfd_archive_filename (input_bfd),
4228 h->root.root.string);
4235 /* Make pc-relative. */
4236 value -= (input_section->output_section->vma
4237 + input_section->output_offset
4238 + rel->r_offset) & ~ (bfd_vma) 0x3;
4239 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4242 case R_IA64_SEGREL32MSB:
4243 case R_IA64_SEGREL32LSB:
4244 case R_IA64_SEGREL64MSB:
4245 case R_IA64_SEGREL64LSB:
4248 /* If the input section was discarded from the output, then
4254 struct elf_segment_map *m;
4255 Elf_Internal_Phdr *p;
4257 /* Find the segment that contains the output_section. */
4258 for (m = elf_tdata (output_bfd)->segment_map,
4259 p = elf_tdata (output_bfd)->phdr;
4264 for (i = m->count - 1; i >= 0; i--)
4265 if (m->sections[i] == sym_sec->output_section)
4273 r = bfd_reloc_notsupported;
4277 /* The VMA of the segment is the vaddr of the associated
4279 if (value > p->p_vaddr)
4280 value -= p->p_vaddr;
4283 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4289 case R_IA64_SECREL32MSB:
4290 case R_IA64_SECREL32LSB:
4291 case R_IA64_SECREL64MSB:
4292 case R_IA64_SECREL64LSB:
4293 /* Make output-section relative. */
4294 if (value > input_section->output_section->vma)
4295 value -= input_section->output_section->vma;
4298 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4301 case R_IA64_IPLTMSB:
4302 case R_IA64_IPLTLSB:
4303 /* Install a dynamic relocation for this reloc. */
4304 if ((dynamic_symbol_p || info->shared)
4305 && (input_section->flags & SEC_ALLOC) != 0)
4307 BFD_ASSERT (srel != NULL);
4309 /* If we don't need dynamic symbol lookup, install two
4310 RELATIVE relocations. */
4311 if (! dynamic_symbol_p)
4313 unsigned int dyn_r_type;
4315 if (r_type == R_IA64_IPLTMSB)
4316 dyn_r_type = R_IA64_REL64MSB;
4318 dyn_r_type = R_IA64_REL64LSB;
4320 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4322 srel, rel->r_offset,
4323 dyn_r_type, 0, value);
4324 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4326 srel, rel->r_offset + 8,
4327 dyn_r_type, 0, gp_val);
4330 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4331 srel, rel->r_offset, r_type,
4332 h->dynindx, rel->r_addend);
4335 if (r_type == R_IA64_IPLTMSB)
4336 r_type = R_IA64_DIR64MSB;
4338 r_type = R_IA64_DIR64LSB;
4339 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4340 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
4344 case R_IA64_TPREL14:
4345 case R_IA64_TPREL22:
4346 case R_IA64_TPREL64I:
4347 value -= elfNN_ia64_tprel_base (info);
4348 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4351 case R_IA64_DTPREL14:
4352 case R_IA64_DTPREL22:
4353 case R_IA64_DTPREL64I:
4354 case R_IA64_DTPREL64LSB:
4355 case R_IA64_DTPREL64MSB:
4356 value -= elfNN_ia64_dtprel_base (info);
4357 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4360 case R_IA64_LTOFF_TPREL22:
4361 case R_IA64_LTOFF_DTPMOD22:
4362 case R_IA64_LTOFF_DTPREL22:
4365 long dynindx = h ? h->dynindx : -1;
4366 bfd_vma r_addend = rel->r_addend;
4371 case R_IA64_LTOFF_TPREL22:
4372 if (!dynamic_symbol_p)
4375 value -= elfNN_ia64_tprel_base (info);
4378 r_addend += value - elfNN_ia64_dtprel_base (info);
4382 got_r_type = R_IA64_TPREL64LSB;
4384 case R_IA64_LTOFF_DTPMOD22:
4385 if (!dynamic_symbol_p && !info->shared)
4387 got_r_type = R_IA64_DTPMOD64LSB;
4389 case R_IA64_LTOFF_DTPREL22:
4390 if (!dynamic_symbol_p)
4391 value -= elfNN_ia64_dtprel_base (info);
4392 got_r_type = R_IA64_DTPREL64LSB;
4395 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4396 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
4399 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4405 r = bfd_reloc_notsupported;
4414 case bfd_reloc_undefined:
4415 /* This can happen for global table relative relocs if
4416 __gp is undefined. This is a panic situation so we
4417 don't try to continue. */
4418 (*info->callbacks->undefined_symbol)
4419 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4422 case bfd_reloc_notsupported:
4427 name = h->root.root.string;
4430 name = bfd_elf_string_from_elf_section (input_bfd,
4431 symtab_hdr->sh_link,
4436 name = bfd_section_name (input_bfd, input_section);
4438 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4440 input_section, rel->r_offset))
4446 case bfd_reloc_dangerous:
4447 case bfd_reloc_outofrange:
4448 case bfd_reloc_overflow:
4454 name = h->root.root.string;
4457 name = bfd_elf_string_from_elf_section (input_bfd,
4458 symtab_hdr->sh_link,
4463 name = bfd_section_name (input_bfd, input_section);
4465 if (!(*info->callbacks->reloc_overflow) (info, name,
4482 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4484 struct bfd_link_info *info;
4485 struct elf_link_hash_entry *h;
4486 Elf_Internal_Sym *sym;
4488 struct elfNN_ia64_link_hash_table *ia64_info;
4489 struct elfNN_ia64_dyn_sym_info *dyn_i;
4491 ia64_info = elfNN_ia64_hash_table (info);
4492 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4494 /* Fill in the PLT data, if required. */
4495 if (dyn_i && dyn_i->want_plt)
4497 Elf_Internal_Rela outrel;
4500 bfd_vma plt_addr, pltoff_addr, gp_val, index;
4502 gp_val = _bfd_get_gp_value (output_bfd);
4504 /* Initialize the minimal PLT entry. */
4506 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4507 plt_sec = ia64_info->plt_sec;
4508 loc = plt_sec->contents + dyn_i->plt_offset;
4510 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4511 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4512 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4515 plt_addr = (plt_sec->output_section->vma
4516 + plt_sec->output_offset
4517 + dyn_i->plt_offset);
4518 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
4520 /* Initialize the FULL PLT entry, if needed. */
4521 if (dyn_i->want_plt2)
4523 loc = plt_sec->contents + dyn_i->plt2_offset;
4525 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4526 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4529 /* Mark the symbol as undefined, rather than as defined in the
4530 plt section. Leave the value alone. */
4531 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4532 first place. But perhaps elflink.h did some for us. */
4533 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4534 sym->st_shndx = SHN_UNDEF;
4537 /* Create the dynamic relocation. */
4538 outrel.r_offset = pltoff_addr;
4539 if (bfd_little_endian (output_bfd))
4540 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4542 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4543 outrel.r_addend = 0;
4545 /* This is fun. In the .IA_64.pltoff section, we've got entries
4546 that correspond both to real PLT entries, and those that
4547 happened to resolve to local symbols but need to be created
4548 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4549 relocations for the real PLT should come at the end of the
4550 section, so that they can be indexed by plt entry at runtime.
4552 We emitted all of the relocations for the non-PLT @pltoff
4553 entries during relocate_section. So we can consider the
4554 existing sec->reloc_count to be the base of the array of
4557 loc = ia64_info->rel_pltoff_sec->contents;
4558 loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
4559 * sizeof (Elf64_External_Rela));
4560 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4563 /* Mark some specially defined symbols as absolute. */
4564 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4565 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4566 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4567 sym->st_shndx = SHN_ABS;
4573 elfNN_ia64_finish_dynamic_sections (abfd, info)
4575 struct bfd_link_info *info;
4577 struct elfNN_ia64_link_hash_table *ia64_info;
4580 ia64_info = elfNN_ia64_hash_table (info);
4581 dynobj = ia64_info->root.dynobj;
4583 if (elf_hash_table (info)->dynamic_sections_created)
4585 ElfNN_External_Dyn *dyncon, *dynconend;
4586 asection *sdyn, *sgotplt;
4589 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4590 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4591 BFD_ASSERT (sdyn != NULL);
4592 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4593 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4595 gp_val = _bfd_get_gp_value (abfd);
4597 for (; dyncon < dynconend; dyncon++)
4599 Elf_Internal_Dyn dyn;
4601 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4606 dyn.d_un.d_ptr = gp_val;
4610 dyn.d_un.d_val = (ia64_info->minplt_entries
4611 * sizeof (ElfNN_External_Rela));
4615 /* See the comment above in finish_dynamic_symbol. */
4616 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4617 + ia64_info->rel_pltoff_sec->output_offset
4618 + (ia64_info->rel_pltoff_sec->reloc_count
4619 * sizeof (ElfNN_External_Rela)));
4622 case DT_IA_64_PLT_RESERVE:
4623 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4624 + sgotplt->output_offset);
4628 /* Do not have RELASZ include JMPREL. This makes things
4629 easier on ld.so. This is not what the rest of BFD set up. */
4630 dyn.d_un.d_val -= (ia64_info->minplt_entries
4631 * sizeof (ElfNN_External_Rela));
4635 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4638 /* Initialize the PLT0 entry. */
4639 if (ia64_info->plt_sec)
4641 bfd_byte *loc = ia64_info->plt_sec->contents;
4644 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4646 pltres = (sgotplt->output_section->vma
4647 + sgotplt->output_offset
4650 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4657 /* ELF file flag handling: */
4659 /* Function to keep IA-64 specific file flags. */
4661 elfNN_ia64_set_private_flags (abfd, flags)
4665 BFD_ASSERT (!elf_flags_init (abfd)
4666 || elf_elfheader (abfd)->e_flags == flags);
4668 elf_elfheader (abfd)->e_flags = flags;
4669 elf_flags_init (abfd) = TRUE;
4673 /* Merge backend specific data from an object file to the output
4674 object file when linking. */
4676 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4681 bfd_boolean ok = TRUE;
4683 /* Don't even pretend to support mixed-format linking. */
4684 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4685 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4688 in_flags = elf_elfheader (ibfd)->e_flags;
4689 out_flags = elf_elfheader (obfd)->e_flags;
4691 if (! elf_flags_init (obfd))
4693 elf_flags_init (obfd) = TRUE;
4694 elf_elfheader (obfd)->e_flags = in_flags;
4696 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4697 && bfd_get_arch_info (obfd)->the_default)
4699 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4700 bfd_get_mach (ibfd));
4706 /* Check flag compatibility. */
4707 if (in_flags == out_flags)
4710 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4711 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4712 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4714 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4716 (*_bfd_error_handler)
4717 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4718 bfd_archive_filename (ibfd));
4720 bfd_set_error (bfd_error_bad_value);
4723 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4725 (*_bfd_error_handler)
4726 (_("%s: linking big-endian files with little-endian files"),
4727 bfd_archive_filename (ibfd));
4729 bfd_set_error (bfd_error_bad_value);
4732 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4734 (*_bfd_error_handler)
4735 (_("%s: linking 64-bit files with 32-bit files"),
4736 bfd_archive_filename (ibfd));
4738 bfd_set_error (bfd_error_bad_value);
4741 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4743 (*_bfd_error_handler)
4744 (_("%s: linking constant-gp files with non-constant-gp files"),
4745 bfd_archive_filename (ibfd));
4747 bfd_set_error (bfd_error_bad_value);
4750 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4751 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4753 (*_bfd_error_handler)
4754 (_("%s: linking auto-pic files with non-auto-pic files"),
4755 bfd_archive_filename (ibfd));
4757 bfd_set_error (bfd_error_bad_value);
4765 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4769 FILE *file = (FILE *) ptr;
4770 flagword flags = elf_elfheader (abfd)->e_flags;
4772 BFD_ASSERT (abfd != NULL && ptr != NULL);
4774 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4775 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4776 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4777 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4778 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4779 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4780 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4781 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4782 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4784 _bfd_elf_print_private_bfd_data (abfd, ptr);
4788 static enum elf_reloc_type_class
4789 elfNN_ia64_reloc_type_class (rela)
4790 const Elf_Internal_Rela *rela;
4792 switch ((int) ELFNN_R_TYPE (rela->r_info))
4794 case R_IA64_REL32MSB:
4795 case R_IA64_REL32LSB:
4796 case R_IA64_REL64MSB:
4797 case R_IA64_REL64LSB:
4798 return reloc_class_relative;
4799 case R_IA64_IPLTMSB:
4800 case R_IA64_IPLTLSB:
4801 return reloc_class_plt;
4803 return reloc_class_copy;
4805 return reloc_class_normal;
4810 elfNN_ia64_hpux_vec (const bfd_target *vec)
4812 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4813 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4817 elfNN_hpux_post_process_headers (abfd, info)
4819 struct bfd_link_info *info ATTRIBUTE_UNUSED;
4821 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4823 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4824 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4828 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
4829 bfd *abfd ATTRIBUTE_UNUSED;
4833 if (bfd_is_com_section (sec))
4835 *retval = SHN_IA_64_ANSI_COMMON;
4841 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4842 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4843 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4844 #define TARGET_BIG_NAME "elfNN-ia64-big"
4845 #define ELF_ARCH bfd_arch_ia64
4846 #define ELF_MACHINE_CODE EM_IA_64
4847 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4848 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4849 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4851 #define elf_backend_section_from_shdr \
4852 elfNN_ia64_section_from_shdr
4853 #define elf_backend_section_flags \
4854 elfNN_ia64_section_flags
4855 #define elf_backend_fake_sections \
4856 elfNN_ia64_fake_sections
4857 #define elf_backend_final_write_processing \
4858 elfNN_ia64_final_write_processing
4859 #define elf_backend_add_symbol_hook \
4860 elfNN_ia64_add_symbol_hook
4861 #define elf_backend_additional_program_headers \
4862 elfNN_ia64_additional_program_headers
4863 #define elf_backend_modify_segment_map \
4864 elfNN_ia64_modify_segment_map
4865 #define elf_info_to_howto \
4866 elfNN_ia64_info_to_howto
4868 #define bfd_elfNN_bfd_reloc_type_lookup \
4869 elfNN_ia64_reloc_type_lookup
4870 #define bfd_elfNN_bfd_is_local_label_name \
4871 elfNN_ia64_is_local_label_name
4872 #define bfd_elfNN_bfd_relax_section \
4873 elfNN_ia64_relax_section
4875 /* Stuff for the BFD linker: */
4876 #define bfd_elfNN_bfd_link_hash_table_create \
4877 elfNN_ia64_hash_table_create
4878 #define elf_backend_create_dynamic_sections \
4879 elfNN_ia64_create_dynamic_sections
4880 #define elf_backend_check_relocs \
4881 elfNN_ia64_check_relocs
4882 #define elf_backend_adjust_dynamic_symbol \
4883 elfNN_ia64_adjust_dynamic_symbol
4884 #define elf_backend_size_dynamic_sections \
4885 elfNN_ia64_size_dynamic_sections
4886 #define elf_backend_relocate_section \
4887 elfNN_ia64_relocate_section
4888 #define elf_backend_finish_dynamic_symbol \
4889 elfNN_ia64_finish_dynamic_symbol
4890 #define elf_backend_finish_dynamic_sections \
4891 elfNN_ia64_finish_dynamic_sections
4892 #define bfd_elfNN_bfd_final_link \
4893 elfNN_ia64_final_link
4895 #define bfd_elfNN_bfd_merge_private_bfd_data \
4896 elfNN_ia64_merge_private_bfd_data
4897 #define bfd_elfNN_bfd_set_private_flags \
4898 elfNN_ia64_set_private_flags
4899 #define bfd_elfNN_bfd_print_private_bfd_data \
4900 elfNN_ia64_print_private_bfd_data
4902 #define elf_backend_plt_readonly 1
4903 #define elf_backend_want_plt_sym 0
4904 #define elf_backend_plt_alignment 5
4905 #define elf_backend_got_header_size 0
4906 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4907 #define elf_backend_want_got_plt 1
4908 #define elf_backend_may_use_rel_p 1
4909 #define elf_backend_may_use_rela_p 1
4910 #define elf_backend_default_use_rela_p 1
4911 #define elf_backend_want_dynbss 0
4912 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4913 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4914 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4915 #define elf_backend_rela_normal 1
4917 #include "elfNN-target.h"
4919 /* AIX-specific vectors. */
4921 #undef TARGET_LITTLE_SYM
4922 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4923 #undef TARGET_LITTLE_NAME
4924 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4925 #undef TARGET_BIG_SYM
4926 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4927 #undef TARGET_BIG_NAME
4928 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4930 #undef elf_backend_add_symbol_hook
4931 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4933 #undef bfd_elfNN_bfd_link_add_symbols
4934 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4936 #define elfNN_bed elfNN_ia64_aix_bed
4938 #include "elfNN-target.h"
4940 /* HPUX-specific vectors. */
4942 #undef TARGET_LITTLE_SYM
4943 #undef TARGET_LITTLE_NAME
4944 #undef TARGET_BIG_SYM
4945 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4946 #undef TARGET_BIG_NAME
4947 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4949 /* We need to undo the AIX specific functions. */
4951 #undef elf_backend_add_symbol_hook
4952 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
4954 #undef bfd_elfNN_bfd_link_add_symbols
4955 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
4957 /* These are HP-UX specific functions. */
4959 #undef elf_backend_post_process_headers
4960 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4962 #undef elf_backend_section_from_bfd_section
4963 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4965 #undef elf_backend_want_p_paddr_set_to_zero
4966 #define elf_backend_want_p_paddr_set_to_zero 1
4968 #undef ELF_MAXPAGESIZE
4969 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4972 #define elfNN_bed elfNN_ia64_hpux_bed
4974 #include "elfNN-target.h"
4976 #undef elf_backend_want_p_paddr_set_to_zero