Support for more than 64k ELF sections.
[binutils.git] / bfd / elfxx-ia64.c
blob8f43563c43852987d08ee946c3d0cff69ca9daab
1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001 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. */
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "opcode/ia64.h"
26 #include "elf/ia64.h"
29 * THE RULES for all the stuff the linker creates --
31 * GOT Entries created in response to LTOFF or LTOFF_FPTR
32 * relocations. Dynamic relocs created for dynamic
33 * symbols in an application; REL relocs for locals
34 * in a shared library.
36 * FPTR The canonical function descriptor. Created for local
37 * symbols in applications. Descriptors for dynamic symbols
38 * and local symbols in shared libraries are created by
39 * ld.so. Thus there are no dynamic relocs against these
40 * objects. The FPTR relocs for such _are_ passed through
41 * to the dynamic relocation tables.
43 * FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
44 * Requires the creation of a PLTOFF entry. This does not
45 * require any dynamic relocations.
47 * PLTOFF Created by PLTOFF relocations. For local symbols, this
48 * is an alternate function descriptor, and in shared libraries
49 * requires two REL relocations. Note that this cannot be
50 * transformed into an FPTR relocation, since it must be in
51 * range of the GP. For dynamic symbols, this is a function
52 * descriptor for a MIN_PLT entry, and requires one IPLT reloc.
54 * MIN_PLT Created by PLTOFF entries against dynamic symbols. This
55 * does not reqire dynamic relocations.
58 #define USE_RELA /* we want RELA relocs, not REL */
60 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
62 typedef struct bfd_hash_entry *(*new_hash_entry_func)
63 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
65 /* In dynamically (linker-) created sections, we generally need to keep track
66 of the place a symbol or expression got allocated to. This is done via hash
67 tables that store entries of the following type. */
69 struct elfNN_ia64_dyn_sym_info
71 /* The addend for which this entry is relevant. */
72 bfd_vma addend;
74 /* Next addend in the list. */
75 struct elfNN_ia64_dyn_sym_info *next;
77 bfd_vma got_offset;
78 bfd_vma fptr_offset;
79 bfd_vma pltoff_offset;
80 bfd_vma plt_offset;
81 bfd_vma plt2_offset;
83 /* The symbol table entry, if any, that this was derrived from. */
84 struct elf_link_hash_entry *h;
86 /* Used to count non-got, non-plt relocations for delayed sizing
87 of relocation sections. */
88 struct elfNN_ia64_dyn_reloc_entry
90 struct elfNN_ia64_dyn_reloc_entry *next;
91 asection *srel;
92 int type;
93 int count;
94 } *reloc_entries;
96 /* True when the section contents have been updated. */
97 unsigned got_done : 1;
98 unsigned fptr_done : 1;
99 unsigned pltoff_done : 1;
101 /* True for the different kinds of linker data we want created. */
102 unsigned want_got : 1;
103 unsigned want_fptr : 1;
104 unsigned want_ltoff_fptr : 1;
105 unsigned want_plt : 1;
106 unsigned want_plt2 : 1;
107 unsigned want_pltoff : 1;
110 struct elfNN_ia64_local_hash_entry
112 struct bfd_hash_entry root;
113 struct elfNN_ia64_dyn_sym_info *info;
115 /* True if this hash entry's addends was translated for
116 SHF_MERGE optimization. */
117 unsigned sec_merge_done : 1;
120 struct elfNN_ia64_local_hash_table
122 struct bfd_hash_table root;
123 /* No additional fields for now. */
126 struct elfNN_ia64_link_hash_entry
128 struct elf_link_hash_entry root;
129 struct elfNN_ia64_dyn_sym_info *info;
132 struct elfNN_ia64_link_hash_table
134 /* The main hash table */
135 struct elf_link_hash_table root;
137 asection *got_sec; /* the linkage table section (or NULL) */
138 asection *rel_got_sec; /* dynamic relocation section for same */
139 asection *fptr_sec; /* function descriptor table (or NULL) */
140 asection *plt_sec; /* the primary plt section (or NULL) */
141 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
142 asection *rel_pltoff_sec; /* dynamic relocation section for same */
144 bfd_size_type minplt_entries; /* number of minplt entries */
145 unsigned reltext : 1; /* are there relocs against readonly sections? */
147 struct elfNN_ia64_local_hash_table loc_hash_table;
150 #define elfNN_ia64_hash_table(p) \
151 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
153 static bfd_reloc_status_type elfNN_ia64_reloc
154 PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
155 asection *input_section, bfd *output_bfd, char **error_message));
156 static reloc_howto_type * lookup_howto
157 PARAMS ((unsigned int rtype));
158 static reloc_howto_type *elfNN_ia64_reloc_type_lookup
159 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
160 static void elfNN_ia64_info_to_howto
161 PARAMS ((bfd *abfd, arelent *bfd_reloc, ElfNN_Internal_Rela *elf_reloc));
162 static boolean elfNN_ia64_relax_section
163 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
164 boolean *again));
165 static boolean is_unwind_section_name
166 PARAMS ((const char *));
167 static boolean elfNN_ia64_section_from_shdr
168 PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *));
169 static boolean elfNN_ia64_section_flags
170 PARAMS ((flagword *, ElfNN_Internal_Shdr *));
171 static boolean elfNN_ia64_fake_sections
172 PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec));
173 static void elfNN_ia64_final_write_processing
174 PARAMS ((bfd *abfd, boolean linker));
175 static boolean elfNN_ia64_add_symbol_hook
176 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
177 const char **namep, flagword *flagsp, asection **secp,
178 bfd_vma *valp));
179 static boolean elfNN_ia64_aix_vec
180 PARAMS ((const bfd_target *vec));
181 static boolean elfNN_ia64_aix_add_symbol_hook
182 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
183 const char **namep, flagword *flagsp, asection **secp,
184 bfd_vma *valp));
185 static boolean elfNN_ia64_aix_link_add_symbols
186 PARAMS ((bfd *abfd, struct bfd_link_info *info));
187 static int elfNN_ia64_additional_program_headers
188 PARAMS ((bfd *abfd));
189 static boolean elfNN_ia64_modify_segment_map
190 PARAMS ((bfd *));
191 static boolean elfNN_ia64_is_local_label_name
192 PARAMS ((bfd *abfd, const char *name));
193 static boolean elfNN_ia64_dynamic_symbol_p
194 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
195 static boolean elfNN_ia64_local_hash_table_init
196 PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
197 new_hash_entry_func new));
198 static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
199 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
200 const char *string));
201 static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
202 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
203 const char *string));
204 static void elfNN_ia64_hash_copy_indirect
205 PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
206 static void elfNN_ia64_hash_hide_symbol
207 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
208 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
209 PARAMS ((bfd *abfd));
210 static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
211 PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
212 boolean create, boolean copy));
213 static boolean elfNN_ia64_global_dyn_sym_thunk
214 PARAMS ((struct bfd_hash_entry *, PTR));
215 static boolean elfNN_ia64_local_dyn_sym_thunk
216 PARAMS ((struct bfd_hash_entry *, PTR));
217 static void elfNN_ia64_dyn_sym_traverse
218 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
219 boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
220 PTR info));
221 static boolean elfNN_ia64_create_dynamic_sections
222 PARAMS ((bfd *abfd, struct bfd_link_info *info));
223 static struct elfNN_ia64_local_hash_entry * get_local_sym_hash
224 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
225 bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
226 static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
227 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
228 struct elf_link_hash_entry *h,
229 bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
230 static asection *get_got
231 PARAMS ((bfd *abfd, struct bfd_link_info *info,
232 struct elfNN_ia64_link_hash_table *ia64_info));
233 static asection *get_fptr
234 PARAMS ((bfd *abfd, struct bfd_link_info *info,
235 struct elfNN_ia64_link_hash_table *ia64_info));
236 static asection *get_pltoff
237 PARAMS ((bfd *abfd, struct bfd_link_info *info,
238 struct elfNN_ia64_link_hash_table *ia64_info));
239 static asection *get_reloc_section
240 PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
241 asection *sec, boolean create));
242 static boolean count_dyn_reloc
243 PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
244 asection *srel, int type));
245 static boolean elfNN_ia64_check_relocs
246 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
247 const Elf_Internal_Rela *relocs));
248 static boolean elfNN_ia64_adjust_dynamic_symbol
249 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
250 static long global_sym_index
251 PARAMS ((struct elf_link_hash_entry *h));
252 static boolean allocate_fptr
253 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
254 static boolean allocate_global_data_got
255 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
256 static boolean allocate_global_fptr_got
257 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
258 static boolean allocate_local_got
259 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
260 static boolean allocate_pltoff_entries
261 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
262 static boolean allocate_plt_entries
263 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
264 static boolean allocate_plt2_entries
265 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
266 static boolean allocate_dynrel_entries
267 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
268 static boolean elfNN_ia64_size_dynamic_sections
269 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
270 static bfd_reloc_status_type elfNN_ia64_install_value
271 PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
272 static void elfNN_ia64_install_dyn_reloc
273 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
274 asection *srel, bfd_vma offset, unsigned int type,
275 long dynindx, bfd_vma addend));
276 static bfd_vma set_got_entry
277 PARAMS ((bfd *abfd, struct bfd_link_info *info,
278 struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
279 bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
280 static bfd_vma set_fptr_entry
281 PARAMS ((bfd *abfd, struct bfd_link_info *info,
282 struct elfNN_ia64_dyn_sym_info *dyn_i,
283 bfd_vma value));
284 static bfd_vma set_pltoff_entry
285 PARAMS ((bfd *abfd, struct bfd_link_info *info,
286 struct elfNN_ia64_dyn_sym_info *dyn_i,
287 bfd_vma value, boolean));
288 static int elfNN_ia64_unwind_entry_compare
289 PARAMS ((const PTR, const PTR));
290 static boolean elfNN_ia64_final_link
291 PARAMS ((bfd *abfd, struct bfd_link_info *info));
292 static boolean elfNN_ia64_relocate_section
293 PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
294 asection *input_section, bfd_byte *contents,
295 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
296 asection **local_sections));
297 static boolean elfNN_ia64_finish_dynamic_symbol
298 PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
299 struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
300 static boolean elfNN_ia64_finish_dynamic_sections
301 PARAMS ((bfd *abfd, struct bfd_link_info *info));
302 static boolean elfNN_ia64_set_private_flags
303 PARAMS ((bfd *abfd, flagword flags));
304 static boolean elfNN_ia64_copy_private_bfd_data
305 PARAMS ((bfd *ibfd, bfd *obfd));
306 static boolean elfNN_ia64_merge_private_bfd_data
307 PARAMS ((bfd *ibfd, bfd *obfd));
308 static boolean elfNN_ia64_print_private_bfd_data
309 PARAMS ((bfd *abfd, PTR ptr));
310 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
311 PARAMS ((const Elf_Internal_Rela *));
313 /* ia64-specific relocation */
315 /* Perform a relocation. Not much to do here as all the hard work is
316 done in elfNN_ia64_final_link_relocate. */
317 static bfd_reloc_status_type
318 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
319 output_bfd, error_message)
320 bfd *abfd ATTRIBUTE_UNUSED;
321 arelent *reloc;
322 asymbol *sym ATTRIBUTE_UNUSED;
323 PTR data ATTRIBUTE_UNUSED;
324 asection *input_section;
325 bfd *output_bfd;
326 char **error_message;
328 if (output_bfd)
330 reloc->address += input_section->output_offset;
331 return bfd_reloc_ok;
333 *error_message = "Unsupported call to elfNN_ia64_reloc";
334 return bfd_reloc_notsupported;
337 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
338 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
339 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
341 /* This table has to be sorted according to increasing number of the
342 TYPE field. */
343 static reloc_howto_type ia64_howto_table[] =
345 IA64_HOWTO (R_IA64_NONE, "NONE", 0, false, true),
347 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, false, true),
348 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, false, true),
349 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, false, true),
350 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, false, true),
351 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, false, true),
352 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, false, true),
353 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, false, true),
355 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, false, true),
356 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, false, true),
357 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, false, true),
358 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, false, true),
359 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, false, true),
360 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, false, true),
362 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, false, true),
363 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, false, true),
365 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, false, true),
366 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, false, true),
367 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, false, true),
368 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, false, true),
370 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, false, true),
371 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, false, true),
372 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, false, true),
373 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, false, true),
374 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, false, true),
376 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, true, true),
377 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, true, true),
378 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, true, true),
379 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, true, true),
380 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, true, true),
381 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, true, true),
382 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, true, true),
383 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, true, true),
385 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true),
386 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true),
387 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, false, true),
388 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, false, true),
389 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
390 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
392 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
393 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
394 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
395 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, false, true),
397 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, false, true),
398 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, false, true),
399 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, false, true),
400 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, false, true),
402 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, false, true),
403 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, false, true),
404 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, false, true),
405 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, false, true),
407 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, false, true),
408 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, false, true),
409 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, false, true),
410 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, false, true),
412 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, true, true),
413 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, true, true),
414 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, true, true),
416 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, false, true),
417 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, false, true),
418 IA64_HOWTO (R_IA64_COPY, "COPY", 4, false, true),
419 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, false, true),
420 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, false, true),
422 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, false, false),
423 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 8, false, false),
424 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 8, false, false),
425 IA64_HOWTO (R_IA64_LTOFF_TP22, "LTOFF_TP22", 0, false, false),
428 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
430 /* Given a BFD reloc type, return the matching HOWTO structure. */
432 static reloc_howto_type*
433 lookup_howto (rtype)
434 unsigned int rtype;
436 static int inited = 0;
437 int i;
439 if (!inited)
441 inited = 1;
443 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
444 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
445 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
448 BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
449 i = elf_code_to_howto_index[rtype];
450 if (i >= NELEMS (ia64_howto_table))
451 return 0;
452 return ia64_howto_table + i;
455 static reloc_howto_type*
456 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
457 bfd *abfd ATTRIBUTE_UNUSED;
458 bfd_reloc_code_real_type bfd_code;
460 unsigned int rtype;
462 switch (bfd_code)
464 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
466 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
467 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
468 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
470 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
471 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
472 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
473 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
475 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
476 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
477 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
478 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
479 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
480 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
482 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
483 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
485 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
486 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
487 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
488 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
489 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
490 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
491 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
492 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
493 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
495 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
496 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
497 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
498 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
499 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
500 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
501 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
502 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
503 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
504 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
505 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
507 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
508 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
509 case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
510 case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
511 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
512 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
514 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
515 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
516 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
517 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
519 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
520 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
521 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
522 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
524 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
525 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
526 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
527 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
529 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
530 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
531 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
532 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
534 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
535 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
536 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
537 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
538 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
540 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
541 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
542 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
543 case BFD_RELOC_IA64_LTOFF_TP22: rtype = R_IA64_LTOFF_TP22; break;
545 default: return 0;
547 return lookup_howto (rtype);
550 /* Given a ELF reloc, return the matching HOWTO structure. */
552 static void
553 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
554 bfd *abfd ATTRIBUTE_UNUSED;
555 arelent *bfd_reloc;
556 ElfNN_Internal_Rela *elf_reloc;
558 bfd_reloc->howto
559 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
562 #define PLT_HEADER_SIZE (3 * 16)
563 #define PLT_MIN_ENTRY_SIZE (1 * 16)
564 #define PLT_FULL_ENTRY_SIZE (2 * 16)
565 #define PLT_RESERVED_WORDS 3
567 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
569 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
570 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
571 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
572 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
573 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
574 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
575 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
576 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
577 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
580 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
582 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
583 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
584 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
587 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
589 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
590 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
591 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
592 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
593 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
594 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
597 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
598 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
599 #define DYNAMIC_INTERPRETER(abfd) \
600 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
602 /* Select out of range branch fixup type. Note that Itanium does
603 not support brl, and so it gets emulated by the kernel. */
604 #undef USE_BRL
606 static const bfd_byte oor_brl[16] =
608 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
610 0x00, 0x00, 0x00, 0xc0
613 static const bfd_byte oor_ip[48] =
615 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
616 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
617 0x01, 0x00, 0x00, 0x60,
618 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
619 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
620 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
621 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
622 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
623 0x60, 0x00, 0x80, 0x00 /* br b6;; */
626 /* These functions do relaxation for IA-64 ELF.
628 This is primarily to support branches to targets out of range;
629 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
631 static boolean
632 elfNN_ia64_relax_section (abfd, sec, link_info, again)
633 bfd *abfd;
634 asection *sec;
635 struct bfd_link_info *link_info;
636 boolean *again;
638 struct one_fixup
640 struct one_fixup *next;
641 asection *tsec;
642 bfd_vma toff;
643 bfd_vma trampoff;
646 Elf_Internal_Shdr *symtab_hdr;
647 Elf_Internal_Shdr *shndx_hdr;
648 Elf_Internal_Rela *internal_relocs;
649 Elf_Internal_Rela *free_relocs = NULL;
650 Elf_Internal_Rela *irel, *irelend;
651 bfd_byte *contents;
652 bfd_byte *free_contents = NULL;
653 ElfNN_External_Sym *extsyms;
654 ElfNN_External_Sym *free_extsyms = NULL;
655 Elf_External_Sym_Shndx *shndx_buf = NULL;
656 struct elfNN_ia64_link_hash_table *ia64_info;
657 struct one_fixup *fixups = NULL;
658 boolean changed_contents = false;
659 boolean changed_relocs = false;
661 /* Assume we're not going to change any sizes, and we'll only need
662 one pass. */
663 *again = false;
665 /* Nothing to do if there are no relocations. */
666 if ((sec->flags & SEC_RELOC) == 0
667 || sec->reloc_count == 0)
668 return true;
670 /* If this is the first time we have been called for this section,
671 initialize the cooked size. */
672 if (sec->_cooked_size == 0)
673 sec->_cooked_size = sec->_raw_size;
675 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
677 /* Load the relocations for this section. */
678 internal_relocs = (_bfd_elfNN_link_read_relocs
679 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
680 link_info->keep_memory));
681 if (internal_relocs == NULL)
682 goto error_return;
684 if (! link_info->keep_memory)
685 free_relocs = internal_relocs;
687 ia64_info = elfNN_ia64_hash_table (link_info);
688 irelend = internal_relocs + sec->reloc_count;
690 for (irel = internal_relocs; irel < irelend; irel++)
691 if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
692 break;
694 /* No branch-type relocations. */
695 if (irel == irelend)
697 if (free_relocs != NULL)
698 free (free_relocs);
699 return true;
702 /* Get the section contents. */
703 if (elf_section_data (sec)->this_hdr.contents != NULL)
704 contents = elf_section_data (sec)->this_hdr.contents;
705 else
707 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
708 if (contents == NULL)
709 goto error_return;
710 free_contents = contents;
712 if (! bfd_get_section_contents (abfd, sec, contents,
713 (file_ptr) 0, sec->_raw_size))
714 goto error_return;
717 /* Read this BFD's local symbols. */
718 if (symtab_hdr->contents != NULL)
719 extsyms = (ElfNN_External_Sym *) symtab_hdr->contents;
720 else
722 bfd_size_type amt;
724 amt = symtab_hdr->sh_info * sizeof (ElfNN_External_Sym);
725 extsyms = (ElfNN_External_Sym *) bfd_malloc (amt);
726 if (extsyms == NULL)
727 goto error_return;
728 free_extsyms = extsyms;
729 if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
730 || bfd_bread (extsyms, amt, abfd) != amt)
731 goto error_return;
734 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
735 if (shndx_hdr->sh_size != 0)
737 bfd_size_type amt;
739 amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
740 shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
741 if (shndx_buf == NULL)
742 goto error_return;
743 if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
744 || bfd_bread (shndx_buf, amt, abfd) != amt)
745 goto error_return;
748 for (; irel < irelend; irel++)
750 bfd_vma symaddr, reladdr, trampoff, toff, roff;
751 Elf_Internal_Sym isym;
752 asection *tsec;
753 struct one_fixup *f;
754 bfd_size_type amt;
756 if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
757 continue;
759 /* Get the value of the symbol referred to by the reloc. */
760 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
762 ElfNN_External_Sym *esym;
763 Elf_External_Sym_Shndx *shndx;
765 /* A local symbol. */
766 esym = extsyms + ELFNN_R_SYM (irel->r_info);
767 shndx = shndx_buf + (shndx_buf ? ELFNN_R_SYM (irel->r_info) : 0);
768 bfd_elfNN_swap_symbol_in (abfd, esym, shndx, &isym);
769 if (isym.st_shndx == SHN_UNDEF)
770 continue; /* We can't do anthing with undefined symbols. */
771 else if (isym.st_shndx == SHN_ABS)
772 tsec = bfd_abs_section_ptr;
773 else if (isym.st_shndx == SHN_COMMON)
774 tsec = bfd_com_section_ptr;
775 else
776 tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
778 toff = isym.st_value;
780 else
782 unsigned long indx;
783 struct elf_link_hash_entry *h;
784 struct elfNN_ia64_dyn_sym_info *dyn_i;
786 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
787 h = elf_sym_hashes (abfd)[indx];
788 BFD_ASSERT (h != NULL);
790 while (h->root.type == bfd_link_hash_indirect
791 || h->root.type == bfd_link_hash_warning)
792 h = (struct elf_link_hash_entry *) h->root.u.i.link;
794 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
796 /* For branches to dynamic symbols, we're interested instead
797 in a branch to the PLT entry. */
798 if (dyn_i && dyn_i->want_plt2)
800 tsec = ia64_info->plt_sec;
801 toff = dyn_i->plt2_offset;
803 else
805 /* We can't do anthing with undefined symbols. */
806 if (h->root.type == bfd_link_hash_undefined
807 || h->root.type == bfd_link_hash_undefweak)
808 continue;
810 tsec = h->root.u.def.section;
811 toff = h->root.u.def.value;
815 symaddr = (tsec->output_section->vma
816 + tsec->output_offset
817 + toff
818 + irel->r_addend);
820 roff = irel->r_offset;
821 reladdr = (sec->output_section->vma
822 + sec->output_offset
823 + roff) & (bfd_vma) -4;
825 /* If the branch is in range, no need to do anything. */
826 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
827 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
828 continue;
830 /* If the branch and target are in the same section, you've
831 got one honking big section and we can't help you. You'll
832 get an error message later. */
833 if (tsec == sec)
834 continue;
836 /* Look for an existing fixup to this address. */
837 for (f = fixups; f ; f = f->next)
838 if (f->tsec == tsec && f->toff == toff)
839 break;
841 if (f == NULL)
843 /* Two alternatives: If it's a branch to a PLT entry, we can
844 make a copy of the FULL_PLT entry. Otherwise, we'll have
845 to use a `brl' insn to get where we're going. */
847 size_t size;
849 if (tsec == ia64_info->plt_sec)
850 size = sizeof (plt_full_entry);
851 else
853 #ifdef USE_BRL
854 size = sizeof (oor_brl);
855 #else
856 size = sizeof (oor_ip);
857 #endif
860 /* Resize the current section to make room for the new branch. */
861 trampoff = (sec->_cooked_size + 15) & (bfd_vma) -16;
862 amt = trampoff + size;
863 contents = (bfd_byte *) bfd_realloc (contents, amt);
864 if (contents == NULL)
865 goto error_return;
866 sec->_cooked_size = amt;
868 if (tsec == ia64_info->plt_sec)
870 memcpy (contents + trampoff, plt_full_entry, size);
872 /* Hijack the old relocation for use as the PLTOFF reloc. */
873 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
874 R_IA64_PLTOFF22);
875 irel->r_offset = trampoff;
877 else
879 #ifdef USE_BRL
880 memcpy (contents + trampoff, oor_brl, size);
881 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
882 R_IA64_PCREL60B);
883 irel->r_offset = trampoff + 2;
884 #else
885 memcpy (contents + trampoff, oor_ip, size);
886 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
887 R_IA64_PCREL64I);
888 irel->r_addend -= 16;
889 irel->r_offset = trampoff + 2;
890 #endif
893 /* Record the fixup so we don't do it again this section. */
894 f = (struct one_fixup *) bfd_malloc ((bfd_size_type) sizeof (*f));
895 f->next = fixups;
896 f->tsec = tsec;
897 f->toff = toff;
898 f->trampoff = trampoff;
899 fixups = f;
901 else
903 /* Nop out the reloc, since we're finalizing things here. */
904 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
907 /* Fix up the existing branch to hit the trampoline. Hope like
908 hell this doesn't overflow too. */
909 if (elfNN_ia64_install_value (abfd, contents + roff,
910 f->trampoff - (roff & (bfd_vma) -4),
911 R_IA64_PCREL21B) != bfd_reloc_ok)
912 goto error_return;
914 changed_contents = true;
915 changed_relocs = true;
918 /* Clean up and go home. */
919 while (fixups)
921 struct one_fixup *f = fixups;
922 fixups = fixups->next;
923 free (f);
926 if (changed_relocs)
927 elf_section_data (sec)->relocs = internal_relocs;
928 else if (free_relocs != NULL)
929 free (free_relocs);
931 if (changed_contents)
932 elf_section_data (sec)->this_hdr.contents = contents;
933 else if (free_contents != NULL)
935 if (! link_info->keep_memory)
936 free (free_contents);
937 else
939 /* Cache the section contents for elf_link_input_bfd. */
940 elf_section_data (sec)->this_hdr.contents = contents;
944 if (shndx_buf != NULL)
945 free (shndx_buf);
947 if (free_extsyms != NULL)
949 if (! link_info->keep_memory)
950 free (free_extsyms);
951 else
953 /* Cache the symbols for elf_link_input_bfd. */
954 symtab_hdr->contents = (unsigned char *) extsyms;
958 *again = changed_contents || changed_relocs;
959 return true;
961 error_return:
962 if (free_relocs != NULL)
963 free (free_relocs);
964 if (free_contents != NULL)
965 free (free_contents);
966 if (shndx_buf != NULL)
967 free (shndx_buf);
968 if (free_extsyms != NULL)
969 free (free_extsyms);
970 return false;
973 /* Return true if NAME is an unwind table section name. */
975 static inline boolean
976 is_unwind_section_name (name)
977 const char *name;
979 size_t len1, len2, len3;
981 len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
982 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
983 len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
984 return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
985 && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
986 || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
989 /* Handle an IA-64 specific section when reading an object file. This
990 is called when elfcode.h finds a section with an unknown type. */
992 static boolean
993 elfNN_ia64_section_from_shdr (abfd, hdr, name)
994 bfd *abfd;
995 ElfNN_Internal_Shdr *hdr;
996 char *name;
998 asection *newsect;
1000 /* There ought to be a place to keep ELF backend specific flags, but
1001 at the moment there isn't one. We just keep track of the
1002 sections by their name, instead. Fortunately, the ABI gives
1003 suggested names for all the MIPS specific sections, so we will
1004 probably get away with this. */
1005 switch (hdr->sh_type)
1007 case SHT_IA_64_UNWIND:
1008 break;
1010 case SHT_IA_64_EXT:
1011 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1012 return false;
1013 break;
1015 default:
1016 return false;
1019 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
1020 return false;
1021 newsect = hdr->bfd_section;
1023 return true;
1026 /* Convert IA-64 specific section flags to bfd internal section flags. */
1028 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1029 flag. */
1031 static boolean
1032 elfNN_ia64_section_flags (flags, hdr)
1033 flagword *flags;
1034 ElfNN_Internal_Shdr *hdr;
1036 if (hdr->sh_flags & SHF_IA_64_SHORT)
1037 *flags |= SEC_SMALL_DATA;
1039 return true;
1042 /* Set the correct type for an IA-64 ELF section. We do this by the
1043 section name, which is a hack, but ought to work. */
1045 static boolean
1046 elfNN_ia64_fake_sections (abfd, hdr, sec)
1047 bfd *abfd ATTRIBUTE_UNUSED;
1048 ElfNN_Internal_Shdr *hdr;
1049 asection *sec;
1051 register const char *name;
1053 name = bfd_get_section_name (abfd, sec);
1055 if (is_unwind_section_name (name))
1057 /* We don't have the sections numbered at this point, so sh_info
1058 is set later, in elfNN_ia64_final_write_processing. */
1059 hdr->sh_type = SHT_IA_64_UNWIND;
1060 hdr->sh_flags |= SHF_LINK_ORDER;
1062 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1063 hdr->sh_type = SHT_IA_64_EXT;
1064 else if (strcmp (name, ".reloc") == 0)
1066 * This is an ugly, but unfortunately necessary hack that is
1067 * needed when producing EFI binaries on IA-64. It tells
1068 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1069 * containing ELF relocation info. We need this hack in order to
1070 * be able to generate ELF binaries that can be translated into
1071 * EFI applications (which are essentially COFF objects). Those
1072 * files contain a COFF ".reloc" section inside an ELFNN object,
1073 * which would normally cause BFD to segfault because it would
1074 * attempt to interpret this section as containing relocation
1075 * entries for section "oc". With this hack enabled, ".reloc"
1076 * will be treated as a normal data section, which will avoid the
1077 * segfault. However, you won't be able to create an ELFNN binary
1078 * with a section named "oc" that needs relocations, but that's
1079 * the kind of ugly side-effects you get when detecting section
1080 * types based on their names... In practice, this limitation is
1081 * unlikely to bite.
1083 hdr->sh_type = SHT_PROGBITS;
1085 if (sec->flags & SEC_SMALL_DATA)
1086 hdr->sh_flags |= SHF_IA_64_SHORT;
1088 return true;
1091 /* The final processing done just before writing out an IA-64 ELF
1092 object file. */
1094 static void
1095 elfNN_ia64_final_write_processing (abfd, linker)
1096 bfd *abfd;
1097 boolean linker ATTRIBUTE_UNUSED;
1099 Elf_Internal_Shdr *hdr;
1100 const char *sname;
1101 asection *text_sect, *s;
1102 size_t len;
1104 for (s = abfd->sections; s; s = s->next)
1106 hdr = &elf_section_data (s)->this_hdr;
1107 switch (hdr->sh_type)
1109 case SHT_IA_64_UNWIND:
1110 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1111 have to do this. */
1112 sname = bfd_get_section_name (abfd, s);
1113 len = sizeof (ELF_STRING_ia64_unwind) - 1;
1114 if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0)
1116 sname += len;
1118 if (sname[0] == '\0')
1119 /* .IA_64.unwind -> .text */
1120 text_sect = bfd_get_section_by_name (abfd, ".text");
1121 else
1122 /* .IA_64.unwindFOO -> FOO */
1123 text_sect = bfd_get_section_by_name (abfd, sname);
1125 else if (sname
1126 && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
1127 strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
1129 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1130 size_t len2 = sizeof (".gnu.linkonce.t.") - 1;
1131 char *once_name = alloca (len2 + strlen (sname) - len + 1);
1133 memcpy (once_name, ".gnu.linkonce.t.", len2);
1134 strcpy (once_name + len2, sname + len);
1135 text_sect = bfd_get_section_by_name (abfd, once_name);
1137 else
1138 /* last resort: fall back on .text */
1139 text_sect = bfd_get_section_by_name (abfd, ".text");
1141 if (text_sect)
1143 /* The IA-64 processor-specific ABI requires setting
1144 sh_link to the unwind section, whereas HP-UX requires
1145 sh_info to do so. For maximum compatibility, we'll
1146 set both for now... */
1147 hdr->sh_link = elf_section_data (text_sect)->this_idx;
1148 hdr->sh_info = elf_section_data (text_sect)->this_idx;
1150 break;
1155 /* Hook called by the linker routine which adds symbols from an object
1156 file. We use it to put .comm items in .sbss, and not .bss. */
1158 static boolean
1159 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1160 bfd *abfd;
1161 struct bfd_link_info *info;
1162 const Elf_Internal_Sym *sym;
1163 const char **namep ATTRIBUTE_UNUSED;
1164 flagword *flagsp ATTRIBUTE_UNUSED;
1165 asection **secp;
1166 bfd_vma *valp;
1168 if (sym->st_shndx == SHN_COMMON
1169 && !info->relocateable
1170 && sym->st_size <= elf_gp_size (abfd))
1172 /* Common symbols less than or equal to -G nn bytes are
1173 automatically put into .sbss. */
1175 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1177 if (scomm == NULL)
1179 scomm = bfd_make_section (abfd, ".scommon");
1180 if (scomm == NULL
1181 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1182 | SEC_IS_COMMON
1183 | SEC_LINKER_CREATED)))
1184 return false;
1187 *secp = scomm;
1188 *valp = sym->st_size;
1191 return true;
1194 static boolean
1195 elfNN_ia64_aix_vec (const bfd_target *vec)
1197 extern const bfd_target bfd_elfNN_ia64_aix_little_vec;
1198 extern const bfd_target bfd_elfNN_ia64_aix_big_vec;
1200 return (/**/vec == & bfd_elfNN_ia64_aix_little_vec
1201 || vec == & bfd_elfNN_ia64_aix_big_vec);
1204 /* Hook called by the linker routine which adds symbols from an object
1205 file. We use it to handle OS-specific symbols. */
1207 static boolean
1208 elfNN_ia64_aix_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1209 bfd *abfd;
1210 struct bfd_link_info *info;
1211 const Elf_Internal_Sym *sym;
1212 const char **namep;
1213 flagword *flagsp;
1214 asection **secp;
1215 bfd_vma *valp;
1217 if (strcmp (*namep, "__GLOB_DATA_PTR") == 0)
1219 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1220 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1221 no one else should use it b/c it is undocumented. */
1222 struct elf_link_hash_entry *h;
1224 h = elf_link_hash_lookup (elf_hash_table (info), *namep,
1225 false, false, false);
1226 if (h == NULL)
1228 struct elf_backend_data *bed;
1229 struct elfNN_ia64_link_hash_table *ia64_info;
1231 bed = get_elf_backend_data (abfd);
1232 ia64_info = elfNN_ia64_hash_table (info);
1234 if (!(_bfd_generic_link_add_one_symbol
1235 (info, abfd, *namep, BSF_GLOBAL,
1236 bfd_get_section_by_name (abfd, ".bss"),
1237 bed->got_symbol_offset, (const char *) NULL, false,
1238 bed->collect, (struct bfd_link_hash_entry **) &h)))
1239 return false;
1241 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1242 h->type = STT_OBJECT;
1244 if (! _bfd_elf_link_record_dynamic_symbol (info, h))
1245 return false;
1248 return true;
1250 else if (sym->st_shndx == SHN_LOOS)
1252 unsigned int i;
1254 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1255 is only relevant when compiling code for extended system calls.
1256 Replace the "special" section with .text, if possible.
1257 Note that these symbols are always assumed to be in .text. */
1258 for (i = 1; i < elf_numsections (abfd); i++)
1260 asection * sec = bfd_section_from_elf_index (abfd, i);
1262 if (sec && strcmp (sec->name, ".text") == 0)
1264 *secp = sec;
1265 break;
1269 if (*secp == NULL)
1270 *secp = bfd_abs_section_ptr;
1272 *valp = sym->st_size;
1274 return true;
1276 else
1278 return elfNN_ia64_add_symbol_hook (abfd, info, sym,
1279 namep, flagsp, secp, valp);
1283 boolean
1284 elfNN_ia64_aix_link_add_symbols (abfd, info)
1285 bfd *abfd;
1286 struct bfd_link_info *info;
1288 /* Make sure dynamic sections are always created. */
1289 if (! elf_hash_table (info)->dynamic_sections_created
1290 && abfd->xvec == info->hash->creator)
1292 if (! bfd_elfNN_link_create_dynamic_sections (abfd, info))
1293 return false;
1296 /* Now do the standard call. */
1297 return bfd_elfNN_bfd_link_add_symbols (abfd, info);
1300 /* Return the number of additional phdrs we will need. */
1302 static int
1303 elfNN_ia64_additional_program_headers (abfd)
1304 bfd *abfd;
1306 asection *s;
1307 int ret = 0;
1309 /* See if we need a PT_IA_64_ARCHEXT segment. */
1310 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1311 if (s && (s->flags & SEC_LOAD))
1312 ++ret;
1314 /* Count how many PT_IA_64_UNWIND segments we need. */
1315 for (s = abfd->sections; s; s = s->next)
1316 if (is_unwind_section_name(s->name) && (s->flags & SEC_LOAD))
1317 ++ret;
1319 return ret;
1322 static boolean
1323 elfNN_ia64_modify_segment_map (abfd)
1324 bfd *abfd;
1326 struct elf_segment_map *m, **pm;
1327 Elf_Internal_Shdr *hdr;
1328 asection *s;
1330 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1331 all PT_LOAD segments. */
1332 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1333 if (s && (s->flags & SEC_LOAD))
1335 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1336 if (m->p_type == PT_IA_64_ARCHEXT)
1337 break;
1338 if (m == NULL)
1340 m = ((struct elf_segment_map *)
1341 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1342 if (m == NULL)
1343 return false;
1345 m->p_type = PT_IA_64_ARCHEXT;
1346 m->count = 1;
1347 m->sections[0] = s;
1349 /* We want to put it after the PHDR and INTERP segments. */
1350 pm = &elf_tdata (abfd)->segment_map;
1351 while (*pm != NULL
1352 && ((*pm)->p_type == PT_PHDR
1353 || (*pm)->p_type == PT_INTERP))
1354 pm = &(*pm)->next;
1356 m->next = *pm;
1357 *pm = m;
1361 /* Install PT_IA_64_UNWIND segments, if needed. */
1362 for (s = abfd->sections; s; s = s->next)
1364 hdr = &elf_section_data (s)->this_hdr;
1365 if (hdr->sh_type != SHT_IA_64_UNWIND)
1366 continue;
1368 if (s && (s->flags & SEC_LOAD))
1370 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1371 if (m->p_type == PT_IA_64_UNWIND && m->sections[0] == s)
1372 break;
1374 if (m == NULL)
1376 m = ((struct elf_segment_map *)
1377 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1378 if (m == NULL)
1379 return false;
1381 m->p_type = PT_IA_64_UNWIND;
1382 m->count = 1;
1383 m->sections[0] = s;
1384 m->next = NULL;
1386 /* We want to put it last. */
1387 pm = &elf_tdata (abfd)->segment_map;
1388 while (*pm != NULL)
1389 pm = &(*pm)->next;
1390 *pm = m;
1395 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1396 the input sections for each output section in the segment and testing
1397 for SHF_IA_64_NORECOV on each. */
1398 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1399 if (m->p_type == PT_LOAD)
1401 int i;
1402 for (i = m->count - 1; i >= 0; --i)
1404 struct bfd_link_order *order = m->sections[i]->link_order_head;
1405 while (order)
1407 if (order->type == bfd_indirect_link_order)
1409 asection *is = order->u.indirect.section;
1410 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1411 if (flags & SHF_IA_64_NORECOV)
1413 m->p_flags |= PF_IA_64_NORECOV;
1414 goto found;
1417 order = order->next;
1420 found:;
1423 return true;
1426 /* According to the Tahoe assembler spec, all labels starting with a
1427 '.' are local. */
1429 static boolean
1430 elfNN_ia64_is_local_label_name (abfd, name)
1431 bfd *abfd ATTRIBUTE_UNUSED;
1432 const char *name;
1434 return name[0] == '.';
1437 /* Should we do dynamic things to this symbol? */
1439 static boolean
1440 elfNN_ia64_dynamic_symbol_p (h, info)
1441 struct elf_link_hash_entry *h;
1442 struct bfd_link_info *info;
1444 if (h == NULL)
1445 return false;
1447 while (h->root.type == bfd_link_hash_indirect
1448 || h->root.type == bfd_link_hash_warning)
1449 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1451 if (h->dynindx == -1)
1452 return false;
1453 switch (ELF_ST_VISIBILITY (h->other))
1455 case STV_INTERNAL:
1456 case STV_HIDDEN:
1457 return false;
1460 if (h->root.type == bfd_link_hash_undefweak
1461 || h->root.type == bfd_link_hash_defweak)
1462 return true;
1464 if ((info->shared && (!info->symbolic || info->allow_shlib_undefined))
1465 || ((h->elf_link_hash_flags
1466 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1467 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1468 return true;
1470 return false;
1473 static boolean
1474 elfNN_ia64_local_hash_table_init (ht, abfd, new)
1475 struct elfNN_ia64_local_hash_table *ht;
1476 bfd *abfd ATTRIBUTE_UNUSED;
1477 new_hash_entry_func new;
1479 memset (ht, 0, sizeof (*ht));
1480 return bfd_hash_table_init (&ht->root, new);
1483 static struct bfd_hash_entry*
1484 elfNN_ia64_new_loc_hash_entry (entry, table, string)
1485 struct bfd_hash_entry *entry;
1486 struct bfd_hash_table *table;
1487 const char *string;
1489 struct elfNN_ia64_local_hash_entry *ret;
1490 ret = (struct elfNN_ia64_local_hash_entry *) entry;
1492 /* Allocate the structure if it has not already been allocated by a
1493 subclass. */
1494 if (!ret)
1495 ret = bfd_hash_allocate (table, sizeof (*ret));
1497 if (!ret)
1498 return 0;
1500 /* Initialize our local data. All zeros, and definitely easier
1501 than setting a handful of bit fields. */
1502 memset (ret, 0, sizeof (*ret));
1504 /* Call the allocation method of the superclass. */
1505 ret = ((struct elfNN_ia64_local_hash_entry *)
1506 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1508 return (struct bfd_hash_entry *) ret;
1511 static struct bfd_hash_entry*
1512 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1513 struct bfd_hash_entry *entry;
1514 struct bfd_hash_table *table;
1515 const char *string;
1517 struct elfNN_ia64_link_hash_entry *ret;
1518 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1520 /* Allocate the structure if it has not already been allocated by a
1521 subclass. */
1522 if (!ret)
1523 ret = bfd_hash_allocate (table, sizeof (*ret));
1525 if (!ret)
1526 return 0;
1528 /* Initialize our local data. All zeros, and definitely easier
1529 than setting a handful of bit fields. */
1530 memset (ret, 0, sizeof (*ret));
1532 /* Call the allocation method of the superclass. */
1533 ret = ((struct elfNN_ia64_link_hash_entry *)
1534 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1535 table, string));
1537 return (struct bfd_hash_entry *) ret;
1540 static void
1541 elfNN_ia64_hash_copy_indirect (xdir, xind)
1542 struct elf_link_hash_entry *xdir, *xind;
1544 struct elfNN_ia64_link_hash_entry *dir, *ind;
1546 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1547 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1549 /* Copy down any references that we may have already seen to the
1550 symbol which just became indirect. */
1552 dir->root.elf_link_hash_flags |=
1553 (ind->root.elf_link_hash_flags
1554 & (ELF_LINK_HASH_REF_DYNAMIC
1555 | ELF_LINK_HASH_REF_REGULAR
1556 | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1558 if (ind->root.root.type != bfd_link_hash_indirect)
1559 return;
1561 /* Copy over the got and plt data. This would have been done
1562 by check_relocs. */
1564 if (dir->info == NULL)
1566 struct elfNN_ia64_dyn_sym_info *dyn_i;
1568 dir->info = dyn_i = ind->info;
1569 ind->info = NULL;
1571 /* Fix up the dyn_sym_info pointers to the global symbol. */
1572 for (; dyn_i; dyn_i = dyn_i->next)
1573 dyn_i->h = &dir->root;
1575 BFD_ASSERT (ind->info == NULL);
1577 /* Copy over the dynindx. */
1579 if (dir->root.dynindx == -1)
1581 dir->root.dynindx = ind->root.dynindx;
1582 dir->root.dynstr_index = ind->root.dynstr_index;
1583 ind->root.dynindx = -1;
1584 ind->root.dynstr_index = 0;
1586 BFD_ASSERT (ind->root.dynindx == -1);
1589 static void
1590 elfNN_ia64_hash_hide_symbol (info, xh)
1591 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1592 struct elf_link_hash_entry *xh;
1594 struct elfNN_ia64_link_hash_entry *h;
1595 struct elfNN_ia64_dyn_sym_info *dyn_i;
1597 h = (struct elfNN_ia64_link_hash_entry *)xh;
1599 h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
1600 if ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
1601 h->root.dynindx = -1;
1603 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1604 dyn_i->want_plt2 = 0;
1607 /* Create the derived linker hash table. The IA-64 ELF port uses this
1608 derived hash table to keep information specific to the IA-64 ElF
1609 linker (without using static variables). */
1611 static struct bfd_link_hash_table*
1612 elfNN_ia64_hash_table_create (abfd)
1613 bfd *abfd;
1615 struct elfNN_ia64_link_hash_table *ret;
1617 ret = bfd_zalloc (abfd, (bfd_size_type) sizeof (*ret));
1618 if (!ret)
1619 return 0;
1620 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1621 elfNN_ia64_new_elf_hash_entry))
1623 bfd_release (abfd, ret);
1624 return 0;
1627 if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1628 elfNN_ia64_new_loc_hash_entry))
1629 return 0;
1630 return &ret->root.root;
1633 /* Look up an entry in a Alpha ELF linker hash table. */
1635 static INLINE struct elfNN_ia64_local_hash_entry *
1636 elfNN_ia64_local_hash_lookup(table, string, create, copy)
1637 struct elfNN_ia64_local_hash_table *table;
1638 const char *string;
1639 boolean create, copy;
1641 return ((struct elfNN_ia64_local_hash_entry *)
1642 bfd_hash_lookup (&table->root, string, create, copy));
1645 /* Traverse both local and global hash tables. */
1647 struct elfNN_ia64_dyn_sym_traverse_data
1649 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1650 PTR data;
1653 static boolean
1654 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1655 struct bfd_hash_entry *xentry;
1656 PTR xdata;
1658 struct elfNN_ia64_link_hash_entry *entry
1659 = (struct elfNN_ia64_link_hash_entry *) xentry;
1660 struct elfNN_ia64_dyn_sym_traverse_data *data
1661 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1662 struct elfNN_ia64_dyn_sym_info *dyn_i;
1664 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1665 if (! (*data->func) (dyn_i, data->data))
1666 return false;
1667 return true;
1670 static boolean
1671 elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1672 struct bfd_hash_entry *xentry;
1673 PTR xdata;
1675 struct elfNN_ia64_local_hash_entry *entry
1676 = (struct elfNN_ia64_local_hash_entry *) xentry;
1677 struct elfNN_ia64_dyn_sym_traverse_data *data
1678 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1679 struct elfNN_ia64_dyn_sym_info *dyn_i;
1681 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1682 if (! (*data->func) (dyn_i, data->data))
1683 return false;
1684 return true;
1687 static void
1688 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1689 struct elfNN_ia64_link_hash_table *ia64_info;
1690 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1691 PTR data;
1693 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1695 xdata.func = func;
1696 xdata.data = data;
1698 elf_link_hash_traverse (&ia64_info->root,
1699 elfNN_ia64_global_dyn_sym_thunk, &xdata);
1700 bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1701 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1704 static boolean
1705 elfNN_ia64_create_dynamic_sections (abfd, info)
1706 bfd *abfd;
1707 struct bfd_link_info *info;
1709 struct elfNN_ia64_link_hash_table *ia64_info;
1710 asection *s;
1712 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1713 return false;
1715 ia64_info = elfNN_ia64_hash_table (info);
1717 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1718 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1721 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1722 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1725 if (!get_pltoff (abfd, info, ia64_info))
1726 return false;
1728 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1729 if (s == NULL
1730 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1731 | SEC_HAS_CONTENTS
1732 | SEC_IN_MEMORY
1733 | SEC_LINKER_CREATED
1734 | SEC_READONLY))
1735 || !bfd_set_section_alignment (abfd, s, 3))
1736 return false;
1737 ia64_info->rel_pltoff_sec = s;
1739 s = bfd_make_section(abfd, ".rela.got");
1740 if (s == NULL
1741 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1742 | SEC_HAS_CONTENTS
1743 | SEC_IN_MEMORY
1744 | SEC_LINKER_CREATED
1745 | SEC_READONLY))
1746 || !bfd_set_section_alignment (abfd, s, 3))
1747 return false;
1748 ia64_info->rel_got_sec = s;
1750 return true;
1753 /* Find and/or create a hash entry for local symbol. */
1754 static struct elfNN_ia64_local_hash_entry *
1755 get_local_sym_hash (ia64_info, abfd, rel, create)
1756 struct elfNN_ia64_link_hash_table *ia64_info;
1757 bfd *abfd;
1758 const Elf_Internal_Rela *rel;
1759 boolean create;
1761 char *addr_name;
1762 size_t len;
1764 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1765 name describes what was once anonymous memory. */
1767 len = sizeof (void*)*2 + 1 + sizeof (bfd_vma)*4 + 1 + 1;
1768 len += 10; /* %p slop */
1770 addr_name = alloca (len);
1771 sprintf (addr_name, "%p:%lx",
1772 (void *) abfd, (unsigned long) ELFNN_R_SYM (rel->r_info));
1774 /* Collect the canonical entry data for this address. */
1775 return elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1776 addr_name, create, create);
1779 /* Find and/or create a descriptor for dynamic symbol info. This will
1780 vary based on global or local symbol, and the addend to the reloc. */
1782 static struct elfNN_ia64_dyn_sym_info *
1783 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1784 struct elfNN_ia64_link_hash_table *ia64_info;
1785 struct elf_link_hash_entry *h;
1786 bfd *abfd;
1787 const Elf_Internal_Rela *rel;
1788 boolean create;
1790 struct elfNN_ia64_dyn_sym_info **pp;
1791 struct elfNN_ia64_dyn_sym_info *dyn_i;
1792 bfd_vma addend = rel ? rel->r_addend : 0;
1794 if (h)
1795 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1796 else
1798 struct elfNN_ia64_local_hash_entry *loc_h;
1800 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1801 BFD_ASSERT (loc_h);
1803 pp = &loc_h->info;
1806 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1807 pp = &dyn_i->next;
1809 if (dyn_i == NULL && create)
1811 dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
1812 bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
1813 *pp = dyn_i;
1814 dyn_i->addend = addend;
1817 return dyn_i;
1820 static asection *
1821 get_got (abfd, info, ia64_info)
1822 bfd *abfd;
1823 struct bfd_link_info *info;
1824 struct elfNN_ia64_link_hash_table *ia64_info;
1826 asection *got;
1827 bfd *dynobj;
1829 got = ia64_info->got_sec;
1830 if (!got)
1832 flagword flags;
1834 dynobj = ia64_info->root.dynobj;
1835 if (!dynobj)
1836 ia64_info->root.dynobj = dynobj = abfd;
1837 if (!_bfd_elf_create_got_section (dynobj, info))
1838 return 0;
1840 got = bfd_get_section_by_name (dynobj, ".got");
1841 BFD_ASSERT (got);
1842 ia64_info->got_sec = got;
1844 flags = bfd_get_section_flags (abfd, got);
1845 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1848 return got;
1851 /* Create function descriptor section (.opd). This section is called .opd
1852 because it contains "official prodecure descriptors". The "official"
1853 refers to the fact that these descriptors are used when taking the address
1854 of a procedure, thus ensuring a unique address for each procedure. */
1856 static asection *
1857 get_fptr (abfd, info, ia64_info)
1858 bfd *abfd;
1859 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1860 struct elfNN_ia64_link_hash_table *ia64_info;
1862 asection *fptr;
1863 bfd *dynobj;
1865 fptr = ia64_info->fptr_sec;
1866 if (!fptr)
1868 dynobj = ia64_info->root.dynobj;
1869 if (!dynobj)
1870 ia64_info->root.dynobj = dynobj = abfd;
1872 fptr = bfd_make_section (dynobj, ".opd");
1873 if (!fptr
1874 || !bfd_set_section_flags (dynobj, fptr,
1875 (SEC_ALLOC
1876 | SEC_LOAD
1877 | SEC_HAS_CONTENTS
1878 | SEC_IN_MEMORY
1879 | SEC_READONLY
1880 | SEC_LINKER_CREATED))
1881 || !bfd_set_section_alignment (abfd, fptr, 4))
1883 BFD_ASSERT (0);
1884 return NULL;
1887 ia64_info->fptr_sec = fptr;
1890 return fptr;
1893 static asection *
1894 get_pltoff (abfd, info, ia64_info)
1895 bfd *abfd;
1896 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1897 struct elfNN_ia64_link_hash_table *ia64_info;
1899 asection *pltoff;
1900 bfd *dynobj;
1902 pltoff = ia64_info->pltoff_sec;
1903 if (!pltoff)
1905 dynobj = ia64_info->root.dynobj;
1906 if (!dynobj)
1907 ia64_info->root.dynobj = dynobj = abfd;
1909 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
1910 if (!pltoff
1911 || !bfd_set_section_flags (dynobj, pltoff,
1912 (SEC_ALLOC
1913 | SEC_LOAD
1914 | SEC_HAS_CONTENTS
1915 | SEC_IN_MEMORY
1916 | SEC_SMALL_DATA
1917 | SEC_LINKER_CREATED))
1918 || !bfd_set_section_alignment (abfd, pltoff, 4))
1920 BFD_ASSERT (0);
1921 return NULL;
1924 ia64_info->pltoff_sec = pltoff;
1927 return pltoff;
1930 static asection *
1931 get_reloc_section (abfd, ia64_info, sec, create)
1932 bfd *abfd;
1933 struct elfNN_ia64_link_hash_table *ia64_info;
1934 asection *sec;
1935 boolean create;
1937 const char *srel_name;
1938 asection *srel;
1939 bfd *dynobj;
1941 srel_name = (bfd_elf_string_from_elf_section
1942 (abfd, elf_elfheader(abfd)->e_shstrndx,
1943 elf_section_data(sec)->rel_hdr.sh_name));
1944 if (srel_name == NULL)
1945 return NULL;
1947 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
1948 && strcmp (bfd_get_section_name (abfd, sec),
1949 srel_name+5) == 0)
1950 || (strncmp (srel_name, ".rel", 4) == 0
1951 && strcmp (bfd_get_section_name (abfd, sec),
1952 srel_name+4) == 0));
1954 dynobj = ia64_info->root.dynobj;
1955 if (!dynobj)
1956 ia64_info->root.dynobj = dynobj = abfd;
1958 srel = bfd_get_section_by_name (dynobj, srel_name);
1959 if (srel == NULL && create)
1961 srel = bfd_make_section (dynobj, srel_name);
1962 if (srel == NULL
1963 || !bfd_set_section_flags (dynobj, srel,
1964 (SEC_ALLOC
1965 | SEC_LOAD
1966 | SEC_HAS_CONTENTS
1967 | SEC_IN_MEMORY
1968 | SEC_LINKER_CREATED
1969 | SEC_READONLY))
1970 || !bfd_set_section_alignment (dynobj, srel, 3))
1971 return NULL;
1974 if (sec->flags & SEC_READONLY)
1975 ia64_info->reltext = 1;
1977 return srel;
1980 static boolean
1981 count_dyn_reloc (abfd, dyn_i, srel, type)
1982 bfd *abfd;
1983 struct elfNN_ia64_dyn_sym_info *dyn_i;
1984 asection *srel;
1985 int type;
1987 struct elfNN_ia64_dyn_reloc_entry *rent;
1989 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
1990 if (rent->srel == srel && rent->type == type)
1991 break;
1993 if (!rent)
1995 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
1996 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
1997 if (!rent)
1998 return false;
2000 rent->next = dyn_i->reloc_entries;
2001 rent->srel = srel;
2002 rent->type = type;
2003 rent->count = 0;
2004 dyn_i->reloc_entries = rent;
2006 rent->count++;
2008 return true;
2011 static boolean
2012 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2013 bfd *abfd;
2014 struct bfd_link_info *info;
2015 asection *sec;
2016 const Elf_Internal_Rela *relocs;
2018 struct elfNN_ia64_link_hash_table *ia64_info;
2019 const Elf_Internal_Rela *relend;
2020 Elf_Internal_Shdr *symtab_hdr;
2021 const Elf_Internal_Rela *rel;
2022 asection *got, *fptr, *srel;
2024 if (info->relocateable)
2025 return true;
2027 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2028 ia64_info = elfNN_ia64_hash_table (info);
2030 got = fptr = srel = NULL;
2032 relend = relocs + sec->reloc_count;
2033 for (rel = relocs; rel < relend; ++rel)
2035 enum {
2036 NEED_GOT = 1,
2037 NEED_FPTR = 2,
2038 NEED_PLTOFF = 4,
2039 NEED_MIN_PLT = 8,
2040 NEED_FULL_PLT = 16,
2041 NEED_DYNREL = 32,
2042 NEED_LTOFF_FPTR = 64,
2045 struct elf_link_hash_entry *h = NULL;
2046 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2047 struct elfNN_ia64_dyn_sym_info *dyn_i;
2048 int need_entry;
2049 boolean maybe_dynamic;
2050 int dynrel_type = R_IA64_NONE;
2052 if (r_symndx >= symtab_hdr->sh_info)
2054 /* We're dealing with a global symbol -- find its hash entry
2055 and mark it as being referenced. */
2056 long indx = r_symndx - symtab_hdr->sh_info;
2057 h = elf_sym_hashes (abfd)[indx];
2058 while (h->root.type == bfd_link_hash_indirect
2059 || h->root.type == bfd_link_hash_warning)
2060 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2062 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2065 /* We can only get preliminary data on whether a symbol is
2066 locally or externally defined, as not all of the input files
2067 have yet been processed. Do something with what we know, as
2068 this may help reduce memory usage and processing time later. */
2069 maybe_dynamic = false;
2070 if (h && ((info->shared
2071 && (!info->symbolic || info->allow_shlib_undefined))
2072 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
2073 || h->root.type == bfd_link_hash_defweak
2074 || elfNN_ia64_aix_vec (abfd->xvec)))
2075 maybe_dynamic = true;
2077 need_entry = 0;
2078 switch (ELFNN_R_TYPE (rel->r_info))
2080 case R_IA64_TPREL22:
2081 case R_IA64_TPREL64MSB:
2082 case R_IA64_TPREL64LSB:
2083 case R_IA64_LTOFF_TP22:
2084 return false;
2086 case R_IA64_LTOFF_FPTR22:
2087 case R_IA64_LTOFF_FPTR64I:
2088 case R_IA64_LTOFF_FPTR32MSB:
2089 case R_IA64_LTOFF_FPTR32LSB:
2090 case R_IA64_LTOFF_FPTR64MSB:
2091 case R_IA64_LTOFF_FPTR64LSB:
2092 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2093 break;
2095 case R_IA64_FPTR64I:
2096 case R_IA64_FPTR32MSB:
2097 case R_IA64_FPTR32LSB:
2098 case R_IA64_FPTR64MSB:
2099 case R_IA64_FPTR64LSB:
2100 if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
2101 need_entry = NEED_FPTR | NEED_DYNREL;
2102 else
2103 need_entry = NEED_FPTR;
2104 dynrel_type = R_IA64_FPTR64LSB;
2105 break;
2107 case R_IA64_LTOFF22:
2108 case R_IA64_LTOFF22X:
2109 case R_IA64_LTOFF64I:
2110 need_entry = NEED_GOT;
2111 break;
2113 case R_IA64_PLTOFF22:
2114 case R_IA64_PLTOFF64I:
2115 case R_IA64_PLTOFF64MSB:
2116 case R_IA64_PLTOFF64LSB:
2117 need_entry = NEED_PLTOFF;
2118 if (h)
2120 if (maybe_dynamic)
2121 need_entry |= NEED_MIN_PLT;
2123 else
2125 (*info->callbacks->warning)
2126 (info, _("@pltoff reloc against local symbol"), 0,
2127 abfd, 0, (bfd_vma) 0);
2129 break;
2131 case R_IA64_PCREL21B:
2132 case R_IA64_PCREL60B:
2133 /* Depending on where this symbol is defined, we may or may not
2134 need a full plt entry. Only skip if we know we'll not need
2135 the entry -- static or symbolic, and the symbol definition
2136 has already been seen. */
2137 if (maybe_dynamic && rel->r_addend == 0)
2138 need_entry = NEED_FULL_PLT;
2139 break;
2141 case R_IA64_IMM14:
2142 case R_IA64_IMM22:
2143 case R_IA64_IMM64:
2144 case R_IA64_DIR32MSB:
2145 case R_IA64_DIR32LSB:
2146 case R_IA64_DIR64MSB:
2147 case R_IA64_DIR64LSB:
2148 /* Shared objects will always need at least a REL relocation. */
2149 if (info->shared || maybe_dynamic
2150 || (elfNN_ia64_aix_vec (abfd->xvec)
2151 && (!h || strcmp (h->root.root.string,
2152 "__GLOB_DATA_PTR") != 0)))
2153 need_entry = NEED_DYNREL;
2154 dynrel_type = R_IA64_DIR64LSB;
2155 break;
2157 case R_IA64_IPLTMSB:
2158 case R_IA64_IPLTLSB:
2159 /* Shared objects will always need at least a REL relocation. */
2160 if (info->shared || maybe_dynamic)
2161 need_entry = NEED_DYNREL;
2162 dynrel_type = R_IA64_IPLTLSB;
2163 break;
2165 case R_IA64_PCREL22:
2166 case R_IA64_PCREL64I:
2167 case R_IA64_PCREL32MSB:
2168 case R_IA64_PCREL32LSB:
2169 case R_IA64_PCREL64MSB:
2170 case R_IA64_PCREL64LSB:
2171 if (maybe_dynamic)
2172 need_entry = NEED_DYNREL;
2173 dynrel_type = R_IA64_PCREL64LSB;
2174 break;
2177 if (!need_entry)
2178 continue;
2180 if ((need_entry & NEED_FPTR) != 0
2181 && rel->r_addend)
2183 (*info->callbacks->warning)
2184 (info, _("non-zero addend in @fptr reloc"), 0,
2185 abfd, 0, (bfd_vma) 0);
2188 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
2190 /* Record whether or not this is a local symbol. */
2191 dyn_i->h = h;
2193 /* Create what's needed. */
2194 if (need_entry & NEED_GOT)
2196 if (!got)
2198 got = get_got (abfd, info, ia64_info);
2199 if (!got)
2200 return false;
2202 dyn_i->want_got = 1;
2204 if (need_entry & NEED_FPTR)
2206 if (!fptr)
2208 fptr = get_fptr (abfd, info, ia64_info);
2209 if (!fptr)
2210 return false;
2213 /* FPTRs for shared libraries are allocated by the dynamic
2214 linker. Make sure this local symbol will appear in the
2215 dynamic symbol table. */
2216 if (!h && (info->shared
2217 /* AIX also needs one */
2218 || elfNN_ia64_aix_vec (abfd->xvec)))
2220 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2221 (info, abfd, (long) r_symndx)))
2222 return false;
2225 dyn_i->want_fptr = 1;
2227 if (need_entry & NEED_LTOFF_FPTR)
2228 dyn_i->want_ltoff_fptr = 1;
2229 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2231 if (!ia64_info->root.dynobj)
2232 ia64_info->root.dynobj = abfd;
2233 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2234 dyn_i->want_plt = 1;
2236 if (need_entry & NEED_FULL_PLT)
2237 dyn_i->want_plt2 = 1;
2238 if (need_entry & NEED_PLTOFF)
2239 dyn_i->want_pltoff = 1;
2240 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2242 if (!srel)
2244 srel = get_reloc_section (abfd, ia64_info, sec, true);
2245 if (!srel)
2246 return false;
2248 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2249 return false;
2253 return true;
2256 struct elfNN_ia64_allocate_data
2258 struct bfd_link_info *info;
2259 bfd_size_type ofs;
2262 /* For cleanliness, and potentially faster dynamic loading, allocate
2263 external GOT entries first. */
2265 static boolean
2266 allocate_global_data_got (dyn_i, data)
2267 struct elfNN_ia64_dyn_sym_info *dyn_i;
2268 PTR data;
2270 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2272 if (dyn_i->want_got
2273 && ! dyn_i->want_fptr
2274 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2275 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2276 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2277 "__GLOB_DATA_PTR") != 0))))
2279 dyn_i->got_offset = x->ofs;
2280 x->ofs += 8;
2282 return true;
2285 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2287 static boolean
2288 allocate_global_fptr_got (dyn_i, data)
2289 struct elfNN_ia64_dyn_sym_info *dyn_i;
2290 PTR data;
2292 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2294 if (dyn_i->want_got
2295 && dyn_i->want_fptr
2296 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2297 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2299 dyn_i->got_offset = x->ofs;
2300 x->ofs += 8;
2302 return true;
2305 /* Lastly, allocate all the GOT entries for local data. */
2307 static boolean
2308 allocate_local_got (dyn_i, data)
2309 struct elfNN_ia64_dyn_sym_info *dyn_i;
2310 PTR data;
2312 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2314 if (dyn_i->want_got
2315 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2316 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2318 dyn_i->got_offset = x->ofs;
2319 x->ofs += 8;
2321 return true;
2324 /* Search for the index of a global symbol in it's defining object file. */
2326 static long
2327 global_sym_index (h)
2328 struct elf_link_hash_entry *h;
2330 struct elf_link_hash_entry **p;
2331 bfd *obj;
2333 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2334 || h->root.type == bfd_link_hash_defweak);
2336 obj = h->root.u.def.section->owner;
2337 for (p = elf_sym_hashes (obj); *p != h; ++p)
2338 continue;
2340 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2343 /* Allocate function descriptors. We can do these for every function
2344 in a main executable that is not exported. */
2346 static boolean
2347 allocate_fptr (dyn_i, data)
2348 struct elfNN_ia64_dyn_sym_info *dyn_i;
2349 PTR data;
2351 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2353 if (dyn_i->want_fptr)
2355 struct elf_link_hash_entry *h = dyn_i->h;
2357 if (h)
2358 while (h->root.type == bfd_link_hash_indirect
2359 || h->root.type == bfd_link_hash_warning)
2360 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2362 if (x->info->shared
2363 /* AIX needs an FPTR in this case. */
2364 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2365 && (!h
2366 || h->root.type == bfd_link_hash_defined
2367 || h->root.type == bfd_link_hash_defweak)))
2369 if (h && h->dynindx == -1)
2371 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2372 || (h->root.type == bfd_link_hash_defweak));
2374 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2375 (x->info, h->root.u.def.section->owner,
2376 global_sym_index (h)))
2377 return false;
2380 dyn_i->want_fptr = 0;
2382 else if (h == NULL || h->dynindx == -1)
2384 dyn_i->fptr_offset = x->ofs;
2385 x->ofs += 16;
2387 else
2388 dyn_i->want_fptr = 0;
2390 return true;
2393 /* Allocate all the minimal PLT entries. */
2395 static boolean
2396 allocate_plt_entries (dyn_i, data)
2397 struct elfNN_ia64_dyn_sym_info *dyn_i;
2398 PTR data;
2400 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2402 if (dyn_i->want_plt)
2404 struct elf_link_hash_entry *h = dyn_i->h;
2406 if (h)
2407 while (h->root.type == bfd_link_hash_indirect
2408 || h->root.type == bfd_link_hash_warning)
2409 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2411 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2412 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2414 bfd_size_type offset = x->ofs;
2415 if (offset == 0)
2416 offset = PLT_HEADER_SIZE;
2417 dyn_i->plt_offset = offset;
2418 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2420 dyn_i->want_pltoff = 1;
2422 else
2424 dyn_i->want_plt = 0;
2425 dyn_i->want_plt2 = 0;
2428 return true;
2431 /* Allocate all the full PLT entries. */
2433 static boolean
2434 allocate_plt2_entries (dyn_i, data)
2435 struct elfNN_ia64_dyn_sym_info *dyn_i;
2436 PTR data;
2438 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2440 if (dyn_i->want_plt2)
2442 struct elf_link_hash_entry *h = dyn_i->h;
2443 bfd_size_type ofs = x->ofs;
2445 dyn_i->plt2_offset = ofs;
2446 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2448 while (h->root.type == bfd_link_hash_indirect
2449 || h->root.type == bfd_link_hash_warning)
2450 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2451 dyn_i->h->plt.offset = ofs;
2453 return true;
2456 /* Allocate all the PLTOFF entries requested by relocations and
2457 plt entries. We can't share space with allocated FPTR entries,
2458 because the latter are not necessarily addressable by the GP.
2459 ??? Relaxation might be able to determine that they are. */
2461 static boolean
2462 allocate_pltoff_entries (dyn_i, data)
2463 struct elfNN_ia64_dyn_sym_info *dyn_i;
2464 PTR data;
2466 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2468 if (dyn_i->want_pltoff)
2470 dyn_i->pltoff_offset = x->ofs;
2471 x->ofs += 16;
2473 return true;
2476 /* Allocate dynamic relocations for those symbols that turned out
2477 to be dynamic. */
2479 static boolean
2480 allocate_dynrel_entries (dyn_i, data)
2481 struct elfNN_ia64_dyn_sym_info *dyn_i;
2482 PTR data;
2484 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2485 struct elfNN_ia64_link_hash_table *ia64_info;
2486 struct elfNN_ia64_dyn_reloc_entry *rent;
2487 boolean dynamic_symbol, shared;
2489 ia64_info = elfNN_ia64_hash_table (x->info);
2490 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2491 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2492 /* Don't allocate an entry for __GLOB_DATA_PTR */
2493 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2494 "__GLOB_DATA_PTR") != 0));
2495 shared = x->info->shared;
2497 /* Take care of the normal data relocations. */
2499 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2501 int count = rent->count;
2503 switch (rent->type)
2505 case R_IA64_FPTR64LSB:
2506 /* Allocate one iff !want_fptr, which by this point will
2507 be true only if we're actually allocating one statically
2508 in the main executable. */
2509 if (dyn_i->want_fptr)
2510 continue;
2511 break;
2512 case R_IA64_PCREL64LSB:
2513 if (!dynamic_symbol)
2514 continue;
2515 break;
2516 case R_IA64_DIR64LSB:
2517 if (!dynamic_symbol && !shared)
2518 continue;
2519 break;
2520 case R_IA64_IPLTLSB:
2521 if (!dynamic_symbol && !shared)
2522 continue;
2523 /* Use two REL relocations for IPLT relocations
2524 against local symbols. */
2525 if (!dynamic_symbol)
2526 count *= 2;
2527 break;
2528 default:
2529 abort ();
2531 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2534 /* Take care of the GOT and PLT relocations. */
2536 if (((dynamic_symbol || shared) && dyn_i->want_got)
2537 || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2538 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2540 if (dyn_i->want_pltoff)
2542 bfd_size_type t = 0;
2544 /* Dynamic symbols get one IPLT relocation. Local symbols in
2545 shared libraries get two REL relocations. Local symbols in
2546 main applications get nothing. */
2547 if (dynamic_symbol)
2548 t = sizeof (ElfNN_External_Rela);
2549 else if (shared)
2550 t = 2 * sizeof (ElfNN_External_Rela);
2552 ia64_info->rel_pltoff_sec->_raw_size += t;
2555 return true;
2558 static boolean
2559 elfNN_ia64_adjust_dynamic_symbol (info, h)
2560 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2561 struct elf_link_hash_entry *h;
2563 /* ??? Undefined symbols with PLT entries should be re-defined
2564 to be the PLT entry. */
2566 /* If this is a weak symbol, and there is a real definition, the
2567 processor independent code will have arranged for us to see the
2568 real definition first, and we can just use the same value. */
2569 if (h->weakdef != NULL)
2571 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2572 || h->weakdef->root.type == bfd_link_hash_defweak);
2573 h->root.u.def.section = h->weakdef->root.u.def.section;
2574 h->root.u.def.value = h->weakdef->root.u.def.value;
2575 return true;
2578 /* If this is a reference to a symbol defined by a dynamic object which
2579 is not a function, we might allocate the symbol in our .dynbss section
2580 and allocate a COPY dynamic relocation.
2582 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2583 of hackery. */
2585 return true;
2588 static boolean
2589 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2590 bfd *output_bfd;
2591 struct bfd_link_info *info;
2593 struct elfNN_ia64_allocate_data data;
2594 struct elfNN_ia64_link_hash_table *ia64_info;
2595 asection *sec;
2596 bfd *dynobj;
2597 boolean relplt = false;
2599 dynobj = elf_hash_table(info)->dynobj;
2600 ia64_info = elfNN_ia64_hash_table (info);
2601 BFD_ASSERT(dynobj != NULL);
2602 data.info = info;
2604 /* Set the contents of the .interp section to the interpreter. */
2605 if (ia64_info->root.dynamic_sections_created
2606 && !info->shared)
2608 sec = bfd_get_section_by_name (dynobj, ".interp");
2609 BFD_ASSERT (sec != NULL);
2610 sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd);
2611 sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1;
2614 /* Allocate the GOT entries. */
2616 if (ia64_info->got_sec)
2618 data.ofs = 0;
2619 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2620 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2621 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2622 ia64_info->got_sec->_raw_size = data.ofs;
2625 /* Allocate the FPTR entries. */
2627 if (ia64_info->fptr_sec)
2629 data.ofs = 0;
2630 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2631 ia64_info->fptr_sec->_raw_size = data.ofs;
2634 /* Now that we've seen all of the input files, we can decide which
2635 symbols need plt entries. Allocate the minimal PLT entries first.
2636 We do this even though dynamic_sections_created may be false, because
2637 this has the side-effect of clearing want_plt and want_plt2. */
2639 data.ofs = 0;
2640 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2642 ia64_info->minplt_entries = 0;
2643 if (data.ofs)
2645 ia64_info->minplt_entries
2646 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2649 /* Align the pointer for the plt2 entries. */
2650 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2652 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2653 if (data.ofs != 0)
2655 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2657 ia64_info->plt_sec->_raw_size = data.ofs;
2659 /* If we've got a .plt, we need some extra memory for the dynamic
2660 linker. We stuff these in .got.plt. */
2661 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2662 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2665 /* Allocate the PLTOFF entries. */
2667 if (ia64_info->pltoff_sec)
2669 data.ofs = 0;
2670 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2671 ia64_info->pltoff_sec->_raw_size = data.ofs;
2674 if (ia64_info->root.dynamic_sections_created)
2676 /* Allocate space for the dynamic relocations that turned out to be
2677 required. */
2679 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2682 /* We have now determined the sizes of the various dynamic sections.
2683 Allocate memory for them. */
2684 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2686 boolean strip;
2688 if (!(sec->flags & SEC_LINKER_CREATED))
2689 continue;
2691 /* If we don't need this section, strip it from the output file.
2692 There were several sections primarily related to dynamic
2693 linking that must be create before the linker maps input
2694 sections to output sections. The linker does that before
2695 bfd_elf_size_dynamic_sections is called, and it is that
2696 function which decides whether anything needs to go into
2697 these sections. */
2699 strip = (sec->_raw_size == 0);
2701 if (sec == ia64_info->got_sec)
2702 strip = false;
2703 else if (sec == ia64_info->rel_got_sec)
2705 if (strip)
2706 ia64_info->rel_got_sec = NULL;
2707 else
2708 /* We use the reloc_count field as a counter if we need to
2709 copy relocs into the output file. */
2710 sec->reloc_count = 0;
2712 else if (sec == ia64_info->fptr_sec)
2714 if (strip)
2715 ia64_info->fptr_sec = NULL;
2717 else if (sec == ia64_info->plt_sec)
2719 if (strip)
2720 ia64_info->plt_sec = NULL;
2722 else if (sec == ia64_info->pltoff_sec)
2724 if (strip)
2725 ia64_info->pltoff_sec = NULL;
2727 else if (sec == ia64_info->rel_pltoff_sec)
2729 if (strip)
2730 ia64_info->rel_pltoff_sec = NULL;
2731 else
2733 relplt = true;
2734 /* We use the reloc_count field as a counter if we need to
2735 copy relocs into the output file. */
2736 sec->reloc_count = 0;
2739 else
2741 const char *name;
2743 /* It's OK to base decisions on the section name, because none
2744 of the dynobj section names depend upon the input files. */
2745 name = bfd_get_section_name (dynobj, sec);
2747 if (strcmp (name, ".got.plt") == 0)
2748 strip = false;
2749 else if (strncmp (name, ".rel", 4) == 0)
2751 if (!strip)
2753 /* We use the reloc_count field as a counter if we need to
2754 copy relocs into the output file. */
2755 sec->reloc_count = 0;
2758 else
2759 continue;
2762 if (strip)
2763 _bfd_strip_section_from_output (info, sec);
2764 else
2766 /* Allocate memory for the section contents. */
2767 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
2768 if (sec->contents == NULL && sec->_raw_size != 0)
2769 return false;
2773 if (elf_hash_table (info)->dynamic_sections_created)
2775 /* Add some entries to the .dynamic section. We fill in the values
2776 later (in finish_dynamic_sections) but we must add the entries now
2777 so that we get the correct size for the .dynamic section. */
2779 if (!info->shared)
2781 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2782 by the debugger. */
2783 #define add_dynamic_entry(TAG, VAL) \
2784 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
2786 if (!add_dynamic_entry (DT_DEBUG, 0))
2787 return false;
2790 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
2791 return false;
2792 if (!add_dynamic_entry (DT_PLTGOT, 0))
2793 return false;
2795 if (relplt)
2797 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
2798 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2799 || !add_dynamic_entry (DT_JMPREL, 0))
2800 return false;
2803 if (!add_dynamic_entry (DT_RELA, 0)
2804 || !add_dynamic_entry (DT_RELASZ, 0)
2805 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
2806 return false;
2808 if (ia64_info->reltext)
2810 if (!add_dynamic_entry (DT_TEXTREL, 0))
2811 return false;
2812 info->flags |= DF_TEXTREL;
2816 /* ??? Perhaps force __gp local. */
2818 return true;
2821 static bfd_reloc_status_type
2822 elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
2823 bfd *abfd;
2824 bfd_byte *hit_addr;
2825 bfd_vma v;
2826 unsigned int r_type;
2828 const struct ia64_operand *op;
2829 int bigendian = 0, shift = 0;
2830 bfd_vma t0, t1, insn, dword;
2831 enum ia64_opnd opnd;
2832 const char *err;
2833 size_t size = 8;
2834 #ifdef BFD_HOST_U_64_BIT
2835 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
2836 #else
2837 bfd_vma val = v;
2838 #endif
2840 opnd = IA64_OPND_NIL;
2841 switch (r_type)
2843 case R_IA64_NONE:
2844 case R_IA64_LDXMOV:
2845 return bfd_reloc_ok;
2847 /* Instruction relocations. */
2849 case R_IA64_IMM14: opnd = IA64_OPND_IMM14; break;
2851 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
2852 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
2853 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
2854 case R_IA64_PCREL21B:
2855 case R_IA64_PCREL21BI:
2856 opnd = IA64_OPND_TGT25c;
2857 break;
2859 case R_IA64_IMM22:
2860 case R_IA64_GPREL22:
2861 case R_IA64_LTOFF22:
2862 case R_IA64_LTOFF22X:
2863 case R_IA64_PLTOFF22:
2864 case R_IA64_PCREL22:
2865 case R_IA64_LTOFF_FPTR22:
2866 opnd = IA64_OPND_IMM22;
2867 break;
2869 case R_IA64_IMM64:
2870 case R_IA64_GPREL64I:
2871 case R_IA64_LTOFF64I:
2872 case R_IA64_PLTOFF64I:
2873 case R_IA64_PCREL64I:
2874 case R_IA64_FPTR64I:
2875 case R_IA64_LTOFF_FPTR64I:
2876 opnd = IA64_OPND_IMMU64;
2877 break;
2879 /* Data relocations. */
2881 case R_IA64_DIR32MSB:
2882 case R_IA64_GPREL32MSB:
2883 case R_IA64_FPTR32MSB:
2884 case R_IA64_PCREL32MSB:
2885 case R_IA64_LTOFF_FPTR32MSB:
2886 case R_IA64_SEGREL32MSB:
2887 case R_IA64_SECREL32MSB:
2888 case R_IA64_LTV32MSB:
2889 size = 4; bigendian = 1;
2890 break;
2892 case R_IA64_DIR32LSB:
2893 case R_IA64_GPREL32LSB:
2894 case R_IA64_FPTR32LSB:
2895 case R_IA64_PCREL32LSB:
2896 case R_IA64_LTOFF_FPTR32LSB:
2897 case R_IA64_SEGREL32LSB:
2898 case R_IA64_SECREL32LSB:
2899 case R_IA64_LTV32LSB:
2900 size = 4; bigendian = 0;
2901 break;
2903 case R_IA64_DIR64MSB:
2904 case R_IA64_GPREL64MSB:
2905 case R_IA64_PLTOFF64MSB:
2906 case R_IA64_FPTR64MSB:
2907 case R_IA64_PCREL64MSB:
2908 case R_IA64_LTOFF_FPTR64MSB:
2909 case R_IA64_SEGREL64MSB:
2910 case R_IA64_SECREL64MSB:
2911 case R_IA64_LTV64MSB:
2912 size = 8; bigendian = 1;
2913 break;
2915 case R_IA64_DIR64LSB:
2916 case R_IA64_GPREL64LSB:
2917 case R_IA64_PLTOFF64LSB:
2918 case R_IA64_FPTR64LSB:
2919 case R_IA64_PCREL64LSB:
2920 case R_IA64_LTOFF_FPTR64LSB:
2921 case R_IA64_SEGREL64LSB:
2922 case R_IA64_SECREL64LSB:
2923 case R_IA64_LTV64LSB:
2924 size = 8; bigendian = 0;
2925 break;
2927 /* Unsupported / Dynamic relocations. */
2928 default:
2929 return bfd_reloc_notsupported;
2932 switch (opnd)
2934 case IA64_OPND_IMMU64:
2935 hit_addr -= (long) hit_addr & 0x3;
2936 t0 = bfd_get_64 (abfd, hit_addr);
2937 t1 = bfd_get_64 (abfd, hit_addr + 8);
2939 /* tmpl/s: bits 0.. 5 in t0
2940 slot 0: bits 5..45 in t0
2941 slot 1: bits 46..63 in t0, bits 0..22 in t1
2942 slot 2: bits 23..63 in t1 */
2944 /* First, clear the bits that form the 64 bit constant. */
2945 t0 &= ~(0x3ffffLL << 46);
2946 t1 &= ~(0x7fffffLL
2947 | (( (0x07fLL << 13) | (0x1ffLL << 27)
2948 | (0x01fLL << 22) | (0x001LL << 21)
2949 | (0x001LL << 36)) << 23));
2951 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
2952 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
2953 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
2954 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
2955 | (((val >> 16) & 0x01f) << 22) /* imm5c */
2956 | (((val >> 21) & 0x001) << 21) /* ic */
2957 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
2959 bfd_put_64 (abfd, t0, hit_addr);
2960 bfd_put_64 (abfd, t1, hit_addr + 8);
2961 break;
2963 case IA64_OPND_TGT64:
2964 hit_addr -= (long) hit_addr & 0x3;
2965 t0 = bfd_get_64 (abfd, hit_addr);
2966 t1 = bfd_get_64 (abfd, hit_addr + 8);
2968 /* tmpl/s: bits 0.. 5 in t0
2969 slot 0: bits 5..45 in t0
2970 slot 1: bits 46..63 in t0, bits 0..22 in t1
2971 slot 2: bits 23..63 in t1 */
2973 /* First, clear the bits that form the 64 bit constant. */
2974 t0 &= ~(0x3ffffLL << 46);
2975 t1 &= ~(0x7fffffLL
2976 | ((1LL << 36 | 0xfffffLL << 13) << 23));
2978 val >>= 4;
2979 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
2980 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
2981 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
2982 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
2984 bfd_put_64 (abfd, t0, hit_addr);
2985 bfd_put_64 (abfd, t1, hit_addr + 8);
2986 break;
2988 default:
2989 switch ((long) hit_addr & 0x3)
2991 case 0: shift = 5; break;
2992 case 1: shift = 14; hit_addr += 3; break;
2993 case 2: shift = 23; hit_addr += 6; break;
2994 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
2996 dword = bfd_get_64 (abfd, hit_addr);
2997 insn = (dword >> shift) & 0x1ffffffffffLL;
2999 op = elf64_ia64_operands + opnd;
3000 err = (*op->insert) (op, val, (ia64_insn *)& insn);
3001 if (err)
3002 return bfd_reloc_overflow;
3004 dword &= ~(0x1ffffffffffLL << shift);
3005 dword |= (insn << shift);
3006 bfd_put_64 (abfd, dword, hit_addr);
3007 break;
3009 case IA64_OPND_NIL:
3010 /* A data relocation. */
3011 if (bigendian)
3012 if (size == 4)
3013 bfd_putb32 (val, hit_addr);
3014 else
3015 bfd_putb64 (val, hit_addr);
3016 else
3017 if (size == 4)
3018 bfd_putl32 (val, hit_addr);
3019 else
3020 bfd_putl64 (val, hit_addr);
3021 break;
3024 return bfd_reloc_ok;
3027 static void
3028 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3029 dynindx, addend)
3030 bfd *abfd;
3031 struct bfd_link_info *info;
3032 asection *sec;
3033 asection *srel;
3034 bfd_vma offset;
3035 unsigned int type;
3036 long dynindx;
3037 bfd_vma addend;
3039 Elf_Internal_Rela outrel;
3041 offset += sec->output_section->vma + sec->output_offset;
3043 BFD_ASSERT (dynindx != -1);
3044 outrel.r_info = ELFNN_R_INFO (dynindx, type);
3045 outrel.r_addend = addend;
3046 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3047 if (outrel.r_offset == (bfd_vma) -1)
3049 /* Run for the hills. We shouldn't be outputting a relocation
3050 for this. So do what everyone else does and output a no-op. */
3051 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3052 outrel.r_addend = 0;
3053 outrel.r_offset = 0;
3056 bfd_elfNN_swap_reloca_out (abfd, &outrel,
3057 ((ElfNN_External_Rela *) srel->contents
3058 + srel->reloc_count++));
3059 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3060 <= srel->_cooked_size);
3063 /* Store an entry for target address TARGET_ADDR in the linkage table
3064 and return the gp-relative address of the linkage table entry. */
3066 static bfd_vma
3067 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3068 bfd *abfd;
3069 struct bfd_link_info *info;
3070 struct elfNN_ia64_dyn_sym_info *dyn_i;
3071 long dynindx;
3072 bfd_vma addend;
3073 bfd_vma value;
3074 unsigned int dyn_r_type;
3076 struct elfNN_ia64_link_hash_table *ia64_info;
3077 asection *got_sec;
3079 ia64_info = elfNN_ia64_hash_table (info);
3080 got_sec = ia64_info->got_sec;
3082 BFD_ASSERT ((dyn_i->got_offset & 7) == 0);
3084 if (! dyn_i->got_done)
3086 dyn_i->got_done = true;
3088 /* Store the target address in the linkage table entry. */
3089 bfd_put_64 (abfd, value, got_sec->contents + dyn_i->got_offset);
3091 /* Install a dynamic relocation if needed. */
3092 if (info->shared
3093 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
3094 || elfNN_ia64_aix_vec (abfd->xvec)
3095 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3097 if (dynindx == -1)
3099 dyn_r_type = R_IA64_REL64LSB;
3100 dynindx = 0;
3101 addend = value;
3104 if (bfd_big_endian (abfd))
3106 switch (dyn_r_type)
3108 case R_IA64_REL64LSB:
3109 dyn_r_type = R_IA64_REL64MSB;
3110 break;
3111 case R_IA64_DIR64LSB:
3112 dyn_r_type = R_IA64_DIR64MSB;
3113 break;
3114 case R_IA64_FPTR64LSB:
3115 dyn_r_type = R_IA64_FPTR64MSB;
3116 break;
3117 default:
3118 BFD_ASSERT (false);
3119 break;
3123 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3124 ia64_info->rel_got_sec,
3125 dyn_i->got_offset, dyn_r_type,
3126 dynindx, addend);
3130 /* Return the address of the linkage table entry. */
3131 value = (got_sec->output_section->vma
3132 + got_sec->output_offset
3133 + dyn_i->got_offset);
3135 return value;
3138 /* Fill in a function descriptor consisting of the function's code
3139 address and its global pointer. Return the descriptor's address. */
3141 static bfd_vma
3142 set_fptr_entry (abfd, info, dyn_i, value)
3143 bfd *abfd;
3144 struct bfd_link_info *info;
3145 struct elfNN_ia64_dyn_sym_info *dyn_i;
3146 bfd_vma value;
3148 struct elfNN_ia64_link_hash_table *ia64_info;
3149 asection *fptr_sec;
3151 ia64_info = elfNN_ia64_hash_table (info);
3152 fptr_sec = ia64_info->fptr_sec;
3154 if (!dyn_i->fptr_done)
3156 dyn_i->fptr_done = 1;
3158 /* Fill in the function descriptor. */
3159 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3160 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3161 fptr_sec->contents + dyn_i->fptr_offset + 8);
3164 /* Return the descriptor's address. */
3165 value = (fptr_sec->output_section->vma
3166 + fptr_sec->output_offset
3167 + dyn_i->fptr_offset);
3169 return value;
3172 /* Fill in a PLTOFF entry consisting of the function's code address
3173 and its global pointer. Return the descriptor's address. */
3175 static bfd_vma
3176 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3177 bfd *abfd;
3178 struct bfd_link_info *info;
3179 struct elfNN_ia64_dyn_sym_info *dyn_i;
3180 bfd_vma value;
3181 boolean is_plt;
3183 struct elfNN_ia64_link_hash_table *ia64_info;
3184 asection *pltoff_sec;
3186 ia64_info = elfNN_ia64_hash_table (info);
3187 pltoff_sec = ia64_info->pltoff_sec;
3189 /* Don't do anything if this symbol uses a real PLT entry. In
3190 that case, we'll fill this in during finish_dynamic_symbol. */
3191 if ((! dyn_i->want_plt || is_plt)
3192 && !dyn_i->pltoff_done)
3194 bfd_vma gp = _bfd_get_gp_value (abfd);
3196 /* Fill in the function descriptor. */
3197 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3198 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3200 /* Install dynamic relocations if needed. */
3201 if (!is_plt && info->shared)
3203 unsigned int dyn_r_type;
3205 if (bfd_big_endian (abfd))
3206 dyn_r_type = R_IA64_REL64MSB;
3207 else
3208 dyn_r_type = R_IA64_REL64LSB;
3210 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3211 ia64_info->rel_pltoff_sec,
3212 dyn_i->pltoff_offset,
3213 dyn_r_type, 0, value);
3214 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3215 ia64_info->rel_pltoff_sec,
3216 dyn_i->pltoff_offset + 8,
3217 dyn_r_type, 0, gp);
3220 dyn_i->pltoff_done = 1;
3223 /* Return the descriptor's address. */
3224 value = (pltoff_sec->output_section->vma
3225 + pltoff_sec->output_offset
3226 + dyn_i->pltoff_offset);
3228 return value;
3231 /* Called through qsort to sort the .IA_64.unwind section during a
3232 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3233 to the output bfd so we can do proper endianness frobbing. */
3235 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3237 static int
3238 elfNN_ia64_unwind_entry_compare (a, b)
3239 const PTR a;
3240 const PTR b;
3242 bfd_vma av, bv;
3244 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3245 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3247 return (av < bv ? -1 : av > bv ? 1 : 0);
3250 static boolean
3251 elfNN_ia64_final_link (abfd, info)
3252 bfd *abfd;
3253 struct bfd_link_info *info;
3255 struct elfNN_ia64_link_hash_table *ia64_info;
3256 asection *unwind_output_sec;
3258 ia64_info = elfNN_ia64_hash_table (info);
3260 /* Make sure we've got ourselves a nice fat __gp value. */
3261 if (!info->relocateable)
3263 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3264 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3265 struct elf_link_hash_entry *gp;
3266 bfd_vma gp_val;
3267 asection *os;
3269 /* Find the min and max vma of all sections marked short. Also
3270 collect min and max vma of any type, for use in selecting a
3271 nice gp. */
3272 for (os = abfd->sections; os ; os = os->next)
3274 bfd_vma lo, hi;
3276 if ((os->flags & SEC_ALLOC) == 0)
3277 continue;
3279 lo = os->vma;
3280 hi = os->vma + os->_raw_size;
3281 if (hi < lo)
3282 hi = (bfd_vma) -1;
3284 if (min_vma > lo)
3285 min_vma = lo;
3286 if (max_vma < hi)
3287 max_vma = hi;
3288 if (os->flags & SEC_SMALL_DATA)
3290 if (min_short_vma > lo)
3291 min_short_vma = lo;
3292 if (max_short_vma < hi)
3293 max_short_vma = hi;
3297 /* See if the user wants to force a value. */
3298 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
3299 false, false);
3301 if (gp
3302 && (gp->root.type == bfd_link_hash_defined
3303 || gp->root.type == bfd_link_hash_defweak))
3305 asection *gp_sec = gp->root.u.def.section;
3306 gp_val = (gp->root.u.def.value
3307 + gp_sec->output_section->vma
3308 + gp_sec->output_offset);
3310 else
3312 /* Pick a sensible value. */
3314 asection *got_sec = ia64_info->got_sec;
3316 /* Start with just the address of the .got. */
3317 if (got_sec)
3318 gp_val = got_sec->output_section->vma;
3319 else if (max_short_vma != 0)
3320 gp_val = min_short_vma;
3321 else
3322 gp_val = min_vma;
3324 /* If it is possible to address the entire image, but we
3325 don't with the choice above, adjust. */
3326 if (max_vma - min_vma < 0x400000
3327 && max_vma - gp_val <= 0x200000
3328 && gp_val - min_vma > 0x200000)
3329 gp_val = min_vma + 0x200000;
3330 else if (max_short_vma != 0)
3332 /* If we don't cover all the short data, adjust. */
3333 if (max_short_vma - gp_val >= 0x200000)
3334 gp_val = min_short_vma + 0x200000;
3336 /* If we're addressing stuff past the end, adjust back. */
3337 if (gp_val > max_vma)
3338 gp_val = max_vma - 0x200000 + 8;
3342 /* Validate whether all SHF_IA_64_SHORT sections are within
3343 range of the chosen GP. */
3345 if (max_short_vma != 0)
3347 if (max_short_vma - min_short_vma >= 0x400000)
3349 (*_bfd_error_handler)
3350 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3351 bfd_get_filename (abfd),
3352 (unsigned long) (max_short_vma - min_short_vma));
3353 return false;
3355 else if ((gp_val > min_short_vma
3356 && gp_val - min_short_vma > 0x200000)
3357 || (gp_val < max_short_vma
3358 && max_short_vma - gp_val >= 0x200000))
3360 (*_bfd_error_handler)
3361 (_("%s: __gp does not cover short data segment"),
3362 bfd_get_filename (abfd));
3363 return false;
3367 _bfd_set_gp_value (abfd, gp_val);
3369 if (gp)
3371 gp->root.type = bfd_link_hash_defined;
3372 gp->root.u.def.value = gp_val;
3373 gp->root.u.def.section = bfd_abs_section_ptr;
3377 /* If we're producing a final executable, we need to sort the contents
3378 of the .IA_64.unwind section. Force this section to be relocated
3379 into memory rather than written immediately to the output file. */
3380 unwind_output_sec = NULL;
3381 if (!info->relocateable)
3383 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3384 if (s)
3386 unwind_output_sec = s->output_section;
3387 unwind_output_sec->contents
3388 = bfd_malloc (unwind_output_sec->_raw_size);
3389 if (unwind_output_sec->contents == NULL)
3390 return false;
3394 /* Invoke the regular ELF backend linker to do all the work. */
3395 if (!bfd_elfNN_bfd_final_link (abfd, info))
3396 return false;
3398 if (unwind_output_sec)
3400 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3401 qsort (unwind_output_sec->contents,
3402 (size_t) (unwind_output_sec->_raw_size / 24),
3404 elfNN_ia64_unwind_entry_compare);
3406 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3407 unwind_output_sec->contents, (bfd_vma) 0,
3408 unwind_output_sec->_raw_size))
3409 return false;
3412 return true;
3415 static boolean
3416 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3417 contents, relocs, local_syms, local_sections)
3418 bfd *output_bfd;
3419 struct bfd_link_info *info;
3420 bfd *input_bfd;
3421 asection *input_section;
3422 bfd_byte *contents;
3423 Elf_Internal_Rela *relocs;
3424 Elf_Internal_Sym *local_syms;
3425 asection **local_sections;
3427 struct elfNN_ia64_link_hash_table *ia64_info;
3428 Elf_Internal_Shdr *symtab_hdr;
3429 Elf_Internal_Rela *rel;
3430 Elf_Internal_Rela *relend;
3431 asection *srel;
3432 boolean ret_val = true; /* for non-fatal errors */
3433 bfd_vma gp_val;
3435 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3436 ia64_info = elfNN_ia64_hash_table (info);
3438 /* Infect various flags from the input section to the output section. */
3439 if (info->relocateable)
3441 bfd_vma flags;
3443 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3444 flags &= SHF_IA_64_NORECOV;
3446 elf_section_data(input_section->output_section)
3447 ->this_hdr.sh_flags |= flags;
3450 gp_val = _bfd_get_gp_value (output_bfd);
3451 srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3453 rel = relocs;
3454 relend = relocs + input_section->reloc_count;
3455 for (; rel < relend; ++rel)
3457 struct elf_link_hash_entry *h;
3458 struct elfNN_ia64_dyn_sym_info *dyn_i;
3459 bfd_reloc_status_type r;
3460 reloc_howto_type *howto;
3461 unsigned long r_symndx;
3462 Elf_Internal_Sym *sym;
3463 unsigned int r_type;
3464 bfd_vma value;
3465 asection *sym_sec;
3466 bfd_byte *hit_addr;
3467 boolean dynamic_symbol_p;
3468 boolean undef_weak_ref;
3470 r_type = ELFNN_R_TYPE (rel->r_info);
3471 if (r_type > R_IA64_MAX_RELOC_CODE)
3473 (*_bfd_error_handler)
3474 (_("%s: unknown relocation type %d"),
3475 bfd_archive_filename (input_bfd), (int)r_type);
3476 bfd_set_error (bfd_error_bad_value);
3477 ret_val = false;
3478 continue;
3480 howto = lookup_howto (r_type);
3481 r_symndx = ELFNN_R_SYM (rel->r_info);
3483 if (info->relocateable)
3485 /* This is a relocateable link. We don't have to change
3486 anything, unless the reloc is against a section symbol,
3487 in which case we have to adjust according to where the
3488 section symbol winds up in the output section. */
3489 if (r_symndx < symtab_hdr->sh_info)
3491 sym = local_syms + r_symndx;
3492 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3494 sym_sec = local_sections[r_symndx];
3495 rel->r_addend += sym_sec->output_offset;
3498 continue;
3501 /* This is a final link. */
3503 h = NULL;
3504 sym = NULL;
3505 sym_sec = NULL;
3506 undef_weak_ref = false;
3508 if (r_symndx < symtab_hdr->sh_info)
3510 /* Reloc against local symbol. */
3511 sym = local_syms + r_symndx;
3512 sym_sec = local_sections[r_symndx];
3513 value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel);
3514 if ((sym_sec->flags & SEC_MERGE)
3515 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3516 && (elf_section_data (sym_sec)->sec_info_type
3517 == ELF_INFO_TYPE_MERGE))
3519 struct elfNN_ia64_local_hash_entry *loc_h;
3521 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, false);
3522 if (loc_h && ! loc_h->sec_merge_done)
3524 struct elfNN_ia64_dyn_sym_info *dynent;
3525 asection *msec;
3527 for (dynent = loc_h->info; dynent; dynent = dynent->next)
3529 msec = sym_sec;
3530 dynent->addend =
3531 _bfd_merged_section_offset (output_bfd, &msec,
3532 elf_section_data (msec)->
3533 sec_info,
3534 sym->st_value
3535 + dynent->addend,
3536 (bfd_vma) 0);
3537 dynent->addend -= sym->st_value;
3538 dynent->addend += msec->output_section->vma
3539 + msec->output_offset
3540 - sym_sec->output_section->vma
3541 - sym_sec->output_offset;
3543 loc_h->sec_merge_done = 1;
3547 else
3549 long indx;
3551 /* Reloc against global symbol. */
3552 indx = r_symndx - symtab_hdr->sh_info;
3553 h = elf_sym_hashes (input_bfd)[indx];
3554 while (h->root.type == bfd_link_hash_indirect
3555 || h->root.type == bfd_link_hash_warning)
3556 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3558 value = 0;
3559 if (h->root.type == bfd_link_hash_defined
3560 || h->root.type == bfd_link_hash_defweak)
3562 sym_sec = h->root.u.def.section;
3564 /* Detect the cases that sym_sec->output_section is
3565 expected to be NULL -- all cases in which the symbol
3566 is defined in another shared module. This includes
3567 PLT relocs for which we've created a PLT entry and
3568 other relocs for which we're prepared to create
3569 dynamic relocations. */
3570 /* ??? Just accept it NULL and continue. */
3572 if (sym_sec->output_section != NULL)
3574 value = (h->root.u.def.value
3575 + sym_sec->output_section->vma
3576 + sym_sec->output_offset);
3579 else if (h->root.type == bfd_link_hash_undefweak)
3580 undef_weak_ref = true;
3581 else if (info->shared
3582 && (!info->symbolic || info->allow_shlib_undefined)
3583 && !info->no_undefined
3584 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3586 else
3588 if (! ((*info->callbacks->undefined_symbol)
3589 (info, h->root.root.string, input_bfd,
3590 input_section, rel->r_offset,
3591 (!info->shared || info->no_undefined
3592 || ELF_ST_VISIBILITY (h->other)))))
3593 return false;
3594 ret_val = false;
3595 continue;
3599 hit_addr = contents + rel->r_offset;
3600 value += rel->r_addend;
3601 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3603 switch (r_type)
3605 case R_IA64_NONE:
3606 case R_IA64_LDXMOV:
3607 continue;
3609 case R_IA64_IMM14:
3610 case R_IA64_IMM22:
3611 case R_IA64_IMM64:
3612 case R_IA64_DIR32MSB:
3613 case R_IA64_DIR32LSB:
3614 case R_IA64_DIR64MSB:
3615 case R_IA64_DIR64LSB:
3616 /* Install a dynamic relocation for this reloc. */
3617 if ((dynamic_symbol_p || info->shared
3618 || (elfNN_ia64_aix_vec (info->hash->creator)
3619 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3620 && (!h || strcmp (h->root.root.string,
3621 "__GLOB_DATA_PTR") != 0)))
3622 && r_symndx != 0
3623 && (input_section->flags & SEC_ALLOC) != 0)
3625 unsigned int dyn_r_type;
3626 long dynindx;
3627 bfd_vma addend;
3629 BFD_ASSERT (srel != NULL);
3631 /* If we don't need dynamic symbol lookup, find a
3632 matching RELATIVE relocation. */
3633 dyn_r_type = r_type;
3634 if (dynamic_symbol_p)
3636 dynindx = h->dynindx;
3637 addend = rel->r_addend;
3638 value = 0;
3640 else
3642 switch (r_type)
3644 case R_IA64_DIR32MSB:
3645 dyn_r_type = R_IA64_REL32MSB;
3646 break;
3647 case R_IA64_DIR32LSB:
3648 dyn_r_type = R_IA64_REL32LSB;
3649 break;
3650 case R_IA64_DIR64MSB:
3651 dyn_r_type = R_IA64_REL64MSB;
3652 break;
3653 case R_IA64_DIR64LSB:
3654 dyn_r_type = R_IA64_REL64LSB;
3655 break;
3657 default:
3658 /* We can't represent this without a dynamic symbol.
3659 Adjust the relocation to be against an output
3660 section symbol, which are always present in the
3661 dynamic symbol table. */
3662 /* ??? People shouldn't be doing non-pic code in
3663 shared libraries. Hork. */
3664 (*_bfd_error_handler)
3665 (_("%s: linking non-pic code in a shared library"),
3666 bfd_archive_filename (input_bfd));
3667 ret_val = false;
3668 continue;
3670 dynindx = 0;
3671 addend = value;
3674 if (elfNN_ia64_aix_vec (info->hash->creator))
3675 rel->r_addend = value;
3676 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3677 srel, rel->r_offset, dyn_r_type,
3678 dynindx, addend);
3680 /* FALLTHRU */
3682 case R_IA64_LTV32MSB:
3683 case R_IA64_LTV32LSB:
3684 case R_IA64_LTV64MSB:
3685 case R_IA64_LTV64LSB:
3686 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3687 break;
3689 case R_IA64_GPREL22:
3690 case R_IA64_GPREL64I:
3691 case R_IA64_GPREL32MSB:
3692 case R_IA64_GPREL32LSB:
3693 case R_IA64_GPREL64MSB:
3694 case R_IA64_GPREL64LSB:
3695 if (dynamic_symbol_p)
3697 (*_bfd_error_handler)
3698 (_("%s: @gprel relocation against dynamic symbol %s"),
3699 bfd_archive_filename (input_bfd), h->root.root.string);
3700 ret_val = false;
3701 continue;
3703 value -= gp_val;
3704 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3705 break;
3707 case R_IA64_LTOFF22:
3708 case R_IA64_LTOFF22X:
3709 case R_IA64_LTOFF64I:
3710 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3711 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
3712 rel->r_addend, value, R_IA64_DIR64LSB);
3713 value -= gp_val;
3714 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3715 break;
3717 case R_IA64_PLTOFF22:
3718 case R_IA64_PLTOFF64I:
3719 case R_IA64_PLTOFF64MSB:
3720 case R_IA64_PLTOFF64LSB:
3721 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3722 value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
3723 value -= gp_val;
3724 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3725 break;
3727 case R_IA64_FPTR64I:
3728 case R_IA64_FPTR32MSB:
3729 case R_IA64_FPTR32LSB:
3730 case R_IA64_FPTR64MSB:
3731 case R_IA64_FPTR64LSB:
3732 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3733 if (dyn_i->want_fptr)
3735 if (!undef_weak_ref)
3736 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3738 else
3740 long dynindx;
3742 /* Otherwise, we expect the dynamic linker to create
3743 the entry. */
3745 if (h)
3747 if (h->dynindx != -1)
3748 dynindx = h->dynindx;
3749 else
3750 dynindx = (_bfd_elf_link_lookup_local_dynindx
3751 (info, h->root.u.def.section->owner,
3752 global_sym_index (h)));
3754 else
3756 dynindx = (_bfd_elf_link_lookup_local_dynindx
3757 (info, input_bfd, (long) r_symndx));
3760 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3761 srel, rel->r_offset, r_type,
3762 dynindx, rel->r_addend);
3763 value = 0;
3766 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3767 break;
3769 case R_IA64_LTOFF_FPTR22:
3770 case R_IA64_LTOFF_FPTR64I:
3771 case R_IA64_LTOFF_FPTR32MSB:
3772 case R_IA64_LTOFF_FPTR32LSB:
3773 case R_IA64_LTOFF_FPTR64MSB:
3774 case R_IA64_LTOFF_FPTR64LSB:
3776 long dynindx;
3778 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3779 if (dyn_i->want_fptr)
3781 BFD_ASSERT (h == NULL || h->dynindx == -1)
3782 if (!undef_weak_ref)
3783 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3784 dynindx = -1;
3786 else
3788 /* Otherwise, we expect the dynamic linker to create
3789 the entry. */
3790 if (h)
3792 if (h->dynindx != -1)
3793 dynindx = h->dynindx;
3794 else
3795 dynindx = (_bfd_elf_link_lookup_local_dynindx
3796 (info, h->root.u.def.section->owner,
3797 global_sym_index (h)));
3799 else
3800 dynindx = (_bfd_elf_link_lookup_local_dynindx
3801 (info, input_bfd, (long) r_symndx));
3802 value = 0;
3805 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
3806 rel->r_addend, value, R_IA64_FPTR64LSB);
3807 value -= gp_val;
3808 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3810 break;
3812 case R_IA64_PCREL32MSB:
3813 case R_IA64_PCREL32LSB:
3814 case R_IA64_PCREL64MSB:
3815 case R_IA64_PCREL64LSB:
3816 /* Install a dynamic relocation for this reloc. */
3817 if ((dynamic_symbol_p
3818 || elfNN_ia64_aix_vec (info->hash->creator))
3819 && r_symndx != 0)
3821 BFD_ASSERT (srel != NULL);
3823 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3824 srel, rel->r_offset, r_type,
3825 h->dynindx, rel->r_addend);
3827 goto finish_pcrel;
3829 case R_IA64_PCREL21BI:
3830 case R_IA64_PCREL21F:
3831 case R_IA64_PCREL21M:
3832 /* ??? These two are only used for speculation fixup code.
3833 They should never be dynamic. */
3834 if (dynamic_symbol_p)
3836 (*_bfd_error_handler)
3837 (_("%s: dynamic relocation against speculation fixup"),
3838 bfd_archive_filename (input_bfd));
3839 ret_val = false;
3840 continue;
3842 if (undef_weak_ref)
3844 (*_bfd_error_handler)
3845 (_("%s: speculation fixup against undefined weak symbol"),
3846 bfd_archive_filename (input_bfd));
3847 ret_val = false;
3848 continue;
3850 goto finish_pcrel;
3852 case R_IA64_PCREL21B:
3853 case R_IA64_PCREL60B:
3854 /* We should have created a PLT entry for any dynamic symbol. */
3855 dyn_i = NULL;
3856 if (h)
3857 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3859 if (dyn_i && dyn_i->want_plt2)
3861 /* Should have caught this earlier. */
3862 BFD_ASSERT (rel->r_addend == 0);
3864 value = (ia64_info->plt_sec->output_section->vma
3865 + ia64_info->plt_sec->output_offset
3866 + dyn_i->plt2_offset);
3868 else
3870 /* Since there's no PLT entry, Validate that this is
3871 locally defined. */
3872 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
3874 /* If the symbol is undef_weak, we shouldn't be trying
3875 to call it. There's every chance that we'd wind up
3876 with an out-of-range fixup here. Don't bother setting
3877 any value at all. */
3878 if (undef_weak_ref)
3879 continue;
3881 goto finish_pcrel;
3883 case R_IA64_PCREL22:
3884 case R_IA64_PCREL64I:
3885 finish_pcrel:
3886 /* Make pc-relative. */
3887 value -= (input_section->output_section->vma
3888 + input_section->output_offset
3889 + rel->r_offset) & ~ (bfd_vma) 0x3;
3890 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3891 break;
3893 case R_IA64_SEGREL32MSB:
3894 case R_IA64_SEGREL32LSB:
3895 case R_IA64_SEGREL64MSB:
3896 case R_IA64_SEGREL64LSB:
3897 if (r_symndx == 0)
3899 /* If the input section was discarded from the output, then
3900 do nothing. */
3901 r = bfd_reloc_ok;
3903 else
3905 struct elf_segment_map *m;
3906 Elf_Internal_Phdr *p;
3908 /* Find the segment that contains the output_section. */
3909 for (m = elf_tdata (output_bfd)->segment_map,
3910 p = elf_tdata (output_bfd)->phdr;
3911 m != NULL;
3912 m = m->next, p++)
3914 int i;
3915 for (i = m->count - 1; i >= 0; i--)
3916 if (m->sections[i] == sym_sec->output_section)
3917 break;
3918 if (i >= 0)
3919 break;
3922 if (m == NULL)
3924 r = bfd_reloc_notsupported;
3926 else
3928 /* The VMA of the segment is the vaddr of the associated
3929 program header. */
3930 if (value > p->p_vaddr)
3931 value -= p->p_vaddr;
3932 else
3933 value = 0;
3934 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
3935 r_type);
3937 break;
3940 case R_IA64_SECREL32MSB:
3941 case R_IA64_SECREL32LSB:
3942 case R_IA64_SECREL64MSB:
3943 case R_IA64_SECREL64LSB:
3944 /* Make output-section relative. */
3945 if (value > input_section->output_section->vma)
3946 value -= input_section->output_section->vma;
3947 else
3948 value = 0;
3949 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3950 break;
3952 case R_IA64_IPLTMSB:
3953 case R_IA64_IPLTLSB:
3954 /* Install a dynamic relocation for this reloc. */
3955 if ((dynamic_symbol_p || info->shared)
3956 && (input_section->flags & SEC_ALLOC) != 0)
3958 BFD_ASSERT (srel != NULL);
3960 /* If we don't need dynamic symbol lookup, install two
3961 RELATIVE relocations. */
3962 if (! dynamic_symbol_p)
3964 unsigned int dyn_r_type;
3966 if (r_type == R_IA64_IPLTMSB)
3967 dyn_r_type = R_IA64_REL64MSB;
3968 else
3969 dyn_r_type = R_IA64_REL64LSB;
3971 elfNN_ia64_install_dyn_reloc (output_bfd, info,
3972 input_section,
3973 srel, rel->r_offset,
3974 dyn_r_type, 0, value);
3975 elfNN_ia64_install_dyn_reloc (output_bfd, info,
3976 input_section,
3977 srel, rel->r_offset + 8,
3978 dyn_r_type, 0, gp_val);
3980 else
3981 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3982 srel, rel->r_offset, r_type,
3983 h->dynindx, rel->r_addend);
3986 if (r_type == R_IA64_IPLTMSB)
3987 r_type = R_IA64_DIR64MSB;
3988 else
3989 r_type = R_IA64_DIR64LSB;
3990 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3991 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
3992 r_type);
3993 break;
3995 default:
3996 r = bfd_reloc_notsupported;
3997 break;
4000 switch (r)
4002 case bfd_reloc_ok:
4003 break;
4005 case bfd_reloc_undefined:
4006 /* This can happen for global table relative relocs if
4007 __gp is undefined. This is a panic situation so we
4008 don't try to continue. */
4009 (*info->callbacks->undefined_symbol)
4010 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4011 return false;
4013 case bfd_reloc_notsupported:
4015 const char *name;
4017 if (h)
4018 name = h->root.root.string;
4019 else
4021 name = bfd_elf_string_from_elf_section (input_bfd,
4022 symtab_hdr->sh_link,
4023 sym->st_name);
4024 if (name == NULL)
4025 return false;
4026 if (*name == '\0')
4027 name = bfd_section_name (input_bfd, input_section);
4029 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4030 name, input_bfd,
4031 input_section, rel->r_offset))
4032 return false;
4033 ret_val = false;
4035 break;
4037 case bfd_reloc_dangerous:
4038 case bfd_reloc_outofrange:
4039 case bfd_reloc_overflow:
4040 default:
4042 const char *name;
4044 if (h)
4045 name = h->root.root.string;
4046 else
4048 name = bfd_elf_string_from_elf_section (input_bfd,
4049 symtab_hdr->sh_link,
4050 sym->st_name);
4051 if (name == NULL)
4052 return false;
4053 if (*name == '\0')
4054 name = bfd_section_name (input_bfd, input_section);
4056 if (!(*info->callbacks->reloc_overflow) (info, name,
4057 howto->name,
4058 (bfd_vma) 0,
4059 input_bfd,
4060 input_section,
4061 rel->r_offset))
4062 return false;
4063 ret_val = false;
4065 break;
4069 return ret_val;
4072 static boolean
4073 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4074 bfd *output_bfd;
4075 struct bfd_link_info *info;
4076 struct elf_link_hash_entry *h;
4077 Elf_Internal_Sym *sym;
4079 struct elfNN_ia64_link_hash_table *ia64_info;
4080 struct elfNN_ia64_dyn_sym_info *dyn_i;
4082 ia64_info = elfNN_ia64_hash_table (info);
4083 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
4085 /* Fill in the PLT data, if required. */
4086 if (dyn_i && dyn_i->want_plt)
4088 Elf_Internal_Rela outrel;
4089 bfd_byte *loc;
4090 asection *plt_sec;
4091 bfd_vma plt_addr, pltoff_addr, gp_val, index;
4092 ElfNN_External_Rela *rel;
4094 gp_val = _bfd_get_gp_value (output_bfd);
4096 /* Initialize the minimal PLT entry. */
4098 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4099 plt_sec = ia64_info->plt_sec;
4100 loc = plt_sec->contents + dyn_i->plt_offset;
4102 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4103 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4104 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4105 R_IA64_PCREL21B);
4107 plt_addr = (plt_sec->output_section->vma
4108 + plt_sec->output_offset
4109 + dyn_i->plt_offset);
4110 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
4112 /* Initialize the FULL PLT entry, if needed. */
4113 if (dyn_i->want_plt2)
4115 loc = plt_sec->contents + dyn_i->plt2_offset;
4117 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4118 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4119 R_IA64_IMM22);
4121 /* Mark the symbol as undefined, rather than as defined in the
4122 plt section. Leave the value alone. */
4123 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4124 first place. But perhaps elflink.h did some for us. */
4125 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4126 sym->st_shndx = SHN_UNDEF;
4129 /* Create the dynamic relocation. */
4130 outrel.r_offset = pltoff_addr;
4131 if (bfd_little_endian (output_bfd))
4132 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4133 else
4134 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4135 outrel.r_addend = 0;
4137 /* This is fun. In the .IA_64.pltoff section, we've got entries
4138 that correspond both to real PLT entries, and those that
4139 happened to resolve to local symbols but need to be created
4140 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4141 relocations for the real PLT should come at the end of the
4142 section, so that they can be indexed by plt entry at runtime.
4144 We emitted all of the relocations for the non-PLT @pltoff
4145 entries during relocate_section. So we can consider the
4146 existing sec->reloc_count to be the base of the array of
4147 PLT relocations. */
4149 rel = (ElfNN_External_Rela *)ia64_info->rel_pltoff_sec->contents;
4150 rel += ia64_info->rel_pltoff_sec->reloc_count;
4152 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, rel + index);
4155 /* Mark some specially defined symbols as absolute. */
4156 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4157 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4158 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4159 sym->st_shndx = SHN_ABS;
4161 return true;
4164 static boolean
4165 elfNN_ia64_finish_dynamic_sections (abfd, info)
4166 bfd *abfd;
4167 struct bfd_link_info *info;
4169 struct elfNN_ia64_link_hash_table *ia64_info;
4170 bfd *dynobj;
4172 ia64_info = elfNN_ia64_hash_table (info);
4173 dynobj = ia64_info->root.dynobj;
4175 if (elf_hash_table (info)->dynamic_sections_created)
4177 ElfNN_External_Dyn *dyncon, *dynconend;
4178 asection *sdyn, *sgotplt;
4179 bfd_vma gp_val;
4181 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4182 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4183 BFD_ASSERT (sdyn != NULL);
4184 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4185 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4187 gp_val = _bfd_get_gp_value (abfd);
4189 for (; dyncon < dynconend; dyncon++)
4191 Elf_Internal_Dyn dyn;
4193 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4195 switch (dyn.d_tag)
4197 case DT_PLTGOT:
4198 dyn.d_un.d_ptr = gp_val;
4199 break;
4201 case DT_PLTRELSZ:
4202 dyn.d_un.d_val = (ia64_info->minplt_entries
4203 * sizeof (ElfNN_External_Rela));
4204 break;
4206 case DT_JMPREL:
4207 /* See the comment above in finish_dynamic_symbol. */
4208 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4209 + ia64_info->rel_pltoff_sec->output_offset
4210 + (ia64_info->rel_pltoff_sec->reloc_count
4211 * sizeof (ElfNN_External_Rela)));
4212 break;
4214 case DT_IA_64_PLT_RESERVE:
4215 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4216 + sgotplt->output_offset);
4217 break;
4219 case DT_RELASZ:
4220 /* Do not have RELASZ include JMPREL. This makes things
4221 easier on ld.so. This is not what the rest of BFD set up. */
4222 dyn.d_un.d_val -= (ia64_info->minplt_entries
4223 * sizeof (ElfNN_External_Rela));
4224 break;
4227 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4230 /* Initialize the PLT0 entry */
4231 if (ia64_info->plt_sec)
4233 bfd_byte *loc = ia64_info->plt_sec->contents;
4234 bfd_vma pltres;
4236 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4238 pltres = (sgotplt->output_section->vma
4239 + sgotplt->output_offset
4240 - gp_val);
4242 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4246 return true;
4249 /* ELF file flag handling: */
4251 /* Function to keep IA-64 specific file flags. */
4252 static boolean
4253 elfNN_ia64_set_private_flags (abfd, flags)
4254 bfd *abfd;
4255 flagword flags;
4257 BFD_ASSERT (!elf_flags_init (abfd)
4258 || elf_elfheader (abfd)->e_flags == flags);
4260 elf_elfheader (abfd)->e_flags = flags;
4261 elf_flags_init (abfd) = true;
4262 return true;
4265 /* Copy backend specific data from one object module to another */
4266 static boolean
4267 elfNN_ia64_copy_private_bfd_data (ibfd, obfd)
4268 bfd *ibfd, *obfd;
4270 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4271 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4272 return true;
4274 BFD_ASSERT (!elf_flags_init (obfd)
4275 || (elf_elfheader (obfd)->e_flags
4276 == elf_elfheader (ibfd)->e_flags));
4278 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
4279 elf_flags_init (obfd) = true;
4280 return true;
4283 /* Merge backend specific data from an object file to the output
4284 object file when linking. */
4285 static boolean
4286 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4287 bfd *ibfd, *obfd;
4289 flagword out_flags;
4290 flagword in_flags;
4291 boolean ok = true;
4293 /* Don't even pretend to support mixed-format linking. */
4294 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4295 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4296 return false;
4298 in_flags = elf_elfheader (ibfd)->e_flags;
4299 out_flags = elf_elfheader (obfd)->e_flags;
4301 if (! elf_flags_init (obfd))
4303 elf_flags_init (obfd) = true;
4304 elf_elfheader (obfd)->e_flags = in_flags;
4306 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4307 && bfd_get_arch_info (obfd)->the_default)
4309 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4310 bfd_get_mach (ibfd));
4313 return true;
4316 /* Check flag compatibility. */
4317 if (in_flags == out_flags)
4318 return true;
4320 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4321 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4322 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4324 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4326 (*_bfd_error_handler)
4327 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4328 bfd_archive_filename (ibfd));
4330 bfd_set_error (bfd_error_bad_value);
4331 ok = false;
4333 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4335 (*_bfd_error_handler)
4336 (_("%s: linking big-endian files with little-endian files"),
4337 bfd_archive_filename (ibfd));
4339 bfd_set_error (bfd_error_bad_value);
4340 ok = false;
4342 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4344 (*_bfd_error_handler)
4345 (_("%s: linking 64-bit files with 32-bit files"),
4346 bfd_archive_filename (ibfd));
4348 bfd_set_error (bfd_error_bad_value);
4349 ok = false;
4351 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4353 (*_bfd_error_handler)
4354 (_("%s: linking constant-gp files with non-constant-gp files"),
4355 bfd_archive_filename (ibfd));
4357 bfd_set_error (bfd_error_bad_value);
4358 ok = false;
4360 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4361 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4363 (*_bfd_error_handler)
4364 (_("%s: linking auto-pic files with non-auto-pic files"),
4365 bfd_archive_filename (ibfd));
4367 bfd_set_error (bfd_error_bad_value);
4368 ok = false;
4371 return ok;
4374 static boolean
4375 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4376 bfd *abfd;
4377 PTR ptr;
4379 FILE *file = (FILE *) ptr;
4380 flagword flags = elf_elfheader (abfd)->e_flags;
4382 BFD_ASSERT (abfd != NULL && ptr != NULL);
4384 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4385 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4386 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4387 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4388 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4389 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4390 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4391 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4392 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4394 _bfd_elf_print_private_bfd_data (abfd, ptr);
4395 return true;
4398 static enum elf_reloc_type_class
4399 elfNN_ia64_reloc_type_class (rela)
4400 const Elf_Internal_Rela *rela;
4402 switch ((int) ELFNN_R_TYPE (rela->r_info))
4404 case R_IA64_REL32MSB:
4405 case R_IA64_REL32LSB:
4406 case R_IA64_REL64MSB:
4407 case R_IA64_REL64LSB:
4408 return reloc_class_relative;
4409 case R_IA64_IPLTMSB:
4410 case R_IA64_IPLTLSB:
4411 return reloc_class_plt;
4412 case R_IA64_COPY:
4413 return reloc_class_copy;
4414 default:
4415 return reloc_class_normal;
4419 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4420 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4421 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4422 #define TARGET_BIG_NAME "elfNN-ia64-big"
4423 #define ELF_ARCH bfd_arch_ia64
4424 #define ELF_MACHINE_CODE EM_IA_64
4425 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4426 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4427 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4429 #define elf_backend_section_from_shdr \
4430 elfNN_ia64_section_from_shdr
4431 #define elf_backend_section_flags \
4432 elfNN_ia64_section_flags
4433 #define elf_backend_fake_sections \
4434 elfNN_ia64_fake_sections
4435 #define elf_backend_final_write_processing \
4436 elfNN_ia64_final_write_processing
4437 #define elf_backend_add_symbol_hook \
4438 elfNN_ia64_add_symbol_hook
4439 #define elf_backend_additional_program_headers \
4440 elfNN_ia64_additional_program_headers
4441 #define elf_backend_modify_segment_map \
4442 elfNN_ia64_modify_segment_map
4443 #define elf_info_to_howto \
4444 elfNN_ia64_info_to_howto
4446 #define bfd_elfNN_bfd_reloc_type_lookup \
4447 elfNN_ia64_reloc_type_lookup
4448 #define bfd_elfNN_bfd_is_local_label_name \
4449 elfNN_ia64_is_local_label_name
4450 #define bfd_elfNN_bfd_relax_section \
4451 elfNN_ia64_relax_section
4453 /* Stuff for the BFD linker: */
4454 #define bfd_elfNN_bfd_link_hash_table_create \
4455 elfNN_ia64_hash_table_create
4456 #define elf_backend_create_dynamic_sections \
4457 elfNN_ia64_create_dynamic_sections
4458 #define elf_backend_check_relocs \
4459 elfNN_ia64_check_relocs
4460 #define elf_backend_adjust_dynamic_symbol \
4461 elfNN_ia64_adjust_dynamic_symbol
4462 #define elf_backend_size_dynamic_sections \
4463 elfNN_ia64_size_dynamic_sections
4464 #define elf_backend_relocate_section \
4465 elfNN_ia64_relocate_section
4466 #define elf_backend_finish_dynamic_symbol \
4467 elfNN_ia64_finish_dynamic_symbol
4468 #define elf_backend_finish_dynamic_sections \
4469 elfNN_ia64_finish_dynamic_sections
4470 #define bfd_elfNN_bfd_final_link \
4471 elfNN_ia64_final_link
4473 #define bfd_elfNN_bfd_copy_private_bfd_data \
4474 elfNN_ia64_copy_private_bfd_data
4475 #define bfd_elfNN_bfd_merge_private_bfd_data \
4476 elfNN_ia64_merge_private_bfd_data
4477 #define bfd_elfNN_bfd_set_private_flags \
4478 elfNN_ia64_set_private_flags
4479 #define bfd_elfNN_bfd_print_private_bfd_data \
4480 elfNN_ia64_print_private_bfd_data
4482 #define elf_backend_plt_readonly 1
4483 #define elf_backend_want_plt_sym 0
4484 #define elf_backend_plt_alignment 5
4485 #define elf_backend_got_header_size 0
4486 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4487 #define elf_backend_want_got_plt 1
4488 #define elf_backend_may_use_rel_p 1
4489 #define elf_backend_may_use_rela_p 1
4490 #define elf_backend_default_use_rela_p 1
4491 #define elf_backend_want_dynbss 0
4492 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4493 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4494 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4496 #include "elfNN-target.h"
4498 /* AIX-specific vectors. */
4500 #undef TARGET_LITTLE_SYM
4501 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4502 #undef TARGET_LITTLE_NAME
4503 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4504 #undef TARGET_BIG_SYM
4505 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4506 #undef TARGET_BIG_NAME
4507 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4509 #undef elf_backend_add_symbol_hook
4510 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4512 #undef bfd_elfNN_bfd_link_add_symbols
4513 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4515 #define elfNN_bed elfNN_ia64_aix_bed
4517 #include "elfNN-target.h"