config:
[binutils.git] / bfd / elfxx-ia64.c
blobcc3f2fc0449435a85c873d656163acebe2e540bc
1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
4 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "opcode/ia64.h"
27 #include "elf/ia64.h"
28 #include "objalloc.h"
29 #include "hashtab.h"
31 #define ARCH_SIZE NN
33 #if ARCH_SIZE == 64
34 #define LOG_SECTION_ALIGN 3
35 #endif
37 #if ARCH_SIZE == 32
38 #define LOG_SECTION_ALIGN 2
39 #endif
41 /* THE RULES for all the stuff the linker creates --
43 GOT Entries created in response to LTOFF or LTOFF_FPTR
44 relocations. Dynamic relocs created for dynamic
45 symbols in an application; REL relocs for locals
46 in a shared library.
48 FPTR The canonical function descriptor. Created for local
49 symbols in applications. Descriptors for dynamic symbols
50 and local symbols in shared libraries are created by
51 ld.so. Thus there are no dynamic relocs against these
52 objects. The FPTR relocs for such _are_ passed through
53 to the dynamic relocation tables.
55 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
56 Requires the creation of a PLTOFF entry. This does not
57 require any dynamic relocations.
59 PLTOFF Created by PLTOFF relocations. For local symbols, this
60 is an alternate function descriptor, and in shared libraries
61 requires two REL relocations. Note that this cannot be
62 transformed into an FPTR relocation, since it must be in
63 range of the GP. For dynamic symbols, this is a function
64 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
66 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
67 does not require dynamic relocations. */
69 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
71 typedef struct bfd_hash_entry *(*new_hash_entry_func)
72 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
74 /* In dynamically (linker-) created sections, we generally need to keep track
75 of the place a symbol or expression got allocated to. This is done via hash
76 tables that store entries of the following type. */
78 struct elfNN_ia64_dyn_sym_info
80 /* The addend for which this entry is relevant. */
81 bfd_vma addend;
83 bfd_vma got_offset;
84 bfd_vma fptr_offset;
85 bfd_vma pltoff_offset;
86 bfd_vma plt_offset;
87 bfd_vma plt2_offset;
88 bfd_vma tprel_offset;
89 bfd_vma dtpmod_offset;
90 bfd_vma dtprel_offset;
92 /* The symbol table entry, if any, that this was derived from. */
93 struct elf_link_hash_entry *h;
95 /* Used to count non-got, non-plt relocations for delayed sizing
96 of relocation sections. */
97 struct elfNN_ia64_dyn_reloc_entry
99 struct elfNN_ia64_dyn_reloc_entry *next;
100 asection *srel;
101 int type;
102 int count;
104 /* Is this reloc against readonly section? */
105 bfd_boolean reltext;
106 } *reloc_entries;
108 /* TRUE when the section contents have been updated. */
109 unsigned got_done : 1;
110 unsigned fptr_done : 1;
111 unsigned pltoff_done : 1;
112 unsigned tprel_done : 1;
113 unsigned dtpmod_done : 1;
114 unsigned dtprel_done : 1;
116 /* TRUE for the different kinds of linker data we want created. */
117 unsigned want_got : 1;
118 unsigned want_gotx : 1;
119 unsigned want_fptr : 1;
120 unsigned want_ltoff_fptr : 1;
121 unsigned want_plt : 1;
122 unsigned want_plt2 : 1;
123 unsigned want_pltoff : 1;
124 unsigned want_tprel : 1;
125 unsigned want_dtpmod : 1;
126 unsigned want_dtprel : 1;
129 struct elfNN_ia64_local_hash_entry
131 int id;
132 unsigned int r_sym;
133 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
134 unsigned int count;
135 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
136 unsigned int sorted_count;
137 /* The size of elfNN_ia64_dyn_sym_info array. */
138 unsigned int size;
139 /* The array of elfNN_ia64_dyn_sym_info. */
140 struct elfNN_ia64_dyn_sym_info *info;
142 /* TRUE if this hash entry's addends was translated for
143 SHF_MERGE optimization. */
144 unsigned sec_merge_done : 1;
147 struct elfNN_ia64_link_hash_entry
149 struct elf_link_hash_entry root;
150 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
151 unsigned int count;
152 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
153 unsigned int sorted_count;
154 /* The size of elfNN_ia64_dyn_sym_info array. */
155 unsigned int size;
156 /* The array of elfNN_ia64_dyn_sym_info. */
157 struct elfNN_ia64_dyn_sym_info *info;
160 struct elfNN_ia64_link_hash_table
162 /* The main hash table. */
163 struct elf_link_hash_table root;
165 asection *got_sec; /* the linkage table section (or NULL) */
166 asection *rel_got_sec; /* dynamic relocation section for same */
167 asection *fptr_sec; /* function descriptor table (or NULL) */
168 asection *rel_fptr_sec; /* dynamic relocation section for same */
169 asection *plt_sec; /* the primary plt section (or NULL) */
170 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
171 asection *rel_pltoff_sec; /* dynamic relocation section for same */
173 bfd_size_type minplt_entries; /* number of minplt entries */
174 unsigned reltext : 1; /* are there relocs against readonly sections? */
175 unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
176 bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry */
178 htab_t loc_hash_table;
179 void *loc_hash_memory;
182 struct elfNN_ia64_allocate_data
184 struct bfd_link_info *info;
185 bfd_size_type ofs;
186 bfd_boolean only_got;
189 #define elfNN_ia64_hash_table(p) \
190 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
192 static bfd_reloc_status_type elfNN_ia64_reloc
193 PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
194 asection *input_section, bfd *output_bfd, char **error_message));
195 static reloc_howto_type * lookup_howto
196 PARAMS ((unsigned int rtype));
197 static reloc_howto_type *elfNN_ia64_reloc_type_lookup
198 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
199 static void elfNN_ia64_info_to_howto
200 PARAMS ((bfd *abfd, arelent *bfd_reloc, Elf_Internal_Rela *elf_reloc));
201 static bfd_boolean elfNN_ia64_relax_section
202 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
203 bfd_boolean *again));
204 static void elfNN_ia64_relax_ldxmov
205 PARAMS((bfd_byte *contents, bfd_vma off));
206 static bfd_boolean is_unwind_section_name
207 PARAMS ((bfd *abfd, const char *));
208 static bfd_boolean elfNN_ia64_section_flags
209 PARAMS ((flagword *, const Elf_Internal_Shdr *));
210 static bfd_boolean elfNN_ia64_fake_sections
211 PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec));
212 static void elfNN_ia64_final_write_processing
213 PARAMS ((bfd *abfd, bfd_boolean linker));
214 static bfd_boolean elfNN_ia64_add_symbol_hook
215 PARAMS ((bfd *abfd, struct bfd_link_info *info, Elf_Internal_Sym *sym,
216 const char **namep, flagword *flagsp, asection **secp,
217 bfd_vma *valp));
218 static bfd_boolean elfNN_ia64_is_local_label_name
219 PARAMS ((bfd *abfd, const char *name));
220 static bfd_boolean elfNN_ia64_dynamic_symbol_p
221 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info, int));
222 static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
223 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
224 const char *string));
225 static void elfNN_ia64_hash_copy_indirect
226 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *,
227 struct elf_link_hash_entry *));
228 static void elfNN_ia64_hash_hide_symbol
229 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
230 static hashval_t elfNN_ia64_local_htab_hash PARAMS ((const void *));
231 static int elfNN_ia64_local_htab_eq PARAMS ((const void *ptr1,
232 const void *ptr2));
233 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
234 PARAMS ((bfd *abfd));
235 static void elfNN_ia64_hash_table_free
236 PARAMS ((struct bfd_link_hash_table *hash));
237 static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
238 PARAMS ((struct bfd_hash_entry *, PTR));
239 static int elfNN_ia64_local_dyn_sym_thunk
240 PARAMS ((void **, PTR));
241 static void elfNN_ia64_dyn_sym_traverse
242 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
243 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
244 PTR info));
245 static bfd_boolean elfNN_ia64_create_dynamic_sections
246 PARAMS ((bfd *abfd, struct bfd_link_info *info));
247 static struct elfNN_ia64_local_hash_entry * get_local_sym_hash
248 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
249 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
250 static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
251 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
252 struct elf_link_hash_entry *h,
253 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
254 static asection *get_got
255 PARAMS ((bfd *abfd, struct bfd_link_info *info,
256 struct elfNN_ia64_link_hash_table *ia64_info));
257 static asection *get_fptr
258 PARAMS ((bfd *abfd, struct bfd_link_info *info,
259 struct elfNN_ia64_link_hash_table *ia64_info));
260 static asection *get_pltoff
261 PARAMS ((bfd *abfd, struct bfd_link_info *info,
262 struct elfNN_ia64_link_hash_table *ia64_info));
263 static asection *get_reloc_section
264 PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
265 asection *sec, bfd_boolean create));
266 static bfd_boolean elfNN_ia64_check_relocs
267 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
268 const Elf_Internal_Rela *relocs));
269 static bfd_boolean elfNN_ia64_adjust_dynamic_symbol
270 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
271 static long global_sym_index
272 PARAMS ((struct elf_link_hash_entry *h));
273 static bfd_boolean allocate_fptr
274 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
275 static bfd_boolean allocate_global_data_got
276 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
277 static bfd_boolean allocate_global_fptr_got
278 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
279 static bfd_boolean allocate_local_got
280 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
281 static bfd_boolean allocate_pltoff_entries
282 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
283 static bfd_boolean allocate_plt_entries
284 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
285 static bfd_boolean allocate_plt2_entries
286 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
287 static bfd_boolean allocate_dynrel_entries
288 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
289 static bfd_boolean elfNN_ia64_size_dynamic_sections
290 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
291 static bfd_reloc_status_type elfNN_ia64_install_value
292 PARAMS ((bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
293 static void elfNN_ia64_install_dyn_reloc
294 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
295 asection *srel, bfd_vma offset, unsigned int type,
296 long dynindx, bfd_vma addend));
297 static bfd_vma set_got_entry
298 PARAMS ((bfd *abfd, struct bfd_link_info *info,
299 struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
300 bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
301 static bfd_vma set_fptr_entry
302 PARAMS ((bfd *abfd, struct bfd_link_info *info,
303 struct elfNN_ia64_dyn_sym_info *dyn_i,
304 bfd_vma value));
305 static bfd_vma set_pltoff_entry
306 PARAMS ((bfd *abfd, struct bfd_link_info *info,
307 struct elfNN_ia64_dyn_sym_info *dyn_i,
308 bfd_vma value, bfd_boolean));
309 static bfd_vma elfNN_ia64_tprel_base
310 PARAMS ((struct bfd_link_info *info));
311 static bfd_vma elfNN_ia64_dtprel_base
312 PARAMS ((struct bfd_link_info *info));
313 static int elfNN_ia64_unwind_entry_compare
314 PARAMS ((const PTR, const PTR));
315 static bfd_boolean elfNN_ia64_choose_gp
316 PARAMS ((bfd *abfd, struct bfd_link_info *info));
317 static bfd_boolean elfNN_ia64_final_link
318 PARAMS ((bfd *abfd, struct bfd_link_info *info));
319 static bfd_boolean elfNN_ia64_relocate_section
320 PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
321 asection *input_section, bfd_byte *contents,
322 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
323 asection **local_sections));
324 static bfd_boolean elfNN_ia64_finish_dynamic_symbol
325 PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
326 struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
327 static bfd_boolean elfNN_ia64_finish_dynamic_sections
328 PARAMS ((bfd *abfd, struct bfd_link_info *info));
329 static bfd_boolean elfNN_ia64_set_private_flags
330 PARAMS ((bfd *abfd, flagword flags));
331 static bfd_boolean elfNN_ia64_merge_private_bfd_data
332 PARAMS ((bfd *ibfd, bfd *obfd));
333 static bfd_boolean elfNN_ia64_print_private_bfd_data
334 PARAMS ((bfd *abfd, PTR ptr));
335 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
336 PARAMS ((const Elf_Internal_Rela *));
337 static bfd_boolean elfNN_ia64_hpux_vec
338 PARAMS ((const bfd_target *vec));
339 static void elfNN_hpux_post_process_headers
340 PARAMS ((bfd *abfd, struct bfd_link_info *info));
341 bfd_boolean elfNN_hpux_backend_section_from_bfd_section
342 PARAMS ((bfd *abfd, asection *sec, int *retval));
344 /* ia64-specific relocation. */
346 /* Perform a relocation. Not much to do here as all the hard work is
347 done in elfNN_ia64_final_link_relocate. */
348 static bfd_reloc_status_type
349 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
350 output_bfd, error_message)
351 bfd *abfd ATTRIBUTE_UNUSED;
352 arelent *reloc;
353 asymbol *sym ATTRIBUTE_UNUSED;
354 PTR data ATTRIBUTE_UNUSED;
355 asection *input_section;
356 bfd *output_bfd;
357 char **error_message;
359 if (output_bfd)
361 reloc->address += input_section->output_offset;
362 return bfd_reloc_ok;
365 if (input_section->flags & SEC_DEBUGGING)
366 return bfd_reloc_continue;
368 *error_message = "Unsupported call to elfNN_ia64_reloc";
369 return bfd_reloc_notsupported;
372 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
373 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
374 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
376 /* This table has to be sorted according to increasing number of the
377 TYPE field. */
378 static reloc_howto_type ia64_howto_table[] =
380 IA64_HOWTO (R_IA64_NONE, "NONE", 0, FALSE, TRUE),
382 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, FALSE, TRUE),
383 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, FALSE, TRUE),
384 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, FALSE, TRUE),
385 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, FALSE, TRUE),
386 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, FALSE, TRUE),
387 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, FALSE, TRUE),
388 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, FALSE, TRUE),
390 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, FALSE, TRUE),
391 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, FALSE, TRUE),
392 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, FALSE, TRUE),
393 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, FALSE, TRUE),
394 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, FALSE, TRUE),
395 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, FALSE, TRUE),
397 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, FALSE, TRUE),
398 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, FALSE, TRUE),
400 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, FALSE, TRUE),
401 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, FALSE, TRUE),
402 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, FALSE, TRUE),
403 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, FALSE, TRUE),
405 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, FALSE, TRUE),
406 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, FALSE, TRUE),
407 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, FALSE, TRUE),
408 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, FALSE, TRUE),
409 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, FALSE, TRUE),
411 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, TRUE, TRUE),
412 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, TRUE, TRUE),
413 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, TRUE, TRUE),
414 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, TRUE, TRUE),
415 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, TRUE, TRUE),
416 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, TRUE, TRUE),
417 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, TRUE, TRUE),
418 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, TRUE, TRUE),
420 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, FALSE, TRUE),
421 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, FALSE, TRUE),
422 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, FALSE, TRUE),
423 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, FALSE, TRUE),
424 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, FALSE, TRUE),
425 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, FALSE, TRUE),
427 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, FALSE, TRUE),
428 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, FALSE, TRUE),
429 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, FALSE, TRUE),
430 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, FALSE, TRUE),
432 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, FALSE, TRUE),
433 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, FALSE, TRUE),
434 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, FALSE, TRUE),
435 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, FALSE, TRUE),
437 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, FALSE, TRUE),
438 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, FALSE, TRUE),
439 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, FALSE, TRUE),
440 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, FALSE, TRUE),
442 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, FALSE, TRUE),
443 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, FALSE, TRUE),
444 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, FALSE, TRUE),
445 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, FALSE, TRUE),
447 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, TRUE, TRUE),
448 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, TRUE, TRUE),
449 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, TRUE, TRUE),
451 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, FALSE, TRUE),
452 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, FALSE, TRUE),
453 IA64_HOWTO (R_IA64_COPY, "COPY", 4, FALSE, TRUE),
454 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, FALSE, TRUE),
455 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, FALSE, TRUE),
457 IA64_HOWTO (R_IA64_TPREL14, "TPREL14", 0, FALSE, FALSE),
458 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, FALSE, FALSE),
459 IA64_HOWTO (R_IA64_TPREL64I, "TPREL64I", 0, FALSE, FALSE),
460 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 4, FALSE, FALSE),
461 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 4, FALSE, FALSE),
462 IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, FALSE, FALSE),
464 IA64_HOWTO (R_IA64_DTPMOD64MSB, "DTPMOD64MSB", 4, FALSE, FALSE),
465 IA64_HOWTO (R_IA64_DTPMOD64LSB, "DTPMOD64LSB", 4, FALSE, FALSE),
466 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
468 IA64_HOWTO (R_IA64_DTPREL14, "DTPREL14", 0, FALSE, FALSE),
469 IA64_HOWTO (R_IA64_DTPREL22, "DTPREL22", 0, FALSE, FALSE),
470 IA64_HOWTO (R_IA64_DTPREL64I, "DTPREL64I", 0, FALSE, FALSE),
471 IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE),
472 IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE),
473 IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE),
474 IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE),
475 IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
478 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
480 /* Given a BFD reloc type, return the matching HOWTO structure. */
482 static reloc_howto_type *
483 lookup_howto (rtype)
484 unsigned int rtype;
486 static int inited = 0;
487 int i;
489 if (!inited)
491 inited = 1;
493 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
494 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
495 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
498 if (rtype > R_IA64_MAX_RELOC_CODE)
499 return 0;
500 i = elf_code_to_howto_index[rtype];
501 if (i >= NELEMS (ia64_howto_table))
502 return 0;
503 return ia64_howto_table + i;
506 static reloc_howto_type*
507 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
508 bfd *abfd ATTRIBUTE_UNUSED;
509 bfd_reloc_code_real_type bfd_code;
511 unsigned int rtype;
513 switch (bfd_code)
515 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
517 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
518 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
519 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
521 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
522 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
523 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
524 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
526 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
527 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
528 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
529 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
530 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
531 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
533 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
534 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
536 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
537 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
538 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
539 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
540 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
541 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
542 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
543 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
544 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
546 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
547 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
548 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
549 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
550 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
551 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
552 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
553 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
554 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
555 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
556 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
558 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
559 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
560 case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
561 case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
562 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
563 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
565 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
566 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
567 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
568 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
570 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
571 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
572 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
573 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
575 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
576 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
577 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
578 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
580 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
581 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
582 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
583 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
585 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
586 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
587 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
588 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
589 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
591 case BFD_RELOC_IA64_TPREL14: rtype = R_IA64_TPREL14; break;
592 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
593 case BFD_RELOC_IA64_TPREL64I: rtype = R_IA64_TPREL64I; break;
594 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
595 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
596 case BFD_RELOC_IA64_LTOFF_TPREL22: rtype = R_IA64_LTOFF_TPREL22; break;
598 case BFD_RELOC_IA64_DTPMOD64MSB: rtype = R_IA64_DTPMOD64MSB; break;
599 case BFD_RELOC_IA64_DTPMOD64LSB: rtype = R_IA64_DTPMOD64LSB; break;
600 case BFD_RELOC_IA64_LTOFF_DTPMOD22: rtype = R_IA64_LTOFF_DTPMOD22; break;
602 case BFD_RELOC_IA64_DTPREL14: rtype = R_IA64_DTPREL14; break;
603 case BFD_RELOC_IA64_DTPREL22: rtype = R_IA64_DTPREL22; break;
604 case BFD_RELOC_IA64_DTPREL64I: rtype = R_IA64_DTPREL64I; break;
605 case BFD_RELOC_IA64_DTPREL32MSB: rtype = R_IA64_DTPREL32MSB; break;
606 case BFD_RELOC_IA64_DTPREL32LSB: rtype = R_IA64_DTPREL32LSB; break;
607 case BFD_RELOC_IA64_DTPREL64MSB: rtype = R_IA64_DTPREL64MSB; break;
608 case BFD_RELOC_IA64_DTPREL64LSB: rtype = R_IA64_DTPREL64LSB; break;
609 case BFD_RELOC_IA64_LTOFF_DTPREL22: rtype = R_IA64_LTOFF_DTPREL22; break;
611 default: return 0;
613 return lookup_howto (rtype);
616 static reloc_howto_type *
617 elfNN_ia64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
618 const char *r_name)
620 unsigned int i;
622 for (i = 0;
623 i < sizeof (ia64_howto_table) / sizeof (ia64_howto_table[0]);
624 i++)
625 if (ia64_howto_table[i].name != NULL
626 && strcasecmp (ia64_howto_table[i].name, r_name) == 0)
627 return &ia64_howto_table[i];
629 return NULL;
632 /* Given a ELF reloc, return the matching HOWTO structure. */
634 static void
635 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
636 bfd *abfd ATTRIBUTE_UNUSED;
637 arelent *bfd_reloc;
638 Elf_Internal_Rela *elf_reloc;
640 bfd_reloc->howto
641 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
644 #define PLT_HEADER_SIZE (3 * 16)
645 #define PLT_MIN_ENTRY_SIZE (1 * 16)
646 #define PLT_FULL_ENTRY_SIZE (2 * 16)
647 #define PLT_RESERVED_WORDS 3
649 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
651 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
652 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
653 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
654 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
655 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
656 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
657 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
658 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
659 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
662 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
664 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
665 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
666 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
669 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
671 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
672 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
673 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
674 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
675 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
676 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
679 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
681 static const bfd_byte oor_brl[16] =
683 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
685 0x00, 0x00, 0x00, 0xc0
688 static const bfd_byte oor_ip[48] =
690 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
691 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
692 0x01, 0x00, 0x00, 0x60,
693 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
694 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
695 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
696 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
697 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
698 0x60, 0x00, 0x80, 0x00 /* br b6;; */
701 static size_t oor_branch_size = sizeof (oor_brl);
703 void
704 bfd_elfNN_ia64_after_parse (int itanium)
706 oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
709 #define BTYPE_SHIFT 6
710 #define Y_SHIFT 26
711 #define X6_SHIFT 27
712 #define X4_SHIFT 27
713 #define X3_SHIFT 33
714 #define X2_SHIFT 31
715 #define X_SHIFT 33
716 #define OPCODE_SHIFT 37
718 #define OPCODE_BITS (0xfLL << OPCODE_SHIFT)
719 #define X6_BITS (0x3fLL << X6_SHIFT)
720 #define X4_BITS (0xfLL << X4_SHIFT)
721 #define X3_BITS (0x7LL << X3_SHIFT)
722 #define X2_BITS (0x3LL << X2_SHIFT)
723 #define X_BITS (0x1LL << X_SHIFT)
724 #define Y_BITS (0x1LL << Y_SHIFT)
725 #define BTYPE_BITS (0x7LL << BTYPE_SHIFT)
726 #define PREDICATE_BITS (0x3fLL)
728 #define IS_NOP_B(i) \
729 (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
730 #define IS_NOP_F(i) \
731 (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
732 == (0x1LL << X6_SHIFT))
733 #define IS_NOP_I(i) \
734 (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
735 == (0x1LL << X6_SHIFT))
736 #define IS_NOP_M(i) \
737 (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
738 == (0x1LL << X4_SHIFT))
739 #define IS_BR_COND(i) \
740 (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
741 #define IS_BR_CALL(i) \
742 (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
744 static bfd_boolean
745 elfNN_ia64_relax_br (bfd_byte *contents, bfd_vma off)
747 unsigned int template, mlx;
748 bfd_vma t0, t1, s0, s1, s2, br_code;
749 long br_slot;
750 bfd_byte *hit_addr;
752 hit_addr = (bfd_byte *) (contents + off);
753 br_slot = (long) hit_addr & 0x3;
754 hit_addr -= br_slot;
755 t0 = bfd_getl64 (hit_addr + 0);
756 t1 = bfd_getl64 (hit_addr + 8);
758 /* Check if we can turn br into brl. A label is always at the start
759 of the bundle. Even if there are predicates on NOPs, we still
760 perform this optimization. */
761 template = t0 & 0x1e;
762 s0 = (t0 >> 5) & 0x1ffffffffffLL;
763 s1 = ((t0 >> 46) | (t1 << 18)) & 0x1ffffffffffLL;
764 s2 = (t1 >> 23) & 0x1ffffffffffLL;
765 switch (br_slot)
767 case 0:
768 /* Check if slot 1 and slot 2 are NOPs. Possible template is
769 BBB. We only need to check nop.b. */
770 if (!(IS_NOP_B (s1) && IS_NOP_B (s2)))
771 return FALSE;
772 br_code = s0;
773 break;
774 case 1:
775 /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
776 For BBB, slot 0 also has to be nop.b. */
777 if (!((template == 0x12 /* MBB */
778 && IS_NOP_B (s2))
779 || (template == 0x16 /* BBB */
780 && IS_NOP_B (s0)
781 && IS_NOP_B (s2))))
782 return FALSE;
783 br_code = s1;
784 break;
785 case 2:
786 /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
787 MMB and MFB. For BBB, slot 0 also has to be nop.b. */
788 if (!((template == 0x10 /* MIB */
789 && IS_NOP_I (s1))
790 || (template == 0x12 /* MBB */
791 && IS_NOP_B (s1))
792 || (template == 0x16 /* BBB */
793 && IS_NOP_B (s0)
794 && IS_NOP_B (s1))
795 || (template == 0x18 /* MMB */
796 && IS_NOP_M (s1))
797 || (template == 0x1c /* MFB */
798 && IS_NOP_F (s1))))
799 return FALSE;
800 br_code = s2;
801 break;
802 default:
803 /* It should never happen. */
804 abort ();
807 /* We can turn br.cond/br.call into brl.cond/brl.call. */
808 if (!(IS_BR_COND (br_code) || IS_BR_CALL (br_code)))
809 return FALSE;
811 /* Turn br into brl by setting bit 40. */
812 br_code |= 0x1LL << 40;
814 /* Turn the old bundle into a MLX bundle with the same stop-bit
815 variety. */
816 if (t0 & 0x1)
817 mlx = 0x5;
818 else
819 mlx = 0x4;
821 if (template == 0x16)
823 /* For BBB, we need to put nop.m in slot 0. We keep the original
824 predicate only if slot 0 isn't br. */
825 if (br_slot == 0)
826 t0 = 0LL;
827 else
828 t0 &= PREDICATE_BITS << 5;
829 t0 |= 0x1LL << (X4_SHIFT + 5);
831 else
833 /* Keep the original instruction in slot 0. */
834 t0 &= 0x1ffffffffffLL << 5;
837 t0 |= mlx;
839 /* Put brl in slot 1. */
840 t1 = br_code << 23;
842 bfd_putl64 (t0, hit_addr);
843 bfd_putl64 (t1, hit_addr + 8);
844 return TRUE;
847 static void
848 elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
850 int template;
851 bfd_byte *hit_addr;
852 bfd_vma t0, t1, i0, i1, i2;
854 hit_addr = (bfd_byte *) (contents + off);
855 hit_addr -= (long) hit_addr & 0x3;
856 t0 = bfd_getl64 (hit_addr);
857 t1 = bfd_getl64 (hit_addr + 8);
859 /* Keep the instruction in slot 0. */
860 i0 = (t0 >> 5) & 0x1ffffffffffLL;
861 /* Use nop.b for slot 1. */
862 i1 = 0x4000000000LL;
863 /* For slot 2, turn brl into br by masking out bit 40. */
864 i2 = (t1 >> 23) & 0x0ffffffffffLL;
866 /* Turn a MLX bundle into a MBB bundle with the same stop-bit
867 variety. */
868 if (t0 & 0x1)
869 template = 0x13;
870 else
871 template = 0x12;
872 t0 = (i1 << 46) | (i0 << 5) | template;
873 t1 = (i2 << 23) | (i1 >> 18);
875 bfd_putl64 (t0, hit_addr);
876 bfd_putl64 (t1, hit_addr + 8);
879 /* Rename some of the generic section flags to better document how they
880 are used here. */
881 #define skip_relax_pass_0 need_finalize_relax
882 #define skip_relax_pass_1 has_gp_reloc
885 /* These functions do relaxation for IA-64 ELF. */
887 static bfd_boolean
888 elfNN_ia64_relax_section (abfd, sec, link_info, again)
889 bfd *abfd;
890 asection *sec;
891 struct bfd_link_info *link_info;
892 bfd_boolean *again;
894 struct one_fixup
896 struct one_fixup *next;
897 asection *tsec;
898 bfd_vma toff;
899 bfd_vma trampoff;
902 Elf_Internal_Shdr *symtab_hdr;
903 Elf_Internal_Rela *internal_relocs;
904 Elf_Internal_Rela *irel, *irelend;
905 bfd_byte *contents;
906 Elf_Internal_Sym *isymbuf = NULL;
907 struct elfNN_ia64_link_hash_table *ia64_info;
908 struct one_fixup *fixups = NULL;
909 bfd_boolean changed_contents = FALSE;
910 bfd_boolean changed_relocs = FALSE;
911 bfd_boolean changed_got = FALSE;
912 bfd_boolean skip_relax_pass_0 = TRUE;
913 bfd_boolean skip_relax_pass_1 = TRUE;
914 bfd_vma gp = 0;
916 /* Assume we're not going to change any sizes, and we'll only need
917 one pass. */
918 *again = FALSE;
920 /* Don't even try to relax for non-ELF outputs. */
921 if (!is_elf_hash_table (link_info->hash))
922 return FALSE;
924 /* Nothing to do if there are no relocations or there is no need for
925 the current pass. */
926 if ((sec->flags & SEC_RELOC) == 0
927 || sec->reloc_count == 0
928 || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
929 || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
930 return TRUE;
932 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
934 /* Load the relocations for this section. */
935 internal_relocs = (_bfd_elf_link_read_relocs
936 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
937 link_info->keep_memory));
938 if (internal_relocs == NULL)
939 return FALSE;
941 ia64_info = elfNN_ia64_hash_table (link_info);
942 irelend = internal_relocs + sec->reloc_count;
944 /* Get the section contents. */
945 if (elf_section_data (sec)->this_hdr.contents != NULL)
946 contents = elf_section_data (sec)->this_hdr.contents;
947 else
949 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
950 goto error_return;
953 for (irel = internal_relocs; irel < irelend; irel++)
955 unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
956 bfd_vma symaddr, reladdr, trampoff, toff, roff;
957 asection *tsec;
958 struct one_fixup *f;
959 bfd_size_type amt;
960 bfd_boolean is_branch;
961 struct elfNN_ia64_dyn_sym_info *dyn_i;
962 char symtype;
964 switch (r_type)
966 case R_IA64_PCREL21B:
967 case R_IA64_PCREL21BI:
968 case R_IA64_PCREL21M:
969 case R_IA64_PCREL21F:
970 /* In pass 1, all br relaxations are done. We can skip it. */
971 if (link_info->relax_pass == 1)
972 continue;
973 skip_relax_pass_0 = FALSE;
974 is_branch = TRUE;
975 break;
977 case R_IA64_PCREL60B:
978 /* We can't optimize brl to br in pass 0 since br relaxations
979 will increase the code size. Defer it to pass 1. */
980 if (link_info->relax_pass == 0)
982 skip_relax_pass_1 = FALSE;
983 continue;
985 is_branch = TRUE;
986 break;
988 case R_IA64_LTOFF22X:
989 case R_IA64_LDXMOV:
990 /* We can't relax ldx/mov in pass 0 since br relaxations will
991 increase the code size. Defer it to pass 1. */
992 if (link_info->relax_pass == 0)
994 skip_relax_pass_1 = FALSE;
995 continue;
997 is_branch = FALSE;
998 break;
1000 default:
1001 continue;
1004 /* Get the value of the symbol referred to by the reloc. */
1005 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1007 /* A local symbol. */
1008 Elf_Internal_Sym *isym;
1010 /* Read this BFD's local symbols. */
1011 if (isymbuf == NULL)
1013 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1014 if (isymbuf == NULL)
1015 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1016 symtab_hdr->sh_info, 0,
1017 NULL, NULL, NULL);
1018 if (isymbuf == 0)
1019 goto error_return;
1022 isym = isymbuf + ELFNN_R_SYM (irel->r_info);
1023 if (isym->st_shndx == SHN_UNDEF)
1024 continue; /* We can't do anything with undefined symbols. */
1025 else if (isym->st_shndx == SHN_ABS)
1026 tsec = bfd_abs_section_ptr;
1027 else if (isym->st_shndx == SHN_COMMON)
1028 tsec = bfd_com_section_ptr;
1029 else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
1030 tsec = bfd_com_section_ptr;
1031 else
1032 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1034 toff = isym->st_value;
1035 dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
1036 symtype = ELF_ST_TYPE (isym->st_info);
1038 else
1040 unsigned long indx;
1041 struct elf_link_hash_entry *h;
1043 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1044 h = elf_sym_hashes (abfd)[indx];
1045 BFD_ASSERT (h != NULL);
1047 while (h->root.type == bfd_link_hash_indirect
1048 || h->root.type == bfd_link_hash_warning)
1049 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1051 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
1053 /* For branches to dynamic symbols, we're interested instead
1054 in a branch to the PLT entry. */
1055 if (is_branch && dyn_i && dyn_i->want_plt2)
1057 /* Internal branches shouldn't be sent to the PLT.
1058 Leave this for now and we'll give an error later. */
1059 if (r_type != R_IA64_PCREL21B)
1060 continue;
1062 tsec = ia64_info->plt_sec;
1063 toff = dyn_i->plt2_offset;
1064 BFD_ASSERT (irel->r_addend == 0);
1067 /* Can't do anything else with dynamic symbols. */
1068 else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
1069 continue;
1071 else
1073 /* We can't do anything with undefined symbols. */
1074 if (h->root.type == bfd_link_hash_undefined
1075 || h->root.type == bfd_link_hash_undefweak)
1076 continue;
1078 tsec = h->root.u.def.section;
1079 toff = h->root.u.def.value;
1082 symtype = h->type;
1085 if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
1087 /* At this stage in linking, no SEC_MERGE symbol has been
1088 adjusted, so all references to such symbols need to be
1089 passed through _bfd_merged_section_offset. (Later, in
1090 relocate_section, all SEC_MERGE symbols *except* for
1091 section symbols have been adjusted.)
1093 gas may reduce relocations against symbols in SEC_MERGE
1094 sections to a relocation against the section symbol when
1095 the original addend was zero. When the reloc is against
1096 a section symbol we should include the addend in the
1097 offset passed to _bfd_merged_section_offset, since the
1098 location of interest is the original symbol. On the
1099 other hand, an access to "sym+addend" where "sym" is not
1100 a section symbol should not include the addend; Such an
1101 access is presumed to be an offset from "sym"; The
1102 location of interest is just "sym". */
1103 if (symtype == STT_SECTION)
1104 toff += irel->r_addend;
1106 toff = _bfd_merged_section_offset (abfd, &tsec,
1107 elf_section_data (tsec)->sec_info,
1108 toff);
1110 if (symtype != STT_SECTION)
1111 toff += irel->r_addend;
1113 else
1114 toff += irel->r_addend;
1116 symaddr = tsec->output_section->vma + tsec->output_offset + toff;
1118 roff = irel->r_offset;
1120 if (is_branch)
1122 bfd_signed_vma offset;
1124 reladdr = (sec->output_section->vma
1125 + sec->output_offset
1126 + roff) & (bfd_vma) -4;
1128 /* If the branch is in range, no need to do anything. */
1129 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
1130 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
1132 /* If the 60-bit branch is in 21-bit range, optimize it. */
1133 if (r_type == R_IA64_PCREL60B)
1135 elfNN_ia64_relax_brl (contents, roff);
1137 irel->r_info
1138 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1139 R_IA64_PCREL21B);
1141 /* If the original relocation offset points to slot
1142 1, change it to slot 2. */
1143 if ((irel->r_offset & 3) == 1)
1144 irel->r_offset += 1;
1147 continue;
1149 else if (r_type == R_IA64_PCREL60B)
1150 continue;
1151 else if (elfNN_ia64_relax_br (contents, roff))
1153 irel->r_info
1154 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1155 R_IA64_PCREL60B);
1157 /* Make the relocation offset point to slot 1. */
1158 irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
1159 continue;
1162 /* We can't put a trampoline in a .init/.fini section. Issue
1163 an error. */
1164 if (strcmp (sec->output_section->name, ".init") == 0
1165 || strcmp (sec->output_section->name, ".fini") == 0)
1167 (*_bfd_error_handler)
1168 (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
1169 sec->owner, sec, (unsigned long) roff);
1170 bfd_set_error (bfd_error_bad_value);
1171 goto error_return;
1174 /* If the branch and target are in the same section, you've
1175 got one honking big section and we can't help you unless
1176 you are branching backwards. You'll get an error message
1177 later. */
1178 if (tsec == sec && toff > roff)
1179 continue;
1181 /* Look for an existing fixup to this address. */
1182 for (f = fixups; f ; f = f->next)
1183 if (f->tsec == tsec && f->toff == toff)
1184 break;
1186 if (f == NULL)
1188 /* Two alternatives: If it's a branch to a PLT entry, we can
1189 make a copy of the FULL_PLT entry. Otherwise, we'll have
1190 to use a `brl' insn to get where we're going. */
1192 size_t size;
1194 if (tsec == ia64_info->plt_sec)
1195 size = sizeof (plt_full_entry);
1196 else
1197 size = oor_branch_size;
1199 /* Resize the current section to make room for the new branch. */
1200 trampoff = (sec->size + 15) & (bfd_vma) -16;
1202 /* If trampoline is out of range, there is nothing we
1203 can do. */
1204 offset = trampoff - (roff & (bfd_vma) -4);
1205 if (offset < -0x1000000 || offset > 0x0FFFFF0)
1206 continue;
1208 amt = trampoff + size;
1209 contents = (bfd_byte *) bfd_realloc (contents, amt);
1210 if (contents == NULL)
1211 goto error_return;
1212 sec->size = amt;
1214 if (tsec == ia64_info->plt_sec)
1216 memcpy (contents + trampoff, plt_full_entry, size);
1218 /* Hijack the old relocation for use as the PLTOFF reloc. */
1219 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1220 R_IA64_PLTOFF22);
1221 irel->r_offset = trampoff;
1223 else
1225 if (size == sizeof (oor_ip))
1227 memcpy (contents + trampoff, oor_ip, size);
1228 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1229 R_IA64_PCREL64I);
1230 irel->r_addend -= 16;
1231 irel->r_offset = trampoff + 2;
1233 else
1235 memcpy (contents + trampoff, oor_brl, size);
1236 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1237 R_IA64_PCREL60B);
1238 irel->r_offset = trampoff + 2;
1243 /* Record the fixup so we don't do it again this section. */
1244 f = (struct one_fixup *)
1245 bfd_malloc ((bfd_size_type) sizeof (*f));
1246 f->next = fixups;
1247 f->tsec = tsec;
1248 f->toff = toff;
1249 f->trampoff = trampoff;
1250 fixups = f;
1252 else
1254 /* If trampoline is out of range, there is nothing we
1255 can do. */
1256 offset = f->trampoff - (roff & (bfd_vma) -4);
1257 if (offset < -0x1000000 || offset > 0x0FFFFF0)
1258 continue;
1260 /* Nop out the reloc, since we're finalizing things here. */
1261 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1264 /* Fix up the existing branch to hit the trampoline. */
1265 if (elfNN_ia64_install_value (contents + roff, offset, r_type)
1266 != bfd_reloc_ok)
1267 goto error_return;
1269 changed_contents = TRUE;
1270 changed_relocs = TRUE;
1272 else
1274 /* Fetch the gp. */
1275 if (gp == 0)
1277 bfd *obfd = sec->output_section->owner;
1278 gp = _bfd_get_gp_value (obfd);
1279 if (gp == 0)
1281 if (!elfNN_ia64_choose_gp (obfd, link_info))
1282 goto error_return;
1283 gp = _bfd_get_gp_value (obfd);
1287 /* If the data is out of range, do nothing. */
1288 if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
1289 ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
1290 continue;
1292 if (r_type == R_IA64_LTOFF22X)
1294 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1295 R_IA64_GPREL22);
1296 changed_relocs = TRUE;
1297 if (dyn_i->want_gotx)
1299 dyn_i->want_gotx = 0;
1300 changed_got |= !dyn_i->want_got;
1303 else
1305 elfNN_ia64_relax_ldxmov (contents, roff);
1306 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1307 changed_contents = TRUE;
1308 changed_relocs = TRUE;
1313 /* ??? If we created fixups, this may push the code segment large
1314 enough that the data segment moves, which will change the GP.
1315 Reset the GP so that we re-calculate next round. We need to
1316 do this at the _beginning_ of the next round; now will not do. */
1318 /* Clean up and go home. */
1319 while (fixups)
1321 struct one_fixup *f = fixups;
1322 fixups = fixups->next;
1323 free (f);
1326 if (isymbuf != NULL
1327 && symtab_hdr->contents != (unsigned char *) isymbuf)
1329 if (! link_info->keep_memory)
1330 free (isymbuf);
1331 else
1333 /* Cache the symbols for elf_link_input_bfd. */
1334 symtab_hdr->contents = (unsigned char *) isymbuf;
1338 if (contents != NULL
1339 && elf_section_data (sec)->this_hdr.contents != contents)
1341 if (!changed_contents && !link_info->keep_memory)
1342 free (contents);
1343 else
1345 /* Cache the section contents for elf_link_input_bfd. */
1346 elf_section_data (sec)->this_hdr.contents = contents;
1350 if (elf_section_data (sec)->relocs != internal_relocs)
1352 if (!changed_relocs)
1353 free (internal_relocs);
1354 else
1355 elf_section_data (sec)->relocs = internal_relocs;
1358 if (changed_got)
1360 struct elfNN_ia64_allocate_data data;
1361 data.info = link_info;
1362 data.ofs = 0;
1363 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
1365 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
1366 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
1367 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
1368 ia64_info->got_sec->size = data.ofs;
1370 if (ia64_info->root.dynamic_sections_created
1371 && ia64_info->rel_got_sec != NULL)
1373 /* Resize .rela.got. */
1374 ia64_info->rel_got_sec->size = 0;
1375 if (link_info->shared
1376 && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
1377 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
1378 data.only_got = TRUE;
1379 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
1380 &data);
1384 if (link_info->relax_pass == 0)
1386 /* Pass 0 is only needed to relax br. */
1387 sec->skip_relax_pass_0 = skip_relax_pass_0;
1388 sec->skip_relax_pass_1 = skip_relax_pass_1;
1391 *again = changed_contents || changed_relocs;
1392 return TRUE;
1394 error_return:
1395 if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
1396 free (isymbuf);
1397 if (contents != NULL
1398 && elf_section_data (sec)->this_hdr.contents != contents)
1399 free (contents);
1400 if (internal_relocs != NULL
1401 && elf_section_data (sec)->relocs != internal_relocs)
1402 free (internal_relocs);
1403 return FALSE;
1405 #undef skip_relax_pass_0
1406 #undef skip_relax_pass_1
1408 static void
1409 elfNN_ia64_relax_ldxmov (contents, off)
1410 bfd_byte *contents;
1411 bfd_vma off;
1413 int shift, r1, r3;
1414 bfd_vma dword, insn;
1416 switch ((int)off & 0x3)
1418 case 0: shift = 5; break;
1419 case 1: shift = 14; off += 3; break;
1420 case 2: shift = 23; off += 6; break;
1421 default:
1422 abort ();
1425 dword = bfd_getl64 (contents + off);
1426 insn = (dword >> shift) & 0x1ffffffffffLL;
1428 r1 = (insn >> 6) & 127;
1429 r3 = (insn >> 20) & 127;
1430 if (r1 == r3)
1431 insn = 0x8000000; /* nop */
1432 else
1433 insn = (insn & 0x7f01fff) | 0x10800000000LL; /* (qp) mov r1 = r3 */
1435 dword &= ~(0x1ffffffffffLL << shift);
1436 dword |= (insn << shift);
1437 bfd_putl64 (dword, contents + off);
1440 /* Return TRUE if NAME is an unwind table section name. */
1442 static inline bfd_boolean
1443 is_unwind_section_name (bfd *abfd, const char *name)
1445 if (elfNN_ia64_hpux_vec (abfd->xvec)
1446 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
1447 return FALSE;
1449 return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
1450 && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
1451 || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
1454 /* Handle an IA-64 specific section when reading an object file. This
1455 is called when bfd_section_from_shdr finds a section with an unknown
1456 type. */
1458 static bfd_boolean
1459 elfNN_ia64_section_from_shdr (bfd *abfd,
1460 Elf_Internal_Shdr *hdr,
1461 const char *name,
1462 int shindex)
1464 asection *newsect;
1466 /* There ought to be a place to keep ELF backend specific flags, but
1467 at the moment there isn't one. We just keep track of the
1468 sections by their name, instead. Fortunately, the ABI gives
1469 suggested names for all the MIPS specific sections, so we will
1470 probably get away with this. */
1471 switch (hdr->sh_type)
1473 case SHT_IA_64_UNWIND:
1474 case SHT_IA_64_HP_OPT_ANOT:
1475 break;
1477 case SHT_IA_64_EXT:
1478 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1479 return FALSE;
1480 break;
1482 default:
1483 return FALSE;
1486 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
1487 return FALSE;
1488 newsect = hdr->bfd_section;
1490 return TRUE;
1493 /* Convert IA-64 specific section flags to bfd internal section flags. */
1495 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1496 flag. */
1498 static bfd_boolean
1499 elfNN_ia64_section_flags (flags, hdr)
1500 flagword *flags;
1501 const Elf_Internal_Shdr *hdr;
1503 if (hdr->sh_flags & SHF_IA_64_SHORT)
1504 *flags |= SEC_SMALL_DATA;
1506 return TRUE;
1509 /* Set the correct type for an IA-64 ELF section. We do this by the
1510 section name, which is a hack, but ought to work. */
1512 static bfd_boolean
1513 elfNN_ia64_fake_sections (abfd, hdr, sec)
1514 bfd *abfd ATTRIBUTE_UNUSED;
1515 Elf_Internal_Shdr *hdr;
1516 asection *sec;
1518 register const char *name;
1520 name = bfd_get_section_name (abfd, sec);
1522 if (is_unwind_section_name (abfd, name))
1524 /* We don't have the sections numbered at this point, so sh_info
1525 is set later, in elfNN_ia64_final_write_processing. */
1526 hdr->sh_type = SHT_IA_64_UNWIND;
1527 hdr->sh_flags |= SHF_LINK_ORDER;
1529 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1530 hdr->sh_type = SHT_IA_64_EXT;
1531 else if (strcmp (name, ".HP.opt_annot") == 0)
1532 hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
1533 else if (strcmp (name, ".reloc") == 0)
1534 /* This is an ugly, but unfortunately necessary hack that is
1535 needed when producing EFI binaries on IA-64. It tells
1536 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1537 containing ELF relocation info. We need this hack in order to
1538 be able to generate ELF binaries that can be translated into
1539 EFI applications (which are essentially COFF objects). Those
1540 files contain a COFF ".reloc" section inside an ELFNN object,
1541 which would normally cause BFD to segfault because it would
1542 attempt to interpret this section as containing relocation
1543 entries for section "oc". With this hack enabled, ".reloc"
1544 will be treated as a normal data section, which will avoid the
1545 segfault. However, you won't be able to create an ELFNN binary
1546 with a section named "oc" that needs relocations, but that's
1547 the kind of ugly side-effects you get when detecting section
1548 types based on their names... In practice, this limitation is
1549 unlikely to bite. */
1550 hdr->sh_type = SHT_PROGBITS;
1552 if (sec->flags & SEC_SMALL_DATA)
1553 hdr->sh_flags |= SHF_IA_64_SHORT;
1555 /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
1557 if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
1558 hdr->sh_flags |= SHF_IA_64_HP_TLS;
1560 return TRUE;
1563 /* The final processing done just before writing out an IA-64 ELF
1564 object file. */
1566 static void
1567 elfNN_ia64_final_write_processing (abfd, linker)
1568 bfd *abfd;
1569 bfd_boolean linker ATTRIBUTE_UNUSED;
1571 Elf_Internal_Shdr *hdr;
1572 asection *s;
1574 for (s = abfd->sections; s; s = s->next)
1576 hdr = &elf_section_data (s)->this_hdr;
1577 switch (hdr->sh_type)
1579 case SHT_IA_64_UNWIND:
1580 /* The IA-64 processor-specific ABI requires setting sh_link
1581 to the unwind section, whereas HP-UX requires sh_info to
1582 do so. For maximum compatibility, we'll set both for
1583 now... */
1584 hdr->sh_info = hdr->sh_link;
1585 break;
1589 if (! elf_flags_init (abfd))
1591 unsigned long flags = 0;
1593 if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
1594 flags |= EF_IA_64_BE;
1595 if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
1596 flags |= EF_IA_64_ABI64;
1598 elf_elfheader(abfd)->e_flags = flags;
1599 elf_flags_init (abfd) = TRUE;
1603 /* Hook called by the linker routine which adds symbols from an object
1604 file. We use it to put .comm items in .sbss, and not .bss. */
1606 static bfd_boolean
1607 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1608 bfd *abfd;
1609 struct bfd_link_info *info;
1610 Elf_Internal_Sym *sym;
1611 const char **namep ATTRIBUTE_UNUSED;
1612 flagword *flagsp ATTRIBUTE_UNUSED;
1613 asection **secp;
1614 bfd_vma *valp;
1616 if (sym->st_shndx == SHN_COMMON
1617 && !info->relocatable
1618 && sym->st_size <= elf_gp_size (abfd))
1620 /* Common symbols less than or equal to -G nn bytes are
1621 automatically put into .sbss. */
1623 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1625 if (scomm == NULL)
1627 scomm = bfd_make_section_with_flags (abfd, ".scommon",
1628 (SEC_ALLOC
1629 | SEC_IS_COMMON
1630 | SEC_LINKER_CREATED));
1631 if (scomm == NULL)
1632 return FALSE;
1635 *secp = scomm;
1636 *valp = sym->st_size;
1639 return TRUE;
1642 /* Return the number of additional phdrs we will need. */
1644 static int
1645 elfNN_ia64_additional_program_headers (bfd *abfd,
1646 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1648 asection *s;
1649 int ret = 0;
1651 /* See if we need a PT_IA_64_ARCHEXT segment. */
1652 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1653 if (s && (s->flags & SEC_LOAD))
1654 ++ret;
1656 /* Count how many PT_IA_64_UNWIND segments we need. */
1657 for (s = abfd->sections; s; s = s->next)
1658 if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1659 ++ret;
1661 return ret;
1664 static bfd_boolean
1665 elfNN_ia64_modify_segment_map (bfd *abfd,
1666 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1668 struct elf_segment_map *m, **pm;
1669 Elf_Internal_Shdr *hdr;
1670 asection *s;
1672 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1673 all PT_LOAD segments. */
1674 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1675 if (s && (s->flags & SEC_LOAD))
1677 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1678 if (m->p_type == PT_IA_64_ARCHEXT)
1679 break;
1680 if (m == NULL)
1682 m = ((struct elf_segment_map *)
1683 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1684 if (m == NULL)
1685 return FALSE;
1687 m->p_type = PT_IA_64_ARCHEXT;
1688 m->count = 1;
1689 m->sections[0] = s;
1691 /* We want to put it after the PHDR and INTERP segments. */
1692 pm = &elf_tdata (abfd)->segment_map;
1693 while (*pm != NULL
1694 && ((*pm)->p_type == PT_PHDR
1695 || (*pm)->p_type == PT_INTERP))
1696 pm = &(*pm)->next;
1698 m->next = *pm;
1699 *pm = m;
1703 /* Install PT_IA_64_UNWIND segments, if needed. */
1704 for (s = abfd->sections; s; s = s->next)
1706 hdr = &elf_section_data (s)->this_hdr;
1707 if (hdr->sh_type != SHT_IA_64_UNWIND)
1708 continue;
1710 if (s && (s->flags & SEC_LOAD))
1712 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1713 if (m->p_type == PT_IA_64_UNWIND)
1715 int i;
1717 /* Look through all sections in the unwind segment
1718 for a match since there may be multiple sections
1719 to a segment. */
1720 for (i = m->count - 1; i >= 0; --i)
1721 if (m->sections[i] == s)
1722 break;
1724 if (i >= 0)
1725 break;
1728 if (m == NULL)
1730 m = ((struct elf_segment_map *)
1731 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1732 if (m == NULL)
1733 return FALSE;
1735 m->p_type = PT_IA_64_UNWIND;
1736 m->count = 1;
1737 m->sections[0] = s;
1738 m->next = NULL;
1740 /* We want to put it last. */
1741 pm = &elf_tdata (abfd)->segment_map;
1742 while (*pm != NULL)
1743 pm = &(*pm)->next;
1744 *pm = m;
1749 return TRUE;
1752 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1753 the input sections for each output section in the segment and testing
1754 for SHF_IA_64_NORECOV on each. */
1756 static bfd_boolean
1757 elfNN_ia64_modify_program_headers (bfd *abfd,
1758 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1760 struct elf_obj_tdata *tdata = elf_tdata (abfd);
1761 struct elf_segment_map *m;
1762 Elf_Internal_Phdr *p;
1764 for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
1765 if (m->p_type == PT_LOAD)
1767 int i;
1768 for (i = m->count - 1; i >= 0; --i)
1770 struct bfd_link_order *order = m->sections[i]->map_head.link_order;
1772 while (order != NULL)
1774 if (order->type == bfd_indirect_link_order)
1776 asection *is = order->u.indirect.section;
1777 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1778 if (flags & SHF_IA_64_NORECOV)
1780 p->p_flags |= PF_IA_64_NORECOV;
1781 goto found;
1784 order = order->next;
1787 found:;
1790 return TRUE;
1793 /* According to the Tahoe assembler spec, all labels starting with a
1794 '.' are local. */
1796 static bfd_boolean
1797 elfNN_ia64_is_local_label_name (abfd, name)
1798 bfd *abfd ATTRIBUTE_UNUSED;
1799 const char *name;
1801 return name[0] == '.';
1804 /* Should we do dynamic things to this symbol? */
1806 static bfd_boolean
1807 elfNN_ia64_dynamic_symbol_p (h, info, r_type)
1808 struct elf_link_hash_entry *h;
1809 struct bfd_link_info *info;
1810 int r_type;
1812 bfd_boolean ignore_protected
1813 = ((r_type & 0xf8) == 0x40 /* FPTR relocs */
1814 || (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */
1816 return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
1819 static struct bfd_hash_entry*
1820 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1821 struct bfd_hash_entry *entry;
1822 struct bfd_hash_table *table;
1823 const char *string;
1825 struct elfNN_ia64_link_hash_entry *ret;
1826 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1828 /* Allocate the structure if it has not already been allocated by a
1829 subclass. */
1830 if (!ret)
1831 ret = bfd_hash_allocate (table, sizeof (*ret));
1833 if (!ret)
1834 return 0;
1836 /* Call the allocation method of the superclass. */
1837 ret = ((struct elfNN_ia64_link_hash_entry *)
1838 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1839 table, string));
1841 ret->info = NULL;
1842 ret->count = 0;
1843 ret->sorted_count = 0;
1844 ret->size = 0;
1845 return (struct bfd_hash_entry *) ret;
1848 static void
1849 elfNN_ia64_hash_copy_indirect (info, xdir, xind)
1850 struct bfd_link_info *info;
1851 struct elf_link_hash_entry *xdir, *xind;
1853 struct elfNN_ia64_link_hash_entry *dir, *ind;
1855 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1856 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1858 /* Copy down any references that we may have already seen to the
1859 symbol which just became indirect. */
1861 dir->root.ref_dynamic |= ind->root.ref_dynamic;
1862 dir->root.ref_regular |= ind->root.ref_regular;
1863 dir->root.ref_regular_nonweak |= ind->root.ref_regular_nonweak;
1864 dir->root.needs_plt |= ind->root.needs_plt;
1866 if (ind->root.root.type != bfd_link_hash_indirect)
1867 return;
1869 /* Copy over the got and plt data. This would have been done
1870 by check_relocs. */
1872 if (ind->info != NULL)
1874 struct elfNN_ia64_dyn_sym_info *dyn_i;
1875 unsigned int count;
1877 if (dir->info)
1878 free (dir->info);
1880 dir->info = ind->info;
1881 dir->count = ind->count;
1882 dir->sorted_count = ind->sorted_count;
1883 dir->size = ind->size;
1885 ind->info = NULL;
1886 ind->count = 0;
1887 ind->sorted_count = 0;
1888 ind->size = 0;
1890 /* Fix up the dyn_sym_info pointers to the global symbol. */
1891 for (count = dir->count, dyn_i = dir->info;
1892 count != 0;
1893 count--, dyn_i++)
1894 dyn_i->h = &dir->root;
1897 /* Copy over the dynindx. */
1899 if (ind->root.dynindx != -1)
1901 if (dir->root.dynindx != -1)
1902 _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
1903 dir->root.dynstr_index);
1904 dir->root.dynindx = ind->root.dynindx;
1905 dir->root.dynstr_index = ind->root.dynstr_index;
1906 ind->root.dynindx = -1;
1907 ind->root.dynstr_index = 0;
1911 static void
1912 elfNN_ia64_hash_hide_symbol (info, xh, force_local)
1913 struct bfd_link_info *info;
1914 struct elf_link_hash_entry *xh;
1915 bfd_boolean force_local;
1917 struct elfNN_ia64_link_hash_entry *h;
1918 struct elfNN_ia64_dyn_sym_info *dyn_i;
1919 unsigned int count;
1921 h = (struct elfNN_ia64_link_hash_entry *)xh;
1923 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1925 for (count = h->count, dyn_i = h->info;
1926 count != 0;
1927 count--, dyn_i++)
1929 dyn_i->want_plt2 = 0;
1930 dyn_i->want_plt = 0;
1934 /* Compute a hash of a local hash entry. */
1936 static hashval_t
1937 elfNN_ia64_local_htab_hash (ptr)
1938 const void *ptr;
1940 struct elfNN_ia64_local_hash_entry *entry
1941 = (struct elfNN_ia64_local_hash_entry *) ptr;
1943 return (((entry->id & 0xff) << 24) | ((entry->id & 0xff00) << 8))
1944 ^ entry->r_sym ^ (entry->id >> 16);
1947 /* Compare local hash entries. */
1949 static int
1950 elfNN_ia64_local_htab_eq (ptr1, ptr2)
1951 const void *ptr1, *ptr2;
1953 struct elfNN_ia64_local_hash_entry *entry1
1954 = (struct elfNN_ia64_local_hash_entry *) ptr1;
1955 struct elfNN_ia64_local_hash_entry *entry2
1956 = (struct elfNN_ia64_local_hash_entry *) ptr2;
1958 return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
1961 /* Create the derived linker hash table. The IA-64 ELF port uses this
1962 derived hash table to keep information specific to the IA-64 ElF
1963 linker (without using static variables). */
1965 static struct bfd_link_hash_table*
1966 elfNN_ia64_hash_table_create (abfd)
1967 bfd *abfd;
1969 struct elfNN_ia64_link_hash_table *ret;
1971 ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
1972 if (!ret)
1973 return 0;
1975 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1976 elfNN_ia64_new_elf_hash_entry,
1977 sizeof (struct elfNN_ia64_link_hash_entry)))
1979 free (ret);
1980 return 0;
1983 ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
1984 elfNN_ia64_local_htab_eq, NULL);
1985 ret->loc_hash_memory = objalloc_create ();
1986 if (!ret->loc_hash_table || !ret->loc_hash_memory)
1988 free (ret);
1989 return 0;
1992 return &ret->root.root;
1995 /* Free the global elfNN_ia64_dyn_sym_info array. */
1997 static bfd_boolean
1998 elfNN_ia64_global_dyn_info_free (void **xentry,
1999 PTR unused ATTRIBUTE_UNUSED)
2001 struct elfNN_ia64_link_hash_entry *entry
2002 = (struct elfNN_ia64_link_hash_entry *) xentry;
2004 if (entry->root.root.type == bfd_link_hash_warning)
2005 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
2007 if (entry->info)
2009 free (entry->info);
2010 entry->info = NULL;
2011 entry->count = 0;
2012 entry->sorted_count = 0;
2013 entry->size = 0;
2016 return TRUE;
2019 /* Free the local elfNN_ia64_dyn_sym_info array. */
2021 static bfd_boolean
2022 elfNN_ia64_local_dyn_info_free (void **slot,
2023 PTR unused ATTRIBUTE_UNUSED)
2025 struct elfNN_ia64_local_hash_entry *entry
2026 = (struct elfNN_ia64_local_hash_entry *) *slot;
2028 if (entry->info)
2030 free (entry->info);
2031 entry->info = NULL;
2032 entry->count = 0;
2033 entry->sorted_count = 0;
2034 entry->size = 0;
2037 return TRUE;
2040 /* Destroy IA-64 linker hash table. */
2042 static void
2043 elfNN_ia64_hash_table_free (hash)
2044 struct bfd_link_hash_table *hash;
2046 struct elfNN_ia64_link_hash_table *ia64_info
2047 = (struct elfNN_ia64_link_hash_table *) hash;
2048 if (ia64_info->loc_hash_table)
2050 htab_traverse (ia64_info->loc_hash_table,
2051 elfNN_ia64_local_dyn_info_free, NULL);
2052 htab_delete (ia64_info->loc_hash_table);
2054 if (ia64_info->loc_hash_memory)
2055 objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
2056 elf_link_hash_traverse (&ia64_info->root,
2057 elfNN_ia64_global_dyn_info_free, NULL);
2058 _bfd_generic_link_hash_table_free (hash);
2061 /* Traverse both local and global hash tables. */
2063 struct elfNN_ia64_dyn_sym_traverse_data
2065 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
2066 PTR data;
2069 static bfd_boolean
2070 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
2071 struct bfd_hash_entry *xentry;
2072 PTR xdata;
2074 struct elfNN_ia64_link_hash_entry *entry
2075 = (struct elfNN_ia64_link_hash_entry *) xentry;
2076 struct elfNN_ia64_dyn_sym_traverse_data *data
2077 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
2078 struct elfNN_ia64_dyn_sym_info *dyn_i;
2079 unsigned int count;
2081 if (entry->root.root.type == bfd_link_hash_warning)
2082 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
2084 for (count = entry->count, dyn_i = entry->info;
2085 count != 0;
2086 count--, dyn_i++)
2087 if (! (*data->func) (dyn_i, data->data))
2088 return FALSE;
2089 return TRUE;
2092 static bfd_boolean
2093 elfNN_ia64_local_dyn_sym_thunk (slot, xdata)
2094 void **slot;
2095 PTR xdata;
2097 struct elfNN_ia64_local_hash_entry *entry
2098 = (struct elfNN_ia64_local_hash_entry *) *slot;
2099 struct elfNN_ia64_dyn_sym_traverse_data *data
2100 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
2101 struct elfNN_ia64_dyn_sym_info *dyn_i;
2102 unsigned int count;
2104 for (count = entry->count, dyn_i = entry->info;
2105 count != 0;
2106 count--, dyn_i++)
2107 if (! (*data->func) (dyn_i, data->data))
2108 return FALSE;
2109 return TRUE;
2112 static void
2113 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
2114 struct elfNN_ia64_link_hash_table *ia64_info;
2115 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
2116 PTR data;
2118 struct elfNN_ia64_dyn_sym_traverse_data xdata;
2120 xdata.func = func;
2121 xdata.data = data;
2123 elf_link_hash_traverse (&ia64_info->root,
2124 elfNN_ia64_global_dyn_sym_thunk, &xdata);
2125 htab_traverse (ia64_info->loc_hash_table,
2126 elfNN_ia64_local_dyn_sym_thunk, &xdata);
2129 static bfd_boolean
2130 elfNN_ia64_create_dynamic_sections (abfd, info)
2131 bfd *abfd;
2132 struct bfd_link_info *info;
2134 struct elfNN_ia64_link_hash_table *ia64_info;
2135 asection *s;
2137 if (! _bfd_elf_create_dynamic_sections (abfd, info))
2138 return FALSE;
2140 ia64_info = elfNN_ia64_hash_table (info);
2142 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
2143 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
2146 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
2147 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
2148 /* The .got section is always aligned at 8 bytes. */
2149 bfd_set_section_alignment (abfd, ia64_info->got_sec, 3);
2152 if (!get_pltoff (abfd, info, ia64_info))
2153 return FALSE;
2155 s = bfd_make_section_with_flags (abfd, ".rela.IA_64.pltoff",
2156 (SEC_ALLOC | SEC_LOAD
2157 | SEC_HAS_CONTENTS
2158 | SEC_IN_MEMORY
2159 | SEC_LINKER_CREATED
2160 | SEC_READONLY));
2161 if (s == NULL
2162 || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
2163 return FALSE;
2164 ia64_info->rel_pltoff_sec = s;
2166 s = bfd_make_section_with_flags (abfd, ".rela.got",
2167 (SEC_ALLOC | SEC_LOAD
2168 | SEC_HAS_CONTENTS
2169 | SEC_IN_MEMORY
2170 | SEC_LINKER_CREATED
2171 | SEC_READONLY));
2172 if (s == NULL
2173 || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
2174 return FALSE;
2175 ia64_info->rel_got_sec = s;
2177 return TRUE;
2180 /* Find and/or create a hash entry for local symbol. */
2181 static struct elfNN_ia64_local_hash_entry *
2182 get_local_sym_hash (ia64_info, abfd, rel, create)
2183 struct elfNN_ia64_link_hash_table *ia64_info;
2184 bfd *abfd;
2185 const Elf_Internal_Rela *rel;
2186 bfd_boolean create;
2188 struct elfNN_ia64_local_hash_entry e, *ret;
2189 asection *sec = abfd->sections;
2190 hashval_t h = (((sec->id & 0xff) << 24) | ((sec->id & 0xff00) << 8))
2191 ^ ELFNN_R_SYM (rel->r_info) ^ (sec->id >> 16);
2192 void **slot;
2194 e.id = sec->id;
2195 e.r_sym = ELFNN_R_SYM (rel->r_info);
2196 slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
2197 create ? INSERT : NO_INSERT);
2199 if (!slot)
2200 return NULL;
2202 if (*slot)
2203 return (struct elfNN_ia64_local_hash_entry *) *slot;
2205 ret = (struct elfNN_ia64_local_hash_entry *)
2206 objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
2207 sizeof (struct elfNN_ia64_local_hash_entry));
2208 if (ret)
2210 memset (ret, 0, sizeof (*ret));
2211 ret->id = sec->id;
2212 ret->r_sym = ELFNN_R_SYM (rel->r_info);
2213 *slot = ret;
2215 return ret;
2218 /* Used to sort elfNN_ia64_dyn_sym_info array. */
2220 static int
2221 addend_compare (const void *xp, const void *yp)
2223 const struct elfNN_ia64_dyn_sym_info *x
2224 = (const struct elfNN_ia64_dyn_sym_info *) xp;
2225 const struct elfNN_ia64_dyn_sym_info *y
2226 = (const struct elfNN_ia64_dyn_sym_info *) yp;
2228 return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
2231 /* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
2233 static unsigned int
2234 sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
2235 unsigned int count)
2237 bfd_vma curr, prev;
2238 unsigned int i, dup, diff, dest, src, len;
2240 qsort (info, count, sizeof (*info), addend_compare);
2242 /* Find the first duplicate. */
2243 prev = info [0].addend;
2244 for (i = 1; i < count; i++)
2246 curr = info [i].addend;
2247 if (curr == prev)
2248 break;
2249 prev = curr;
2252 /* Remove duplicates. */
2253 if (i < count)
2255 /* We need to move a block of elements to here. */
2256 dest = i++;
2257 while (i < count)
2259 curr = info [i].addend;
2261 /* Move a block of elements whose first one is different from
2262 the previous. */
2263 if (curr == prev)
2265 for (src = i + 1; src < count; src++)
2266 if (info [src].addend != curr)
2267 break;
2269 else
2270 src = i;
2272 if (src >= count)
2273 break;
2275 /* Find the next duplicate. */
2276 prev = info [src].addend;
2277 for (dup = src + 1; dup < count; dup++)
2279 curr = info [dup].addend;
2280 if (curr == prev)
2281 break;
2282 prev = curr;
2285 /* How much to move. */
2286 len = dup - src;
2287 i = dup + 1;
2289 if (len == 1 && dup < count)
2291 /* If we only move 1 element, we combine it with the next
2292 one. Find the next different one. */
2293 for (diff = dup + 1, src++; diff < count; diff++, src++)
2294 if (info [diff].addend != curr)
2295 break;
2297 if (diff < count)
2299 /* Find the next duplicate. */
2300 prev = info [diff].addend;
2301 for (dup = diff + 1; dup < count; dup++)
2303 curr = info [dup].addend;
2304 if (curr == prev)
2305 break;
2306 prev = curr;
2307 diff++;
2310 len = diff - src + 1;
2311 i = diff + 1;
2315 memmove (&info [dest], &info [src], len * sizeof (*info));
2317 dest += len;
2320 count = dest;
2323 return count;
2326 /* Find and/or create a descriptor for dynamic symbol info. This will
2327 vary based on global or local symbol, and the addend to the reloc.
2329 We don't sort when inserting. Also, we sort and eliminate
2330 duplicates if there is an unsorted section. Typically, this will
2331 only happen once, because we do all insertions before lookups. We
2332 then use bsearch to do a lookup. This also allows lookups to be
2333 fast. So we have fast insertion (O(log N) due to duplicate check),
2334 fast lookup (O(log N)) and one sort (O(N log N) expected time).
2335 Previously, all lookups were O(N) because of the use of the linked
2336 list and also all insertions were O(N) because of the check for
2337 duplicates. There are some complications here because the array
2338 size grows occasionally, which may add an O(N) factor, but this
2339 should be rare. Also, we free the excess array allocation, which
2340 requires a copy which is O(N), but this only happens once. */
2342 static struct elfNN_ia64_dyn_sym_info *
2343 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
2344 struct elfNN_ia64_link_hash_table *ia64_info;
2345 struct elf_link_hash_entry *h;
2346 bfd *abfd;
2347 const Elf_Internal_Rela *rel;
2348 bfd_boolean create;
2350 struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
2351 unsigned int *count_p, *sorted_count_p, *size_p;
2352 unsigned int count, sorted_count, size;
2353 bfd_vma addend = rel ? rel->r_addend : 0;
2354 bfd_size_type amt;
2356 if (h)
2358 struct elfNN_ia64_link_hash_entry *global_h;
2360 global_h = (struct elfNN_ia64_link_hash_entry *) h;
2361 info_p = &global_h->info;
2362 count_p = &global_h->count;
2363 sorted_count_p = &global_h->sorted_count;
2364 size_p = &global_h->size;
2366 else
2368 struct elfNN_ia64_local_hash_entry *loc_h;
2370 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
2371 if (!loc_h)
2373 BFD_ASSERT (!create);
2374 return NULL;
2377 info_p = &loc_h->info;
2378 count_p = &loc_h->count;
2379 sorted_count_p = &loc_h->sorted_count;
2380 size_p = &loc_h->size;
2383 count = *count_p;
2384 sorted_count = *sorted_count_p;
2385 size = *size_p;
2386 info = *info_p;
2387 if (create)
2389 /* When we create the array, we don't check for duplicates,
2390 except in the previously sorted section if one exists, and
2391 against the last inserted entry. This allows insertions to
2392 be fast. */
2393 if (info)
2395 if (sorted_count)
2397 /* Try bsearch first on the sorted section. */
2398 key.addend = addend;
2399 dyn_i = bsearch (&key, info, sorted_count,
2400 sizeof (*info), addend_compare);
2402 if (dyn_i)
2404 return dyn_i;
2408 /* Do a quick check for the last inserted entry. */
2409 dyn_i = info + count - 1;
2410 if (dyn_i->addend == addend)
2412 return dyn_i;
2416 if (size == 0)
2418 /* It is the very first element. We create the array of size
2419 1. */
2420 size = 1;
2421 amt = size * sizeof (*info);
2422 info = bfd_malloc (amt);
2424 else if (size <= count)
2426 /* We double the array size every time when we reach the
2427 size limit. */
2428 size += size;
2429 amt = size * sizeof (*info);
2430 info = bfd_realloc (info, amt);
2432 else
2433 goto has_space;
2435 if (info == NULL)
2436 return NULL;
2437 *size_p = size;
2438 *info_p = info;
2440 has_space:
2441 /* Append the new one to the array. */
2442 dyn_i = info + count;
2443 memset (dyn_i, 0, sizeof (*dyn_i));
2444 dyn_i->addend = addend;
2446 /* We increment count only since the new ones are unsorted and
2447 may have duplicate. */
2448 (*count_p)++;
2450 else
2452 /* It is a lookup without insertion. Sort array if part of the
2453 array isn't sorted. */
2454 if (count != sorted_count)
2456 count = sort_dyn_sym_info (info, count);
2457 *count_p = count;
2458 *sorted_count_p = count;
2461 /* Free unused memory. */
2462 if (size != count)
2464 amt = count * sizeof (*info);
2465 info = bfd_malloc (amt);
2466 if (info != NULL)
2468 memcpy (info, *info_p, amt);
2469 free (*info_p);
2470 *size_p = count;
2471 *info_p = info;
2475 key.addend = addend;
2476 dyn_i = bsearch (&key, info, count,
2477 sizeof (*info), addend_compare);
2480 return dyn_i;
2483 static asection *
2484 get_got (abfd, info, ia64_info)
2485 bfd *abfd;
2486 struct bfd_link_info *info;
2487 struct elfNN_ia64_link_hash_table *ia64_info;
2489 asection *got;
2490 bfd *dynobj;
2492 got = ia64_info->got_sec;
2493 if (!got)
2495 flagword flags;
2497 dynobj = ia64_info->root.dynobj;
2498 if (!dynobj)
2499 ia64_info->root.dynobj = dynobj = abfd;
2500 if (!_bfd_elf_create_got_section (dynobj, info))
2501 return 0;
2503 got = bfd_get_section_by_name (dynobj, ".got");
2504 BFD_ASSERT (got);
2505 ia64_info->got_sec = got;
2507 /* The .got section is always aligned at 8 bytes. */
2508 if (!bfd_set_section_alignment (abfd, got, 3))
2509 return 0;
2511 flags = bfd_get_section_flags (abfd, got);
2512 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2515 return got;
2518 /* Create function descriptor section (.opd). This section is called .opd
2519 because it contains "official procedure descriptors". The "official"
2520 refers to the fact that these descriptors are used when taking the address
2521 of a procedure, thus ensuring a unique address for each procedure. */
2523 static asection *
2524 get_fptr (abfd, info, ia64_info)
2525 bfd *abfd;
2526 struct bfd_link_info *info;
2527 struct elfNN_ia64_link_hash_table *ia64_info;
2529 asection *fptr;
2530 bfd *dynobj;
2532 fptr = ia64_info->fptr_sec;
2533 if (!fptr)
2535 dynobj = ia64_info->root.dynobj;
2536 if (!dynobj)
2537 ia64_info->root.dynobj = dynobj = abfd;
2539 fptr = bfd_make_section_with_flags (dynobj, ".opd",
2540 (SEC_ALLOC
2541 | SEC_LOAD
2542 | SEC_HAS_CONTENTS
2543 | SEC_IN_MEMORY
2544 | (info->pie ? 0 : SEC_READONLY)
2545 | SEC_LINKER_CREATED));
2546 if (!fptr
2547 || !bfd_set_section_alignment (abfd, fptr, 4))
2549 BFD_ASSERT (0);
2550 return NULL;
2553 ia64_info->fptr_sec = fptr;
2555 if (info->pie)
2557 asection *fptr_rel;
2558 fptr_rel = bfd_make_section_with_flags (dynobj, ".rela.opd",
2559 (SEC_ALLOC | SEC_LOAD
2560 | SEC_HAS_CONTENTS
2561 | SEC_IN_MEMORY
2562 | SEC_LINKER_CREATED
2563 | SEC_READONLY));
2564 if (fptr_rel == NULL
2565 || !bfd_set_section_alignment (abfd, fptr_rel,
2566 LOG_SECTION_ALIGN))
2568 BFD_ASSERT (0);
2569 return NULL;
2572 ia64_info->rel_fptr_sec = fptr_rel;
2576 return fptr;
2579 static asection *
2580 get_pltoff (abfd, info, ia64_info)
2581 bfd *abfd;
2582 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2583 struct elfNN_ia64_link_hash_table *ia64_info;
2585 asection *pltoff;
2586 bfd *dynobj;
2588 pltoff = ia64_info->pltoff_sec;
2589 if (!pltoff)
2591 dynobj = ia64_info->root.dynobj;
2592 if (!dynobj)
2593 ia64_info->root.dynobj = dynobj = abfd;
2595 pltoff = bfd_make_section_with_flags (dynobj,
2596 ELF_STRING_ia64_pltoff,
2597 (SEC_ALLOC
2598 | SEC_LOAD
2599 | SEC_HAS_CONTENTS
2600 | SEC_IN_MEMORY
2601 | SEC_SMALL_DATA
2602 | SEC_LINKER_CREATED));
2603 if (!pltoff
2604 || !bfd_set_section_alignment (abfd, pltoff, 4))
2606 BFD_ASSERT (0);
2607 return NULL;
2610 ia64_info->pltoff_sec = pltoff;
2613 return pltoff;
2616 static asection *
2617 get_reloc_section (abfd, ia64_info, sec, create)
2618 bfd *abfd;
2619 struct elfNN_ia64_link_hash_table *ia64_info;
2620 asection *sec;
2621 bfd_boolean create;
2623 const char *srel_name;
2624 asection *srel;
2625 bfd *dynobj;
2627 srel_name = (bfd_elf_string_from_elf_section
2628 (abfd, elf_elfheader(abfd)->e_shstrndx,
2629 elf_section_data(sec)->rel_hdr.sh_name));
2630 if (srel_name == NULL)
2631 return NULL;
2633 BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela")
2634 && strcmp (bfd_get_section_name (abfd, sec),
2635 srel_name+5) == 0)
2636 || (CONST_STRNEQ (srel_name, ".rel")
2637 && strcmp (bfd_get_section_name (abfd, sec),
2638 srel_name+4) == 0));
2640 dynobj = ia64_info->root.dynobj;
2641 if (!dynobj)
2642 ia64_info->root.dynobj = dynobj = abfd;
2644 srel = bfd_get_section_by_name (dynobj, srel_name);
2645 if (srel == NULL && create)
2647 srel = bfd_make_section_with_flags (dynobj, srel_name,
2648 (SEC_ALLOC | SEC_LOAD
2649 | SEC_HAS_CONTENTS
2650 | SEC_IN_MEMORY
2651 | SEC_LINKER_CREATED
2652 | SEC_READONLY));
2653 if (srel == NULL
2654 || !bfd_set_section_alignment (dynobj, srel,
2655 LOG_SECTION_ALIGN))
2656 return NULL;
2659 return srel;
2662 static bfd_boolean
2663 count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
2664 asection *srel, int type, bfd_boolean reltext)
2666 struct elfNN_ia64_dyn_reloc_entry *rent;
2668 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2669 if (rent->srel == srel && rent->type == type)
2670 break;
2672 if (!rent)
2674 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2675 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2676 if (!rent)
2677 return FALSE;
2679 rent->next = dyn_i->reloc_entries;
2680 rent->srel = srel;
2681 rent->type = type;
2682 rent->count = 0;
2683 dyn_i->reloc_entries = rent;
2685 rent->reltext = reltext;
2686 rent->count++;
2688 return TRUE;
2691 static bfd_boolean
2692 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2693 bfd *abfd;
2694 struct bfd_link_info *info;
2695 asection *sec;
2696 const Elf_Internal_Rela *relocs;
2698 struct elfNN_ia64_link_hash_table *ia64_info;
2699 const Elf_Internal_Rela *relend;
2700 Elf_Internal_Shdr *symtab_hdr;
2701 const Elf_Internal_Rela *rel;
2702 asection *got, *fptr, *srel, *pltoff;
2703 enum {
2704 NEED_GOT = 1,
2705 NEED_GOTX = 2,
2706 NEED_FPTR = 4,
2707 NEED_PLTOFF = 8,
2708 NEED_MIN_PLT = 16,
2709 NEED_FULL_PLT = 32,
2710 NEED_DYNREL = 64,
2711 NEED_LTOFF_FPTR = 128,
2712 NEED_TPREL = 256,
2713 NEED_DTPMOD = 512,
2714 NEED_DTPREL = 1024
2716 int need_entry;
2717 struct elf_link_hash_entry *h;
2718 unsigned long r_symndx;
2719 bfd_boolean maybe_dynamic;
2721 if (info->relocatable)
2722 return TRUE;
2724 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2725 ia64_info = elfNN_ia64_hash_table (info);
2727 got = fptr = srel = pltoff = NULL;
2729 relend = relocs + sec->reloc_count;
2731 /* We scan relocations first to create dynamic relocation arrays. We
2732 modified get_dyn_sym_info to allow fast insertion and support fast
2733 lookup in the next loop. */
2734 for (rel = relocs; rel < relend; ++rel)
2736 r_symndx = ELFNN_R_SYM (rel->r_info);
2737 if (r_symndx >= symtab_hdr->sh_info)
2739 long indx = r_symndx - symtab_hdr->sh_info;
2740 h = elf_sym_hashes (abfd)[indx];
2741 while (h->root.type == bfd_link_hash_indirect
2742 || h->root.type == bfd_link_hash_warning)
2743 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2745 else
2746 h = NULL;
2748 /* We can only get preliminary data on whether a symbol is
2749 locally or externally defined, as not all of the input files
2750 have yet been processed. Do something with what we know, as
2751 this may help reduce memory usage and processing time later. */
2752 maybe_dynamic = (h && ((!info->executable
2753 && (!SYMBOLIC_BIND (info, h)
2754 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2755 || !h->def_regular
2756 || h->root.type == bfd_link_hash_defweak));
2758 need_entry = 0;
2759 switch (ELFNN_R_TYPE (rel->r_info))
2761 case R_IA64_TPREL64MSB:
2762 case R_IA64_TPREL64LSB:
2763 if (info->shared || maybe_dynamic)
2764 need_entry = NEED_DYNREL;
2765 break;
2767 case R_IA64_LTOFF_TPREL22:
2768 need_entry = NEED_TPREL;
2769 if (info->shared)
2770 info->flags |= DF_STATIC_TLS;
2771 break;
2773 case R_IA64_DTPREL32MSB:
2774 case R_IA64_DTPREL32LSB:
2775 case R_IA64_DTPREL64MSB:
2776 case R_IA64_DTPREL64LSB:
2777 if (info->shared || maybe_dynamic)
2778 need_entry = NEED_DYNREL;
2779 break;
2781 case R_IA64_LTOFF_DTPREL22:
2782 need_entry = NEED_DTPREL;
2783 break;
2785 case R_IA64_DTPMOD64MSB:
2786 case R_IA64_DTPMOD64LSB:
2787 if (info->shared || maybe_dynamic)
2788 need_entry = NEED_DYNREL;
2789 break;
2791 case R_IA64_LTOFF_DTPMOD22:
2792 need_entry = NEED_DTPMOD;
2793 break;
2795 case R_IA64_LTOFF_FPTR22:
2796 case R_IA64_LTOFF_FPTR64I:
2797 case R_IA64_LTOFF_FPTR32MSB:
2798 case R_IA64_LTOFF_FPTR32LSB:
2799 case R_IA64_LTOFF_FPTR64MSB:
2800 case R_IA64_LTOFF_FPTR64LSB:
2801 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2802 break;
2804 case R_IA64_FPTR64I:
2805 case R_IA64_FPTR32MSB:
2806 case R_IA64_FPTR32LSB:
2807 case R_IA64_FPTR64MSB:
2808 case R_IA64_FPTR64LSB:
2809 if (info->shared || h)
2810 need_entry = NEED_FPTR | NEED_DYNREL;
2811 else
2812 need_entry = NEED_FPTR;
2813 break;
2815 case R_IA64_LTOFF22:
2816 case R_IA64_LTOFF64I:
2817 need_entry = NEED_GOT;
2818 break;
2820 case R_IA64_LTOFF22X:
2821 need_entry = NEED_GOTX;
2822 break;
2824 case R_IA64_PLTOFF22:
2825 case R_IA64_PLTOFF64I:
2826 case R_IA64_PLTOFF64MSB:
2827 case R_IA64_PLTOFF64LSB:
2828 need_entry = NEED_PLTOFF;
2829 if (h)
2831 if (maybe_dynamic)
2832 need_entry |= NEED_MIN_PLT;
2834 else
2836 (*info->callbacks->warning)
2837 (info, _("@pltoff reloc against local symbol"), 0,
2838 abfd, 0, (bfd_vma) 0);
2840 break;
2842 case R_IA64_PCREL21B:
2843 case R_IA64_PCREL60B:
2844 /* Depending on where this symbol is defined, we may or may not
2845 need a full plt entry. Only skip if we know we'll not need
2846 the entry -- static or symbolic, and the symbol definition
2847 has already been seen. */
2848 if (maybe_dynamic && rel->r_addend == 0)
2849 need_entry = NEED_FULL_PLT;
2850 break;
2852 case R_IA64_IMM14:
2853 case R_IA64_IMM22:
2854 case R_IA64_IMM64:
2855 case R_IA64_DIR32MSB:
2856 case R_IA64_DIR32LSB:
2857 case R_IA64_DIR64MSB:
2858 case R_IA64_DIR64LSB:
2859 /* Shared objects will always need at least a REL relocation. */
2860 if (info->shared || maybe_dynamic)
2861 need_entry = NEED_DYNREL;
2862 break;
2864 case R_IA64_IPLTMSB:
2865 case R_IA64_IPLTLSB:
2866 /* Shared objects will always need at least a REL relocation. */
2867 if (info->shared || maybe_dynamic)
2868 need_entry = NEED_DYNREL;
2869 break;
2871 case R_IA64_PCREL22:
2872 case R_IA64_PCREL64I:
2873 case R_IA64_PCREL32MSB:
2874 case R_IA64_PCREL32LSB:
2875 case R_IA64_PCREL64MSB:
2876 case R_IA64_PCREL64LSB:
2877 if (maybe_dynamic)
2878 need_entry = NEED_DYNREL;
2879 break;
2882 if (!need_entry)
2883 continue;
2885 if ((need_entry & NEED_FPTR) != 0
2886 && rel->r_addend)
2888 (*info->callbacks->warning)
2889 (info, _("non-zero addend in @fptr reloc"), 0,
2890 abfd, 0, (bfd_vma) 0);
2893 if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
2894 return FALSE;
2897 /* Now, we only do lookup without insertion, which is very fast
2898 with the modified get_dyn_sym_info. */
2899 for (rel = relocs; rel < relend; ++rel)
2901 struct elfNN_ia64_dyn_sym_info *dyn_i;
2902 int dynrel_type = R_IA64_NONE;
2904 r_symndx = ELFNN_R_SYM (rel->r_info);
2905 if (r_symndx >= symtab_hdr->sh_info)
2907 /* We're dealing with a global symbol -- find its hash entry
2908 and mark it as being referenced. */
2909 long indx = r_symndx - symtab_hdr->sh_info;
2910 h = elf_sym_hashes (abfd)[indx];
2911 while (h->root.type == bfd_link_hash_indirect
2912 || h->root.type == bfd_link_hash_warning)
2913 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2915 h->ref_regular = 1;
2917 else
2918 h = NULL;
2920 /* We can only get preliminary data on whether a symbol is
2921 locally or externally defined, as not all of the input files
2922 have yet been processed. Do something with what we know, as
2923 this may help reduce memory usage and processing time later. */
2924 maybe_dynamic = (h && ((!info->executable
2925 && (!SYMBOLIC_BIND (info, h)
2926 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2927 || !h->def_regular
2928 || h->root.type == bfd_link_hash_defweak));
2930 need_entry = 0;
2931 switch (ELFNN_R_TYPE (rel->r_info))
2933 case R_IA64_TPREL64MSB:
2934 case R_IA64_TPREL64LSB:
2935 if (info->shared || maybe_dynamic)
2936 need_entry = NEED_DYNREL;
2937 dynrel_type = R_IA64_TPREL64LSB;
2938 if (info->shared)
2939 info->flags |= DF_STATIC_TLS;
2940 break;
2942 case R_IA64_LTOFF_TPREL22:
2943 need_entry = NEED_TPREL;
2944 if (info->shared)
2945 info->flags |= DF_STATIC_TLS;
2946 break;
2948 case R_IA64_DTPREL32MSB:
2949 case R_IA64_DTPREL32LSB:
2950 case R_IA64_DTPREL64MSB:
2951 case R_IA64_DTPREL64LSB:
2952 if (info->shared || maybe_dynamic)
2953 need_entry = NEED_DYNREL;
2954 dynrel_type = R_IA64_DTPRELNNLSB;
2955 break;
2957 case R_IA64_LTOFF_DTPREL22:
2958 need_entry = NEED_DTPREL;
2959 break;
2961 case R_IA64_DTPMOD64MSB:
2962 case R_IA64_DTPMOD64LSB:
2963 if (info->shared || maybe_dynamic)
2964 need_entry = NEED_DYNREL;
2965 dynrel_type = R_IA64_DTPMOD64LSB;
2966 break;
2968 case R_IA64_LTOFF_DTPMOD22:
2969 need_entry = NEED_DTPMOD;
2970 break;
2972 case R_IA64_LTOFF_FPTR22:
2973 case R_IA64_LTOFF_FPTR64I:
2974 case R_IA64_LTOFF_FPTR32MSB:
2975 case R_IA64_LTOFF_FPTR32LSB:
2976 case R_IA64_LTOFF_FPTR64MSB:
2977 case R_IA64_LTOFF_FPTR64LSB:
2978 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2979 break;
2981 case R_IA64_FPTR64I:
2982 case R_IA64_FPTR32MSB:
2983 case R_IA64_FPTR32LSB:
2984 case R_IA64_FPTR64MSB:
2985 case R_IA64_FPTR64LSB:
2986 if (info->shared || h)
2987 need_entry = NEED_FPTR | NEED_DYNREL;
2988 else
2989 need_entry = NEED_FPTR;
2990 dynrel_type = R_IA64_FPTRNNLSB;
2991 break;
2993 case R_IA64_LTOFF22:
2994 case R_IA64_LTOFF64I:
2995 need_entry = NEED_GOT;
2996 break;
2998 case R_IA64_LTOFF22X:
2999 need_entry = NEED_GOTX;
3000 break;
3002 case R_IA64_PLTOFF22:
3003 case R_IA64_PLTOFF64I:
3004 case R_IA64_PLTOFF64MSB:
3005 case R_IA64_PLTOFF64LSB:
3006 need_entry = NEED_PLTOFF;
3007 if (h)
3009 if (maybe_dynamic)
3010 need_entry |= NEED_MIN_PLT;
3012 break;
3014 case R_IA64_PCREL21B:
3015 case R_IA64_PCREL60B:
3016 /* Depending on where this symbol is defined, we may or may not
3017 need a full plt entry. Only skip if we know we'll not need
3018 the entry -- static or symbolic, and the symbol definition
3019 has already been seen. */
3020 if (maybe_dynamic && rel->r_addend == 0)
3021 need_entry = NEED_FULL_PLT;
3022 break;
3024 case R_IA64_IMM14:
3025 case R_IA64_IMM22:
3026 case R_IA64_IMM64:
3027 case R_IA64_DIR32MSB:
3028 case R_IA64_DIR32LSB:
3029 case R_IA64_DIR64MSB:
3030 case R_IA64_DIR64LSB:
3031 /* Shared objects will always need at least a REL relocation. */
3032 if (info->shared || maybe_dynamic)
3033 need_entry = NEED_DYNREL;
3034 dynrel_type = R_IA64_DIRNNLSB;
3035 break;
3037 case R_IA64_IPLTMSB:
3038 case R_IA64_IPLTLSB:
3039 /* Shared objects will always need at least a REL relocation. */
3040 if (info->shared || maybe_dynamic)
3041 need_entry = NEED_DYNREL;
3042 dynrel_type = R_IA64_IPLTLSB;
3043 break;
3045 case R_IA64_PCREL22:
3046 case R_IA64_PCREL64I:
3047 case R_IA64_PCREL32MSB:
3048 case R_IA64_PCREL32LSB:
3049 case R_IA64_PCREL64MSB:
3050 case R_IA64_PCREL64LSB:
3051 if (maybe_dynamic)
3052 need_entry = NEED_DYNREL;
3053 dynrel_type = R_IA64_PCRELNNLSB;
3054 break;
3057 if (!need_entry)
3058 continue;
3060 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
3062 /* Record whether or not this is a local symbol. */
3063 dyn_i->h = h;
3065 /* Create what's needed. */
3066 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
3067 | NEED_DTPMOD | NEED_DTPREL))
3069 if (!got)
3071 got = get_got (abfd, info, ia64_info);
3072 if (!got)
3073 return FALSE;
3075 if (need_entry & NEED_GOT)
3076 dyn_i->want_got = 1;
3077 if (need_entry & NEED_GOTX)
3078 dyn_i->want_gotx = 1;
3079 if (need_entry & NEED_TPREL)
3080 dyn_i->want_tprel = 1;
3081 if (need_entry & NEED_DTPMOD)
3082 dyn_i->want_dtpmod = 1;
3083 if (need_entry & NEED_DTPREL)
3084 dyn_i->want_dtprel = 1;
3086 if (need_entry & NEED_FPTR)
3088 if (!fptr)
3090 fptr = get_fptr (abfd, info, ia64_info);
3091 if (!fptr)
3092 return FALSE;
3095 /* FPTRs for shared libraries are allocated by the dynamic
3096 linker. Make sure this local symbol will appear in the
3097 dynamic symbol table. */
3098 if (!h && info->shared)
3100 if (! (bfd_elf_link_record_local_dynamic_symbol
3101 (info, abfd, (long) r_symndx)))
3102 return FALSE;
3105 dyn_i->want_fptr = 1;
3107 if (need_entry & NEED_LTOFF_FPTR)
3108 dyn_i->want_ltoff_fptr = 1;
3109 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
3111 if (!ia64_info->root.dynobj)
3112 ia64_info->root.dynobj = abfd;
3113 h->needs_plt = 1;
3114 dyn_i->want_plt = 1;
3116 if (need_entry & NEED_FULL_PLT)
3117 dyn_i->want_plt2 = 1;
3118 if (need_entry & NEED_PLTOFF)
3120 /* This is needed here, in case @pltoff is used in a non-shared
3121 link. */
3122 if (!pltoff)
3124 pltoff = get_pltoff (abfd, info, ia64_info);
3125 if (!pltoff)
3126 return FALSE;
3129 dyn_i->want_pltoff = 1;
3131 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
3133 if (!srel)
3135 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
3136 if (!srel)
3137 return FALSE;
3139 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
3140 (sec->flags & SEC_READONLY) != 0))
3141 return FALSE;
3145 return TRUE;
3148 /* For cleanliness, and potentially faster dynamic loading, allocate
3149 external GOT entries first. */
3151 static bfd_boolean
3152 allocate_global_data_got (dyn_i, data)
3153 struct elfNN_ia64_dyn_sym_info *dyn_i;
3154 PTR data;
3156 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3158 if ((dyn_i->want_got || dyn_i->want_gotx)
3159 && ! dyn_i->want_fptr
3160 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3162 dyn_i->got_offset = x->ofs;
3163 x->ofs += 8;
3165 if (dyn_i->want_tprel)
3167 dyn_i->tprel_offset = x->ofs;
3168 x->ofs += 8;
3170 if (dyn_i->want_dtpmod)
3172 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3174 dyn_i->dtpmod_offset = x->ofs;
3175 x->ofs += 8;
3177 else
3179 struct elfNN_ia64_link_hash_table *ia64_info;
3181 ia64_info = elfNN_ia64_hash_table (x->info);
3182 if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
3184 ia64_info->self_dtpmod_offset = x->ofs;
3185 x->ofs += 8;
3187 dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
3190 if (dyn_i->want_dtprel)
3192 dyn_i->dtprel_offset = x->ofs;
3193 x->ofs += 8;
3195 return TRUE;
3198 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
3200 static bfd_boolean
3201 allocate_global_fptr_got (dyn_i, data)
3202 struct elfNN_ia64_dyn_sym_info *dyn_i;
3203 PTR data;
3205 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3207 if (dyn_i->want_got
3208 && dyn_i->want_fptr
3209 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
3211 dyn_i->got_offset = x->ofs;
3212 x->ofs += 8;
3214 return TRUE;
3217 /* Lastly, allocate all the GOT entries for local data. */
3219 static bfd_boolean
3220 allocate_local_got (dyn_i, data)
3221 struct elfNN_ia64_dyn_sym_info *dyn_i;
3222 PTR data;
3224 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3226 if ((dyn_i->want_got || dyn_i->want_gotx)
3227 && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3229 dyn_i->got_offset = x->ofs;
3230 x->ofs += 8;
3232 return TRUE;
3235 /* Search for the index of a global symbol in it's defining object file. */
3237 static long
3238 global_sym_index (h)
3239 struct elf_link_hash_entry *h;
3241 struct elf_link_hash_entry **p;
3242 bfd *obj;
3244 BFD_ASSERT (h->root.type == bfd_link_hash_defined
3245 || h->root.type == bfd_link_hash_defweak);
3247 obj = h->root.u.def.section->owner;
3248 for (p = elf_sym_hashes (obj); *p != h; ++p)
3249 continue;
3251 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
3254 /* Allocate function descriptors. We can do these for every function
3255 in a main executable that is not exported. */
3257 static bfd_boolean
3258 allocate_fptr (dyn_i, data)
3259 struct elfNN_ia64_dyn_sym_info *dyn_i;
3260 PTR data;
3262 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3264 if (dyn_i->want_fptr)
3266 struct elf_link_hash_entry *h = dyn_i->h;
3268 if (h)
3269 while (h->root.type == bfd_link_hash_indirect
3270 || h->root.type == bfd_link_hash_warning)
3271 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3273 if (!x->info->executable
3274 && (!h
3275 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3276 || (h->root.type != bfd_link_hash_undefweak
3277 && h->root.type != bfd_link_hash_undefined)))
3279 if (h && h->dynindx == -1)
3281 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
3282 || (h->root.type == bfd_link_hash_defweak));
3284 if (!bfd_elf_link_record_local_dynamic_symbol
3285 (x->info, h->root.u.def.section->owner,
3286 global_sym_index (h)))
3287 return FALSE;
3290 dyn_i->want_fptr = 0;
3292 else if (h == NULL || h->dynindx == -1)
3294 dyn_i->fptr_offset = x->ofs;
3295 x->ofs += 16;
3297 else
3298 dyn_i->want_fptr = 0;
3300 return TRUE;
3303 /* Allocate all the minimal PLT entries. */
3305 static bfd_boolean
3306 allocate_plt_entries (dyn_i, data)
3307 struct elfNN_ia64_dyn_sym_info *dyn_i;
3308 PTR data;
3310 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3312 if (dyn_i->want_plt)
3314 struct elf_link_hash_entry *h = dyn_i->h;
3316 if (h)
3317 while (h->root.type == bfd_link_hash_indirect
3318 || h->root.type == bfd_link_hash_warning)
3319 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3321 /* ??? Versioned symbols seem to lose NEEDS_PLT. */
3322 if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
3324 bfd_size_type offset = x->ofs;
3325 if (offset == 0)
3326 offset = PLT_HEADER_SIZE;
3327 dyn_i->plt_offset = offset;
3328 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
3330 dyn_i->want_pltoff = 1;
3332 else
3334 dyn_i->want_plt = 0;
3335 dyn_i->want_plt2 = 0;
3338 return TRUE;
3341 /* Allocate all the full PLT entries. */
3343 static bfd_boolean
3344 allocate_plt2_entries (dyn_i, data)
3345 struct elfNN_ia64_dyn_sym_info *dyn_i;
3346 PTR data;
3348 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3350 if (dyn_i->want_plt2)
3352 struct elf_link_hash_entry *h = dyn_i->h;
3353 bfd_size_type ofs = x->ofs;
3355 dyn_i->plt2_offset = ofs;
3356 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
3358 while (h->root.type == bfd_link_hash_indirect
3359 || h->root.type == bfd_link_hash_warning)
3360 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3361 dyn_i->h->plt.offset = ofs;
3363 return TRUE;
3366 /* Allocate all the PLTOFF entries requested by relocations and
3367 plt entries. We can't share space with allocated FPTR entries,
3368 because the latter are not necessarily addressable by the GP.
3369 ??? Relaxation might be able to determine that they are. */
3371 static bfd_boolean
3372 allocate_pltoff_entries (dyn_i, data)
3373 struct elfNN_ia64_dyn_sym_info *dyn_i;
3374 PTR data;
3376 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3378 if (dyn_i->want_pltoff)
3380 dyn_i->pltoff_offset = x->ofs;
3381 x->ofs += 16;
3383 return TRUE;
3386 /* Allocate dynamic relocations for those symbols that turned out
3387 to be dynamic. */
3389 static bfd_boolean
3390 allocate_dynrel_entries (dyn_i, data)
3391 struct elfNN_ia64_dyn_sym_info *dyn_i;
3392 PTR data;
3394 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3395 struct elfNN_ia64_link_hash_table *ia64_info;
3396 struct elfNN_ia64_dyn_reloc_entry *rent;
3397 bfd_boolean dynamic_symbol, shared, resolved_zero;
3399 ia64_info = elfNN_ia64_hash_table (x->info);
3401 /* Note that this can't be used in relation to FPTR relocs below. */
3402 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
3404 shared = x->info->shared;
3405 resolved_zero = (dyn_i->h
3406 && ELF_ST_VISIBILITY (dyn_i->h->other)
3407 && dyn_i->h->root.type == bfd_link_hash_undefweak);
3409 /* Take care of the GOT and PLT relocations. */
3411 if ((!resolved_zero
3412 && (dynamic_symbol || shared)
3413 && (dyn_i->want_got || dyn_i->want_gotx))
3414 || (dyn_i->want_ltoff_fptr
3415 && dyn_i->h
3416 && dyn_i->h->dynindx != -1))
3418 if (!dyn_i->want_ltoff_fptr
3419 || !x->info->pie
3420 || dyn_i->h == NULL
3421 || dyn_i->h->root.type != bfd_link_hash_undefweak)
3422 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3424 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
3425 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3426 if (dynamic_symbol && dyn_i->want_dtpmod)
3427 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3428 if (dynamic_symbol && dyn_i->want_dtprel)
3429 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3431 if (x->only_got)
3432 return TRUE;
3434 if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
3436 if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
3437 ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
3440 if (!resolved_zero && dyn_i->want_pltoff)
3442 bfd_size_type t = 0;
3444 /* Dynamic symbols get one IPLT relocation. Local symbols in
3445 shared libraries get two REL relocations. Local symbols in
3446 main applications get nothing. */
3447 if (dynamic_symbol)
3448 t = sizeof (ElfNN_External_Rela);
3449 else if (shared)
3450 t = 2 * sizeof (ElfNN_External_Rela);
3452 ia64_info->rel_pltoff_sec->size += t;
3455 /* Take care of the normal data relocations. */
3457 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
3459 int count = rent->count;
3461 switch (rent->type)
3463 case R_IA64_FPTR32LSB:
3464 case R_IA64_FPTR64LSB:
3465 /* Allocate one iff !want_fptr and not PIE, which by this point
3466 will be true only if we're actually allocating one statically
3467 in the main executable. Position independent executables
3468 need a relative reloc. */
3469 if (dyn_i->want_fptr && !x->info->pie)
3470 continue;
3471 break;
3472 case R_IA64_PCREL32LSB:
3473 case R_IA64_PCREL64LSB:
3474 if (!dynamic_symbol)
3475 continue;
3476 break;
3477 case R_IA64_DIR32LSB:
3478 case R_IA64_DIR64LSB:
3479 if (!dynamic_symbol && !shared)
3480 continue;
3481 break;
3482 case R_IA64_IPLTLSB:
3483 if (!dynamic_symbol && !shared)
3484 continue;
3485 /* Use two REL relocations for IPLT relocations
3486 against local symbols. */
3487 if (!dynamic_symbol)
3488 count *= 2;
3489 break;
3490 case R_IA64_DTPREL32LSB:
3491 case R_IA64_TPREL64LSB:
3492 case R_IA64_DTPREL64LSB:
3493 case R_IA64_DTPMOD64LSB:
3494 break;
3495 default:
3496 abort ();
3498 if (rent->reltext)
3499 ia64_info->reltext = 1;
3500 rent->srel->size += sizeof (ElfNN_External_Rela) * count;
3503 return TRUE;
3506 static bfd_boolean
3507 elfNN_ia64_adjust_dynamic_symbol (info, h)
3508 struct bfd_link_info *info ATTRIBUTE_UNUSED;
3509 struct elf_link_hash_entry *h;
3511 /* ??? Undefined symbols with PLT entries should be re-defined
3512 to be the PLT entry. */
3514 /* If this is a weak symbol, and there is a real definition, the
3515 processor independent code will have arranged for us to see the
3516 real definition first, and we can just use the same value. */
3517 if (h->u.weakdef != NULL)
3519 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
3520 || h->u.weakdef->root.type == bfd_link_hash_defweak);
3521 h->root.u.def.section = h->u.weakdef->root.u.def.section;
3522 h->root.u.def.value = h->u.weakdef->root.u.def.value;
3523 return TRUE;
3526 /* If this is a reference to a symbol defined by a dynamic object which
3527 is not a function, we might allocate the symbol in our .dynbss section
3528 and allocate a COPY dynamic relocation.
3530 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
3531 of hackery. */
3533 return TRUE;
3536 static bfd_boolean
3537 elfNN_ia64_size_dynamic_sections (output_bfd, info)
3538 bfd *output_bfd ATTRIBUTE_UNUSED;
3539 struct bfd_link_info *info;
3541 struct elfNN_ia64_allocate_data data;
3542 struct elfNN_ia64_link_hash_table *ia64_info;
3543 asection *sec;
3544 bfd *dynobj;
3545 bfd_boolean relplt = FALSE;
3547 dynobj = elf_hash_table(info)->dynobj;
3548 ia64_info = elfNN_ia64_hash_table (info);
3549 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
3550 BFD_ASSERT(dynobj != NULL);
3551 data.info = info;
3553 /* Set the contents of the .interp section to the interpreter. */
3554 if (ia64_info->root.dynamic_sections_created
3555 && info->executable)
3557 sec = bfd_get_section_by_name (dynobj, ".interp");
3558 BFD_ASSERT (sec != NULL);
3559 sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3560 sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3563 /* Allocate the GOT entries. */
3565 if (ia64_info->got_sec)
3567 data.ofs = 0;
3568 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
3569 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
3570 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
3571 ia64_info->got_sec->size = data.ofs;
3574 /* Allocate the FPTR entries. */
3576 if (ia64_info->fptr_sec)
3578 data.ofs = 0;
3579 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
3580 ia64_info->fptr_sec->size = data.ofs;
3583 /* Now that we've seen all of the input files, we can decide which
3584 symbols need plt entries. Allocate the minimal PLT entries first.
3585 We do this even though dynamic_sections_created may be FALSE, because
3586 this has the side-effect of clearing want_plt and want_plt2. */
3588 data.ofs = 0;
3589 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
3591 ia64_info->minplt_entries = 0;
3592 if (data.ofs)
3594 ia64_info->minplt_entries
3595 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3598 /* Align the pointer for the plt2 entries. */
3599 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
3601 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
3602 if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
3604 /* FIXME: we always reserve the memory for dynamic linker even if
3605 there are no PLT entries since dynamic linker may assume the
3606 reserved memory always exists. */
3608 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
3610 ia64_info->plt_sec->size = data.ofs;
3612 /* If we've got a .plt, we need some extra memory for the dynamic
3613 linker. We stuff these in .got.plt. */
3614 sec = bfd_get_section_by_name (dynobj, ".got.plt");
3615 sec->size = 8 * PLT_RESERVED_WORDS;
3618 /* Allocate the PLTOFF entries. */
3620 if (ia64_info->pltoff_sec)
3622 data.ofs = 0;
3623 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
3624 ia64_info->pltoff_sec->size = data.ofs;
3627 if (ia64_info->root.dynamic_sections_created)
3629 /* Allocate space for the dynamic relocations that turned out to be
3630 required. */
3632 if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
3633 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3634 data.only_got = FALSE;
3635 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
3638 /* We have now determined the sizes of the various dynamic sections.
3639 Allocate memory for them. */
3640 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
3642 bfd_boolean strip;
3644 if (!(sec->flags & SEC_LINKER_CREATED))
3645 continue;
3647 /* If we don't need this section, strip it from the output file.
3648 There were several sections primarily related to dynamic
3649 linking that must be create before the linker maps input
3650 sections to output sections. The linker does that before
3651 bfd_elf_size_dynamic_sections is called, and it is that
3652 function which decides whether anything needs to go into
3653 these sections. */
3655 strip = (sec->size == 0);
3657 if (sec == ia64_info->got_sec)
3658 strip = FALSE;
3659 else if (sec == ia64_info->rel_got_sec)
3661 if (strip)
3662 ia64_info->rel_got_sec = NULL;
3663 else
3664 /* We use the reloc_count field as a counter if we need to
3665 copy relocs into the output file. */
3666 sec->reloc_count = 0;
3668 else if (sec == ia64_info->fptr_sec)
3670 if (strip)
3671 ia64_info->fptr_sec = NULL;
3673 else if (sec == ia64_info->rel_fptr_sec)
3675 if (strip)
3676 ia64_info->rel_fptr_sec = NULL;
3677 else
3678 /* We use the reloc_count field as a counter if we need to
3679 copy relocs into the output file. */
3680 sec->reloc_count = 0;
3682 else if (sec == ia64_info->plt_sec)
3684 if (strip)
3685 ia64_info->plt_sec = NULL;
3687 else if (sec == ia64_info->pltoff_sec)
3689 if (strip)
3690 ia64_info->pltoff_sec = NULL;
3692 else if (sec == ia64_info->rel_pltoff_sec)
3694 if (strip)
3695 ia64_info->rel_pltoff_sec = NULL;
3696 else
3698 relplt = TRUE;
3699 /* We use the reloc_count field as a counter if we need to
3700 copy relocs into the output file. */
3701 sec->reloc_count = 0;
3704 else
3706 const char *name;
3708 /* It's OK to base decisions on the section name, because none
3709 of the dynobj section names depend upon the input files. */
3710 name = bfd_get_section_name (dynobj, sec);
3712 if (strcmp (name, ".got.plt") == 0)
3713 strip = FALSE;
3714 else if (CONST_STRNEQ (name, ".rel"))
3716 if (!strip)
3718 /* We use the reloc_count field as a counter if we need to
3719 copy relocs into the output file. */
3720 sec->reloc_count = 0;
3723 else
3724 continue;
3727 if (strip)
3728 sec->flags |= SEC_EXCLUDE;
3729 else
3731 /* Allocate memory for the section contents. */
3732 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
3733 if (sec->contents == NULL && sec->size != 0)
3734 return FALSE;
3738 if (elf_hash_table (info)->dynamic_sections_created)
3740 /* Add some entries to the .dynamic section. We fill in the values
3741 later (in finish_dynamic_sections) but we must add the entries now
3742 so that we get the correct size for the .dynamic section. */
3744 if (info->executable)
3746 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3747 by the debugger. */
3748 #define add_dynamic_entry(TAG, VAL) \
3749 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3751 if (!add_dynamic_entry (DT_DEBUG, 0))
3752 return FALSE;
3755 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3756 return FALSE;
3757 if (!add_dynamic_entry (DT_PLTGOT, 0))
3758 return FALSE;
3760 if (relplt)
3762 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3763 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3764 || !add_dynamic_entry (DT_JMPREL, 0))
3765 return FALSE;
3768 if (!add_dynamic_entry (DT_RELA, 0)
3769 || !add_dynamic_entry (DT_RELASZ, 0)
3770 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3771 return FALSE;
3773 if (ia64_info->reltext)
3775 if (!add_dynamic_entry (DT_TEXTREL, 0))
3776 return FALSE;
3777 info->flags |= DF_TEXTREL;
3781 /* ??? Perhaps force __gp local. */
3783 return TRUE;
3786 static bfd_reloc_status_type
3787 elfNN_ia64_install_value (hit_addr, v, r_type)
3788 bfd_byte *hit_addr;
3789 bfd_vma v;
3790 unsigned int r_type;
3792 const struct ia64_operand *op;
3793 int bigendian = 0, shift = 0;
3794 bfd_vma t0, t1, dword;
3795 ia64_insn insn;
3796 enum ia64_opnd opnd;
3797 const char *err;
3798 size_t size = 8;
3799 #ifdef BFD_HOST_U_64_BIT
3800 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3801 #else
3802 bfd_vma val = v;
3803 #endif
3805 opnd = IA64_OPND_NIL;
3806 switch (r_type)
3808 case R_IA64_NONE:
3809 case R_IA64_LDXMOV:
3810 return bfd_reloc_ok;
3812 /* Instruction relocations. */
3814 case R_IA64_IMM14:
3815 case R_IA64_TPREL14:
3816 case R_IA64_DTPREL14:
3817 opnd = IA64_OPND_IMM14;
3818 break;
3820 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
3821 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
3822 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
3823 case R_IA64_PCREL21B:
3824 case R_IA64_PCREL21BI:
3825 opnd = IA64_OPND_TGT25c;
3826 break;
3828 case R_IA64_IMM22:
3829 case R_IA64_GPREL22:
3830 case R_IA64_LTOFF22:
3831 case R_IA64_LTOFF22X:
3832 case R_IA64_PLTOFF22:
3833 case R_IA64_PCREL22:
3834 case R_IA64_LTOFF_FPTR22:
3835 case R_IA64_TPREL22:
3836 case R_IA64_DTPREL22:
3837 case R_IA64_LTOFF_TPREL22:
3838 case R_IA64_LTOFF_DTPMOD22:
3839 case R_IA64_LTOFF_DTPREL22:
3840 opnd = IA64_OPND_IMM22;
3841 break;
3843 case R_IA64_IMM64:
3844 case R_IA64_GPREL64I:
3845 case R_IA64_LTOFF64I:
3846 case R_IA64_PLTOFF64I:
3847 case R_IA64_PCREL64I:
3848 case R_IA64_FPTR64I:
3849 case R_IA64_LTOFF_FPTR64I:
3850 case R_IA64_TPREL64I:
3851 case R_IA64_DTPREL64I:
3852 opnd = IA64_OPND_IMMU64;
3853 break;
3855 /* Data relocations. */
3857 case R_IA64_DIR32MSB:
3858 case R_IA64_GPREL32MSB:
3859 case R_IA64_FPTR32MSB:
3860 case R_IA64_PCREL32MSB:
3861 case R_IA64_LTOFF_FPTR32MSB:
3862 case R_IA64_SEGREL32MSB:
3863 case R_IA64_SECREL32MSB:
3864 case R_IA64_LTV32MSB:
3865 case R_IA64_DTPREL32MSB:
3866 size = 4; bigendian = 1;
3867 break;
3869 case R_IA64_DIR32LSB:
3870 case R_IA64_GPREL32LSB:
3871 case R_IA64_FPTR32LSB:
3872 case R_IA64_PCREL32LSB:
3873 case R_IA64_LTOFF_FPTR32LSB:
3874 case R_IA64_SEGREL32LSB:
3875 case R_IA64_SECREL32LSB:
3876 case R_IA64_LTV32LSB:
3877 case R_IA64_DTPREL32LSB:
3878 size = 4; bigendian = 0;
3879 break;
3881 case R_IA64_DIR64MSB:
3882 case R_IA64_GPREL64MSB:
3883 case R_IA64_PLTOFF64MSB:
3884 case R_IA64_FPTR64MSB:
3885 case R_IA64_PCREL64MSB:
3886 case R_IA64_LTOFF_FPTR64MSB:
3887 case R_IA64_SEGREL64MSB:
3888 case R_IA64_SECREL64MSB:
3889 case R_IA64_LTV64MSB:
3890 case R_IA64_TPREL64MSB:
3891 case R_IA64_DTPMOD64MSB:
3892 case R_IA64_DTPREL64MSB:
3893 size = 8; bigendian = 1;
3894 break;
3896 case R_IA64_DIR64LSB:
3897 case R_IA64_GPREL64LSB:
3898 case R_IA64_PLTOFF64LSB:
3899 case R_IA64_FPTR64LSB:
3900 case R_IA64_PCREL64LSB:
3901 case R_IA64_LTOFF_FPTR64LSB:
3902 case R_IA64_SEGREL64LSB:
3903 case R_IA64_SECREL64LSB:
3904 case R_IA64_LTV64LSB:
3905 case R_IA64_TPREL64LSB:
3906 case R_IA64_DTPMOD64LSB:
3907 case R_IA64_DTPREL64LSB:
3908 size = 8; bigendian = 0;
3909 break;
3911 /* Unsupported / Dynamic relocations. */
3912 default:
3913 return bfd_reloc_notsupported;
3916 switch (opnd)
3918 case IA64_OPND_IMMU64:
3919 hit_addr -= (long) hit_addr & 0x3;
3920 t0 = bfd_getl64 (hit_addr);
3921 t1 = bfd_getl64 (hit_addr + 8);
3923 /* tmpl/s: bits 0.. 5 in t0
3924 slot 0: bits 5..45 in t0
3925 slot 1: bits 46..63 in t0, bits 0..22 in t1
3926 slot 2: bits 23..63 in t1 */
3928 /* First, clear the bits that form the 64 bit constant. */
3929 t0 &= ~(0x3ffffLL << 46);
3930 t1 &= ~(0x7fffffLL
3931 | (( (0x07fLL << 13) | (0x1ffLL << 27)
3932 | (0x01fLL << 22) | (0x001LL << 21)
3933 | (0x001LL << 36)) << 23));
3935 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
3936 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
3937 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
3938 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
3939 | (((val >> 16) & 0x01f) << 22) /* imm5c */
3940 | (((val >> 21) & 0x001) << 21) /* ic */
3941 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
3943 bfd_putl64 (t0, hit_addr);
3944 bfd_putl64 (t1, hit_addr + 8);
3945 break;
3947 case IA64_OPND_TGT64:
3948 hit_addr -= (long) hit_addr & 0x3;
3949 t0 = bfd_getl64 (hit_addr);
3950 t1 = bfd_getl64 (hit_addr + 8);
3952 /* tmpl/s: bits 0.. 5 in t0
3953 slot 0: bits 5..45 in t0
3954 slot 1: bits 46..63 in t0, bits 0..22 in t1
3955 slot 2: bits 23..63 in t1 */
3957 /* First, clear the bits that form the 64 bit constant. */
3958 t0 &= ~(0x3ffffLL << 46);
3959 t1 &= ~(0x7fffffLL
3960 | ((1LL << 36 | 0xfffffLL << 13) << 23));
3962 val >>= 4;
3963 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
3964 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
3965 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
3966 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
3968 bfd_putl64 (t0, hit_addr);
3969 bfd_putl64 (t1, hit_addr + 8);
3970 break;
3972 default:
3973 switch ((long) hit_addr & 0x3)
3975 case 0: shift = 5; break;
3976 case 1: shift = 14; hit_addr += 3; break;
3977 case 2: shift = 23; hit_addr += 6; break;
3978 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
3980 dword = bfd_getl64 (hit_addr);
3981 insn = (dword >> shift) & 0x1ffffffffffLL;
3983 op = elf64_ia64_operands + opnd;
3984 err = (*op->insert) (op, val, &insn);
3985 if (err)
3986 return bfd_reloc_overflow;
3988 dword &= ~(0x1ffffffffffLL << shift);
3989 dword |= (insn << shift);
3990 bfd_putl64 (dword, hit_addr);
3991 break;
3993 case IA64_OPND_NIL:
3994 /* A data relocation. */
3995 if (bigendian)
3996 if (size == 4)
3997 bfd_putb32 (val, hit_addr);
3998 else
3999 bfd_putb64 (val, hit_addr);
4000 else
4001 if (size == 4)
4002 bfd_putl32 (val, hit_addr);
4003 else
4004 bfd_putl64 (val, hit_addr);
4005 break;
4008 return bfd_reloc_ok;
4011 static void
4012 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
4013 dynindx, addend)
4014 bfd *abfd;
4015 struct bfd_link_info *info;
4016 asection *sec;
4017 asection *srel;
4018 bfd_vma offset;
4019 unsigned int type;
4020 long dynindx;
4021 bfd_vma addend;
4023 Elf_Internal_Rela outrel;
4024 bfd_byte *loc;
4026 BFD_ASSERT (dynindx != -1);
4027 outrel.r_info = ELFNN_R_INFO (dynindx, type);
4028 outrel.r_addend = addend;
4029 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
4030 if (outrel.r_offset >= (bfd_vma) -2)
4032 /* Run for the hills. We shouldn't be outputting a relocation
4033 for this. So do what everyone else does and output a no-op. */
4034 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
4035 outrel.r_addend = 0;
4036 outrel.r_offset = 0;
4038 else
4039 outrel.r_offset += sec->output_section->vma + sec->output_offset;
4041 loc = srel->contents;
4042 loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
4043 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
4044 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
4047 /* Store an entry for target address TARGET_ADDR in the linkage table
4048 and return the gp-relative address of the linkage table entry. */
4050 static bfd_vma
4051 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
4052 bfd *abfd;
4053 struct bfd_link_info *info;
4054 struct elfNN_ia64_dyn_sym_info *dyn_i;
4055 long dynindx;
4056 bfd_vma addend;
4057 bfd_vma value;
4058 unsigned int dyn_r_type;
4060 struct elfNN_ia64_link_hash_table *ia64_info;
4061 asection *got_sec;
4062 bfd_boolean done;
4063 bfd_vma got_offset;
4065 ia64_info = elfNN_ia64_hash_table (info);
4066 got_sec = ia64_info->got_sec;
4068 switch (dyn_r_type)
4070 case R_IA64_TPREL64LSB:
4071 done = dyn_i->tprel_done;
4072 dyn_i->tprel_done = TRUE;
4073 got_offset = dyn_i->tprel_offset;
4074 break;
4075 case R_IA64_DTPMOD64LSB:
4076 if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
4078 done = dyn_i->dtpmod_done;
4079 dyn_i->dtpmod_done = TRUE;
4081 else
4083 done = ia64_info->self_dtpmod_done;
4084 ia64_info->self_dtpmod_done = TRUE;
4085 dynindx = 0;
4087 got_offset = dyn_i->dtpmod_offset;
4088 break;
4089 case R_IA64_DTPREL32LSB:
4090 case R_IA64_DTPREL64LSB:
4091 done = dyn_i->dtprel_done;
4092 dyn_i->dtprel_done = TRUE;
4093 got_offset = dyn_i->dtprel_offset;
4094 break;
4095 default:
4096 done = dyn_i->got_done;
4097 dyn_i->got_done = TRUE;
4098 got_offset = dyn_i->got_offset;
4099 break;
4102 BFD_ASSERT ((got_offset & 7) == 0);
4104 if (! done)
4106 /* Store the target address in the linkage table entry. */
4107 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
4109 /* Install a dynamic relocation if needed. */
4110 if (((info->shared
4111 && (!dyn_i->h
4112 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
4113 || dyn_i->h->root.type != bfd_link_hash_undefweak)
4114 && dyn_r_type != R_IA64_DTPREL32LSB
4115 && dyn_r_type != R_IA64_DTPREL64LSB)
4116 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
4117 || (dynindx != -1
4118 && (dyn_r_type == R_IA64_FPTR32LSB
4119 || dyn_r_type == R_IA64_FPTR64LSB)))
4120 && (!dyn_i->want_ltoff_fptr
4121 || !info->pie
4122 || !dyn_i->h
4123 || dyn_i->h->root.type != bfd_link_hash_undefweak))
4125 if (dynindx == -1
4126 && dyn_r_type != R_IA64_TPREL64LSB
4127 && dyn_r_type != R_IA64_DTPMOD64LSB
4128 && dyn_r_type != R_IA64_DTPREL32LSB
4129 && dyn_r_type != R_IA64_DTPREL64LSB)
4131 dyn_r_type = R_IA64_RELNNLSB;
4132 dynindx = 0;
4133 addend = value;
4136 if (bfd_big_endian (abfd))
4138 switch (dyn_r_type)
4140 case R_IA64_REL32LSB:
4141 dyn_r_type = R_IA64_REL32MSB;
4142 break;
4143 case R_IA64_DIR32LSB:
4144 dyn_r_type = R_IA64_DIR32MSB;
4145 break;
4146 case R_IA64_FPTR32LSB:
4147 dyn_r_type = R_IA64_FPTR32MSB;
4148 break;
4149 case R_IA64_DTPREL32LSB:
4150 dyn_r_type = R_IA64_DTPREL32MSB;
4151 break;
4152 case R_IA64_REL64LSB:
4153 dyn_r_type = R_IA64_REL64MSB;
4154 break;
4155 case R_IA64_DIR64LSB:
4156 dyn_r_type = R_IA64_DIR64MSB;
4157 break;
4158 case R_IA64_FPTR64LSB:
4159 dyn_r_type = R_IA64_FPTR64MSB;
4160 break;
4161 case R_IA64_TPREL64LSB:
4162 dyn_r_type = R_IA64_TPREL64MSB;
4163 break;
4164 case R_IA64_DTPMOD64LSB:
4165 dyn_r_type = R_IA64_DTPMOD64MSB;
4166 break;
4167 case R_IA64_DTPREL64LSB:
4168 dyn_r_type = R_IA64_DTPREL64MSB;
4169 break;
4170 default:
4171 BFD_ASSERT (FALSE);
4172 break;
4176 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
4177 ia64_info->rel_got_sec,
4178 got_offset, dyn_r_type,
4179 dynindx, addend);
4183 /* Return the address of the linkage table entry. */
4184 value = (got_sec->output_section->vma
4185 + got_sec->output_offset
4186 + got_offset);
4188 return value;
4191 /* Fill in a function descriptor consisting of the function's code
4192 address and its global pointer. Return the descriptor's address. */
4194 static bfd_vma
4195 set_fptr_entry (abfd, info, dyn_i, value)
4196 bfd *abfd;
4197 struct bfd_link_info *info;
4198 struct elfNN_ia64_dyn_sym_info *dyn_i;
4199 bfd_vma value;
4201 struct elfNN_ia64_link_hash_table *ia64_info;
4202 asection *fptr_sec;
4204 ia64_info = elfNN_ia64_hash_table (info);
4205 fptr_sec = ia64_info->fptr_sec;
4207 if (!dyn_i->fptr_done)
4209 dyn_i->fptr_done = 1;
4211 /* Fill in the function descriptor. */
4212 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
4213 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
4214 fptr_sec->contents + dyn_i->fptr_offset + 8);
4215 if (ia64_info->rel_fptr_sec)
4217 Elf_Internal_Rela outrel;
4218 bfd_byte *loc;
4220 if (bfd_little_endian (abfd))
4221 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
4222 else
4223 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
4224 outrel.r_addend = value;
4225 outrel.r_offset = (fptr_sec->output_section->vma
4226 + fptr_sec->output_offset
4227 + dyn_i->fptr_offset);
4228 loc = ia64_info->rel_fptr_sec->contents;
4229 loc += ia64_info->rel_fptr_sec->reloc_count++
4230 * sizeof (ElfNN_External_Rela);
4231 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
4235 /* Return the descriptor's address. */
4236 value = (fptr_sec->output_section->vma
4237 + fptr_sec->output_offset
4238 + dyn_i->fptr_offset);
4240 return value;
4243 /* Fill in a PLTOFF entry consisting of the function's code address
4244 and its global pointer. Return the descriptor's address. */
4246 static bfd_vma
4247 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
4248 bfd *abfd;
4249 struct bfd_link_info *info;
4250 struct elfNN_ia64_dyn_sym_info *dyn_i;
4251 bfd_vma value;
4252 bfd_boolean is_plt;
4254 struct elfNN_ia64_link_hash_table *ia64_info;
4255 asection *pltoff_sec;
4257 ia64_info = elfNN_ia64_hash_table (info);
4258 pltoff_sec = ia64_info->pltoff_sec;
4260 /* Don't do anything if this symbol uses a real PLT entry. In
4261 that case, we'll fill this in during finish_dynamic_symbol. */
4262 if ((! dyn_i->want_plt || is_plt)
4263 && !dyn_i->pltoff_done)
4265 bfd_vma gp = _bfd_get_gp_value (abfd);
4267 /* Fill in the function descriptor. */
4268 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
4269 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
4271 /* Install dynamic relocations if needed. */
4272 if (!is_plt
4273 && info->shared
4274 && (!dyn_i->h
4275 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
4276 || dyn_i->h->root.type != bfd_link_hash_undefweak))
4278 unsigned int dyn_r_type;
4280 if (bfd_big_endian (abfd))
4281 dyn_r_type = R_IA64_RELNNMSB;
4282 else
4283 dyn_r_type = R_IA64_RELNNLSB;
4285 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
4286 ia64_info->rel_pltoff_sec,
4287 dyn_i->pltoff_offset,
4288 dyn_r_type, 0, value);
4289 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
4290 ia64_info->rel_pltoff_sec,
4291 dyn_i->pltoff_offset + ARCH_SIZE / 8,
4292 dyn_r_type, 0, gp);
4295 dyn_i->pltoff_done = 1;
4298 /* Return the descriptor's address. */
4299 value = (pltoff_sec->output_section->vma
4300 + pltoff_sec->output_offset
4301 + dyn_i->pltoff_offset);
4303 return value;
4306 /* Return the base VMA address which should be subtracted from real addresses
4307 when resolving @tprel() relocation.
4308 Main program TLS (whose template starts at PT_TLS p_vaddr)
4309 is assigned offset round(2 * size of pointer, PT_TLS p_align). */
4311 static bfd_vma
4312 elfNN_ia64_tprel_base (info)
4313 struct bfd_link_info *info;
4315 asection *tls_sec = elf_hash_table (info)->tls_sec;
4317 BFD_ASSERT (tls_sec != NULL);
4318 return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
4319 tls_sec->alignment_power);
4322 /* Return the base VMA address which should be subtracted from real addresses
4323 when resolving @dtprel() relocation.
4324 This is PT_TLS segment p_vaddr. */
4326 static bfd_vma
4327 elfNN_ia64_dtprel_base (info)
4328 struct bfd_link_info *info;
4330 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4331 return elf_hash_table (info)->tls_sec->vma;
4334 /* Called through qsort to sort the .IA_64.unwind section during a
4335 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
4336 to the output bfd so we can do proper endianness frobbing. */
4338 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
4340 static int
4341 elfNN_ia64_unwind_entry_compare (a, b)
4342 const PTR a;
4343 const PTR b;
4345 bfd_vma av, bv;
4347 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
4348 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
4350 return (av < bv ? -1 : av > bv ? 1 : 0);
4353 /* Make sure we've got ourselves a nice fat __gp value. */
4354 static bfd_boolean
4355 elfNN_ia64_choose_gp (abfd, info)
4356 bfd *abfd;
4357 struct bfd_link_info *info;
4359 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
4360 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
4361 struct elf_link_hash_entry *gp;
4362 bfd_vma gp_val;
4363 asection *os;
4364 struct elfNN_ia64_link_hash_table *ia64_info;
4366 ia64_info = elfNN_ia64_hash_table (info);
4368 /* Find the min and max vma of all sections marked short. Also collect
4369 min and max vma of any type, for use in selecting a nice gp. */
4370 for (os = abfd->sections; os ; os = os->next)
4372 bfd_vma lo, hi;
4374 if ((os->flags & SEC_ALLOC) == 0)
4375 continue;
4377 lo = os->vma;
4378 hi = os->vma + (os->rawsize ? os->rawsize : os->size);
4379 if (hi < lo)
4380 hi = (bfd_vma) -1;
4382 if (min_vma > lo)
4383 min_vma = lo;
4384 if (max_vma < hi)
4385 max_vma = hi;
4386 if (os->flags & SEC_SMALL_DATA)
4388 if (min_short_vma > lo)
4389 min_short_vma = lo;
4390 if (max_short_vma < hi)
4391 max_short_vma = hi;
4395 /* See if the user wants to force a value. */
4396 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4397 FALSE, FALSE);
4399 if (gp
4400 && (gp->root.type == bfd_link_hash_defined
4401 || gp->root.type == bfd_link_hash_defweak))
4403 asection *gp_sec = gp->root.u.def.section;
4404 gp_val = (gp->root.u.def.value
4405 + gp_sec->output_section->vma
4406 + gp_sec->output_offset);
4408 else
4410 /* Pick a sensible value. */
4412 asection *got_sec = ia64_info->got_sec;
4414 /* Start with just the address of the .got. */
4415 if (got_sec)
4416 gp_val = got_sec->output_section->vma;
4417 else if (max_short_vma != 0)
4418 gp_val = min_short_vma;
4419 else if (max_vma - min_vma < 0x200000)
4420 gp_val = min_vma;
4421 else
4422 gp_val = max_vma - 0x200000 + 8;
4424 /* If it is possible to address the entire image, but we
4425 don't with the choice above, adjust. */
4426 if (max_vma - min_vma < 0x400000
4427 && (max_vma - gp_val >= 0x200000
4428 || gp_val - min_vma > 0x200000))
4429 gp_val = min_vma + 0x200000;
4430 else if (max_short_vma != 0)
4432 /* If we don't cover all the short data, adjust. */
4433 if (max_short_vma - gp_val >= 0x200000)
4434 gp_val = min_short_vma + 0x200000;
4436 /* If we're addressing stuff past the end, adjust back. */
4437 if (gp_val > max_vma)
4438 gp_val = max_vma - 0x200000 + 8;
4442 /* Validate whether all SHF_IA_64_SHORT sections are within
4443 range of the chosen GP. */
4445 if (max_short_vma != 0)
4447 if (max_short_vma - min_short_vma >= 0x400000)
4449 (*_bfd_error_handler)
4450 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
4451 bfd_get_filename (abfd),
4452 (unsigned long) (max_short_vma - min_short_vma));
4453 return FALSE;
4455 else if ((gp_val > min_short_vma
4456 && gp_val - min_short_vma > 0x200000)
4457 || (gp_val < max_short_vma
4458 && max_short_vma - gp_val >= 0x200000))
4460 (*_bfd_error_handler)
4461 (_("%s: __gp does not cover short data segment"),
4462 bfd_get_filename (abfd));
4463 return FALSE;
4467 _bfd_set_gp_value (abfd, gp_val);
4469 return TRUE;
4472 static bfd_boolean
4473 elfNN_ia64_final_link (abfd, info)
4474 bfd *abfd;
4475 struct bfd_link_info *info;
4477 struct elfNN_ia64_link_hash_table *ia64_info;
4478 asection *unwind_output_sec;
4480 ia64_info = elfNN_ia64_hash_table (info);
4482 /* Make sure we've got ourselves a nice fat __gp value. */
4483 if (!info->relocatable)
4485 bfd_vma gp_val;
4486 struct elf_link_hash_entry *gp;
4488 /* We assume after gp is set, section size will only decrease. We
4489 need to adjust gp for it. */
4490 _bfd_set_gp_value (abfd, 0);
4491 if (! elfNN_ia64_choose_gp (abfd, info))
4492 return FALSE;
4493 gp_val = _bfd_get_gp_value (abfd);
4495 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4496 FALSE, FALSE);
4497 if (gp)
4499 gp->root.type = bfd_link_hash_defined;
4500 gp->root.u.def.value = gp_val;
4501 gp->root.u.def.section = bfd_abs_section_ptr;
4505 /* If we're producing a final executable, we need to sort the contents
4506 of the .IA_64.unwind section. Force this section to be relocated
4507 into memory rather than written immediately to the output file. */
4508 unwind_output_sec = NULL;
4509 if (!info->relocatable)
4511 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
4512 if (s)
4514 unwind_output_sec = s->output_section;
4515 unwind_output_sec->contents
4516 = bfd_malloc (unwind_output_sec->size);
4517 if (unwind_output_sec->contents == NULL)
4518 return FALSE;
4522 /* Invoke the regular ELF backend linker to do all the work. */
4523 if (!bfd_elf_final_link (abfd, info))
4524 return FALSE;
4526 if (unwind_output_sec)
4528 elfNN_ia64_unwind_entry_compare_bfd = abfd;
4529 qsort (unwind_output_sec->contents,
4530 (size_t) (unwind_output_sec->size / 24),
4532 elfNN_ia64_unwind_entry_compare);
4534 if (! bfd_set_section_contents (abfd, unwind_output_sec,
4535 unwind_output_sec->contents, (bfd_vma) 0,
4536 unwind_output_sec->size))
4537 return FALSE;
4540 return TRUE;
4543 static bfd_boolean
4544 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
4545 contents, relocs, local_syms, local_sections)
4546 bfd *output_bfd;
4547 struct bfd_link_info *info;
4548 bfd *input_bfd;
4549 asection *input_section;
4550 bfd_byte *contents;
4551 Elf_Internal_Rela *relocs;
4552 Elf_Internal_Sym *local_syms;
4553 asection **local_sections;
4555 struct elfNN_ia64_link_hash_table *ia64_info;
4556 Elf_Internal_Shdr *symtab_hdr;
4557 Elf_Internal_Rela *rel;
4558 Elf_Internal_Rela *relend;
4559 asection *srel;
4560 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
4561 bfd_vma gp_val;
4563 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4564 ia64_info = elfNN_ia64_hash_table (info);
4566 /* Infect various flags from the input section to the output section. */
4567 if (info->relocatable)
4569 bfd_vma flags;
4571 flags = elf_section_data(input_section)->this_hdr.sh_flags;
4572 flags &= SHF_IA_64_NORECOV;
4574 elf_section_data(input_section->output_section)
4575 ->this_hdr.sh_flags |= flags;
4578 gp_val = _bfd_get_gp_value (output_bfd);
4579 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
4581 rel = relocs;
4582 relend = relocs + input_section->reloc_count;
4583 for (; rel < relend; ++rel)
4585 struct elf_link_hash_entry *h;
4586 struct elfNN_ia64_dyn_sym_info *dyn_i;
4587 bfd_reloc_status_type r;
4588 reloc_howto_type *howto;
4589 unsigned long r_symndx;
4590 Elf_Internal_Sym *sym;
4591 unsigned int r_type;
4592 bfd_vma value;
4593 asection *sym_sec;
4594 bfd_byte *hit_addr;
4595 bfd_boolean dynamic_symbol_p;
4596 bfd_boolean undef_weak_ref;
4598 r_type = ELFNN_R_TYPE (rel->r_info);
4599 if (r_type > R_IA64_MAX_RELOC_CODE)
4601 (*_bfd_error_handler)
4602 (_("%B: unknown relocation type %d"),
4603 input_bfd, (int) r_type);
4604 bfd_set_error (bfd_error_bad_value);
4605 ret_val = FALSE;
4606 continue;
4609 howto = lookup_howto (r_type);
4610 r_symndx = ELFNN_R_SYM (rel->r_info);
4611 h = NULL;
4612 sym = NULL;
4613 sym_sec = NULL;
4614 undef_weak_ref = FALSE;
4616 if (r_symndx < symtab_hdr->sh_info)
4618 /* Reloc against local symbol. */
4619 asection *msec;
4620 sym = local_syms + r_symndx;
4621 sym_sec = local_sections[r_symndx];
4622 msec = sym_sec;
4623 value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
4624 if (!info->relocatable
4625 && (sym_sec->flags & SEC_MERGE) != 0
4626 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
4627 && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
4629 struct elfNN_ia64_local_hash_entry *loc_h;
4631 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
4632 if (loc_h && ! loc_h->sec_merge_done)
4634 struct elfNN_ia64_dyn_sym_info *dynent;
4635 unsigned int count;
4637 for (count = loc_h->count, dynent = loc_h->info;
4638 count != 0;
4639 count--, dynent++)
4641 msec = sym_sec;
4642 dynent->addend =
4643 _bfd_merged_section_offset (output_bfd, &msec,
4644 elf_section_data (msec)->
4645 sec_info,
4646 sym->st_value
4647 + dynent->addend);
4648 dynent->addend -= sym->st_value;
4649 dynent->addend += msec->output_section->vma
4650 + msec->output_offset
4651 - sym_sec->output_section->vma
4652 - sym_sec->output_offset;
4655 qsort (loc_h->info, loc_h->count,
4656 sizeof (*loc_h->info), addend_compare);
4658 loc_h->sec_merge_done = 1;
4662 else
4664 bfd_boolean unresolved_reloc;
4665 bfd_boolean warned;
4666 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
4668 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4669 r_symndx, symtab_hdr, sym_hashes,
4670 h, sym_sec, value,
4671 unresolved_reloc, warned);
4673 if (h->root.type == bfd_link_hash_undefweak)
4674 undef_weak_ref = TRUE;
4675 else if (warned)
4676 continue;
4679 /* For relocs against symbols from removed linkonce sections,
4680 or sections discarded by a linker script, we just want the
4681 section contents zeroed. Avoid any special processing. */
4682 if (sym_sec != NULL && elf_discarded_section (sym_sec))
4684 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
4685 rel->r_info = 0;
4686 rel->r_addend = 0;
4687 continue;
4690 if (info->relocatable)
4691 continue;
4693 hit_addr = contents + rel->r_offset;
4694 value += rel->r_addend;
4695 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
4697 switch (r_type)
4699 case R_IA64_NONE:
4700 case R_IA64_LDXMOV:
4701 continue;
4703 case R_IA64_IMM14:
4704 case R_IA64_IMM22:
4705 case R_IA64_IMM64:
4706 case R_IA64_DIR32MSB:
4707 case R_IA64_DIR32LSB:
4708 case R_IA64_DIR64MSB:
4709 case R_IA64_DIR64LSB:
4710 /* Install a dynamic relocation for this reloc. */
4711 if ((dynamic_symbol_p || info->shared)
4712 && r_symndx != 0
4713 && (input_section->flags & SEC_ALLOC) != 0)
4715 unsigned int dyn_r_type;
4716 long dynindx;
4717 bfd_vma addend;
4719 BFD_ASSERT (srel != NULL);
4721 switch (r_type)
4723 case R_IA64_IMM14:
4724 case R_IA64_IMM22:
4725 case R_IA64_IMM64:
4726 /* ??? People shouldn't be doing non-pic code in
4727 shared libraries nor dynamic executables. */
4728 (*_bfd_error_handler)
4729 (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4730 input_bfd,
4731 h ? h->root.root.string
4732 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4733 sym_sec));
4734 ret_val = FALSE;
4735 continue;
4737 default:
4738 break;
4741 /* If we don't need dynamic symbol lookup, find a
4742 matching RELATIVE relocation. */
4743 dyn_r_type = r_type;
4744 if (dynamic_symbol_p)
4746 dynindx = h->dynindx;
4747 addend = rel->r_addend;
4748 value = 0;
4750 else
4752 switch (r_type)
4754 case R_IA64_DIR32MSB:
4755 dyn_r_type = R_IA64_REL32MSB;
4756 break;
4757 case R_IA64_DIR32LSB:
4758 dyn_r_type = R_IA64_REL32LSB;
4759 break;
4760 case R_IA64_DIR64MSB:
4761 dyn_r_type = R_IA64_REL64MSB;
4762 break;
4763 case R_IA64_DIR64LSB:
4764 dyn_r_type = R_IA64_REL64LSB;
4765 break;
4767 default:
4768 break;
4770 dynindx = 0;
4771 addend = value;
4774 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4775 srel, rel->r_offset, dyn_r_type,
4776 dynindx, addend);
4778 /* Fall through. */
4780 case R_IA64_LTV32MSB:
4781 case R_IA64_LTV32LSB:
4782 case R_IA64_LTV64MSB:
4783 case R_IA64_LTV64LSB:
4784 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4785 break;
4787 case R_IA64_GPREL22:
4788 case R_IA64_GPREL64I:
4789 case R_IA64_GPREL32MSB:
4790 case R_IA64_GPREL32LSB:
4791 case R_IA64_GPREL64MSB:
4792 case R_IA64_GPREL64LSB:
4793 if (dynamic_symbol_p)
4795 (*_bfd_error_handler)
4796 (_("%B: @gprel relocation against dynamic symbol %s"),
4797 input_bfd,
4798 h ? h->root.root.string
4799 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4800 sym_sec));
4801 ret_val = FALSE;
4802 continue;
4804 value -= gp_val;
4805 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4806 break;
4808 case R_IA64_LTOFF22:
4809 case R_IA64_LTOFF22X:
4810 case R_IA64_LTOFF64I:
4811 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4812 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4813 rel->r_addend, value, R_IA64_DIRNNLSB);
4814 value -= gp_val;
4815 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4816 break;
4818 case R_IA64_PLTOFF22:
4819 case R_IA64_PLTOFF64I:
4820 case R_IA64_PLTOFF64MSB:
4821 case R_IA64_PLTOFF64LSB:
4822 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4823 value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4824 value -= gp_val;
4825 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4826 break;
4828 case R_IA64_FPTR64I:
4829 case R_IA64_FPTR32MSB:
4830 case R_IA64_FPTR32LSB:
4831 case R_IA64_FPTR64MSB:
4832 case R_IA64_FPTR64LSB:
4833 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4834 if (dyn_i->want_fptr)
4836 if (!undef_weak_ref)
4837 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4839 if (!dyn_i->want_fptr || info->pie)
4841 long dynindx;
4842 unsigned int dyn_r_type = r_type;
4843 bfd_vma addend = rel->r_addend;
4845 /* Otherwise, we expect the dynamic linker to create
4846 the entry. */
4848 if (dyn_i->want_fptr)
4850 if (r_type == R_IA64_FPTR64I)
4852 /* We can't represent this without a dynamic symbol.
4853 Adjust the relocation to be against an output
4854 section symbol, which are always present in the
4855 dynamic symbol table. */
4856 /* ??? People shouldn't be doing non-pic code in
4857 shared libraries. Hork. */
4858 (*_bfd_error_handler)
4859 (_("%B: linking non-pic code in a position independent executable"),
4860 input_bfd);
4861 ret_val = FALSE;
4862 continue;
4864 dynindx = 0;
4865 addend = value;
4866 dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
4868 else if (h)
4870 if (h->dynindx != -1)
4871 dynindx = h->dynindx;
4872 else
4873 dynindx = (_bfd_elf_link_lookup_local_dynindx
4874 (info, h->root.u.def.section->owner,
4875 global_sym_index (h)));
4876 value = 0;
4878 else
4880 dynindx = (_bfd_elf_link_lookup_local_dynindx
4881 (info, input_bfd, (long) r_symndx));
4882 value = 0;
4885 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4886 srel, rel->r_offset, dyn_r_type,
4887 dynindx, addend);
4890 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4891 break;
4893 case R_IA64_LTOFF_FPTR22:
4894 case R_IA64_LTOFF_FPTR64I:
4895 case R_IA64_LTOFF_FPTR32MSB:
4896 case R_IA64_LTOFF_FPTR32LSB:
4897 case R_IA64_LTOFF_FPTR64MSB:
4898 case R_IA64_LTOFF_FPTR64LSB:
4900 long dynindx;
4902 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4903 if (dyn_i->want_fptr)
4905 BFD_ASSERT (h == NULL || h->dynindx == -1);
4906 if (!undef_weak_ref)
4907 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4908 dynindx = -1;
4910 else
4912 /* Otherwise, we expect the dynamic linker to create
4913 the entry. */
4914 if (h)
4916 if (h->dynindx != -1)
4917 dynindx = h->dynindx;
4918 else
4919 dynindx = (_bfd_elf_link_lookup_local_dynindx
4920 (info, h->root.u.def.section->owner,
4921 global_sym_index (h)));
4923 else
4924 dynindx = (_bfd_elf_link_lookup_local_dynindx
4925 (info, input_bfd, (long) r_symndx));
4926 value = 0;
4929 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4930 rel->r_addend, value, R_IA64_FPTRNNLSB);
4931 value -= gp_val;
4932 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4934 break;
4936 case R_IA64_PCREL32MSB:
4937 case R_IA64_PCREL32LSB:
4938 case R_IA64_PCREL64MSB:
4939 case R_IA64_PCREL64LSB:
4940 /* Install a dynamic relocation for this reloc. */
4941 if (dynamic_symbol_p && r_symndx != 0)
4943 BFD_ASSERT (srel != NULL);
4945 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4946 srel, rel->r_offset, r_type,
4947 h->dynindx, rel->r_addend);
4949 goto finish_pcrel;
4951 case R_IA64_PCREL21B:
4952 case R_IA64_PCREL60B:
4953 /* We should have created a PLT entry for any dynamic symbol. */
4954 dyn_i = NULL;
4955 if (h)
4956 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4958 if (dyn_i && dyn_i->want_plt2)
4960 /* Should have caught this earlier. */
4961 BFD_ASSERT (rel->r_addend == 0);
4963 value = (ia64_info->plt_sec->output_section->vma
4964 + ia64_info->plt_sec->output_offset
4965 + dyn_i->plt2_offset);
4967 else
4969 /* Since there's no PLT entry, Validate that this is
4970 locally defined. */
4971 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4973 /* If the symbol is undef_weak, we shouldn't be trying
4974 to call it. There's every chance that we'd wind up
4975 with an out-of-range fixup here. Don't bother setting
4976 any value at all. */
4977 if (undef_weak_ref)
4978 continue;
4980 goto finish_pcrel;
4982 case R_IA64_PCREL21BI:
4983 case R_IA64_PCREL21F:
4984 case R_IA64_PCREL21M:
4985 case R_IA64_PCREL22:
4986 case R_IA64_PCREL64I:
4987 /* The PCREL21BI reloc is specifically not intended for use with
4988 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4989 fixup code, and thus probably ought not be dynamic. The
4990 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4991 if (dynamic_symbol_p)
4993 const char *msg;
4995 if (r_type == R_IA64_PCREL21BI)
4996 msg = _("%B: @internal branch to dynamic symbol %s");
4997 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4998 msg = _("%B: speculation fixup to dynamic symbol %s");
4999 else
5000 msg = _("%B: @pcrel relocation against dynamic symbol %s");
5001 (*_bfd_error_handler) (msg, input_bfd,
5002 h ? h->root.root.string
5003 : bfd_elf_sym_name (input_bfd,
5004 symtab_hdr,
5005 sym,
5006 sym_sec));
5007 ret_val = FALSE;
5008 continue;
5010 goto finish_pcrel;
5012 finish_pcrel:
5013 /* Make pc-relative. */
5014 value -= (input_section->output_section->vma
5015 + input_section->output_offset
5016 + rel->r_offset) & ~ (bfd_vma) 0x3;
5017 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5018 break;
5020 case R_IA64_SEGREL32MSB:
5021 case R_IA64_SEGREL32LSB:
5022 case R_IA64_SEGREL64MSB:
5023 case R_IA64_SEGREL64LSB:
5025 struct elf_segment_map *m;
5026 Elf_Internal_Phdr *p;
5028 /* Find the segment that contains the output_section. */
5029 for (m = elf_tdata (output_bfd)->segment_map,
5030 p = elf_tdata (output_bfd)->phdr;
5031 m != NULL;
5032 m = m->next, p++)
5034 int i;
5035 for (i = m->count - 1; i >= 0; i--)
5036 if (m->sections[i] == input_section->output_section)
5037 break;
5038 if (i >= 0)
5039 break;
5042 if (m == NULL)
5044 r = bfd_reloc_notsupported;
5046 else
5048 /* The VMA of the segment is the vaddr of the associated
5049 program header. */
5050 if (value > p->p_vaddr)
5051 value -= p->p_vaddr;
5052 else
5053 value = 0;
5054 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5056 break;
5059 case R_IA64_SECREL32MSB:
5060 case R_IA64_SECREL32LSB:
5061 case R_IA64_SECREL64MSB:
5062 case R_IA64_SECREL64LSB:
5063 /* Make output-section relative to section where the symbol
5064 is defined. PR 475 */
5065 if (sym_sec)
5066 value -= sym_sec->output_section->vma;
5067 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5068 break;
5070 case R_IA64_IPLTMSB:
5071 case R_IA64_IPLTLSB:
5072 /* Install a dynamic relocation for this reloc. */
5073 if ((dynamic_symbol_p || info->shared)
5074 && (input_section->flags & SEC_ALLOC) != 0)
5076 BFD_ASSERT (srel != NULL);
5078 /* If we don't need dynamic symbol lookup, install two
5079 RELATIVE relocations. */
5080 if (!dynamic_symbol_p)
5082 unsigned int dyn_r_type;
5084 if (r_type == R_IA64_IPLTMSB)
5085 dyn_r_type = R_IA64_REL64MSB;
5086 else
5087 dyn_r_type = R_IA64_REL64LSB;
5089 elfNN_ia64_install_dyn_reloc (output_bfd, info,
5090 input_section,
5091 srel, rel->r_offset,
5092 dyn_r_type, 0, value);
5093 elfNN_ia64_install_dyn_reloc (output_bfd, info,
5094 input_section,
5095 srel, rel->r_offset + 8,
5096 dyn_r_type, 0, gp_val);
5098 else
5099 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
5100 srel, rel->r_offset, r_type,
5101 h->dynindx, rel->r_addend);
5104 if (r_type == R_IA64_IPLTMSB)
5105 r_type = R_IA64_DIR64MSB;
5106 else
5107 r_type = R_IA64_DIR64LSB;
5108 elfNN_ia64_install_value (hit_addr, value, r_type);
5109 r = elfNN_ia64_install_value (hit_addr + 8, gp_val, r_type);
5110 break;
5112 case R_IA64_TPREL14:
5113 case R_IA64_TPREL22:
5114 case R_IA64_TPREL64I:
5115 value -= elfNN_ia64_tprel_base (info);
5116 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5117 break;
5119 case R_IA64_DTPREL14:
5120 case R_IA64_DTPREL22:
5121 case R_IA64_DTPREL64I:
5122 case R_IA64_DTPREL32LSB:
5123 case R_IA64_DTPREL32MSB:
5124 case R_IA64_DTPREL64LSB:
5125 case R_IA64_DTPREL64MSB:
5126 value -= elfNN_ia64_dtprel_base (info);
5127 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5128 break;
5130 case R_IA64_LTOFF_TPREL22:
5131 case R_IA64_LTOFF_DTPMOD22:
5132 case R_IA64_LTOFF_DTPREL22:
5134 int got_r_type;
5135 long dynindx = h ? h->dynindx : -1;
5136 bfd_vma r_addend = rel->r_addend;
5138 switch (r_type)
5140 default:
5141 case R_IA64_LTOFF_TPREL22:
5142 if (!dynamic_symbol_p)
5144 if (!info->shared)
5145 value -= elfNN_ia64_tprel_base (info);
5146 else
5148 r_addend += value - elfNN_ia64_dtprel_base (info);
5149 dynindx = 0;
5152 got_r_type = R_IA64_TPREL64LSB;
5153 break;
5154 case R_IA64_LTOFF_DTPMOD22:
5155 if (!dynamic_symbol_p && !info->shared)
5156 value = 1;
5157 got_r_type = R_IA64_DTPMOD64LSB;
5158 break;
5159 case R_IA64_LTOFF_DTPREL22:
5160 if (!dynamic_symbol_p)
5161 value -= elfNN_ia64_dtprel_base (info);
5162 got_r_type = R_IA64_DTPRELNNLSB;
5163 break;
5165 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
5166 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
5167 value, got_r_type);
5168 value -= gp_val;
5169 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5171 break;
5173 default:
5174 r = bfd_reloc_notsupported;
5175 break;
5178 switch (r)
5180 case bfd_reloc_ok:
5181 break;
5183 case bfd_reloc_undefined:
5184 /* This can happen for global table relative relocs if
5185 __gp is undefined. This is a panic situation so we
5186 don't try to continue. */
5187 (*info->callbacks->undefined_symbol)
5188 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
5189 return FALSE;
5191 case bfd_reloc_notsupported:
5193 const char *name;
5195 if (h)
5196 name = h->root.root.string;
5197 else
5198 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5199 sym_sec);
5200 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
5201 name, input_bfd,
5202 input_section, rel->r_offset))
5203 return FALSE;
5204 ret_val = FALSE;
5206 break;
5208 case bfd_reloc_dangerous:
5209 case bfd_reloc_outofrange:
5210 case bfd_reloc_overflow:
5211 default:
5213 const char *name;
5215 if (h)
5216 name = h->root.root.string;
5217 else
5218 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5219 sym_sec);
5221 switch (r_type)
5223 case R_IA64_PCREL21B:
5224 case R_IA64_PCREL21BI:
5225 case R_IA64_PCREL21M:
5226 case R_IA64_PCREL21F:
5227 if (is_elf_hash_table (info->hash))
5229 /* Relaxtion is always performed for ELF output.
5230 Overflow failures for those relocations mean
5231 that the section is too big to relax. */
5232 (*_bfd_error_handler)
5233 (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
5234 input_bfd, input_section, howto->name, name,
5235 rel->r_offset, input_section->size);
5236 break;
5238 default:
5239 if (!(*info->callbacks->reloc_overflow) (info,
5240 &h->root,
5241 name,
5242 howto->name,
5243 (bfd_vma) 0,
5244 input_bfd,
5245 input_section,
5246 rel->r_offset))
5247 return FALSE;
5248 break;
5251 ret_val = FALSE;
5253 break;
5257 return ret_val;
5260 static bfd_boolean
5261 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
5262 bfd *output_bfd;
5263 struct bfd_link_info *info;
5264 struct elf_link_hash_entry *h;
5265 Elf_Internal_Sym *sym;
5267 struct elfNN_ia64_link_hash_table *ia64_info;
5268 struct elfNN_ia64_dyn_sym_info *dyn_i;
5270 ia64_info = elfNN_ia64_hash_table (info);
5271 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
5273 /* Fill in the PLT data, if required. */
5274 if (dyn_i && dyn_i->want_plt)
5276 Elf_Internal_Rela outrel;
5277 bfd_byte *loc;
5278 asection *plt_sec;
5279 bfd_vma plt_addr, pltoff_addr, gp_val, index;
5281 gp_val = _bfd_get_gp_value (output_bfd);
5283 /* Initialize the minimal PLT entry. */
5285 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
5286 plt_sec = ia64_info->plt_sec;
5287 loc = plt_sec->contents + dyn_i->plt_offset;
5289 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
5290 elfNN_ia64_install_value (loc, index, R_IA64_IMM22);
5291 elfNN_ia64_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
5293 plt_addr = (plt_sec->output_section->vma
5294 + plt_sec->output_offset
5295 + dyn_i->plt_offset);
5296 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
5298 /* Initialize the FULL PLT entry, if needed. */
5299 if (dyn_i->want_plt2)
5301 loc = plt_sec->contents + dyn_i->plt2_offset;
5303 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
5304 elfNN_ia64_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
5306 /* Mark the symbol as undefined, rather than as defined in the
5307 plt section. Leave the value alone. */
5308 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
5309 first place. But perhaps elflink.c did some for us. */
5310 if (!h->def_regular)
5311 sym->st_shndx = SHN_UNDEF;
5314 /* Create the dynamic relocation. */
5315 outrel.r_offset = pltoff_addr;
5316 if (bfd_little_endian (output_bfd))
5317 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
5318 else
5319 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
5320 outrel.r_addend = 0;
5322 /* This is fun. In the .IA_64.pltoff section, we've got entries
5323 that correspond both to real PLT entries, and those that
5324 happened to resolve to local symbols but need to be created
5325 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
5326 relocations for the real PLT should come at the end of the
5327 section, so that they can be indexed by plt entry at runtime.
5329 We emitted all of the relocations for the non-PLT @pltoff
5330 entries during relocate_section. So we can consider the
5331 existing sec->reloc_count to be the base of the array of
5332 PLT relocations. */
5334 loc = ia64_info->rel_pltoff_sec->contents;
5335 loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
5336 * sizeof (ElfNN_External_Rela));
5337 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
5340 /* Mark some specially defined symbols as absolute. */
5341 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
5342 || h == ia64_info->root.hgot
5343 || h == ia64_info->root.hplt)
5344 sym->st_shndx = SHN_ABS;
5346 return TRUE;
5349 static bfd_boolean
5350 elfNN_ia64_finish_dynamic_sections (abfd, info)
5351 bfd *abfd;
5352 struct bfd_link_info *info;
5354 struct elfNN_ia64_link_hash_table *ia64_info;
5355 bfd *dynobj;
5357 ia64_info = elfNN_ia64_hash_table (info);
5358 dynobj = ia64_info->root.dynobj;
5360 if (elf_hash_table (info)->dynamic_sections_created)
5362 ElfNN_External_Dyn *dyncon, *dynconend;
5363 asection *sdyn, *sgotplt;
5364 bfd_vma gp_val;
5366 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
5367 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
5368 BFD_ASSERT (sdyn != NULL);
5369 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
5370 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
5372 gp_val = _bfd_get_gp_value (abfd);
5374 for (; dyncon < dynconend; dyncon++)
5376 Elf_Internal_Dyn dyn;
5378 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
5380 switch (dyn.d_tag)
5382 case DT_PLTGOT:
5383 dyn.d_un.d_ptr = gp_val;
5384 break;
5386 case DT_PLTRELSZ:
5387 dyn.d_un.d_val = (ia64_info->minplt_entries
5388 * sizeof (ElfNN_External_Rela));
5389 break;
5391 case DT_JMPREL:
5392 /* See the comment above in finish_dynamic_symbol. */
5393 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
5394 + ia64_info->rel_pltoff_sec->output_offset
5395 + (ia64_info->rel_pltoff_sec->reloc_count
5396 * sizeof (ElfNN_External_Rela)));
5397 break;
5399 case DT_IA_64_PLT_RESERVE:
5400 dyn.d_un.d_ptr = (sgotplt->output_section->vma
5401 + sgotplt->output_offset);
5402 break;
5404 case DT_RELASZ:
5405 /* Do not have RELASZ include JMPREL. This makes things
5406 easier on ld.so. This is not what the rest of BFD set up. */
5407 dyn.d_un.d_val -= (ia64_info->minplt_entries
5408 * sizeof (ElfNN_External_Rela));
5409 break;
5412 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
5415 /* Initialize the PLT0 entry. */
5416 if (ia64_info->plt_sec)
5418 bfd_byte *loc = ia64_info->plt_sec->contents;
5419 bfd_vma pltres;
5421 memcpy (loc, plt_header, PLT_HEADER_SIZE);
5423 pltres = (sgotplt->output_section->vma
5424 + sgotplt->output_offset
5425 - gp_val);
5427 elfNN_ia64_install_value (loc+1, pltres, R_IA64_GPREL22);
5431 return TRUE;
5434 /* ELF file flag handling: */
5436 /* Function to keep IA-64 specific file flags. */
5437 static bfd_boolean
5438 elfNN_ia64_set_private_flags (abfd, flags)
5439 bfd *abfd;
5440 flagword flags;
5442 BFD_ASSERT (!elf_flags_init (abfd)
5443 || elf_elfheader (abfd)->e_flags == flags);
5445 elf_elfheader (abfd)->e_flags = flags;
5446 elf_flags_init (abfd) = TRUE;
5447 return TRUE;
5450 /* Merge backend specific data from an object file to the output
5451 object file when linking. */
5452 static bfd_boolean
5453 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
5454 bfd *ibfd, *obfd;
5456 flagword out_flags;
5457 flagword in_flags;
5458 bfd_boolean ok = TRUE;
5460 /* Don't even pretend to support mixed-format linking. */
5461 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
5462 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
5463 return FALSE;
5465 in_flags = elf_elfheader (ibfd)->e_flags;
5466 out_flags = elf_elfheader (obfd)->e_flags;
5468 if (! elf_flags_init (obfd))
5470 elf_flags_init (obfd) = TRUE;
5471 elf_elfheader (obfd)->e_flags = in_flags;
5473 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
5474 && bfd_get_arch_info (obfd)->the_default)
5476 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
5477 bfd_get_mach (ibfd));
5480 return TRUE;
5483 /* Check flag compatibility. */
5484 if (in_flags == out_flags)
5485 return TRUE;
5487 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
5488 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
5489 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
5491 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
5493 (*_bfd_error_handler)
5494 (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5495 ibfd);
5497 bfd_set_error (bfd_error_bad_value);
5498 ok = FALSE;
5500 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
5502 (*_bfd_error_handler)
5503 (_("%B: linking big-endian files with little-endian files"),
5504 ibfd);
5506 bfd_set_error (bfd_error_bad_value);
5507 ok = FALSE;
5509 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
5511 (*_bfd_error_handler)
5512 (_("%B: linking 64-bit files with 32-bit files"),
5513 ibfd);
5515 bfd_set_error (bfd_error_bad_value);
5516 ok = FALSE;
5518 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
5520 (*_bfd_error_handler)
5521 (_("%B: linking constant-gp files with non-constant-gp files"),
5522 ibfd);
5524 bfd_set_error (bfd_error_bad_value);
5525 ok = FALSE;
5527 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
5528 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
5530 (*_bfd_error_handler)
5531 (_("%B: linking auto-pic files with non-auto-pic files"),
5532 ibfd);
5534 bfd_set_error (bfd_error_bad_value);
5535 ok = FALSE;
5538 return ok;
5541 static bfd_boolean
5542 elfNN_ia64_print_private_bfd_data (abfd, ptr)
5543 bfd *abfd;
5544 PTR ptr;
5546 FILE *file = (FILE *) ptr;
5547 flagword flags = elf_elfheader (abfd)->e_flags;
5549 BFD_ASSERT (abfd != NULL && ptr != NULL);
5551 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
5552 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
5553 (flags & EF_IA_64_EXT) ? "EXT, " : "",
5554 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
5555 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
5556 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
5557 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
5558 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
5559 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
5561 _bfd_elf_print_private_bfd_data (abfd, ptr);
5562 return TRUE;
5565 static enum elf_reloc_type_class
5566 elfNN_ia64_reloc_type_class (rela)
5567 const Elf_Internal_Rela *rela;
5569 switch ((int) ELFNN_R_TYPE (rela->r_info))
5571 case R_IA64_REL32MSB:
5572 case R_IA64_REL32LSB:
5573 case R_IA64_REL64MSB:
5574 case R_IA64_REL64LSB:
5575 return reloc_class_relative;
5576 case R_IA64_IPLTMSB:
5577 case R_IA64_IPLTLSB:
5578 return reloc_class_plt;
5579 case R_IA64_COPY:
5580 return reloc_class_copy;
5581 default:
5582 return reloc_class_normal;
5586 static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
5588 { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5589 { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5590 { NULL, 0, 0, 0, 0 }
5593 static bfd_boolean
5594 elfNN_ia64_object_p (bfd *abfd)
5596 asection *sec;
5597 asection *group, *unwi, *unw;
5598 flagword flags;
5599 const char *name;
5600 char *unwi_name, *unw_name;
5601 bfd_size_type amt;
5603 if (abfd->flags & DYNAMIC)
5604 return TRUE;
5606 /* Flags for fake group section. */
5607 flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
5608 | SEC_EXCLUDE);
5610 /* We add a fake section group for each .gnu.linkonce.t.* section,
5611 which isn't in a section group, and its unwind sections. */
5612 for (sec = abfd->sections; sec != NULL; sec = sec->next)
5614 if (elf_sec_group (sec) == NULL
5615 && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
5616 == (SEC_LINK_ONCE | SEC_CODE))
5617 && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
5619 name = sec->name + 16;
5621 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
5622 unwi_name = bfd_alloc (abfd, amt);
5623 if (!unwi_name)
5624 return FALSE;
5626 strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
5627 unwi = bfd_get_section_by_name (abfd, unwi_name);
5629 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
5630 unw_name = bfd_alloc (abfd, amt);
5631 if (!unw_name)
5632 return FALSE;
5634 strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
5635 unw = bfd_get_section_by_name (abfd, unw_name);
5637 /* We need to create a fake group section for it and its
5638 unwind sections. */
5639 group = bfd_make_section_anyway_with_flags (abfd, name,
5640 flags);
5641 if (group == NULL)
5642 return FALSE;
5644 /* Move the fake group section to the beginning. */
5645 bfd_section_list_remove (abfd, group);
5646 bfd_section_list_prepend (abfd, group);
5648 elf_next_in_group (group) = sec;
5650 elf_group_name (sec) = name;
5651 elf_next_in_group (sec) = sec;
5652 elf_sec_group (sec) = group;
5654 if (unwi)
5656 elf_group_name (unwi) = name;
5657 elf_next_in_group (unwi) = sec;
5658 elf_next_in_group (sec) = unwi;
5659 elf_sec_group (unwi) = group;
5662 if (unw)
5664 elf_group_name (unw) = name;
5665 if (unwi)
5667 elf_next_in_group (unw) = elf_next_in_group (unwi);
5668 elf_next_in_group (unwi) = unw;
5670 else
5672 elf_next_in_group (unw) = sec;
5673 elf_next_in_group (sec) = unw;
5675 elf_sec_group (unw) = group;
5678 /* Fake SHT_GROUP section header. */
5679 elf_section_data (group)->this_hdr.bfd_section = group;
5680 elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
5683 return TRUE;
5686 static bfd_boolean
5687 elfNN_ia64_hpux_vec (const bfd_target *vec)
5689 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
5690 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
5693 static void
5694 elfNN_hpux_post_process_headers (abfd, info)
5695 bfd *abfd;
5696 struct bfd_link_info *info ATTRIBUTE_UNUSED;
5698 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5700 i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
5701 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
5704 bfd_boolean
5705 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
5706 bfd *abfd ATTRIBUTE_UNUSED;
5707 asection *sec;
5708 int *retval;
5710 if (bfd_is_com_section (sec))
5712 *retval = SHN_IA_64_ANSI_COMMON;
5713 return TRUE;
5715 return FALSE;
5718 static void
5719 elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5720 asymbol *asym)
5722 elf_symbol_type *elfsym = (elf_symbol_type *) asym;
5724 switch (elfsym->internal_elf_sym.st_shndx)
5726 case SHN_IA_64_ANSI_COMMON:
5727 asym->section = bfd_com_section_ptr;
5728 asym->value = elfsym->internal_elf_sym.st_size;
5729 asym->flags &= ~BSF_GLOBAL;
5730 break;
5735 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
5736 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
5737 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
5738 #define TARGET_BIG_NAME "elfNN-ia64-big"
5739 #define ELF_ARCH bfd_arch_ia64
5740 #define ELF_MACHINE_CODE EM_IA_64
5741 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
5742 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
5743 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
5744 #define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
5746 #define elf_backend_section_from_shdr \
5747 elfNN_ia64_section_from_shdr
5748 #define elf_backend_section_flags \
5749 elfNN_ia64_section_flags
5750 #define elf_backend_fake_sections \
5751 elfNN_ia64_fake_sections
5752 #define elf_backend_final_write_processing \
5753 elfNN_ia64_final_write_processing
5754 #define elf_backend_add_symbol_hook \
5755 elfNN_ia64_add_symbol_hook
5756 #define elf_backend_additional_program_headers \
5757 elfNN_ia64_additional_program_headers
5758 #define elf_backend_modify_segment_map \
5759 elfNN_ia64_modify_segment_map
5760 #define elf_backend_modify_program_headers \
5761 elfNN_ia64_modify_program_headers
5762 #define elf_info_to_howto \
5763 elfNN_ia64_info_to_howto
5765 #define bfd_elfNN_bfd_reloc_type_lookup \
5766 elfNN_ia64_reloc_type_lookup
5767 #define bfd_elfNN_bfd_reloc_name_lookup \
5768 elfNN_ia64_reloc_name_lookup
5769 #define bfd_elfNN_bfd_is_local_label_name \
5770 elfNN_ia64_is_local_label_name
5771 #define bfd_elfNN_bfd_relax_section \
5772 elfNN_ia64_relax_section
5774 #define elf_backend_object_p \
5775 elfNN_ia64_object_p
5777 /* Stuff for the BFD linker: */
5778 #define bfd_elfNN_bfd_link_hash_table_create \
5779 elfNN_ia64_hash_table_create
5780 #define bfd_elfNN_bfd_link_hash_table_free \
5781 elfNN_ia64_hash_table_free
5782 #define elf_backend_create_dynamic_sections \
5783 elfNN_ia64_create_dynamic_sections
5784 #define elf_backend_check_relocs \
5785 elfNN_ia64_check_relocs
5786 #define elf_backend_adjust_dynamic_symbol \
5787 elfNN_ia64_adjust_dynamic_symbol
5788 #define elf_backend_size_dynamic_sections \
5789 elfNN_ia64_size_dynamic_sections
5790 #define elf_backend_omit_section_dynsym \
5791 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
5792 #define elf_backend_relocate_section \
5793 elfNN_ia64_relocate_section
5794 #define elf_backend_finish_dynamic_symbol \
5795 elfNN_ia64_finish_dynamic_symbol
5796 #define elf_backend_finish_dynamic_sections \
5797 elfNN_ia64_finish_dynamic_sections
5798 #define bfd_elfNN_bfd_final_link \
5799 elfNN_ia64_final_link
5801 #define bfd_elfNN_bfd_merge_private_bfd_data \
5802 elfNN_ia64_merge_private_bfd_data
5803 #define bfd_elfNN_bfd_set_private_flags \
5804 elfNN_ia64_set_private_flags
5805 #define bfd_elfNN_bfd_print_private_bfd_data \
5806 elfNN_ia64_print_private_bfd_data
5808 #define elf_backend_plt_readonly 1
5809 #define elf_backend_want_plt_sym 0
5810 #define elf_backend_plt_alignment 5
5811 #define elf_backend_got_header_size 0
5812 #define elf_backend_want_got_plt 1
5813 #define elf_backend_may_use_rel_p 1
5814 #define elf_backend_may_use_rela_p 1
5815 #define elf_backend_default_use_rela_p 1
5816 #define elf_backend_want_dynbss 0
5817 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5818 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
5819 #define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
5820 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
5821 #define elf_backend_rela_normal 1
5822 #define elf_backend_special_sections elfNN_ia64_special_sections
5823 #define elf_backend_default_execstack 0
5825 /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5826 SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
5827 We don't want to flood users with so many error messages. We turn
5828 off the warning for now. It will be turned on later when the Intel
5829 compiler is fixed. */
5830 #define elf_backend_link_order_error_handler NULL
5832 #include "elfNN-target.h"
5834 /* HPUX-specific vectors. */
5836 #undef TARGET_LITTLE_SYM
5837 #undef TARGET_LITTLE_NAME
5838 #undef TARGET_BIG_SYM
5839 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
5840 #undef TARGET_BIG_NAME
5841 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
5843 /* These are HP-UX specific functions. */
5845 #undef elf_backend_post_process_headers
5846 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5848 #undef elf_backend_section_from_bfd_section
5849 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5851 #undef elf_backend_symbol_processing
5852 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5854 #undef elf_backend_want_p_paddr_set_to_zero
5855 #define elf_backend_want_p_paddr_set_to_zero 1
5857 #undef ELF_MAXPAGESIZE
5858 #define ELF_MAXPAGESIZE 0x1000 /* 4K */
5859 #undef ELF_COMMONPAGESIZE
5860 #undef ELF_OSABI
5861 #define ELF_OSABI ELFOSABI_HPUX
5863 #undef elfNN_bed
5864 #define elfNN_bed elfNN_ia64_hpux_bed
5866 #include "elfNN-target.h"
5868 #undef elf_backend_want_p_paddr_set_to_zero