Regenerate translation files.
[binutils.git] / bfd / elfxx-ia64.c
blobc25294c0fddc5b599f4c6044eb072f4618edf902
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 3 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,
21 MA 02110-1301, USA. */
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26 #include "elf-bfd.h"
27 #include "opcode/ia64.h"
28 #include "elf/ia64.h"
29 #include "objalloc.h"
30 #include "hashtab.h"
32 #define ARCH_SIZE NN
34 #if ARCH_SIZE == 64
35 #define LOG_SECTION_ALIGN 3
36 #endif
38 #if ARCH_SIZE == 32
39 #define LOG_SECTION_ALIGN 2
40 #endif
42 /* THE RULES for all the stuff the linker creates --
44 GOT Entries created in response to LTOFF or LTOFF_FPTR
45 relocations. Dynamic relocs created for dynamic
46 symbols in an application; REL relocs for locals
47 in a shared library.
49 FPTR The canonical function descriptor. Created for local
50 symbols in applications. Descriptors for dynamic symbols
51 and local symbols in shared libraries are created by
52 ld.so. Thus there are no dynamic relocs against these
53 objects. The FPTR relocs for such _are_ passed through
54 to the dynamic relocation tables.
56 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
57 Requires the creation of a PLTOFF entry. This does not
58 require any dynamic relocations.
60 PLTOFF Created by PLTOFF relocations. For local symbols, this
61 is an alternate function descriptor, and in shared libraries
62 requires two REL relocations. Note that this cannot be
63 transformed into an FPTR relocation, since it must be in
64 range of the GP. For dynamic symbols, this is a function
65 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
67 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
68 does not require dynamic relocations. */
70 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
72 typedef struct bfd_hash_entry *(*new_hash_entry_func)
73 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
75 /* In dynamically (linker-) created sections, we generally need to keep track
76 of the place a symbol or expression got allocated to. This is done via hash
77 tables that store entries of the following type. */
79 struct elfNN_ia64_dyn_sym_info
81 /* The addend for which this entry is relevant. */
82 bfd_vma addend;
84 bfd_vma got_offset;
85 bfd_vma fptr_offset;
86 bfd_vma pltoff_offset;
87 bfd_vma plt_offset;
88 bfd_vma plt2_offset;
89 bfd_vma tprel_offset;
90 bfd_vma dtpmod_offset;
91 bfd_vma dtprel_offset;
93 /* The symbol table entry, if any, that this was derived from. */
94 struct elf_link_hash_entry *h;
96 /* Used to count non-got, non-plt relocations for delayed sizing
97 of relocation sections. */
98 struct elfNN_ia64_dyn_reloc_entry
100 struct elfNN_ia64_dyn_reloc_entry *next;
101 asection *srel;
102 int type;
103 int count;
105 /* Is this reloc against readonly section? */
106 bfd_boolean reltext;
107 } *reloc_entries;
109 /* TRUE when the section contents have been updated. */
110 unsigned got_done : 1;
111 unsigned fptr_done : 1;
112 unsigned pltoff_done : 1;
113 unsigned tprel_done : 1;
114 unsigned dtpmod_done : 1;
115 unsigned dtprel_done : 1;
117 /* TRUE for the different kinds of linker data we want created. */
118 unsigned want_got : 1;
119 unsigned want_gotx : 1;
120 unsigned want_fptr : 1;
121 unsigned want_ltoff_fptr : 1;
122 unsigned want_plt : 1;
123 unsigned want_plt2 : 1;
124 unsigned want_pltoff : 1;
125 unsigned want_tprel : 1;
126 unsigned want_dtpmod : 1;
127 unsigned want_dtprel : 1;
130 struct elfNN_ia64_local_hash_entry
132 int id;
133 unsigned int r_sym;
134 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
135 unsigned int count;
136 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
137 unsigned int sorted_count;
138 /* The size of elfNN_ia64_dyn_sym_info array. */
139 unsigned int size;
140 /* The array of elfNN_ia64_dyn_sym_info. */
141 struct elfNN_ia64_dyn_sym_info *info;
143 /* TRUE if this hash entry's addends was translated for
144 SHF_MERGE optimization. */
145 unsigned sec_merge_done : 1;
148 struct elfNN_ia64_link_hash_entry
150 struct elf_link_hash_entry root;
151 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
152 unsigned int count;
153 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
154 unsigned int sorted_count;
155 /* The size of elfNN_ia64_dyn_sym_info array. */
156 unsigned int size;
157 /* The array of elfNN_ia64_dyn_sym_info. */
158 struct elfNN_ia64_dyn_sym_info *info;
161 struct elfNN_ia64_link_hash_table
163 /* The main hash table. */
164 struct elf_link_hash_table root;
166 asection *got_sec; /* the linkage table section (or NULL) */
167 asection *rel_got_sec; /* dynamic relocation section for same */
168 asection *fptr_sec; /* function descriptor table (or NULL) */
169 asection *rel_fptr_sec; /* dynamic relocation section for same */
170 asection *plt_sec; /* the primary plt section (or NULL) */
171 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
172 asection *rel_pltoff_sec; /* dynamic relocation section for same */
174 bfd_size_type minplt_entries; /* number of minplt entries */
175 unsigned reltext : 1; /* are there relocs against readonly sections? */
176 unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
177 bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry */
179 htab_t loc_hash_table;
180 void *loc_hash_memory;
183 struct elfNN_ia64_allocate_data
185 struct bfd_link_info *info;
186 bfd_size_type ofs;
187 bfd_boolean only_got;
190 #define elfNN_ia64_hash_table(p) \
191 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
193 static bfd_reloc_status_type elfNN_ia64_reloc
194 PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
195 asection *input_section, bfd *output_bfd, char **error_message));
196 static reloc_howto_type * lookup_howto
197 PARAMS ((unsigned int rtype));
198 static reloc_howto_type *elfNN_ia64_reloc_type_lookup
199 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
200 static void elfNN_ia64_info_to_howto
201 PARAMS ((bfd *abfd, arelent *bfd_reloc, Elf_Internal_Rela *elf_reloc));
202 static bfd_boolean elfNN_ia64_relax_section
203 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
204 bfd_boolean *again));
205 static void elfNN_ia64_relax_ldxmov
206 PARAMS((bfd_byte *contents, bfd_vma off));
207 static bfd_boolean is_unwind_section_name
208 PARAMS ((bfd *abfd, const char *));
209 static bfd_boolean elfNN_ia64_section_flags
210 PARAMS ((flagword *, const Elf_Internal_Shdr *));
211 static bfd_boolean elfNN_ia64_fake_sections
212 PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec));
213 static void elfNN_ia64_final_write_processing
214 PARAMS ((bfd *abfd, bfd_boolean linker));
215 static bfd_boolean elfNN_ia64_add_symbol_hook
216 PARAMS ((bfd *abfd, struct bfd_link_info *info, Elf_Internal_Sym *sym,
217 const char **namep, flagword *flagsp, asection **secp,
218 bfd_vma *valp));
219 static bfd_boolean elfNN_ia64_is_local_label_name
220 PARAMS ((bfd *abfd, const char *name));
221 static bfd_boolean elfNN_ia64_dynamic_symbol_p
222 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info, int));
223 static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
224 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
225 const char *string));
226 static void elfNN_ia64_hash_copy_indirect
227 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *,
228 struct elf_link_hash_entry *));
229 static void elfNN_ia64_hash_hide_symbol
230 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
231 static hashval_t elfNN_ia64_local_htab_hash PARAMS ((const void *));
232 static int elfNN_ia64_local_htab_eq PARAMS ((const void *ptr1,
233 const void *ptr2));
234 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
235 PARAMS ((bfd *abfd));
236 static void elfNN_ia64_hash_table_free
237 PARAMS ((struct bfd_link_hash_table *hash));
238 static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
239 PARAMS ((struct bfd_hash_entry *, PTR));
240 static int elfNN_ia64_local_dyn_sym_thunk
241 PARAMS ((void **, PTR));
242 static void elfNN_ia64_dyn_sym_traverse
243 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
244 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
245 PTR info));
246 static bfd_boolean elfNN_ia64_create_dynamic_sections
247 PARAMS ((bfd *abfd, struct bfd_link_info *info));
248 static struct elfNN_ia64_local_hash_entry * get_local_sym_hash
249 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
250 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
251 static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
252 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
253 struct elf_link_hash_entry *h,
254 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
255 static asection *get_got
256 PARAMS ((bfd *abfd, struct bfd_link_info *info,
257 struct elfNN_ia64_link_hash_table *ia64_info));
258 static asection *get_fptr
259 PARAMS ((bfd *abfd, struct bfd_link_info *info,
260 struct elfNN_ia64_link_hash_table *ia64_info));
261 static asection *get_pltoff
262 PARAMS ((bfd *abfd, struct bfd_link_info *info,
263 struct elfNN_ia64_link_hash_table *ia64_info));
264 static asection *get_reloc_section
265 PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
266 asection *sec, bfd_boolean create));
267 static bfd_boolean elfNN_ia64_check_relocs
268 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
269 const Elf_Internal_Rela *relocs));
270 static bfd_boolean elfNN_ia64_adjust_dynamic_symbol
271 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
272 static long global_sym_index
273 PARAMS ((struct elf_link_hash_entry *h));
274 static bfd_boolean allocate_fptr
275 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
276 static bfd_boolean allocate_global_data_got
277 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
278 static bfd_boolean allocate_global_fptr_got
279 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
280 static bfd_boolean allocate_local_got
281 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
282 static bfd_boolean allocate_pltoff_entries
283 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
284 static bfd_boolean allocate_plt_entries
285 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
286 static bfd_boolean allocate_plt2_entries
287 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
288 static bfd_boolean allocate_dynrel_entries
289 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
290 static bfd_boolean elfNN_ia64_size_dynamic_sections
291 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
292 static bfd_reloc_status_type elfNN_ia64_install_value
293 PARAMS ((bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
294 static void elfNN_ia64_install_dyn_reloc
295 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
296 asection *srel, bfd_vma offset, unsigned int type,
297 long dynindx, bfd_vma addend));
298 static bfd_vma set_got_entry
299 PARAMS ((bfd *abfd, struct bfd_link_info *info,
300 struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
301 bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
302 static bfd_vma set_fptr_entry
303 PARAMS ((bfd *abfd, struct bfd_link_info *info,
304 struct elfNN_ia64_dyn_sym_info *dyn_i,
305 bfd_vma value));
306 static bfd_vma set_pltoff_entry
307 PARAMS ((bfd *abfd, struct bfd_link_info *info,
308 struct elfNN_ia64_dyn_sym_info *dyn_i,
309 bfd_vma value, bfd_boolean));
310 static bfd_vma elfNN_ia64_tprel_base
311 PARAMS ((struct bfd_link_info *info));
312 static bfd_vma elfNN_ia64_dtprel_base
313 PARAMS ((struct bfd_link_info *info));
314 static int elfNN_ia64_unwind_entry_compare
315 PARAMS ((const PTR, const PTR));
316 static bfd_boolean elfNN_ia64_choose_gp
317 PARAMS ((bfd *abfd, struct bfd_link_info *info));
318 static bfd_boolean elfNN_ia64_final_link
319 PARAMS ((bfd *abfd, struct bfd_link_info *info));
320 static bfd_boolean elfNN_ia64_relocate_section
321 PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
322 asection *input_section, bfd_byte *contents,
323 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
324 asection **local_sections));
325 static bfd_boolean elfNN_ia64_finish_dynamic_symbol
326 PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
327 struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
328 static bfd_boolean elfNN_ia64_finish_dynamic_sections
329 PARAMS ((bfd *abfd, struct bfd_link_info *info));
330 static bfd_boolean elfNN_ia64_set_private_flags
331 PARAMS ((bfd *abfd, flagword flags));
332 static bfd_boolean elfNN_ia64_merge_private_bfd_data
333 PARAMS ((bfd *ibfd, bfd *obfd));
334 static bfd_boolean elfNN_ia64_print_private_bfd_data
335 PARAMS ((bfd *abfd, PTR ptr));
336 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
337 PARAMS ((const Elf_Internal_Rela *));
338 static bfd_boolean elfNN_ia64_hpux_vec
339 PARAMS ((const bfd_target *vec));
340 static void elfNN_hpux_post_process_headers
341 PARAMS ((bfd *abfd, struct bfd_link_info *info));
342 bfd_boolean elfNN_hpux_backend_section_from_bfd_section
343 PARAMS ((bfd *abfd, asection *sec, int *retval));
345 /* ia64-specific relocation. */
347 /* Perform a relocation. Not much to do here as all the hard work is
348 done in elfNN_ia64_final_link_relocate. */
349 static bfd_reloc_status_type
350 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
351 output_bfd, error_message)
352 bfd *abfd ATTRIBUTE_UNUSED;
353 arelent *reloc;
354 asymbol *sym ATTRIBUTE_UNUSED;
355 PTR data ATTRIBUTE_UNUSED;
356 asection *input_section;
357 bfd *output_bfd;
358 char **error_message;
360 if (output_bfd)
362 reloc->address += input_section->output_offset;
363 return bfd_reloc_ok;
366 if (input_section->flags & SEC_DEBUGGING)
367 return bfd_reloc_continue;
369 *error_message = "Unsupported call to elfNN_ia64_reloc";
370 return bfd_reloc_notsupported;
373 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
374 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
375 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
377 /* This table has to be sorted according to increasing number of the
378 TYPE field. */
379 static reloc_howto_type ia64_howto_table[] =
381 IA64_HOWTO (R_IA64_NONE, "NONE", 0, FALSE, TRUE),
383 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, FALSE, TRUE),
384 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, FALSE, TRUE),
385 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, FALSE, TRUE),
386 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, FALSE, TRUE),
387 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, FALSE, TRUE),
388 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, FALSE, TRUE),
389 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, FALSE, TRUE),
391 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, FALSE, TRUE),
392 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, FALSE, TRUE),
393 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, FALSE, TRUE),
394 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, FALSE, TRUE),
395 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, FALSE, TRUE),
396 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, FALSE, TRUE),
398 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, FALSE, TRUE),
399 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, FALSE, TRUE),
401 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, FALSE, TRUE),
402 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, FALSE, TRUE),
403 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, FALSE, TRUE),
404 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, FALSE, TRUE),
406 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, FALSE, TRUE),
407 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, FALSE, TRUE),
408 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, FALSE, TRUE),
409 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, FALSE, TRUE),
410 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, FALSE, TRUE),
412 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, TRUE, TRUE),
413 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, TRUE, TRUE),
414 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, TRUE, TRUE),
415 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, TRUE, TRUE),
416 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, TRUE, TRUE),
417 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, TRUE, TRUE),
418 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, TRUE, TRUE),
419 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, TRUE, TRUE),
421 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, FALSE, TRUE),
422 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, FALSE, TRUE),
423 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, FALSE, TRUE),
424 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, FALSE, TRUE),
425 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, FALSE, TRUE),
426 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, FALSE, TRUE),
428 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, FALSE, TRUE),
429 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, FALSE, TRUE),
430 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, FALSE, TRUE),
431 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, FALSE, TRUE),
433 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, FALSE, TRUE),
434 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, FALSE, TRUE),
435 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, FALSE, TRUE),
436 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, FALSE, TRUE),
438 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, FALSE, TRUE),
439 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, FALSE, TRUE),
440 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, FALSE, TRUE),
441 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, FALSE, TRUE),
443 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, FALSE, TRUE),
444 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, FALSE, TRUE),
445 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, FALSE, TRUE),
446 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, FALSE, TRUE),
448 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, TRUE, TRUE),
449 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, TRUE, TRUE),
450 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, TRUE, TRUE),
452 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, FALSE, TRUE),
453 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, FALSE, TRUE),
454 IA64_HOWTO (R_IA64_COPY, "COPY", 4, FALSE, TRUE),
455 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, FALSE, TRUE),
456 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, FALSE, TRUE),
458 IA64_HOWTO (R_IA64_TPREL14, "TPREL14", 0, FALSE, FALSE),
459 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, FALSE, FALSE),
460 IA64_HOWTO (R_IA64_TPREL64I, "TPREL64I", 0, FALSE, FALSE),
461 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 4, FALSE, FALSE),
462 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 4, FALSE, FALSE),
463 IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, FALSE, FALSE),
465 IA64_HOWTO (R_IA64_DTPMOD64MSB, "DTPMOD64MSB", 4, FALSE, FALSE),
466 IA64_HOWTO (R_IA64_DTPMOD64LSB, "DTPMOD64LSB", 4, FALSE, FALSE),
467 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
469 IA64_HOWTO (R_IA64_DTPREL14, "DTPREL14", 0, FALSE, FALSE),
470 IA64_HOWTO (R_IA64_DTPREL22, "DTPREL22", 0, FALSE, FALSE),
471 IA64_HOWTO (R_IA64_DTPREL64I, "DTPREL64I", 0, FALSE, FALSE),
472 IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE),
473 IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE),
474 IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE),
475 IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE),
476 IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
479 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
481 /* Given a BFD reloc type, return the matching HOWTO structure. */
483 static reloc_howto_type *
484 lookup_howto (rtype)
485 unsigned int rtype;
487 static int inited = 0;
488 int i;
490 if (!inited)
492 inited = 1;
494 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
495 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
496 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
499 if (rtype > R_IA64_MAX_RELOC_CODE)
500 return 0;
501 i = elf_code_to_howto_index[rtype];
502 if (i >= NELEMS (ia64_howto_table))
503 return 0;
504 return ia64_howto_table + i;
507 static reloc_howto_type*
508 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
509 bfd *abfd ATTRIBUTE_UNUSED;
510 bfd_reloc_code_real_type bfd_code;
512 unsigned int rtype;
514 switch (bfd_code)
516 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
518 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
519 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
520 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
522 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
523 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
524 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
525 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
527 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
528 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
529 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
530 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
531 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
532 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
534 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
535 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
537 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
538 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
539 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
540 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
541 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
542 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
543 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
544 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
545 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
547 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
548 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
549 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
550 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
551 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
552 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
553 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
554 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
555 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
556 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
557 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
559 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
560 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
561 case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
562 case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
563 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
564 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
566 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
567 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
568 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
569 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
571 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
572 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
573 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
574 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
576 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
577 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
578 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
579 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
581 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
582 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
583 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
584 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
586 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
587 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
588 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
589 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
590 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
592 case BFD_RELOC_IA64_TPREL14: rtype = R_IA64_TPREL14; break;
593 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
594 case BFD_RELOC_IA64_TPREL64I: rtype = R_IA64_TPREL64I; break;
595 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
596 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
597 case BFD_RELOC_IA64_LTOFF_TPREL22: rtype = R_IA64_LTOFF_TPREL22; break;
599 case BFD_RELOC_IA64_DTPMOD64MSB: rtype = R_IA64_DTPMOD64MSB; break;
600 case BFD_RELOC_IA64_DTPMOD64LSB: rtype = R_IA64_DTPMOD64LSB; break;
601 case BFD_RELOC_IA64_LTOFF_DTPMOD22: rtype = R_IA64_LTOFF_DTPMOD22; break;
603 case BFD_RELOC_IA64_DTPREL14: rtype = R_IA64_DTPREL14; break;
604 case BFD_RELOC_IA64_DTPREL22: rtype = R_IA64_DTPREL22; break;
605 case BFD_RELOC_IA64_DTPREL64I: rtype = R_IA64_DTPREL64I; break;
606 case BFD_RELOC_IA64_DTPREL32MSB: rtype = R_IA64_DTPREL32MSB; break;
607 case BFD_RELOC_IA64_DTPREL32LSB: rtype = R_IA64_DTPREL32LSB; break;
608 case BFD_RELOC_IA64_DTPREL64MSB: rtype = R_IA64_DTPREL64MSB; break;
609 case BFD_RELOC_IA64_DTPREL64LSB: rtype = R_IA64_DTPREL64LSB; break;
610 case BFD_RELOC_IA64_LTOFF_DTPREL22: rtype = R_IA64_LTOFF_DTPREL22; break;
612 default: return 0;
614 return lookup_howto (rtype);
617 static reloc_howto_type *
618 elfNN_ia64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
619 const char *r_name)
621 unsigned int i;
623 for (i = 0;
624 i < sizeof (ia64_howto_table) / sizeof (ia64_howto_table[0]);
625 i++)
626 if (ia64_howto_table[i].name != NULL
627 && strcasecmp (ia64_howto_table[i].name, r_name) == 0)
628 return &ia64_howto_table[i];
630 return NULL;
633 /* Given a ELF reloc, return the matching HOWTO structure. */
635 static void
636 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
637 bfd *abfd ATTRIBUTE_UNUSED;
638 arelent *bfd_reloc;
639 Elf_Internal_Rela *elf_reloc;
641 bfd_reloc->howto
642 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
645 #define PLT_HEADER_SIZE (3 * 16)
646 #define PLT_MIN_ENTRY_SIZE (1 * 16)
647 #define PLT_FULL_ENTRY_SIZE (2 * 16)
648 #define PLT_RESERVED_WORDS 3
650 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
652 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
653 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
654 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
655 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
656 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
657 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
658 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
659 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
660 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
663 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
665 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
666 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
667 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
670 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
672 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
673 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
674 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
675 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
676 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
677 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
680 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
682 static const bfd_byte oor_brl[16] =
684 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
686 0x00, 0x00, 0x00, 0xc0
689 static const bfd_byte oor_ip[48] =
691 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
692 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
693 0x01, 0x00, 0x00, 0x60,
694 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
695 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
696 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
697 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
698 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
699 0x60, 0x00, 0x80, 0x00 /* br b6;; */
702 static size_t oor_branch_size = sizeof (oor_brl);
704 void
705 bfd_elfNN_ia64_after_parse (int itanium)
707 oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
710 #define BTYPE_SHIFT 6
711 #define Y_SHIFT 26
712 #define X6_SHIFT 27
713 #define X4_SHIFT 27
714 #define X3_SHIFT 33
715 #define X2_SHIFT 31
716 #define X_SHIFT 33
717 #define OPCODE_SHIFT 37
719 #define OPCODE_BITS (0xfLL << OPCODE_SHIFT)
720 #define X6_BITS (0x3fLL << X6_SHIFT)
721 #define X4_BITS (0xfLL << X4_SHIFT)
722 #define X3_BITS (0x7LL << X3_SHIFT)
723 #define X2_BITS (0x3LL << X2_SHIFT)
724 #define X_BITS (0x1LL << X_SHIFT)
725 #define Y_BITS (0x1LL << Y_SHIFT)
726 #define BTYPE_BITS (0x7LL << BTYPE_SHIFT)
727 #define PREDICATE_BITS (0x3fLL)
729 #define IS_NOP_B(i) \
730 (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
731 #define IS_NOP_F(i) \
732 (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
733 == (0x1LL << X6_SHIFT))
734 #define IS_NOP_I(i) \
735 (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
736 == (0x1LL << X6_SHIFT))
737 #define IS_NOP_M(i) \
738 (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
739 == (0x1LL << X4_SHIFT))
740 #define IS_BR_COND(i) \
741 (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
742 #define IS_BR_CALL(i) \
743 (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
745 static bfd_boolean
746 elfNN_ia64_relax_br (bfd_byte *contents, bfd_vma off)
748 unsigned int template, mlx;
749 bfd_vma t0, t1, s0, s1, s2, br_code;
750 long br_slot;
751 bfd_byte *hit_addr;
753 hit_addr = (bfd_byte *) (contents + off);
754 br_slot = (long) hit_addr & 0x3;
755 hit_addr -= br_slot;
756 t0 = bfd_getl64 (hit_addr + 0);
757 t1 = bfd_getl64 (hit_addr + 8);
759 /* Check if we can turn br into brl. A label is always at the start
760 of the bundle. Even if there are predicates on NOPs, we still
761 perform this optimization. */
762 template = t0 & 0x1e;
763 s0 = (t0 >> 5) & 0x1ffffffffffLL;
764 s1 = ((t0 >> 46) | (t1 << 18)) & 0x1ffffffffffLL;
765 s2 = (t1 >> 23) & 0x1ffffffffffLL;
766 switch (br_slot)
768 case 0:
769 /* Check if slot 1 and slot 2 are NOPs. Possible template is
770 BBB. We only need to check nop.b. */
771 if (!(IS_NOP_B (s1) && IS_NOP_B (s2)))
772 return FALSE;
773 br_code = s0;
774 break;
775 case 1:
776 /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
777 For BBB, slot 0 also has to be nop.b. */
778 if (!((template == 0x12 /* MBB */
779 && IS_NOP_B (s2))
780 || (template == 0x16 /* BBB */
781 && IS_NOP_B (s0)
782 && IS_NOP_B (s2))))
783 return FALSE;
784 br_code = s1;
785 break;
786 case 2:
787 /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
788 MMB and MFB. For BBB, slot 0 also has to be nop.b. */
789 if (!((template == 0x10 /* MIB */
790 && IS_NOP_I (s1))
791 || (template == 0x12 /* MBB */
792 && IS_NOP_B (s1))
793 || (template == 0x16 /* BBB */
794 && IS_NOP_B (s0)
795 && IS_NOP_B (s1))
796 || (template == 0x18 /* MMB */
797 && IS_NOP_M (s1))
798 || (template == 0x1c /* MFB */
799 && IS_NOP_F (s1))))
800 return FALSE;
801 br_code = s2;
802 break;
803 default:
804 /* It should never happen. */
805 abort ();
808 /* We can turn br.cond/br.call into brl.cond/brl.call. */
809 if (!(IS_BR_COND (br_code) || IS_BR_CALL (br_code)))
810 return FALSE;
812 /* Turn br into brl by setting bit 40. */
813 br_code |= 0x1LL << 40;
815 /* Turn the old bundle into a MLX bundle with the same stop-bit
816 variety. */
817 if (t0 & 0x1)
818 mlx = 0x5;
819 else
820 mlx = 0x4;
822 if (template == 0x16)
824 /* For BBB, we need to put nop.m in slot 0. We keep the original
825 predicate only if slot 0 isn't br. */
826 if (br_slot == 0)
827 t0 = 0LL;
828 else
829 t0 &= PREDICATE_BITS << 5;
830 t0 |= 0x1LL << (X4_SHIFT + 5);
832 else
834 /* Keep the original instruction in slot 0. */
835 t0 &= 0x1ffffffffffLL << 5;
838 t0 |= mlx;
840 /* Put brl in slot 1. */
841 t1 = br_code << 23;
843 bfd_putl64 (t0, hit_addr);
844 bfd_putl64 (t1, hit_addr + 8);
845 return TRUE;
848 static void
849 elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
851 int template;
852 bfd_byte *hit_addr;
853 bfd_vma t0, t1, i0, i1, i2;
855 hit_addr = (bfd_byte *) (contents + off);
856 hit_addr -= (long) hit_addr & 0x3;
857 t0 = bfd_getl64 (hit_addr);
858 t1 = bfd_getl64 (hit_addr + 8);
860 /* Keep the instruction in slot 0. */
861 i0 = (t0 >> 5) & 0x1ffffffffffLL;
862 /* Use nop.b for slot 1. */
863 i1 = 0x4000000000LL;
864 /* For slot 2, turn brl into br by masking out bit 40. */
865 i2 = (t1 >> 23) & 0x0ffffffffffLL;
867 /* Turn a MLX bundle into a MBB bundle with the same stop-bit
868 variety. */
869 if (t0 & 0x1)
870 template = 0x13;
871 else
872 template = 0x12;
873 t0 = (i1 << 46) | (i0 << 5) | template;
874 t1 = (i2 << 23) | (i1 >> 18);
876 bfd_putl64 (t0, hit_addr);
877 bfd_putl64 (t1, hit_addr + 8);
880 /* Rename some of the generic section flags to better document how they
881 are used here. */
882 #define skip_relax_pass_0 need_finalize_relax
883 #define skip_relax_pass_1 has_gp_reloc
886 /* These functions do relaxation for IA-64 ELF. */
888 static bfd_boolean
889 elfNN_ia64_relax_section (abfd, sec, link_info, again)
890 bfd *abfd;
891 asection *sec;
892 struct bfd_link_info *link_info;
893 bfd_boolean *again;
895 struct one_fixup
897 struct one_fixup *next;
898 asection *tsec;
899 bfd_vma toff;
900 bfd_vma trampoff;
903 Elf_Internal_Shdr *symtab_hdr;
904 Elf_Internal_Rela *internal_relocs;
905 Elf_Internal_Rela *irel, *irelend;
906 bfd_byte *contents;
907 Elf_Internal_Sym *isymbuf = NULL;
908 struct elfNN_ia64_link_hash_table *ia64_info;
909 struct one_fixup *fixups = NULL;
910 bfd_boolean changed_contents = FALSE;
911 bfd_boolean changed_relocs = FALSE;
912 bfd_boolean changed_got = FALSE;
913 bfd_boolean skip_relax_pass_0 = TRUE;
914 bfd_boolean skip_relax_pass_1 = TRUE;
915 bfd_vma gp = 0;
917 /* Assume we're not going to change any sizes, and we'll only need
918 one pass. */
919 *again = FALSE;
921 /* Don't even try to relax for non-ELF outputs. */
922 if (!is_elf_hash_table (link_info->hash))
923 return FALSE;
925 /* Nothing to do if there are no relocations or there is no need for
926 the current pass. */
927 if ((sec->flags & SEC_RELOC) == 0
928 || sec->reloc_count == 0
929 || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
930 || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
931 return TRUE;
933 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
935 /* Load the relocations for this section. */
936 internal_relocs = (_bfd_elf_link_read_relocs
937 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
938 link_info->keep_memory));
939 if (internal_relocs == NULL)
940 return FALSE;
942 ia64_info = elfNN_ia64_hash_table (link_info);
943 irelend = internal_relocs + sec->reloc_count;
945 /* Get the section contents. */
946 if (elf_section_data (sec)->this_hdr.contents != NULL)
947 contents = elf_section_data (sec)->this_hdr.contents;
948 else
950 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
951 goto error_return;
954 for (irel = internal_relocs; irel < irelend; irel++)
956 unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
957 bfd_vma symaddr, reladdr, trampoff, toff, roff;
958 asection *tsec;
959 struct one_fixup *f;
960 bfd_size_type amt;
961 bfd_boolean is_branch;
962 struct elfNN_ia64_dyn_sym_info *dyn_i;
963 char symtype;
965 switch (r_type)
967 case R_IA64_PCREL21B:
968 case R_IA64_PCREL21BI:
969 case R_IA64_PCREL21M:
970 case R_IA64_PCREL21F:
971 /* In pass 1, all br relaxations are done. We can skip it. */
972 if (link_info->relax_pass == 1)
973 continue;
974 skip_relax_pass_0 = FALSE;
975 is_branch = TRUE;
976 break;
978 case R_IA64_PCREL60B:
979 /* We can't optimize brl to br in pass 0 since br relaxations
980 will increase the code size. Defer it to pass 1. */
981 if (link_info->relax_pass == 0)
983 skip_relax_pass_1 = FALSE;
984 continue;
986 is_branch = TRUE;
987 break;
989 case R_IA64_LTOFF22X:
990 case R_IA64_LDXMOV:
991 /* We can't relax ldx/mov in pass 0 since br relaxations will
992 increase the code size. Defer it to pass 1. */
993 if (link_info->relax_pass == 0)
995 skip_relax_pass_1 = FALSE;
996 continue;
998 is_branch = FALSE;
999 break;
1001 default:
1002 continue;
1005 /* Get the value of the symbol referred to by the reloc. */
1006 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1008 /* A local symbol. */
1009 Elf_Internal_Sym *isym;
1011 /* Read this BFD's local symbols. */
1012 if (isymbuf == NULL)
1014 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1015 if (isymbuf == NULL)
1016 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1017 symtab_hdr->sh_info, 0,
1018 NULL, NULL, NULL);
1019 if (isymbuf == 0)
1020 goto error_return;
1023 isym = isymbuf + ELFNN_R_SYM (irel->r_info);
1024 if (isym->st_shndx == SHN_UNDEF)
1025 continue; /* We can't do anything with undefined symbols. */
1026 else if (isym->st_shndx == SHN_ABS)
1027 tsec = bfd_abs_section_ptr;
1028 else if (isym->st_shndx == SHN_COMMON)
1029 tsec = bfd_com_section_ptr;
1030 else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
1031 tsec = bfd_com_section_ptr;
1032 else
1033 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1035 toff = isym->st_value;
1036 dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
1037 symtype = ELF_ST_TYPE (isym->st_info);
1039 else
1041 unsigned long indx;
1042 struct elf_link_hash_entry *h;
1044 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1045 h = elf_sym_hashes (abfd)[indx];
1046 BFD_ASSERT (h != NULL);
1048 while (h->root.type == bfd_link_hash_indirect
1049 || h->root.type == bfd_link_hash_warning)
1050 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1052 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
1054 /* For branches to dynamic symbols, we're interested instead
1055 in a branch to the PLT entry. */
1056 if (is_branch && dyn_i && dyn_i->want_plt2)
1058 /* Internal branches shouldn't be sent to the PLT.
1059 Leave this for now and we'll give an error later. */
1060 if (r_type != R_IA64_PCREL21B)
1061 continue;
1063 tsec = ia64_info->plt_sec;
1064 toff = dyn_i->plt2_offset;
1065 BFD_ASSERT (irel->r_addend == 0);
1068 /* Can't do anything else with dynamic symbols. */
1069 else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
1070 continue;
1072 else
1074 /* We can't do anything with undefined symbols. */
1075 if (h->root.type == bfd_link_hash_undefined
1076 || h->root.type == bfd_link_hash_undefweak)
1077 continue;
1079 tsec = h->root.u.def.section;
1080 toff = h->root.u.def.value;
1083 symtype = h->type;
1086 if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
1088 /* At this stage in linking, no SEC_MERGE symbol has been
1089 adjusted, so all references to such symbols need to be
1090 passed through _bfd_merged_section_offset. (Later, in
1091 relocate_section, all SEC_MERGE symbols *except* for
1092 section symbols have been adjusted.)
1094 gas may reduce relocations against symbols in SEC_MERGE
1095 sections to a relocation against the section symbol when
1096 the original addend was zero. When the reloc is against
1097 a section symbol we should include the addend in the
1098 offset passed to _bfd_merged_section_offset, since the
1099 location of interest is the original symbol. On the
1100 other hand, an access to "sym+addend" where "sym" is not
1101 a section symbol should not include the addend; Such an
1102 access is presumed to be an offset from "sym"; The
1103 location of interest is just "sym". */
1104 if (symtype == STT_SECTION)
1105 toff += irel->r_addend;
1107 toff = _bfd_merged_section_offset (abfd, &tsec,
1108 elf_section_data (tsec)->sec_info,
1109 toff);
1111 if (symtype != STT_SECTION)
1112 toff += irel->r_addend;
1114 else
1115 toff += irel->r_addend;
1117 symaddr = tsec->output_section->vma + tsec->output_offset + toff;
1119 roff = irel->r_offset;
1121 if (is_branch)
1123 bfd_signed_vma offset;
1125 reladdr = (sec->output_section->vma
1126 + sec->output_offset
1127 + roff) & (bfd_vma) -4;
1129 /* If the branch is in range, no need to do anything. */
1130 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
1131 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
1133 /* If the 60-bit branch is in 21-bit range, optimize it. */
1134 if (r_type == R_IA64_PCREL60B)
1136 elfNN_ia64_relax_brl (contents, roff);
1138 irel->r_info
1139 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1140 R_IA64_PCREL21B);
1142 /* If the original relocation offset points to slot
1143 1, change it to slot 2. */
1144 if ((irel->r_offset & 3) == 1)
1145 irel->r_offset += 1;
1148 continue;
1150 else if (r_type == R_IA64_PCREL60B)
1151 continue;
1152 else if (elfNN_ia64_relax_br (contents, roff))
1154 irel->r_info
1155 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1156 R_IA64_PCREL60B);
1158 /* Make the relocation offset point to slot 1. */
1159 irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
1160 continue;
1163 /* We can't put a trampoline in a .init/.fini section. Issue
1164 an error. */
1165 if (strcmp (sec->output_section->name, ".init") == 0
1166 || strcmp (sec->output_section->name, ".fini") == 0)
1168 (*_bfd_error_handler)
1169 (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
1170 sec->owner, sec, (unsigned long) roff);
1171 bfd_set_error (bfd_error_bad_value);
1172 goto error_return;
1175 /* If the branch and target are in the same section, you've
1176 got one honking big section and we can't help you unless
1177 you are branching backwards. You'll get an error message
1178 later. */
1179 if (tsec == sec && toff > roff)
1180 continue;
1182 /* Look for an existing fixup to this address. */
1183 for (f = fixups; f ; f = f->next)
1184 if (f->tsec == tsec && f->toff == toff)
1185 break;
1187 if (f == NULL)
1189 /* Two alternatives: If it's a branch to a PLT entry, we can
1190 make a copy of the FULL_PLT entry. Otherwise, we'll have
1191 to use a `brl' insn to get where we're going. */
1193 size_t size;
1195 if (tsec == ia64_info->plt_sec)
1196 size = sizeof (plt_full_entry);
1197 else
1198 size = oor_branch_size;
1200 /* Resize the current section to make room for the new branch. */
1201 trampoff = (sec->size + 15) & (bfd_vma) -16;
1203 /* If trampoline is out of range, there is nothing we
1204 can do. */
1205 offset = trampoff - (roff & (bfd_vma) -4);
1206 if (offset < -0x1000000 || offset > 0x0FFFFF0)
1207 continue;
1209 amt = trampoff + size;
1210 contents = (bfd_byte *) bfd_realloc (contents, amt);
1211 if (contents == NULL)
1212 goto error_return;
1213 sec->size = amt;
1215 if (tsec == ia64_info->plt_sec)
1217 memcpy (contents + trampoff, plt_full_entry, size);
1219 /* Hijack the old relocation for use as the PLTOFF reloc. */
1220 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1221 R_IA64_PLTOFF22);
1222 irel->r_offset = trampoff;
1224 else
1226 if (size == sizeof (oor_ip))
1228 memcpy (contents + trampoff, oor_ip, size);
1229 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1230 R_IA64_PCREL64I);
1231 irel->r_addend -= 16;
1232 irel->r_offset = trampoff + 2;
1234 else
1236 memcpy (contents + trampoff, oor_brl, size);
1237 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1238 R_IA64_PCREL60B);
1239 irel->r_offset = trampoff + 2;
1244 /* Record the fixup so we don't do it again this section. */
1245 f = (struct one_fixup *)
1246 bfd_malloc ((bfd_size_type) sizeof (*f));
1247 f->next = fixups;
1248 f->tsec = tsec;
1249 f->toff = toff;
1250 f->trampoff = trampoff;
1251 fixups = f;
1253 else
1255 /* If trampoline is out of range, there is nothing we
1256 can do. */
1257 offset = f->trampoff - (roff & (bfd_vma) -4);
1258 if (offset < -0x1000000 || offset > 0x0FFFFF0)
1259 continue;
1261 /* Nop out the reloc, since we're finalizing things here. */
1262 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1265 /* Fix up the existing branch to hit the trampoline. */
1266 if (elfNN_ia64_install_value (contents + roff, offset, r_type)
1267 != bfd_reloc_ok)
1268 goto error_return;
1270 changed_contents = TRUE;
1271 changed_relocs = TRUE;
1273 else
1275 /* Fetch the gp. */
1276 if (gp == 0)
1278 bfd *obfd = sec->output_section->owner;
1279 gp = _bfd_get_gp_value (obfd);
1280 if (gp == 0)
1282 if (!elfNN_ia64_choose_gp (obfd, link_info))
1283 goto error_return;
1284 gp = _bfd_get_gp_value (obfd);
1288 /* If the data is out of range, do nothing. */
1289 if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
1290 ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
1291 continue;
1293 if (r_type == R_IA64_LTOFF22X)
1295 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1296 R_IA64_GPREL22);
1297 changed_relocs = TRUE;
1298 if (dyn_i->want_gotx)
1300 dyn_i->want_gotx = 0;
1301 changed_got |= !dyn_i->want_got;
1304 else
1306 elfNN_ia64_relax_ldxmov (contents, roff);
1307 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1308 changed_contents = TRUE;
1309 changed_relocs = TRUE;
1314 /* ??? If we created fixups, this may push the code segment large
1315 enough that the data segment moves, which will change the GP.
1316 Reset the GP so that we re-calculate next round. We need to
1317 do this at the _beginning_ of the next round; now will not do. */
1319 /* Clean up and go home. */
1320 while (fixups)
1322 struct one_fixup *f = fixups;
1323 fixups = fixups->next;
1324 free (f);
1327 if (isymbuf != NULL
1328 && symtab_hdr->contents != (unsigned char *) isymbuf)
1330 if (! link_info->keep_memory)
1331 free (isymbuf);
1332 else
1334 /* Cache the symbols for elf_link_input_bfd. */
1335 symtab_hdr->contents = (unsigned char *) isymbuf;
1339 if (contents != NULL
1340 && elf_section_data (sec)->this_hdr.contents != contents)
1342 if (!changed_contents && !link_info->keep_memory)
1343 free (contents);
1344 else
1346 /* Cache the section contents for elf_link_input_bfd. */
1347 elf_section_data (sec)->this_hdr.contents = contents;
1351 if (elf_section_data (sec)->relocs != internal_relocs)
1353 if (!changed_relocs)
1354 free (internal_relocs);
1355 else
1356 elf_section_data (sec)->relocs = internal_relocs;
1359 if (changed_got)
1361 struct elfNN_ia64_allocate_data data;
1362 data.info = link_info;
1363 data.ofs = 0;
1364 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
1366 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
1367 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
1368 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
1369 ia64_info->got_sec->size = data.ofs;
1371 if (ia64_info->root.dynamic_sections_created
1372 && ia64_info->rel_got_sec != NULL)
1374 /* Resize .rela.got. */
1375 ia64_info->rel_got_sec->size = 0;
1376 if (link_info->shared
1377 && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
1378 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
1379 data.only_got = TRUE;
1380 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
1381 &data);
1385 if (link_info->relax_pass == 0)
1387 /* Pass 0 is only needed to relax br. */
1388 sec->skip_relax_pass_0 = skip_relax_pass_0;
1389 sec->skip_relax_pass_1 = skip_relax_pass_1;
1392 *again = changed_contents || changed_relocs;
1393 return TRUE;
1395 error_return:
1396 if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
1397 free (isymbuf);
1398 if (contents != NULL
1399 && elf_section_data (sec)->this_hdr.contents != contents)
1400 free (contents);
1401 if (internal_relocs != NULL
1402 && elf_section_data (sec)->relocs != internal_relocs)
1403 free (internal_relocs);
1404 return FALSE;
1406 #undef skip_relax_pass_0
1407 #undef skip_relax_pass_1
1409 static void
1410 elfNN_ia64_relax_ldxmov (contents, off)
1411 bfd_byte *contents;
1412 bfd_vma off;
1414 int shift, r1, r3;
1415 bfd_vma dword, insn;
1417 switch ((int)off & 0x3)
1419 case 0: shift = 5; break;
1420 case 1: shift = 14; off += 3; break;
1421 case 2: shift = 23; off += 6; break;
1422 default:
1423 abort ();
1426 dword = bfd_getl64 (contents + off);
1427 insn = (dword >> shift) & 0x1ffffffffffLL;
1429 r1 = (insn >> 6) & 127;
1430 r3 = (insn >> 20) & 127;
1431 if (r1 == r3)
1432 insn = 0x8000000; /* nop */
1433 else
1434 insn = (insn & 0x7f01fff) | 0x10800000000LL; /* (qp) mov r1 = r3 */
1436 dword &= ~(0x1ffffffffffLL << shift);
1437 dword |= (insn << shift);
1438 bfd_putl64 (dword, contents + off);
1441 /* Return TRUE if NAME is an unwind table section name. */
1443 static inline bfd_boolean
1444 is_unwind_section_name (bfd *abfd, const char *name)
1446 if (elfNN_ia64_hpux_vec (abfd->xvec)
1447 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
1448 return FALSE;
1450 return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
1451 && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
1452 || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
1455 /* Handle an IA-64 specific section when reading an object file. This
1456 is called when bfd_section_from_shdr finds a section with an unknown
1457 type. */
1459 static bfd_boolean
1460 elfNN_ia64_section_from_shdr (bfd *abfd,
1461 Elf_Internal_Shdr *hdr,
1462 const char *name,
1463 int shindex)
1465 asection *newsect;
1467 /* There ought to be a place to keep ELF backend specific flags, but
1468 at the moment there isn't one. We just keep track of the
1469 sections by their name, instead. Fortunately, the ABI gives
1470 suggested names for all the MIPS specific sections, so we will
1471 probably get away with this. */
1472 switch (hdr->sh_type)
1474 case SHT_IA_64_UNWIND:
1475 case SHT_IA_64_HP_OPT_ANOT:
1476 break;
1478 case SHT_IA_64_EXT:
1479 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1480 return FALSE;
1481 break;
1483 default:
1484 return FALSE;
1487 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
1488 return FALSE;
1489 newsect = hdr->bfd_section;
1491 return TRUE;
1494 /* Convert IA-64 specific section flags to bfd internal section flags. */
1496 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1497 flag. */
1499 static bfd_boolean
1500 elfNN_ia64_section_flags (flags, hdr)
1501 flagword *flags;
1502 const Elf_Internal_Shdr *hdr;
1504 if (hdr->sh_flags & SHF_IA_64_SHORT)
1505 *flags |= SEC_SMALL_DATA;
1507 return TRUE;
1510 /* Set the correct type for an IA-64 ELF section. We do this by the
1511 section name, which is a hack, but ought to work. */
1513 static bfd_boolean
1514 elfNN_ia64_fake_sections (abfd, hdr, sec)
1515 bfd *abfd ATTRIBUTE_UNUSED;
1516 Elf_Internal_Shdr *hdr;
1517 asection *sec;
1519 register const char *name;
1521 name = bfd_get_section_name (abfd, sec);
1523 if (is_unwind_section_name (abfd, name))
1525 /* We don't have the sections numbered at this point, so sh_info
1526 is set later, in elfNN_ia64_final_write_processing. */
1527 hdr->sh_type = SHT_IA_64_UNWIND;
1528 hdr->sh_flags |= SHF_LINK_ORDER;
1530 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1531 hdr->sh_type = SHT_IA_64_EXT;
1532 else if (strcmp (name, ".HP.opt_annot") == 0)
1533 hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
1534 else if (strcmp (name, ".reloc") == 0)
1535 /* This is an ugly, but unfortunately necessary hack that is
1536 needed when producing EFI binaries on IA-64. It tells
1537 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1538 containing ELF relocation info. We need this hack in order to
1539 be able to generate ELF binaries that can be translated into
1540 EFI applications (which are essentially COFF objects). Those
1541 files contain a COFF ".reloc" section inside an ELFNN object,
1542 which would normally cause BFD to segfault because it would
1543 attempt to interpret this section as containing relocation
1544 entries for section "oc". With this hack enabled, ".reloc"
1545 will be treated as a normal data section, which will avoid the
1546 segfault. However, you won't be able to create an ELFNN binary
1547 with a section named "oc" that needs relocations, but that's
1548 the kind of ugly side-effects you get when detecting section
1549 types based on their names... In practice, this limitation is
1550 unlikely to bite. */
1551 hdr->sh_type = SHT_PROGBITS;
1553 if (sec->flags & SEC_SMALL_DATA)
1554 hdr->sh_flags |= SHF_IA_64_SHORT;
1556 /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
1558 if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
1559 hdr->sh_flags |= SHF_IA_64_HP_TLS;
1561 return TRUE;
1564 /* The final processing done just before writing out an IA-64 ELF
1565 object file. */
1567 static void
1568 elfNN_ia64_final_write_processing (abfd, linker)
1569 bfd *abfd;
1570 bfd_boolean linker ATTRIBUTE_UNUSED;
1572 Elf_Internal_Shdr *hdr;
1573 asection *s;
1575 for (s = abfd->sections; s; s = s->next)
1577 hdr = &elf_section_data (s)->this_hdr;
1578 switch (hdr->sh_type)
1580 case SHT_IA_64_UNWIND:
1581 /* The IA-64 processor-specific ABI requires setting sh_link
1582 to the unwind section, whereas HP-UX requires sh_info to
1583 do so. For maximum compatibility, we'll set both for
1584 now... */
1585 hdr->sh_info = hdr->sh_link;
1586 break;
1590 if (! elf_flags_init (abfd))
1592 unsigned long flags = 0;
1594 if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
1595 flags |= EF_IA_64_BE;
1596 if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
1597 flags |= EF_IA_64_ABI64;
1599 elf_elfheader(abfd)->e_flags = flags;
1600 elf_flags_init (abfd) = TRUE;
1604 /* Hook called by the linker routine which adds symbols from an object
1605 file. We use it to put .comm items in .sbss, and not .bss. */
1607 static bfd_boolean
1608 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1609 bfd *abfd;
1610 struct bfd_link_info *info;
1611 Elf_Internal_Sym *sym;
1612 const char **namep ATTRIBUTE_UNUSED;
1613 flagword *flagsp ATTRIBUTE_UNUSED;
1614 asection **secp;
1615 bfd_vma *valp;
1617 if (sym->st_shndx == SHN_COMMON
1618 && !info->relocatable
1619 && sym->st_size <= elf_gp_size (abfd))
1621 /* Common symbols less than or equal to -G nn bytes are
1622 automatically put into .sbss. */
1624 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1626 if (scomm == NULL)
1628 scomm = bfd_make_section_with_flags (abfd, ".scommon",
1629 (SEC_ALLOC
1630 | SEC_IS_COMMON
1631 | SEC_LINKER_CREATED));
1632 if (scomm == NULL)
1633 return FALSE;
1636 *secp = scomm;
1637 *valp = sym->st_size;
1640 return TRUE;
1643 /* Return the number of additional phdrs we will need. */
1645 static int
1646 elfNN_ia64_additional_program_headers (bfd *abfd,
1647 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1649 asection *s;
1650 int ret = 0;
1652 /* See if we need a PT_IA_64_ARCHEXT segment. */
1653 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1654 if (s && (s->flags & SEC_LOAD))
1655 ++ret;
1657 /* Count how many PT_IA_64_UNWIND segments we need. */
1658 for (s = abfd->sections; s; s = s->next)
1659 if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1660 ++ret;
1662 return ret;
1665 static bfd_boolean
1666 elfNN_ia64_modify_segment_map (bfd *abfd,
1667 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1669 struct elf_segment_map *m, **pm;
1670 Elf_Internal_Shdr *hdr;
1671 asection *s;
1673 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1674 all PT_LOAD segments. */
1675 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1676 if (s && (s->flags & SEC_LOAD))
1678 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1679 if (m->p_type == PT_IA_64_ARCHEXT)
1680 break;
1681 if (m == NULL)
1683 m = ((struct elf_segment_map *)
1684 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1685 if (m == NULL)
1686 return FALSE;
1688 m->p_type = PT_IA_64_ARCHEXT;
1689 m->count = 1;
1690 m->sections[0] = s;
1692 /* We want to put it after the PHDR and INTERP segments. */
1693 pm = &elf_tdata (abfd)->segment_map;
1694 while (*pm != NULL
1695 && ((*pm)->p_type == PT_PHDR
1696 || (*pm)->p_type == PT_INTERP))
1697 pm = &(*pm)->next;
1699 m->next = *pm;
1700 *pm = m;
1704 /* Install PT_IA_64_UNWIND segments, if needed. */
1705 for (s = abfd->sections; s; s = s->next)
1707 hdr = &elf_section_data (s)->this_hdr;
1708 if (hdr->sh_type != SHT_IA_64_UNWIND)
1709 continue;
1711 if (s && (s->flags & SEC_LOAD))
1713 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1714 if (m->p_type == PT_IA_64_UNWIND)
1716 int i;
1718 /* Look through all sections in the unwind segment
1719 for a match since there may be multiple sections
1720 to a segment. */
1721 for (i = m->count - 1; i >= 0; --i)
1722 if (m->sections[i] == s)
1723 break;
1725 if (i >= 0)
1726 break;
1729 if (m == NULL)
1731 m = ((struct elf_segment_map *)
1732 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1733 if (m == NULL)
1734 return FALSE;
1736 m->p_type = PT_IA_64_UNWIND;
1737 m->count = 1;
1738 m->sections[0] = s;
1739 m->next = NULL;
1741 /* We want to put it last. */
1742 pm = &elf_tdata (abfd)->segment_map;
1743 while (*pm != NULL)
1744 pm = &(*pm)->next;
1745 *pm = m;
1750 return TRUE;
1753 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1754 the input sections for each output section in the segment and testing
1755 for SHF_IA_64_NORECOV on each. */
1757 static bfd_boolean
1758 elfNN_ia64_modify_program_headers (bfd *abfd,
1759 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1761 struct elf_obj_tdata *tdata = elf_tdata (abfd);
1762 struct elf_segment_map *m;
1763 Elf_Internal_Phdr *p;
1765 for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
1766 if (m->p_type == PT_LOAD)
1768 int i;
1769 for (i = m->count - 1; i >= 0; --i)
1771 struct bfd_link_order *order = m->sections[i]->map_head.link_order;
1773 while (order != NULL)
1775 if (order->type == bfd_indirect_link_order)
1777 asection *is = order->u.indirect.section;
1778 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1779 if (flags & SHF_IA_64_NORECOV)
1781 p->p_flags |= PF_IA_64_NORECOV;
1782 goto found;
1785 order = order->next;
1788 found:;
1791 return TRUE;
1794 /* According to the Tahoe assembler spec, all labels starting with a
1795 '.' are local. */
1797 static bfd_boolean
1798 elfNN_ia64_is_local_label_name (abfd, name)
1799 bfd *abfd ATTRIBUTE_UNUSED;
1800 const char *name;
1802 return name[0] == '.';
1805 /* Should we do dynamic things to this symbol? */
1807 static bfd_boolean
1808 elfNN_ia64_dynamic_symbol_p (h, info, r_type)
1809 struct elf_link_hash_entry *h;
1810 struct bfd_link_info *info;
1811 int r_type;
1813 bfd_boolean ignore_protected
1814 = ((r_type & 0xf8) == 0x40 /* FPTR relocs */
1815 || (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */
1817 return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
1820 static struct bfd_hash_entry*
1821 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1822 struct bfd_hash_entry *entry;
1823 struct bfd_hash_table *table;
1824 const char *string;
1826 struct elfNN_ia64_link_hash_entry *ret;
1827 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1829 /* Allocate the structure if it has not already been allocated by a
1830 subclass. */
1831 if (!ret)
1832 ret = bfd_hash_allocate (table, sizeof (*ret));
1834 if (!ret)
1835 return 0;
1837 /* Call the allocation method of the superclass. */
1838 ret = ((struct elfNN_ia64_link_hash_entry *)
1839 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1840 table, string));
1842 ret->info = NULL;
1843 ret->count = 0;
1844 ret->sorted_count = 0;
1845 ret->size = 0;
1846 return (struct bfd_hash_entry *) ret;
1849 static void
1850 elfNN_ia64_hash_copy_indirect (info, xdir, xind)
1851 struct bfd_link_info *info;
1852 struct elf_link_hash_entry *xdir, *xind;
1854 struct elfNN_ia64_link_hash_entry *dir, *ind;
1856 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1857 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1859 /* Copy down any references that we may have already seen to the
1860 symbol which just became indirect. */
1862 dir->root.ref_dynamic |= ind->root.ref_dynamic;
1863 dir->root.ref_regular |= ind->root.ref_regular;
1864 dir->root.ref_regular_nonweak |= ind->root.ref_regular_nonweak;
1865 dir->root.needs_plt |= ind->root.needs_plt;
1867 if (ind->root.root.type != bfd_link_hash_indirect)
1868 return;
1870 /* Copy over the got and plt data. This would have been done
1871 by check_relocs. */
1873 if (ind->info != NULL)
1875 struct elfNN_ia64_dyn_sym_info *dyn_i;
1876 unsigned int count;
1878 if (dir->info)
1879 free (dir->info);
1881 dir->info = ind->info;
1882 dir->count = ind->count;
1883 dir->sorted_count = ind->sorted_count;
1884 dir->size = ind->size;
1886 ind->info = NULL;
1887 ind->count = 0;
1888 ind->sorted_count = 0;
1889 ind->size = 0;
1891 /* Fix up the dyn_sym_info pointers to the global symbol. */
1892 for (count = dir->count, dyn_i = dir->info;
1893 count != 0;
1894 count--, dyn_i++)
1895 dyn_i->h = &dir->root;
1898 /* Copy over the dynindx. */
1900 if (ind->root.dynindx != -1)
1902 if (dir->root.dynindx != -1)
1903 _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
1904 dir->root.dynstr_index);
1905 dir->root.dynindx = ind->root.dynindx;
1906 dir->root.dynstr_index = ind->root.dynstr_index;
1907 ind->root.dynindx = -1;
1908 ind->root.dynstr_index = 0;
1912 static void
1913 elfNN_ia64_hash_hide_symbol (info, xh, force_local)
1914 struct bfd_link_info *info;
1915 struct elf_link_hash_entry *xh;
1916 bfd_boolean force_local;
1918 struct elfNN_ia64_link_hash_entry *h;
1919 struct elfNN_ia64_dyn_sym_info *dyn_i;
1920 unsigned int count;
1922 h = (struct elfNN_ia64_link_hash_entry *)xh;
1924 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1926 for (count = h->count, dyn_i = h->info;
1927 count != 0;
1928 count--, dyn_i++)
1930 dyn_i->want_plt2 = 0;
1931 dyn_i->want_plt = 0;
1935 /* Compute a hash of a local hash entry. */
1937 static hashval_t
1938 elfNN_ia64_local_htab_hash (ptr)
1939 const void *ptr;
1941 struct elfNN_ia64_local_hash_entry *entry
1942 = (struct elfNN_ia64_local_hash_entry *) ptr;
1944 return (((entry->id & 0xff) << 24) | ((entry->id & 0xff00) << 8))
1945 ^ entry->r_sym ^ (entry->id >> 16);
1948 /* Compare local hash entries. */
1950 static int
1951 elfNN_ia64_local_htab_eq (ptr1, ptr2)
1952 const void *ptr1, *ptr2;
1954 struct elfNN_ia64_local_hash_entry *entry1
1955 = (struct elfNN_ia64_local_hash_entry *) ptr1;
1956 struct elfNN_ia64_local_hash_entry *entry2
1957 = (struct elfNN_ia64_local_hash_entry *) ptr2;
1959 return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
1962 /* Create the derived linker hash table. The IA-64 ELF port uses this
1963 derived hash table to keep information specific to the IA-64 ElF
1964 linker (without using static variables). */
1966 static struct bfd_link_hash_table*
1967 elfNN_ia64_hash_table_create (abfd)
1968 bfd *abfd;
1970 struct elfNN_ia64_link_hash_table *ret;
1972 ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
1973 if (!ret)
1974 return 0;
1976 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1977 elfNN_ia64_new_elf_hash_entry,
1978 sizeof (struct elfNN_ia64_link_hash_entry)))
1980 free (ret);
1981 return 0;
1984 ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
1985 elfNN_ia64_local_htab_eq, NULL);
1986 ret->loc_hash_memory = objalloc_create ();
1987 if (!ret->loc_hash_table || !ret->loc_hash_memory)
1989 free (ret);
1990 return 0;
1993 return &ret->root.root;
1996 /* Free the global elfNN_ia64_dyn_sym_info array. */
1998 static bfd_boolean
1999 elfNN_ia64_global_dyn_info_free (void **xentry,
2000 PTR unused ATTRIBUTE_UNUSED)
2002 struct elfNN_ia64_link_hash_entry *entry
2003 = (struct elfNN_ia64_link_hash_entry *) xentry;
2005 if (entry->root.root.type == bfd_link_hash_warning)
2006 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
2008 if (entry->info)
2010 free (entry->info);
2011 entry->info = NULL;
2012 entry->count = 0;
2013 entry->sorted_count = 0;
2014 entry->size = 0;
2017 return TRUE;
2020 /* Free the local elfNN_ia64_dyn_sym_info array. */
2022 static bfd_boolean
2023 elfNN_ia64_local_dyn_info_free (void **slot,
2024 PTR unused ATTRIBUTE_UNUSED)
2026 struct elfNN_ia64_local_hash_entry *entry
2027 = (struct elfNN_ia64_local_hash_entry *) *slot;
2029 if (entry->info)
2031 free (entry->info);
2032 entry->info = NULL;
2033 entry->count = 0;
2034 entry->sorted_count = 0;
2035 entry->size = 0;
2038 return TRUE;
2041 /* Destroy IA-64 linker hash table. */
2043 static void
2044 elfNN_ia64_hash_table_free (hash)
2045 struct bfd_link_hash_table *hash;
2047 struct elfNN_ia64_link_hash_table *ia64_info
2048 = (struct elfNN_ia64_link_hash_table *) hash;
2049 if (ia64_info->loc_hash_table)
2051 htab_traverse (ia64_info->loc_hash_table,
2052 elfNN_ia64_local_dyn_info_free, NULL);
2053 htab_delete (ia64_info->loc_hash_table);
2055 if (ia64_info->loc_hash_memory)
2056 objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
2057 elf_link_hash_traverse (&ia64_info->root,
2058 elfNN_ia64_global_dyn_info_free, NULL);
2059 _bfd_generic_link_hash_table_free (hash);
2062 /* Traverse both local and global hash tables. */
2064 struct elfNN_ia64_dyn_sym_traverse_data
2066 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
2067 PTR data;
2070 static bfd_boolean
2071 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
2072 struct bfd_hash_entry *xentry;
2073 PTR xdata;
2075 struct elfNN_ia64_link_hash_entry *entry
2076 = (struct elfNN_ia64_link_hash_entry *) xentry;
2077 struct elfNN_ia64_dyn_sym_traverse_data *data
2078 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
2079 struct elfNN_ia64_dyn_sym_info *dyn_i;
2080 unsigned int count;
2082 if (entry->root.root.type == bfd_link_hash_warning)
2083 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
2085 for (count = entry->count, dyn_i = entry->info;
2086 count != 0;
2087 count--, dyn_i++)
2088 if (! (*data->func) (dyn_i, data->data))
2089 return FALSE;
2090 return TRUE;
2093 static bfd_boolean
2094 elfNN_ia64_local_dyn_sym_thunk (slot, xdata)
2095 void **slot;
2096 PTR xdata;
2098 struct elfNN_ia64_local_hash_entry *entry
2099 = (struct elfNN_ia64_local_hash_entry *) *slot;
2100 struct elfNN_ia64_dyn_sym_traverse_data *data
2101 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
2102 struct elfNN_ia64_dyn_sym_info *dyn_i;
2103 unsigned int count;
2105 for (count = entry->count, dyn_i = entry->info;
2106 count != 0;
2107 count--, dyn_i++)
2108 if (! (*data->func) (dyn_i, data->data))
2109 return FALSE;
2110 return TRUE;
2113 static void
2114 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
2115 struct elfNN_ia64_link_hash_table *ia64_info;
2116 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
2117 PTR data;
2119 struct elfNN_ia64_dyn_sym_traverse_data xdata;
2121 xdata.func = func;
2122 xdata.data = data;
2124 elf_link_hash_traverse (&ia64_info->root,
2125 elfNN_ia64_global_dyn_sym_thunk, &xdata);
2126 htab_traverse (ia64_info->loc_hash_table,
2127 elfNN_ia64_local_dyn_sym_thunk, &xdata);
2130 static bfd_boolean
2131 elfNN_ia64_create_dynamic_sections (abfd, info)
2132 bfd *abfd;
2133 struct bfd_link_info *info;
2135 struct elfNN_ia64_link_hash_table *ia64_info;
2136 asection *s;
2138 if (! _bfd_elf_create_dynamic_sections (abfd, info))
2139 return FALSE;
2141 ia64_info = elfNN_ia64_hash_table (info);
2143 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
2144 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
2147 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
2148 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
2149 /* The .got section is always aligned at 8 bytes. */
2150 bfd_set_section_alignment (abfd, ia64_info->got_sec, 3);
2153 if (!get_pltoff (abfd, info, ia64_info))
2154 return FALSE;
2156 s = bfd_make_section_with_flags (abfd, ".rela.IA_64.pltoff",
2157 (SEC_ALLOC | SEC_LOAD
2158 | SEC_HAS_CONTENTS
2159 | SEC_IN_MEMORY
2160 | SEC_LINKER_CREATED
2161 | SEC_READONLY));
2162 if (s == NULL
2163 || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
2164 return FALSE;
2165 ia64_info->rel_pltoff_sec = s;
2167 s = bfd_make_section_with_flags (abfd, ".rela.got",
2168 (SEC_ALLOC | SEC_LOAD
2169 | SEC_HAS_CONTENTS
2170 | SEC_IN_MEMORY
2171 | SEC_LINKER_CREATED
2172 | SEC_READONLY));
2173 if (s == NULL
2174 || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
2175 return FALSE;
2176 ia64_info->rel_got_sec = s;
2178 return TRUE;
2181 /* Find and/or create a hash entry for local symbol. */
2182 static struct elfNN_ia64_local_hash_entry *
2183 get_local_sym_hash (ia64_info, abfd, rel, create)
2184 struct elfNN_ia64_link_hash_table *ia64_info;
2185 bfd *abfd;
2186 const Elf_Internal_Rela *rel;
2187 bfd_boolean create;
2189 struct elfNN_ia64_local_hash_entry e, *ret;
2190 asection *sec = abfd->sections;
2191 hashval_t h = (((sec->id & 0xff) << 24) | ((sec->id & 0xff00) << 8))
2192 ^ ELFNN_R_SYM (rel->r_info) ^ (sec->id >> 16);
2193 void **slot;
2195 e.id = sec->id;
2196 e.r_sym = ELFNN_R_SYM (rel->r_info);
2197 slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
2198 create ? INSERT : NO_INSERT);
2200 if (!slot)
2201 return NULL;
2203 if (*slot)
2204 return (struct elfNN_ia64_local_hash_entry *) *slot;
2206 ret = (struct elfNN_ia64_local_hash_entry *)
2207 objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
2208 sizeof (struct elfNN_ia64_local_hash_entry));
2209 if (ret)
2211 memset (ret, 0, sizeof (*ret));
2212 ret->id = sec->id;
2213 ret->r_sym = ELFNN_R_SYM (rel->r_info);
2214 *slot = ret;
2216 return ret;
2219 /* Used to sort elfNN_ia64_dyn_sym_info array. */
2221 static int
2222 addend_compare (const void *xp, const void *yp)
2224 const struct elfNN_ia64_dyn_sym_info *x
2225 = (const struct elfNN_ia64_dyn_sym_info *) xp;
2226 const struct elfNN_ia64_dyn_sym_info *y
2227 = (const struct elfNN_ia64_dyn_sym_info *) yp;
2229 return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
2232 /* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
2234 static unsigned int
2235 sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
2236 unsigned int count)
2238 bfd_vma curr, prev, got_offset;
2239 unsigned int i, kept, dup, diff, dest, src, len;
2241 qsort (info, count, sizeof (*info), addend_compare);
2243 /* Find the first duplicate. */
2244 prev = info [0].addend;
2245 got_offset = info [0].got_offset;
2246 for (i = 1; i < count; i++)
2248 curr = info [i].addend;
2249 if (curr == prev)
2251 /* For duplicates, make sure that GOT_OFFSET is valid. */
2252 if (got_offset == (bfd_vma) -1)
2253 got_offset = info [i].got_offset;
2254 break;
2256 got_offset = info [i].got_offset;
2257 prev = curr;
2260 /* We may move a block of elements to here. */
2261 dest = i++;
2263 /* Remove duplicates. */
2264 if (i < count)
2266 while (i < count)
2268 /* For duplicates, make sure that the kept one has a valid
2269 got_offset. */
2270 kept = dest - 1;
2271 if (got_offset != (bfd_vma) -1)
2272 info [kept].got_offset = got_offset;
2274 curr = info [i].addend;
2275 got_offset = info [i].got_offset;
2277 /* Move a block of elements whose first one is different from
2278 the previous. */
2279 if (curr == prev)
2281 for (src = i + 1; src < count; src++)
2283 if (info [src].addend != curr)
2284 break;
2285 /* For duplicates, make sure that GOT_OFFSET is
2286 valid. */
2287 if (got_offset == (bfd_vma) -1)
2288 got_offset = info [src].got_offset;
2291 /* Make sure that the kept one has a valid got_offset. */
2292 if (got_offset != (bfd_vma) -1)
2293 info [kept].got_offset = got_offset;
2295 else
2296 src = i;
2298 if (src >= count)
2299 break;
2301 /* Find the next duplicate. SRC will be kept. */
2302 prev = info [src].addend;
2303 got_offset = info [src].got_offset;
2304 for (dup = src + 1; dup < count; dup++)
2306 curr = info [dup].addend;
2307 if (curr == prev)
2309 /* Make sure that got_offset is valid. */
2310 if (got_offset == (bfd_vma) -1)
2311 got_offset = info [dup].got_offset;
2313 /* For duplicates, make sure that the kept one has
2314 a valid got_offset. */
2315 if (got_offset != (bfd_vma) -1)
2316 info [dup - 1].got_offset = got_offset;
2317 break;
2319 got_offset = info [dup].got_offset;
2320 prev = curr;
2323 /* How much to move. */
2324 len = dup - src;
2325 i = dup + 1;
2327 if (len == 1 && dup < count)
2329 /* If we only move 1 element, we combine it with the next
2330 one. There must be at least a duplicate. Find the
2331 next different one. */
2332 for (diff = dup + 1, src++; diff < count; diff++, src++)
2334 if (info [diff].addend != curr)
2335 break;
2336 /* Make sure that got_offset is valid. */
2337 if (got_offset == (bfd_vma) -1)
2338 got_offset = info [diff].got_offset;
2341 /* Makre sure that the last duplicated one has an valid
2342 offset. */
2343 BFD_ASSERT (curr == prev);
2344 if (got_offset != (bfd_vma) -1)
2345 info [diff - 1].got_offset = got_offset;
2347 if (diff < count)
2349 /* Find the next duplicate. Track the current valid
2350 offset. */
2351 prev = info [diff].addend;
2352 got_offset = info [diff].got_offset;
2353 for (dup = diff + 1; dup < count; dup++)
2355 curr = info [dup].addend;
2356 if (curr == prev)
2358 /* For duplicates, make sure that GOT_OFFSET
2359 is valid. */
2360 if (got_offset == (bfd_vma) -1)
2361 got_offset = info [dup].got_offset;
2362 break;
2364 got_offset = info [dup].got_offset;
2365 prev = curr;
2366 diff++;
2369 len = diff - src + 1;
2370 i = diff + 1;
2374 memmove (&info [dest], &info [src], len * sizeof (*info));
2376 dest += len;
2379 count = dest;
2381 else
2383 /* When we get here, either there is no duplicate at all or
2384 the only duplicate is the last element. */
2385 if (dest < count)
2387 /* If the last element is a duplicate, make sure that the
2388 kept one has a valid got_offset. We also update count. */
2389 if (got_offset != (bfd_vma) -1)
2390 info [dest - 1].got_offset = got_offset;
2391 count = dest;
2395 return count;
2398 /* Find and/or create a descriptor for dynamic symbol info. This will
2399 vary based on global or local symbol, and the addend to the reloc.
2401 We don't sort when inserting. Also, we sort and eliminate
2402 duplicates if there is an unsorted section. Typically, this will
2403 only happen once, because we do all insertions before lookups. We
2404 then use bsearch to do a lookup. This also allows lookups to be
2405 fast. So we have fast insertion (O(log N) due to duplicate check),
2406 fast lookup (O(log N)) and one sort (O(N log N) expected time).
2407 Previously, all lookups were O(N) because of the use of the linked
2408 list and also all insertions were O(N) because of the check for
2409 duplicates. There are some complications here because the array
2410 size grows occasionally, which may add an O(N) factor, but this
2411 should be rare. Also, we free the excess array allocation, which
2412 requires a copy which is O(N), but this only happens once. */
2414 static struct elfNN_ia64_dyn_sym_info *
2415 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
2416 struct elfNN_ia64_link_hash_table *ia64_info;
2417 struct elf_link_hash_entry *h;
2418 bfd *abfd;
2419 const Elf_Internal_Rela *rel;
2420 bfd_boolean create;
2422 struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
2423 unsigned int *count_p, *sorted_count_p, *size_p;
2424 unsigned int count, sorted_count, size;
2425 bfd_vma addend = rel ? rel->r_addend : 0;
2426 bfd_size_type amt;
2428 if (h)
2430 struct elfNN_ia64_link_hash_entry *global_h;
2432 global_h = (struct elfNN_ia64_link_hash_entry *) h;
2433 info_p = &global_h->info;
2434 count_p = &global_h->count;
2435 sorted_count_p = &global_h->sorted_count;
2436 size_p = &global_h->size;
2438 else
2440 struct elfNN_ia64_local_hash_entry *loc_h;
2442 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
2443 if (!loc_h)
2445 BFD_ASSERT (!create);
2446 return NULL;
2449 info_p = &loc_h->info;
2450 count_p = &loc_h->count;
2451 sorted_count_p = &loc_h->sorted_count;
2452 size_p = &loc_h->size;
2455 count = *count_p;
2456 sorted_count = *sorted_count_p;
2457 size = *size_p;
2458 info = *info_p;
2459 if (create)
2461 /* When we create the array, we don't check for duplicates,
2462 except in the previously sorted section if one exists, and
2463 against the last inserted entry. This allows insertions to
2464 be fast. */
2465 if (info)
2467 if (sorted_count)
2469 /* Try bsearch first on the sorted section. */
2470 key.addend = addend;
2471 dyn_i = bsearch (&key, info, sorted_count,
2472 sizeof (*info), addend_compare);
2474 if (dyn_i)
2476 return dyn_i;
2480 /* Do a quick check for the last inserted entry. */
2481 dyn_i = info + count - 1;
2482 if (dyn_i->addend == addend)
2484 return dyn_i;
2488 if (size == 0)
2490 /* It is the very first element. We create the array of size
2491 1. */
2492 size = 1;
2493 amt = size * sizeof (*info);
2494 info = bfd_malloc (amt);
2496 else if (size <= count)
2498 /* We double the array size every time when we reach the
2499 size limit. */
2500 size += size;
2501 amt = size * sizeof (*info);
2502 info = bfd_realloc (info, amt);
2504 else
2505 goto has_space;
2507 if (info == NULL)
2508 return NULL;
2509 *size_p = size;
2510 *info_p = info;
2512 has_space:
2513 /* Append the new one to the array. */
2514 dyn_i = info + count;
2515 memset (dyn_i, 0, sizeof (*dyn_i));
2516 dyn_i->got_offset = (bfd_vma) -1;
2517 dyn_i->addend = addend;
2519 /* We increment count only since the new ones are unsorted and
2520 may have duplicate. */
2521 (*count_p)++;
2523 else
2525 /* It is a lookup without insertion. Sort array if part of the
2526 array isn't sorted. */
2527 if (count != sorted_count)
2529 count = sort_dyn_sym_info (info, count);
2530 *count_p = count;
2531 *sorted_count_p = count;
2534 /* Free unused memory. */
2535 if (size != count)
2537 amt = count * sizeof (*info);
2538 info = bfd_malloc (amt);
2539 if (info != NULL)
2541 memcpy (info, *info_p, amt);
2542 free (*info_p);
2543 *size_p = count;
2544 *info_p = info;
2548 key.addend = addend;
2549 dyn_i = bsearch (&key, info, count,
2550 sizeof (*info), addend_compare);
2553 return dyn_i;
2556 static asection *
2557 get_got (abfd, info, ia64_info)
2558 bfd *abfd;
2559 struct bfd_link_info *info;
2560 struct elfNN_ia64_link_hash_table *ia64_info;
2562 asection *got;
2563 bfd *dynobj;
2565 got = ia64_info->got_sec;
2566 if (!got)
2568 flagword flags;
2570 dynobj = ia64_info->root.dynobj;
2571 if (!dynobj)
2572 ia64_info->root.dynobj = dynobj = abfd;
2573 if (!_bfd_elf_create_got_section (dynobj, info))
2574 return 0;
2576 got = bfd_get_section_by_name (dynobj, ".got");
2577 BFD_ASSERT (got);
2578 ia64_info->got_sec = got;
2580 /* The .got section is always aligned at 8 bytes. */
2581 if (!bfd_set_section_alignment (abfd, got, 3))
2582 return 0;
2584 flags = bfd_get_section_flags (abfd, got);
2585 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2588 return got;
2591 /* Create function descriptor section (.opd). This section is called .opd
2592 because it contains "official procedure descriptors". The "official"
2593 refers to the fact that these descriptors are used when taking the address
2594 of a procedure, thus ensuring a unique address for each procedure. */
2596 static asection *
2597 get_fptr (abfd, info, ia64_info)
2598 bfd *abfd;
2599 struct bfd_link_info *info;
2600 struct elfNN_ia64_link_hash_table *ia64_info;
2602 asection *fptr;
2603 bfd *dynobj;
2605 fptr = ia64_info->fptr_sec;
2606 if (!fptr)
2608 dynobj = ia64_info->root.dynobj;
2609 if (!dynobj)
2610 ia64_info->root.dynobj = dynobj = abfd;
2612 fptr = bfd_make_section_with_flags (dynobj, ".opd",
2613 (SEC_ALLOC
2614 | SEC_LOAD
2615 | SEC_HAS_CONTENTS
2616 | SEC_IN_MEMORY
2617 | (info->pie ? 0 : SEC_READONLY)
2618 | SEC_LINKER_CREATED));
2619 if (!fptr
2620 || !bfd_set_section_alignment (abfd, fptr, 4))
2622 BFD_ASSERT (0);
2623 return NULL;
2626 ia64_info->fptr_sec = fptr;
2628 if (info->pie)
2630 asection *fptr_rel;
2631 fptr_rel = bfd_make_section_with_flags (dynobj, ".rela.opd",
2632 (SEC_ALLOC | SEC_LOAD
2633 | SEC_HAS_CONTENTS
2634 | SEC_IN_MEMORY
2635 | SEC_LINKER_CREATED
2636 | SEC_READONLY));
2637 if (fptr_rel == NULL
2638 || !bfd_set_section_alignment (abfd, fptr_rel,
2639 LOG_SECTION_ALIGN))
2641 BFD_ASSERT (0);
2642 return NULL;
2645 ia64_info->rel_fptr_sec = fptr_rel;
2649 return fptr;
2652 static asection *
2653 get_pltoff (abfd, info, ia64_info)
2654 bfd *abfd;
2655 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2656 struct elfNN_ia64_link_hash_table *ia64_info;
2658 asection *pltoff;
2659 bfd *dynobj;
2661 pltoff = ia64_info->pltoff_sec;
2662 if (!pltoff)
2664 dynobj = ia64_info->root.dynobj;
2665 if (!dynobj)
2666 ia64_info->root.dynobj = dynobj = abfd;
2668 pltoff = bfd_make_section_with_flags (dynobj,
2669 ELF_STRING_ia64_pltoff,
2670 (SEC_ALLOC
2671 | SEC_LOAD
2672 | SEC_HAS_CONTENTS
2673 | SEC_IN_MEMORY
2674 | SEC_SMALL_DATA
2675 | SEC_LINKER_CREATED));
2676 if (!pltoff
2677 || !bfd_set_section_alignment (abfd, pltoff, 4))
2679 BFD_ASSERT (0);
2680 return NULL;
2683 ia64_info->pltoff_sec = pltoff;
2686 return pltoff;
2689 static asection *
2690 get_reloc_section (abfd, ia64_info, sec, create)
2691 bfd *abfd;
2692 struct elfNN_ia64_link_hash_table *ia64_info;
2693 asection *sec;
2694 bfd_boolean create;
2696 const char *srel_name;
2697 asection *srel;
2698 bfd *dynobj;
2700 srel_name = (bfd_elf_string_from_elf_section
2701 (abfd, elf_elfheader(abfd)->e_shstrndx,
2702 elf_section_data(sec)->rel_hdr.sh_name));
2703 if (srel_name == NULL)
2704 return NULL;
2706 BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela")
2707 && strcmp (bfd_get_section_name (abfd, sec),
2708 srel_name+5) == 0)
2709 || (CONST_STRNEQ (srel_name, ".rel")
2710 && strcmp (bfd_get_section_name (abfd, sec),
2711 srel_name+4) == 0));
2713 dynobj = ia64_info->root.dynobj;
2714 if (!dynobj)
2715 ia64_info->root.dynobj = dynobj = abfd;
2717 srel = bfd_get_section_by_name (dynobj, srel_name);
2718 if (srel == NULL && create)
2720 srel = bfd_make_section_with_flags (dynobj, srel_name,
2721 (SEC_ALLOC | SEC_LOAD
2722 | SEC_HAS_CONTENTS
2723 | SEC_IN_MEMORY
2724 | SEC_LINKER_CREATED
2725 | SEC_READONLY));
2726 if (srel == NULL
2727 || !bfd_set_section_alignment (dynobj, srel,
2728 LOG_SECTION_ALIGN))
2729 return NULL;
2732 return srel;
2735 static bfd_boolean
2736 count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
2737 asection *srel, int type, bfd_boolean reltext)
2739 struct elfNN_ia64_dyn_reloc_entry *rent;
2741 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2742 if (rent->srel == srel && rent->type == type)
2743 break;
2745 if (!rent)
2747 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2748 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2749 if (!rent)
2750 return FALSE;
2752 rent->next = dyn_i->reloc_entries;
2753 rent->srel = srel;
2754 rent->type = type;
2755 rent->count = 0;
2756 dyn_i->reloc_entries = rent;
2758 rent->reltext = reltext;
2759 rent->count++;
2761 return TRUE;
2764 static bfd_boolean
2765 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2766 bfd *abfd;
2767 struct bfd_link_info *info;
2768 asection *sec;
2769 const Elf_Internal_Rela *relocs;
2771 struct elfNN_ia64_link_hash_table *ia64_info;
2772 const Elf_Internal_Rela *relend;
2773 Elf_Internal_Shdr *symtab_hdr;
2774 const Elf_Internal_Rela *rel;
2775 asection *got, *fptr, *srel, *pltoff;
2776 enum {
2777 NEED_GOT = 1,
2778 NEED_GOTX = 2,
2779 NEED_FPTR = 4,
2780 NEED_PLTOFF = 8,
2781 NEED_MIN_PLT = 16,
2782 NEED_FULL_PLT = 32,
2783 NEED_DYNREL = 64,
2784 NEED_LTOFF_FPTR = 128,
2785 NEED_TPREL = 256,
2786 NEED_DTPMOD = 512,
2787 NEED_DTPREL = 1024
2789 int need_entry;
2790 struct elf_link_hash_entry *h;
2791 unsigned long r_symndx;
2792 bfd_boolean maybe_dynamic;
2794 if (info->relocatable)
2795 return TRUE;
2797 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2798 ia64_info = elfNN_ia64_hash_table (info);
2800 got = fptr = srel = pltoff = NULL;
2802 relend = relocs + sec->reloc_count;
2804 /* We scan relocations first to create dynamic relocation arrays. We
2805 modified get_dyn_sym_info to allow fast insertion and support fast
2806 lookup in the next loop. */
2807 for (rel = relocs; rel < relend; ++rel)
2809 r_symndx = ELFNN_R_SYM (rel->r_info);
2810 if (r_symndx >= symtab_hdr->sh_info)
2812 long indx = r_symndx - symtab_hdr->sh_info;
2813 h = elf_sym_hashes (abfd)[indx];
2814 while (h->root.type == bfd_link_hash_indirect
2815 || h->root.type == bfd_link_hash_warning)
2816 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2818 else
2819 h = NULL;
2821 /* We can only get preliminary data on whether a symbol is
2822 locally or externally defined, as not all of the input files
2823 have yet been processed. Do something with what we know, as
2824 this may help reduce memory usage and processing time later. */
2825 maybe_dynamic = (h && ((!info->executable
2826 && (!SYMBOLIC_BIND (info, h)
2827 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2828 || !h->def_regular
2829 || h->root.type == bfd_link_hash_defweak));
2831 need_entry = 0;
2832 switch (ELFNN_R_TYPE (rel->r_info))
2834 case R_IA64_TPREL64MSB:
2835 case R_IA64_TPREL64LSB:
2836 if (info->shared || maybe_dynamic)
2837 need_entry = NEED_DYNREL;
2838 break;
2840 case R_IA64_LTOFF_TPREL22:
2841 need_entry = NEED_TPREL;
2842 if (info->shared)
2843 info->flags |= DF_STATIC_TLS;
2844 break;
2846 case R_IA64_DTPREL32MSB:
2847 case R_IA64_DTPREL32LSB:
2848 case R_IA64_DTPREL64MSB:
2849 case R_IA64_DTPREL64LSB:
2850 if (info->shared || maybe_dynamic)
2851 need_entry = NEED_DYNREL;
2852 break;
2854 case R_IA64_LTOFF_DTPREL22:
2855 need_entry = NEED_DTPREL;
2856 break;
2858 case R_IA64_DTPMOD64MSB:
2859 case R_IA64_DTPMOD64LSB:
2860 if (info->shared || maybe_dynamic)
2861 need_entry = NEED_DYNREL;
2862 break;
2864 case R_IA64_LTOFF_DTPMOD22:
2865 need_entry = NEED_DTPMOD;
2866 break;
2868 case R_IA64_LTOFF_FPTR22:
2869 case R_IA64_LTOFF_FPTR64I:
2870 case R_IA64_LTOFF_FPTR32MSB:
2871 case R_IA64_LTOFF_FPTR32LSB:
2872 case R_IA64_LTOFF_FPTR64MSB:
2873 case R_IA64_LTOFF_FPTR64LSB:
2874 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2875 break;
2877 case R_IA64_FPTR64I:
2878 case R_IA64_FPTR32MSB:
2879 case R_IA64_FPTR32LSB:
2880 case R_IA64_FPTR64MSB:
2881 case R_IA64_FPTR64LSB:
2882 if (info->shared || h)
2883 need_entry = NEED_FPTR | NEED_DYNREL;
2884 else
2885 need_entry = NEED_FPTR;
2886 break;
2888 case R_IA64_LTOFF22:
2889 case R_IA64_LTOFF64I:
2890 need_entry = NEED_GOT;
2891 break;
2893 case R_IA64_LTOFF22X:
2894 need_entry = NEED_GOTX;
2895 break;
2897 case R_IA64_PLTOFF22:
2898 case R_IA64_PLTOFF64I:
2899 case R_IA64_PLTOFF64MSB:
2900 case R_IA64_PLTOFF64LSB:
2901 need_entry = NEED_PLTOFF;
2902 if (h)
2904 if (maybe_dynamic)
2905 need_entry |= NEED_MIN_PLT;
2907 else
2909 (*info->callbacks->warning)
2910 (info, _("@pltoff reloc against local symbol"), 0,
2911 abfd, 0, (bfd_vma) 0);
2913 break;
2915 case R_IA64_PCREL21B:
2916 case R_IA64_PCREL60B:
2917 /* Depending on where this symbol is defined, we may or may not
2918 need a full plt entry. Only skip if we know we'll not need
2919 the entry -- static or symbolic, and the symbol definition
2920 has already been seen. */
2921 if (maybe_dynamic && rel->r_addend == 0)
2922 need_entry = NEED_FULL_PLT;
2923 break;
2925 case R_IA64_IMM14:
2926 case R_IA64_IMM22:
2927 case R_IA64_IMM64:
2928 case R_IA64_DIR32MSB:
2929 case R_IA64_DIR32LSB:
2930 case R_IA64_DIR64MSB:
2931 case R_IA64_DIR64LSB:
2932 /* Shared objects will always need at least a REL relocation. */
2933 if (info->shared || maybe_dynamic)
2934 need_entry = NEED_DYNREL;
2935 break;
2937 case R_IA64_IPLTMSB:
2938 case R_IA64_IPLTLSB:
2939 /* Shared objects will always need at least a REL relocation. */
2940 if (info->shared || maybe_dynamic)
2941 need_entry = NEED_DYNREL;
2942 break;
2944 case R_IA64_PCREL22:
2945 case R_IA64_PCREL64I:
2946 case R_IA64_PCREL32MSB:
2947 case R_IA64_PCREL32LSB:
2948 case R_IA64_PCREL64MSB:
2949 case R_IA64_PCREL64LSB:
2950 if (maybe_dynamic)
2951 need_entry = NEED_DYNREL;
2952 break;
2955 if (!need_entry)
2956 continue;
2958 if ((need_entry & NEED_FPTR) != 0
2959 && rel->r_addend)
2961 (*info->callbacks->warning)
2962 (info, _("non-zero addend in @fptr reloc"), 0,
2963 abfd, 0, (bfd_vma) 0);
2966 if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
2967 return FALSE;
2970 /* Now, we only do lookup without insertion, which is very fast
2971 with the modified get_dyn_sym_info. */
2972 for (rel = relocs; rel < relend; ++rel)
2974 struct elfNN_ia64_dyn_sym_info *dyn_i;
2975 int dynrel_type = R_IA64_NONE;
2977 r_symndx = ELFNN_R_SYM (rel->r_info);
2978 if (r_symndx >= symtab_hdr->sh_info)
2980 /* We're dealing with a global symbol -- find its hash entry
2981 and mark it as being referenced. */
2982 long indx = r_symndx - symtab_hdr->sh_info;
2983 h = elf_sym_hashes (abfd)[indx];
2984 while (h->root.type == bfd_link_hash_indirect
2985 || h->root.type == bfd_link_hash_warning)
2986 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2988 h->ref_regular = 1;
2990 else
2991 h = NULL;
2993 /* We can only get preliminary data on whether a symbol is
2994 locally or externally defined, as not all of the input files
2995 have yet been processed. Do something with what we know, as
2996 this may help reduce memory usage and processing time later. */
2997 maybe_dynamic = (h && ((!info->executable
2998 && (!SYMBOLIC_BIND (info, h)
2999 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
3000 || !h->def_regular
3001 || h->root.type == bfd_link_hash_defweak));
3003 need_entry = 0;
3004 switch (ELFNN_R_TYPE (rel->r_info))
3006 case R_IA64_TPREL64MSB:
3007 case R_IA64_TPREL64LSB:
3008 if (info->shared || maybe_dynamic)
3009 need_entry = NEED_DYNREL;
3010 dynrel_type = R_IA64_TPREL64LSB;
3011 if (info->shared)
3012 info->flags |= DF_STATIC_TLS;
3013 break;
3015 case R_IA64_LTOFF_TPREL22:
3016 need_entry = NEED_TPREL;
3017 if (info->shared)
3018 info->flags |= DF_STATIC_TLS;
3019 break;
3021 case R_IA64_DTPREL32MSB:
3022 case R_IA64_DTPREL32LSB:
3023 case R_IA64_DTPREL64MSB:
3024 case R_IA64_DTPREL64LSB:
3025 if (info->shared || maybe_dynamic)
3026 need_entry = NEED_DYNREL;
3027 dynrel_type = R_IA64_DTPRELNNLSB;
3028 break;
3030 case R_IA64_LTOFF_DTPREL22:
3031 need_entry = NEED_DTPREL;
3032 break;
3034 case R_IA64_DTPMOD64MSB:
3035 case R_IA64_DTPMOD64LSB:
3036 if (info->shared || maybe_dynamic)
3037 need_entry = NEED_DYNREL;
3038 dynrel_type = R_IA64_DTPMOD64LSB;
3039 break;
3041 case R_IA64_LTOFF_DTPMOD22:
3042 need_entry = NEED_DTPMOD;
3043 break;
3045 case R_IA64_LTOFF_FPTR22:
3046 case R_IA64_LTOFF_FPTR64I:
3047 case R_IA64_LTOFF_FPTR32MSB:
3048 case R_IA64_LTOFF_FPTR32LSB:
3049 case R_IA64_LTOFF_FPTR64MSB:
3050 case R_IA64_LTOFF_FPTR64LSB:
3051 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
3052 break;
3054 case R_IA64_FPTR64I:
3055 case R_IA64_FPTR32MSB:
3056 case R_IA64_FPTR32LSB:
3057 case R_IA64_FPTR64MSB:
3058 case R_IA64_FPTR64LSB:
3059 if (info->shared || h)
3060 need_entry = NEED_FPTR | NEED_DYNREL;
3061 else
3062 need_entry = NEED_FPTR;
3063 dynrel_type = R_IA64_FPTRNNLSB;
3064 break;
3066 case R_IA64_LTOFF22:
3067 case R_IA64_LTOFF64I:
3068 need_entry = NEED_GOT;
3069 break;
3071 case R_IA64_LTOFF22X:
3072 need_entry = NEED_GOTX;
3073 break;
3075 case R_IA64_PLTOFF22:
3076 case R_IA64_PLTOFF64I:
3077 case R_IA64_PLTOFF64MSB:
3078 case R_IA64_PLTOFF64LSB:
3079 need_entry = NEED_PLTOFF;
3080 if (h)
3082 if (maybe_dynamic)
3083 need_entry |= NEED_MIN_PLT;
3085 break;
3087 case R_IA64_PCREL21B:
3088 case R_IA64_PCREL60B:
3089 /* Depending on where this symbol is defined, we may or may not
3090 need a full plt entry. Only skip if we know we'll not need
3091 the entry -- static or symbolic, and the symbol definition
3092 has already been seen. */
3093 if (maybe_dynamic && rel->r_addend == 0)
3094 need_entry = NEED_FULL_PLT;
3095 break;
3097 case R_IA64_IMM14:
3098 case R_IA64_IMM22:
3099 case R_IA64_IMM64:
3100 case R_IA64_DIR32MSB:
3101 case R_IA64_DIR32LSB:
3102 case R_IA64_DIR64MSB:
3103 case R_IA64_DIR64LSB:
3104 /* Shared objects will always need at least a REL relocation. */
3105 if (info->shared || maybe_dynamic)
3106 need_entry = NEED_DYNREL;
3107 dynrel_type = R_IA64_DIRNNLSB;
3108 break;
3110 case R_IA64_IPLTMSB:
3111 case R_IA64_IPLTLSB:
3112 /* Shared objects will always need at least a REL relocation. */
3113 if (info->shared || maybe_dynamic)
3114 need_entry = NEED_DYNREL;
3115 dynrel_type = R_IA64_IPLTLSB;
3116 break;
3118 case R_IA64_PCREL22:
3119 case R_IA64_PCREL64I:
3120 case R_IA64_PCREL32MSB:
3121 case R_IA64_PCREL32LSB:
3122 case R_IA64_PCREL64MSB:
3123 case R_IA64_PCREL64LSB:
3124 if (maybe_dynamic)
3125 need_entry = NEED_DYNREL;
3126 dynrel_type = R_IA64_PCRELNNLSB;
3127 break;
3130 if (!need_entry)
3131 continue;
3133 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
3135 /* Record whether or not this is a local symbol. */
3136 dyn_i->h = h;
3138 /* Create what's needed. */
3139 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
3140 | NEED_DTPMOD | NEED_DTPREL))
3142 if (!got)
3144 got = get_got (abfd, info, ia64_info);
3145 if (!got)
3146 return FALSE;
3148 if (need_entry & NEED_GOT)
3149 dyn_i->want_got = 1;
3150 if (need_entry & NEED_GOTX)
3151 dyn_i->want_gotx = 1;
3152 if (need_entry & NEED_TPREL)
3153 dyn_i->want_tprel = 1;
3154 if (need_entry & NEED_DTPMOD)
3155 dyn_i->want_dtpmod = 1;
3156 if (need_entry & NEED_DTPREL)
3157 dyn_i->want_dtprel = 1;
3159 if (need_entry & NEED_FPTR)
3161 if (!fptr)
3163 fptr = get_fptr (abfd, info, ia64_info);
3164 if (!fptr)
3165 return FALSE;
3168 /* FPTRs for shared libraries are allocated by the dynamic
3169 linker. Make sure this local symbol will appear in the
3170 dynamic symbol table. */
3171 if (!h && info->shared)
3173 if (! (bfd_elf_link_record_local_dynamic_symbol
3174 (info, abfd, (long) r_symndx)))
3175 return FALSE;
3178 dyn_i->want_fptr = 1;
3180 if (need_entry & NEED_LTOFF_FPTR)
3181 dyn_i->want_ltoff_fptr = 1;
3182 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
3184 if (!ia64_info->root.dynobj)
3185 ia64_info->root.dynobj = abfd;
3186 h->needs_plt = 1;
3187 dyn_i->want_plt = 1;
3189 if (need_entry & NEED_FULL_PLT)
3190 dyn_i->want_plt2 = 1;
3191 if (need_entry & NEED_PLTOFF)
3193 /* This is needed here, in case @pltoff is used in a non-shared
3194 link. */
3195 if (!pltoff)
3197 pltoff = get_pltoff (abfd, info, ia64_info);
3198 if (!pltoff)
3199 return FALSE;
3202 dyn_i->want_pltoff = 1;
3204 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
3206 if (!srel)
3208 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
3209 if (!srel)
3210 return FALSE;
3212 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
3213 (sec->flags & SEC_READONLY) != 0))
3214 return FALSE;
3218 return TRUE;
3221 /* For cleanliness, and potentially faster dynamic loading, allocate
3222 external GOT entries first. */
3224 static bfd_boolean
3225 allocate_global_data_got (dyn_i, data)
3226 struct elfNN_ia64_dyn_sym_info *dyn_i;
3227 PTR data;
3229 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3231 if ((dyn_i->want_got || dyn_i->want_gotx)
3232 && ! dyn_i->want_fptr
3233 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3235 dyn_i->got_offset = x->ofs;
3236 x->ofs += 8;
3238 if (dyn_i->want_tprel)
3240 dyn_i->tprel_offset = x->ofs;
3241 x->ofs += 8;
3243 if (dyn_i->want_dtpmod)
3245 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3247 dyn_i->dtpmod_offset = x->ofs;
3248 x->ofs += 8;
3250 else
3252 struct elfNN_ia64_link_hash_table *ia64_info;
3254 ia64_info = elfNN_ia64_hash_table (x->info);
3255 if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
3257 ia64_info->self_dtpmod_offset = x->ofs;
3258 x->ofs += 8;
3260 dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
3263 if (dyn_i->want_dtprel)
3265 dyn_i->dtprel_offset = x->ofs;
3266 x->ofs += 8;
3268 return TRUE;
3271 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
3273 static bfd_boolean
3274 allocate_global_fptr_got (dyn_i, data)
3275 struct elfNN_ia64_dyn_sym_info *dyn_i;
3276 PTR data;
3278 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3280 if (dyn_i->want_got
3281 && dyn_i->want_fptr
3282 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
3284 dyn_i->got_offset = x->ofs;
3285 x->ofs += 8;
3287 return TRUE;
3290 /* Lastly, allocate all the GOT entries for local data. */
3292 static bfd_boolean
3293 allocate_local_got (dyn_i, data)
3294 struct elfNN_ia64_dyn_sym_info *dyn_i;
3295 PTR data;
3297 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3299 if ((dyn_i->want_got || dyn_i->want_gotx)
3300 && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3302 dyn_i->got_offset = x->ofs;
3303 x->ofs += 8;
3305 return TRUE;
3308 /* Search for the index of a global symbol in it's defining object file. */
3310 static long
3311 global_sym_index (h)
3312 struct elf_link_hash_entry *h;
3314 struct elf_link_hash_entry **p;
3315 bfd *obj;
3317 BFD_ASSERT (h->root.type == bfd_link_hash_defined
3318 || h->root.type == bfd_link_hash_defweak);
3320 obj = h->root.u.def.section->owner;
3321 for (p = elf_sym_hashes (obj); *p != h; ++p)
3322 continue;
3324 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
3327 /* Allocate function descriptors. We can do these for every function
3328 in a main executable that is not exported. */
3330 static bfd_boolean
3331 allocate_fptr (dyn_i, data)
3332 struct elfNN_ia64_dyn_sym_info *dyn_i;
3333 PTR data;
3335 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3337 if (dyn_i->want_fptr)
3339 struct elf_link_hash_entry *h = dyn_i->h;
3341 if (h)
3342 while (h->root.type == bfd_link_hash_indirect
3343 || h->root.type == bfd_link_hash_warning)
3344 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3346 if (!x->info->executable
3347 && (!h
3348 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3349 || (h->root.type != bfd_link_hash_undefweak
3350 && h->root.type != bfd_link_hash_undefined)))
3352 if (h && h->dynindx == -1)
3354 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
3355 || (h->root.type == bfd_link_hash_defweak));
3357 if (!bfd_elf_link_record_local_dynamic_symbol
3358 (x->info, h->root.u.def.section->owner,
3359 global_sym_index (h)))
3360 return FALSE;
3363 dyn_i->want_fptr = 0;
3365 else if (h == NULL || h->dynindx == -1)
3367 dyn_i->fptr_offset = x->ofs;
3368 x->ofs += 16;
3370 else
3371 dyn_i->want_fptr = 0;
3373 return TRUE;
3376 /* Allocate all the minimal PLT entries. */
3378 static bfd_boolean
3379 allocate_plt_entries (dyn_i, data)
3380 struct elfNN_ia64_dyn_sym_info *dyn_i;
3381 PTR data;
3383 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3385 if (dyn_i->want_plt)
3387 struct elf_link_hash_entry *h = dyn_i->h;
3389 if (h)
3390 while (h->root.type == bfd_link_hash_indirect
3391 || h->root.type == bfd_link_hash_warning)
3392 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3394 /* ??? Versioned symbols seem to lose NEEDS_PLT. */
3395 if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
3397 bfd_size_type offset = x->ofs;
3398 if (offset == 0)
3399 offset = PLT_HEADER_SIZE;
3400 dyn_i->plt_offset = offset;
3401 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
3403 dyn_i->want_pltoff = 1;
3405 else
3407 dyn_i->want_plt = 0;
3408 dyn_i->want_plt2 = 0;
3411 return TRUE;
3414 /* Allocate all the full PLT entries. */
3416 static bfd_boolean
3417 allocate_plt2_entries (dyn_i, data)
3418 struct elfNN_ia64_dyn_sym_info *dyn_i;
3419 PTR data;
3421 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3423 if (dyn_i->want_plt2)
3425 struct elf_link_hash_entry *h = dyn_i->h;
3426 bfd_size_type ofs = x->ofs;
3428 dyn_i->plt2_offset = ofs;
3429 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
3431 while (h->root.type == bfd_link_hash_indirect
3432 || h->root.type == bfd_link_hash_warning)
3433 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3434 dyn_i->h->plt.offset = ofs;
3436 return TRUE;
3439 /* Allocate all the PLTOFF entries requested by relocations and
3440 plt entries. We can't share space with allocated FPTR entries,
3441 because the latter are not necessarily addressable by the GP.
3442 ??? Relaxation might be able to determine that they are. */
3444 static bfd_boolean
3445 allocate_pltoff_entries (dyn_i, data)
3446 struct elfNN_ia64_dyn_sym_info *dyn_i;
3447 PTR data;
3449 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3451 if (dyn_i->want_pltoff)
3453 dyn_i->pltoff_offset = x->ofs;
3454 x->ofs += 16;
3456 return TRUE;
3459 /* Allocate dynamic relocations for those symbols that turned out
3460 to be dynamic. */
3462 static bfd_boolean
3463 allocate_dynrel_entries (dyn_i, data)
3464 struct elfNN_ia64_dyn_sym_info *dyn_i;
3465 PTR data;
3467 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3468 struct elfNN_ia64_link_hash_table *ia64_info;
3469 struct elfNN_ia64_dyn_reloc_entry *rent;
3470 bfd_boolean dynamic_symbol, shared, resolved_zero;
3472 ia64_info = elfNN_ia64_hash_table (x->info);
3474 /* Note that this can't be used in relation to FPTR relocs below. */
3475 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
3477 shared = x->info->shared;
3478 resolved_zero = (dyn_i->h
3479 && ELF_ST_VISIBILITY (dyn_i->h->other)
3480 && dyn_i->h->root.type == bfd_link_hash_undefweak);
3482 /* Take care of the GOT and PLT relocations. */
3484 if ((!resolved_zero
3485 && (dynamic_symbol || shared)
3486 && (dyn_i->want_got || dyn_i->want_gotx))
3487 || (dyn_i->want_ltoff_fptr
3488 && dyn_i->h
3489 && dyn_i->h->dynindx != -1))
3491 if (!dyn_i->want_ltoff_fptr
3492 || !x->info->pie
3493 || dyn_i->h == NULL
3494 || dyn_i->h->root.type != bfd_link_hash_undefweak)
3495 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3497 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
3498 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3499 if (dynamic_symbol && dyn_i->want_dtpmod)
3500 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3501 if (dynamic_symbol && dyn_i->want_dtprel)
3502 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3504 if (x->only_got)
3505 return TRUE;
3507 if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
3509 if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
3510 ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
3513 if (!resolved_zero && dyn_i->want_pltoff)
3515 bfd_size_type t = 0;
3517 /* Dynamic symbols get one IPLT relocation. Local symbols in
3518 shared libraries get two REL relocations. Local symbols in
3519 main applications get nothing. */
3520 if (dynamic_symbol)
3521 t = sizeof (ElfNN_External_Rela);
3522 else if (shared)
3523 t = 2 * sizeof (ElfNN_External_Rela);
3525 ia64_info->rel_pltoff_sec->size += t;
3528 /* Take care of the normal data relocations. */
3530 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
3532 int count = rent->count;
3534 switch (rent->type)
3536 case R_IA64_FPTR32LSB:
3537 case R_IA64_FPTR64LSB:
3538 /* Allocate one iff !want_fptr and not PIE, which by this point
3539 will be true only if we're actually allocating one statically
3540 in the main executable. Position independent executables
3541 need a relative reloc. */
3542 if (dyn_i->want_fptr && !x->info->pie)
3543 continue;
3544 break;
3545 case R_IA64_PCREL32LSB:
3546 case R_IA64_PCREL64LSB:
3547 if (!dynamic_symbol)
3548 continue;
3549 break;
3550 case R_IA64_DIR32LSB:
3551 case R_IA64_DIR64LSB:
3552 if (!dynamic_symbol && !shared)
3553 continue;
3554 break;
3555 case R_IA64_IPLTLSB:
3556 if (!dynamic_symbol && !shared)
3557 continue;
3558 /* Use two REL relocations for IPLT relocations
3559 against local symbols. */
3560 if (!dynamic_symbol)
3561 count *= 2;
3562 break;
3563 case R_IA64_DTPREL32LSB:
3564 case R_IA64_TPREL64LSB:
3565 case R_IA64_DTPREL64LSB:
3566 case R_IA64_DTPMOD64LSB:
3567 break;
3568 default:
3569 abort ();
3571 if (rent->reltext)
3572 ia64_info->reltext = 1;
3573 rent->srel->size += sizeof (ElfNN_External_Rela) * count;
3576 return TRUE;
3579 static bfd_boolean
3580 elfNN_ia64_adjust_dynamic_symbol (info, h)
3581 struct bfd_link_info *info ATTRIBUTE_UNUSED;
3582 struct elf_link_hash_entry *h;
3584 /* ??? Undefined symbols with PLT entries should be re-defined
3585 to be the PLT entry. */
3587 /* If this is a weak symbol, and there is a real definition, the
3588 processor independent code will have arranged for us to see the
3589 real definition first, and we can just use the same value. */
3590 if (h->u.weakdef != NULL)
3592 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
3593 || h->u.weakdef->root.type == bfd_link_hash_defweak);
3594 h->root.u.def.section = h->u.weakdef->root.u.def.section;
3595 h->root.u.def.value = h->u.weakdef->root.u.def.value;
3596 return TRUE;
3599 /* If this is a reference to a symbol defined by a dynamic object which
3600 is not a function, we might allocate the symbol in our .dynbss section
3601 and allocate a COPY dynamic relocation.
3603 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
3604 of hackery. */
3606 return TRUE;
3609 static bfd_boolean
3610 elfNN_ia64_size_dynamic_sections (output_bfd, info)
3611 bfd *output_bfd ATTRIBUTE_UNUSED;
3612 struct bfd_link_info *info;
3614 struct elfNN_ia64_allocate_data data;
3615 struct elfNN_ia64_link_hash_table *ia64_info;
3616 asection *sec;
3617 bfd *dynobj;
3618 bfd_boolean relplt = FALSE;
3620 dynobj = elf_hash_table(info)->dynobj;
3621 ia64_info = elfNN_ia64_hash_table (info);
3622 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
3623 BFD_ASSERT(dynobj != NULL);
3624 data.info = info;
3626 /* Set the contents of the .interp section to the interpreter. */
3627 if (ia64_info->root.dynamic_sections_created
3628 && info->executable)
3630 sec = bfd_get_section_by_name (dynobj, ".interp");
3631 BFD_ASSERT (sec != NULL);
3632 sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3633 sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3636 /* Allocate the GOT entries. */
3638 if (ia64_info->got_sec)
3640 data.ofs = 0;
3641 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
3642 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
3643 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
3644 ia64_info->got_sec->size = data.ofs;
3647 /* Allocate the FPTR entries. */
3649 if (ia64_info->fptr_sec)
3651 data.ofs = 0;
3652 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
3653 ia64_info->fptr_sec->size = data.ofs;
3656 /* Now that we've seen all of the input files, we can decide which
3657 symbols need plt entries. Allocate the minimal PLT entries first.
3658 We do this even though dynamic_sections_created may be FALSE, because
3659 this has the side-effect of clearing want_plt and want_plt2. */
3661 data.ofs = 0;
3662 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
3664 ia64_info->minplt_entries = 0;
3665 if (data.ofs)
3667 ia64_info->minplt_entries
3668 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3671 /* Align the pointer for the plt2 entries. */
3672 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
3674 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
3675 if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
3677 /* FIXME: we always reserve the memory for dynamic linker even if
3678 there are no PLT entries since dynamic linker may assume the
3679 reserved memory always exists. */
3681 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
3683 ia64_info->plt_sec->size = data.ofs;
3685 /* If we've got a .plt, we need some extra memory for the dynamic
3686 linker. We stuff these in .got.plt. */
3687 sec = bfd_get_section_by_name (dynobj, ".got.plt");
3688 sec->size = 8 * PLT_RESERVED_WORDS;
3691 /* Allocate the PLTOFF entries. */
3693 if (ia64_info->pltoff_sec)
3695 data.ofs = 0;
3696 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
3697 ia64_info->pltoff_sec->size = data.ofs;
3700 if (ia64_info->root.dynamic_sections_created)
3702 /* Allocate space for the dynamic relocations that turned out to be
3703 required. */
3705 if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
3706 ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3707 data.only_got = FALSE;
3708 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
3711 /* We have now determined the sizes of the various dynamic sections.
3712 Allocate memory for them. */
3713 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
3715 bfd_boolean strip;
3717 if (!(sec->flags & SEC_LINKER_CREATED))
3718 continue;
3720 /* If we don't need this section, strip it from the output file.
3721 There were several sections primarily related to dynamic
3722 linking that must be create before the linker maps input
3723 sections to output sections. The linker does that before
3724 bfd_elf_size_dynamic_sections is called, and it is that
3725 function which decides whether anything needs to go into
3726 these sections. */
3728 strip = (sec->size == 0);
3730 if (sec == ia64_info->got_sec)
3731 strip = FALSE;
3732 else if (sec == ia64_info->rel_got_sec)
3734 if (strip)
3735 ia64_info->rel_got_sec = NULL;
3736 else
3737 /* We use the reloc_count field as a counter if we need to
3738 copy relocs into the output file. */
3739 sec->reloc_count = 0;
3741 else if (sec == ia64_info->fptr_sec)
3743 if (strip)
3744 ia64_info->fptr_sec = NULL;
3746 else if (sec == ia64_info->rel_fptr_sec)
3748 if (strip)
3749 ia64_info->rel_fptr_sec = NULL;
3750 else
3751 /* We use the reloc_count field as a counter if we need to
3752 copy relocs into the output file. */
3753 sec->reloc_count = 0;
3755 else if (sec == ia64_info->plt_sec)
3757 if (strip)
3758 ia64_info->plt_sec = NULL;
3760 else if (sec == ia64_info->pltoff_sec)
3762 if (strip)
3763 ia64_info->pltoff_sec = NULL;
3765 else if (sec == ia64_info->rel_pltoff_sec)
3767 if (strip)
3768 ia64_info->rel_pltoff_sec = NULL;
3769 else
3771 relplt = TRUE;
3772 /* We use the reloc_count field as a counter if we need to
3773 copy relocs into the output file. */
3774 sec->reloc_count = 0;
3777 else
3779 const char *name;
3781 /* It's OK to base decisions on the section name, because none
3782 of the dynobj section names depend upon the input files. */
3783 name = bfd_get_section_name (dynobj, sec);
3785 if (strcmp (name, ".got.plt") == 0)
3786 strip = FALSE;
3787 else if (CONST_STRNEQ (name, ".rel"))
3789 if (!strip)
3791 /* We use the reloc_count field as a counter if we need to
3792 copy relocs into the output file. */
3793 sec->reloc_count = 0;
3796 else
3797 continue;
3800 if (strip)
3801 sec->flags |= SEC_EXCLUDE;
3802 else
3804 /* Allocate memory for the section contents. */
3805 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
3806 if (sec->contents == NULL && sec->size != 0)
3807 return FALSE;
3811 if (elf_hash_table (info)->dynamic_sections_created)
3813 /* Add some entries to the .dynamic section. We fill in the values
3814 later (in finish_dynamic_sections) but we must add the entries now
3815 so that we get the correct size for the .dynamic section. */
3817 if (info->executable)
3819 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3820 by the debugger. */
3821 #define add_dynamic_entry(TAG, VAL) \
3822 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3824 if (!add_dynamic_entry (DT_DEBUG, 0))
3825 return FALSE;
3828 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3829 return FALSE;
3830 if (!add_dynamic_entry (DT_PLTGOT, 0))
3831 return FALSE;
3833 if (relplt)
3835 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3836 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3837 || !add_dynamic_entry (DT_JMPREL, 0))
3838 return FALSE;
3841 if (!add_dynamic_entry (DT_RELA, 0)
3842 || !add_dynamic_entry (DT_RELASZ, 0)
3843 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3844 return FALSE;
3846 if (ia64_info->reltext)
3848 if (!add_dynamic_entry (DT_TEXTREL, 0))
3849 return FALSE;
3850 info->flags |= DF_TEXTREL;
3854 /* ??? Perhaps force __gp local. */
3856 return TRUE;
3859 static bfd_reloc_status_type
3860 elfNN_ia64_install_value (hit_addr, v, r_type)
3861 bfd_byte *hit_addr;
3862 bfd_vma v;
3863 unsigned int r_type;
3865 const struct ia64_operand *op;
3866 int bigendian = 0, shift = 0;
3867 bfd_vma t0, t1, dword;
3868 ia64_insn insn;
3869 enum ia64_opnd opnd;
3870 const char *err;
3871 size_t size = 8;
3872 #ifdef BFD_HOST_U_64_BIT
3873 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3874 #else
3875 bfd_vma val = v;
3876 #endif
3878 opnd = IA64_OPND_NIL;
3879 switch (r_type)
3881 case R_IA64_NONE:
3882 case R_IA64_LDXMOV:
3883 return bfd_reloc_ok;
3885 /* Instruction relocations. */
3887 case R_IA64_IMM14:
3888 case R_IA64_TPREL14:
3889 case R_IA64_DTPREL14:
3890 opnd = IA64_OPND_IMM14;
3891 break;
3893 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
3894 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
3895 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
3896 case R_IA64_PCREL21B:
3897 case R_IA64_PCREL21BI:
3898 opnd = IA64_OPND_TGT25c;
3899 break;
3901 case R_IA64_IMM22:
3902 case R_IA64_GPREL22:
3903 case R_IA64_LTOFF22:
3904 case R_IA64_LTOFF22X:
3905 case R_IA64_PLTOFF22:
3906 case R_IA64_PCREL22:
3907 case R_IA64_LTOFF_FPTR22:
3908 case R_IA64_TPREL22:
3909 case R_IA64_DTPREL22:
3910 case R_IA64_LTOFF_TPREL22:
3911 case R_IA64_LTOFF_DTPMOD22:
3912 case R_IA64_LTOFF_DTPREL22:
3913 opnd = IA64_OPND_IMM22;
3914 break;
3916 case R_IA64_IMM64:
3917 case R_IA64_GPREL64I:
3918 case R_IA64_LTOFF64I:
3919 case R_IA64_PLTOFF64I:
3920 case R_IA64_PCREL64I:
3921 case R_IA64_FPTR64I:
3922 case R_IA64_LTOFF_FPTR64I:
3923 case R_IA64_TPREL64I:
3924 case R_IA64_DTPREL64I:
3925 opnd = IA64_OPND_IMMU64;
3926 break;
3928 /* Data relocations. */
3930 case R_IA64_DIR32MSB:
3931 case R_IA64_GPREL32MSB:
3932 case R_IA64_FPTR32MSB:
3933 case R_IA64_PCREL32MSB:
3934 case R_IA64_LTOFF_FPTR32MSB:
3935 case R_IA64_SEGREL32MSB:
3936 case R_IA64_SECREL32MSB:
3937 case R_IA64_LTV32MSB:
3938 case R_IA64_DTPREL32MSB:
3939 size = 4; bigendian = 1;
3940 break;
3942 case R_IA64_DIR32LSB:
3943 case R_IA64_GPREL32LSB:
3944 case R_IA64_FPTR32LSB:
3945 case R_IA64_PCREL32LSB:
3946 case R_IA64_LTOFF_FPTR32LSB:
3947 case R_IA64_SEGREL32LSB:
3948 case R_IA64_SECREL32LSB:
3949 case R_IA64_LTV32LSB:
3950 case R_IA64_DTPREL32LSB:
3951 size = 4; bigendian = 0;
3952 break;
3954 case R_IA64_DIR64MSB:
3955 case R_IA64_GPREL64MSB:
3956 case R_IA64_PLTOFF64MSB:
3957 case R_IA64_FPTR64MSB:
3958 case R_IA64_PCREL64MSB:
3959 case R_IA64_LTOFF_FPTR64MSB:
3960 case R_IA64_SEGREL64MSB:
3961 case R_IA64_SECREL64MSB:
3962 case R_IA64_LTV64MSB:
3963 case R_IA64_TPREL64MSB:
3964 case R_IA64_DTPMOD64MSB:
3965 case R_IA64_DTPREL64MSB:
3966 size = 8; bigendian = 1;
3967 break;
3969 case R_IA64_DIR64LSB:
3970 case R_IA64_GPREL64LSB:
3971 case R_IA64_PLTOFF64LSB:
3972 case R_IA64_FPTR64LSB:
3973 case R_IA64_PCREL64LSB:
3974 case R_IA64_LTOFF_FPTR64LSB:
3975 case R_IA64_SEGREL64LSB:
3976 case R_IA64_SECREL64LSB:
3977 case R_IA64_LTV64LSB:
3978 case R_IA64_TPREL64LSB:
3979 case R_IA64_DTPMOD64LSB:
3980 case R_IA64_DTPREL64LSB:
3981 size = 8; bigendian = 0;
3982 break;
3984 /* Unsupported / Dynamic relocations. */
3985 default:
3986 return bfd_reloc_notsupported;
3989 switch (opnd)
3991 case IA64_OPND_IMMU64:
3992 hit_addr -= (long) hit_addr & 0x3;
3993 t0 = bfd_getl64 (hit_addr);
3994 t1 = bfd_getl64 (hit_addr + 8);
3996 /* tmpl/s: bits 0.. 5 in t0
3997 slot 0: bits 5..45 in t0
3998 slot 1: bits 46..63 in t0, bits 0..22 in t1
3999 slot 2: bits 23..63 in t1 */
4001 /* First, clear the bits that form the 64 bit constant. */
4002 t0 &= ~(0x3ffffLL << 46);
4003 t1 &= ~(0x7fffffLL
4004 | (( (0x07fLL << 13) | (0x1ffLL << 27)
4005 | (0x01fLL << 22) | (0x001LL << 21)
4006 | (0x001LL << 36)) << 23));
4008 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
4009 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
4010 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
4011 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
4012 | (((val >> 16) & 0x01f) << 22) /* imm5c */
4013 | (((val >> 21) & 0x001) << 21) /* ic */
4014 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
4016 bfd_putl64 (t0, hit_addr);
4017 bfd_putl64 (t1, hit_addr + 8);
4018 break;
4020 case IA64_OPND_TGT64:
4021 hit_addr -= (long) hit_addr & 0x3;
4022 t0 = bfd_getl64 (hit_addr);
4023 t1 = bfd_getl64 (hit_addr + 8);
4025 /* tmpl/s: bits 0.. 5 in t0
4026 slot 0: bits 5..45 in t0
4027 slot 1: bits 46..63 in t0, bits 0..22 in t1
4028 slot 2: bits 23..63 in t1 */
4030 /* First, clear the bits that form the 64 bit constant. */
4031 t0 &= ~(0x3ffffLL << 46);
4032 t1 &= ~(0x7fffffLL
4033 | ((1LL << 36 | 0xfffffLL << 13) << 23));
4035 val >>= 4;
4036 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
4037 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
4038 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
4039 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
4041 bfd_putl64 (t0, hit_addr);
4042 bfd_putl64 (t1, hit_addr + 8);
4043 break;
4045 default:
4046 switch ((long) hit_addr & 0x3)
4048 case 0: shift = 5; break;
4049 case 1: shift = 14; hit_addr += 3; break;
4050 case 2: shift = 23; hit_addr += 6; break;
4051 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
4053 dword = bfd_getl64 (hit_addr);
4054 insn = (dword >> shift) & 0x1ffffffffffLL;
4056 op = elf64_ia64_operands + opnd;
4057 err = (*op->insert) (op, val, &insn);
4058 if (err)
4059 return bfd_reloc_overflow;
4061 dword &= ~(0x1ffffffffffLL << shift);
4062 dword |= (insn << shift);
4063 bfd_putl64 (dword, hit_addr);
4064 break;
4066 case IA64_OPND_NIL:
4067 /* A data relocation. */
4068 if (bigendian)
4069 if (size == 4)
4070 bfd_putb32 (val, hit_addr);
4071 else
4072 bfd_putb64 (val, hit_addr);
4073 else
4074 if (size == 4)
4075 bfd_putl32 (val, hit_addr);
4076 else
4077 bfd_putl64 (val, hit_addr);
4078 break;
4081 return bfd_reloc_ok;
4084 static void
4085 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
4086 dynindx, addend)
4087 bfd *abfd;
4088 struct bfd_link_info *info;
4089 asection *sec;
4090 asection *srel;
4091 bfd_vma offset;
4092 unsigned int type;
4093 long dynindx;
4094 bfd_vma addend;
4096 Elf_Internal_Rela outrel;
4097 bfd_byte *loc;
4099 BFD_ASSERT (dynindx != -1);
4100 outrel.r_info = ELFNN_R_INFO (dynindx, type);
4101 outrel.r_addend = addend;
4102 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
4103 if (outrel.r_offset >= (bfd_vma) -2)
4105 /* Run for the hills. We shouldn't be outputting a relocation
4106 for this. So do what everyone else does and output a no-op. */
4107 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
4108 outrel.r_addend = 0;
4109 outrel.r_offset = 0;
4111 else
4112 outrel.r_offset += sec->output_section->vma + sec->output_offset;
4114 loc = srel->contents;
4115 loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
4116 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
4117 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
4120 /* Store an entry for target address TARGET_ADDR in the linkage table
4121 and return the gp-relative address of the linkage table entry. */
4123 static bfd_vma
4124 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
4125 bfd *abfd;
4126 struct bfd_link_info *info;
4127 struct elfNN_ia64_dyn_sym_info *dyn_i;
4128 long dynindx;
4129 bfd_vma addend;
4130 bfd_vma value;
4131 unsigned int dyn_r_type;
4133 struct elfNN_ia64_link_hash_table *ia64_info;
4134 asection *got_sec;
4135 bfd_boolean done;
4136 bfd_vma got_offset;
4138 ia64_info = elfNN_ia64_hash_table (info);
4139 got_sec = ia64_info->got_sec;
4141 switch (dyn_r_type)
4143 case R_IA64_TPREL64LSB:
4144 done = dyn_i->tprel_done;
4145 dyn_i->tprel_done = TRUE;
4146 got_offset = dyn_i->tprel_offset;
4147 break;
4148 case R_IA64_DTPMOD64LSB:
4149 if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
4151 done = dyn_i->dtpmod_done;
4152 dyn_i->dtpmod_done = TRUE;
4154 else
4156 done = ia64_info->self_dtpmod_done;
4157 ia64_info->self_dtpmod_done = TRUE;
4158 dynindx = 0;
4160 got_offset = dyn_i->dtpmod_offset;
4161 break;
4162 case R_IA64_DTPREL32LSB:
4163 case R_IA64_DTPREL64LSB:
4164 done = dyn_i->dtprel_done;
4165 dyn_i->dtprel_done = TRUE;
4166 got_offset = dyn_i->dtprel_offset;
4167 break;
4168 default:
4169 done = dyn_i->got_done;
4170 dyn_i->got_done = TRUE;
4171 got_offset = dyn_i->got_offset;
4172 break;
4175 BFD_ASSERT ((got_offset & 7) == 0);
4177 if (! done)
4179 /* Store the target address in the linkage table entry. */
4180 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
4182 /* Install a dynamic relocation if needed. */
4183 if (((info->shared
4184 && (!dyn_i->h
4185 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
4186 || dyn_i->h->root.type != bfd_link_hash_undefweak)
4187 && dyn_r_type != R_IA64_DTPREL32LSB
4188 && dyn_r_type != R_IA64_DTPREL64LSB)
4189 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
4190 || (dynindx != -1
4191 && (dyn_r_type == R_IA64_FPTR32LSB
4192 || dyn_r_type == R_IA64_FPTR64LSB)))
4193 && (!dyn_i->want_ltoff_fptr
4194 || !info->pie
4195 || !dyn_i->h
4196 || dyn_i->h->root.type != bfd_link_hash_undefweak))
4198 if (dynindx == -1
4199 && dyn_r_type != R_IA64_TPREL64LSB
4200 && dyn_r_type != R_IA64_DTPMOD64LSB
4201 && dyn_r_type != R_IA64_DTPREL32LSB
4202 && dyn_r_type != R_IA64_DTPREL64LSB)
4204 dyn_r_type = R_IA64_RELNNLSB;
4205 dynindx = 0;
4206 addend = value;
4209 if (bfd_big_endian (abfd))
4211 switch (dyn_r_type)
4213 case R_IA64_REL32LSB:
4214 dyn_r_type = R_IA64_REL32MSB;
4215 break;
4216 case R_IA64_DIR32LSB:
4217 dyn_r_type = R_IA64_DIR32MSB;
4218 break;
4219 case R_IA64_FPTR32LSB:
4220 dyn_r_type = R_IA64_FPTR32MSB;
4221 break;
4222 case R_IA64_DTPREL32LSB:
4223 dyn_r_type = R_IA64_DTPREL32MSB;
4224 break;
4225 case R_IA64_REL64LSB:
4226 dyn_r_type = R_IA64_REL64MSB;
4227 break;
4228 case R_IA64_DIR64LSB:
4229 dyn_r_type = R_IA64_DIR64MSB;
4230 break;
4231 case R_IA64_FPTR64LSB:
4232 dyn_r_type = R_IA64_FPTR64MSB;
4233 break;
4234 case R_IA64_TPREL64LSB:
4235 dyn_r_type = R_IA64_TPREL64MSB;
4236 break;
4237 case R_IA64_DTPMOD64LSB:
4238 dyn_r_type = R_IA64_DTPMOD64MSB;
4239 break;
4240 case R_IA64_DTPREL64LSB:
4241 dyn_r_type = R_IA64_DTPREL64MSB;
4242 break;
4243 default:
4244 BFD_ASSERT (FALSE);
4245 break;
4249 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
4250 ia64_info->rel_got_sec,
4251 got_offset, dyn_r_type,
4252 dynindx, addend);
4256 /* Return the address of the linkage table entry. */
4257 value = (got_sec->output_section->vma
4258 + got_sec->output_offset
4259 + got_offset);
4261 return value;
4264 /* Fill in a function descriptor consisting of the function's code
4265 address and its global pointer. Return the descriptor's address. */
4267 static bfd_vma
4268 set_fptr_entry (abfd, info, dyn_i, value)
4269 bfd *abfd;
4270 struct bfd_link_info *info;
4271 struct elfNN_ia64_dyn_sym_info *dyn_i;
4272 bfd_vma value;
4274 struct elfNN_ia64_link_hash_table *ia64_info;
4275 asection *fptr_sec;
4277 ia64_info = elfNN_ia64_hash_table (info);
4278 fptr_sec = ia64_info->fptr_sec;
4280 if (!dyn_i->fptr_done)
4282 dyn_i->fptr_done = 1;
4284 /* Fill in the function descriptor. */
4285 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
4286 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
4287 fptr_sec->contents + dyn_i->fptr_offset + 8);
4288 if (ia64_info->rel_fptr_sec)
4290 Elf_Internal_Rela outrel;
4291 bfd_byte *loc;
4293 if (bfd_little_endian (abfd))
4294 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
4295 else
4296 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
4297 outrel.r_addend = value;
4298 outrel.r_offset = (fptr_sec->output_section->vma
4299 + fptr_sec->output_offset
4300 + dyn_i->fptr_offset);
4301 loc = ia64_info->rel_fptr_sec->contents;
4302 loc += ia64_info->rel_fptr_sec->reloc_count++
4303 * sizeof (ElfNN_External_Rela);
4304 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
4308 /* Return the descriptor's address. */
4309 value = (fptr_sec->output_section->vma
4310 + fptr_sec->output_offset
4311 + dyn_i->fptr_offset);
4313 return value;
4316 /* Fill in a PLTOFF entry consisting of the function's code address
4317 and its global pointer. Return the descriptor's address. */
4319 static bfd_vma
4320 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
4321 bfd *abfd;
4322 struct bfd_link_info *info;
4323 struct elfNN_ia64_dyn_sym_info *dyn_i;
4324 bfd_vma value;
4325 bfd_boolean is_plt;
4327 struct elfNN_ia64_link_hash_table *ia64_info;
4328 asection *pltoff_sec;
4330 ia64_info = elfNN_ia64_hash_table (info);
4331 pltoff_sec = ia64_info->pltoff_sec;
4333 /* Don't do anything if this symbol uses a real PLT entry. In
4334 that case, we'll fill this in during finish_dynamic_symbol. */
4335 if ((! dyn_i->want_plt || is_plt)
4336 && !dyn_i->pltoff_done)
4338 bfd_vma gp = _bfd_get_gp_value (abfd);
4340 /* Fill in the function descriptor. */
4341 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
4342 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
4344 /* Install dynamic relocations if needed. */
4345 if (!is_plt
4346 && info->shared
4347 && (!dyn_i->h
4348 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
4349 || dyn_i->h->root.type != bfd_link_hash_undefweak))
4351 unsigned int dyn_r_type;
4353 if (bfd_big_endian (abfd))
4354 dyn_r_type = R_IA64_RELNNMSB;
4355 else
4356 dyn_r_type = R_IA64_RELNNLSB;
4358 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
4359 ia64_info->rel_pltoff_sec,
4360 dyn_i->pltoff_offset,
4361 dyn_r_type, 0, value);
4362 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
4363 ia64_info->rel_pltoff_sec,
4364 dyn_i->pltoff_offset + ARCH_SIZE / 8,
4365 dyn_r_type, 0, gp);
4368 dyn_i->pltoff_done = 1;
4371 /* Return the descriptor's address. */
4372 value = (pltoff_sec->output_section->vma
4373 + pltoff_sec->output_offset
4374 + dyn_i->pltoff_offset);
4376 return value;
4379 /* Return the base VMA address which should be subtracted from real addresses
4380 when resolving @tprel() relocation.
4381 Main program TLS (whose template starts at PT_TLS p_vaddr)
4382 is assigned offset round(2 * size of pointer, PT_TLS p_align). */
4384 static bfd_vma
4385 elfNN_ia64_tprel_base (info)
4386 struct bfd_link_info *info;
4388 asection *tls_sec = elf_hash_table (info)->tls_sec;
4390 BFD_ASSERT (tls_sec != NULL);
4391 return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
4392 tls_sec->alignment_power);
4395 /* Return the base VMA address which should be subtracted from real addresses
4396 when resolving @dtprel() relocation.
4397 This is PT_TLS segment p_vaddr. */
4399 static bfd_vma
4400 elfNN_ia64_dtprel_base (info)
4401 struct bfd_link_info *info;
4403 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4404 return elf_hash_table (info)->tls_sec->vma;
4407 /* Called through qsort to sort the .IA_64.unwind section during a
4408 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
4409 to the output bfd so we can do proper endianness frobbing. */
4411 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
4413 static int
4414 elfNN_ia64_unwind_entry_compare (a, b)
4415 const PTR a;
4416 const PTR b;
4418 bfd_vma av, bv;
4420 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
4421 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
4423 return (av < bv ? -1 : av > bv ? 1 : 0);
4426 /* Make sure we've got ourselves a nice fat __gp value. */
4427 static bfd_boolean
4428 elfNN_ia64_choose_gp (abfd, info)
4429 bfd *abfd;
4430 struct bfd_link_info *info;
4432 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
4433 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
4434 struct elf_link_hash_entry *gp;
4435 bfd_vma gp_val;
4436 asection *os;
4437 struct elfNN_ia64_link_hash_table *ia64_info;
4439 ia64_info = elfNN_ia64_hash_table (info);
4441 /* Find the min and max vma of all sections marked short. Also collect
4442 min and max vma of any type, for use in selecting a nice gp. */
4443 for (os = abfd->sections; os ; os = os->next)
4445 bfd_vma lo, hi;
4447 if ((os->flags & SEC_ALLOC) == 0)
4448 continue;
4450 lo = os->vma;
4451 hi = os->vma + (os->rawsize ? os->rawsize : os->size);
4452 if (hi < lo)
4453 hi = (bfd_vma) -1;
4455 if (min_vma > lo)
4456 min_vma = lo;
4457 if (max_vma < hi)
4458 max_vma = hi;
4459 if (os->flags & SEC_SMALL_DATA)
4461 if (min_short_vma > lo)
4462 min_short_vma = lo;
4463 if (max_short_vma < hi)
4464 max_short_vma = hi;
4468 /* See if the user wants to force a value. */
4469 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4470 FALSE, FALSE);
4472 if (gp
4473 && (gp->root.type == bfd_link_hash_defined
4474 || gp->root.type == bfd_link_hash_defweak))
4476 asection *gp_sec = gp->root.u.def.section;
4477 gp_val = (gp->root.u.def.value
4478 + gp_sec->output_section->vma
4479 + gp_sec->output_offset);
4481 else
4483 /* Pick a sensible value. */
4485 asection *got_sec = ia64_info->got_sec;
4487 /* Start with just the address of the .got. */
4488 if (got_sec)
4489 gp_val = got_sec->output_section->vma;
4490 else if (max_short_vma != 0)
4491 gp_val = min_short_vma;
4492 else if (max_vma - min_vma < 0x200000)
4493 gp_val = min_vma;
4494 else
4495 gp_val = max_vma - 0x200000 + 8;
4497 /* If it is possible to address the entire image, but we
4498 don't with the choice above, adjust. */
4499 if (max_vma - min_vma < 0x400000
4500 && (max_vma - gp_val >= 0x200000
4501 || gp_val - min_vma > 0x200000))
4502 gp_val = min_vma + 0x200000;
4503 else if (max_short_vma != 0)
4505 /* If we don't cover all the short data, adjust. */
4506 if (max_short_vma - gp_val >= 0x200000)
4507 gp_val = min_short_vma + 0x200000;
4509 /* If we're addressing stuff past the end, adjust back. */
4510 if (gp_val > max_vma)
4511 gp_val = max_vma - 0x200000 + 8;
4515 /* Validate whether all SHF_IA_64_SHORT sections are within
4516 range of the chosen GP. */
4518 if (max_short_vma != 0)
4520 if (max_short_vma - min_short_vma >= 0x400000)
4522 (*_bfd_error_handler)
4523 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
4524 bfd_get_filename (abfd),
4525 (unsigned long) (max_short_vma - min_short_vma));
4526 return FALSE;
4528 else if ((gp_val > min_short_vma
4529 && gp_val - min_short_vma > 0x200000)
4530 || (gp_val < max_short_vma
4531 && max_short_vma - gp_val >= 0x200000))
4533 (*_bfd_error_handler)
4534 (_("%s: __gp does not cover short data segment"),
4535 bfd_get_filename (abfd));
4536 return FALSE;
4540 _bfd_set_gp_value (abfd, gp_val);
4542 return TRUE;
4545 static bfd_boolean
4546 elfNN_ia64_final_link (abfd, info)
4547 bfd *abfd;
4548 struct bfd_link_info *info;
4550 struct elfNN_ia64_link_hash_table *ia64_info;
4551 asection *unwind_output_sec;
4553 ia64_info = elfNN_ia64_hash_table (info);
4555 /* Make sure we've got ourselves a nice fat __gp value. */
4556 if (!info->relocatable)
4558 bfd_vma gp_val;
4559 struct elf_link_hash_entry *gp;
4561 /* We assume after gp is set, section size will only decrease. We
4562 need to adjust gp for it. */
4563 _bfd_set_gp_value (abfd, 0);
4564 if (! elfNN_ia64_choose_gp (abfd, info))
4565 return FALSE;
4566 gp_val = _bfd_get_gp_value (abfd);
4568 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4569 FALSE, FALSE);
4570 if (gp)
4572 gp->root.type = bfd_link_hash_defined;
4573 gp->root.u.def.value = gp_val;
4574 gp->root.u.def.section = bfd_abs_section_ptr;
4578 /* If we're producing a final executable, we need to sort the contents
4579 of the .IA_64.unwind section. Force this section to be relocated
4580 into memory rather than written immediately to the output file. */
4581 unwind_output_sec = NULL;
4582 if (!info->relocatable)
4584 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
4585 if (s)
4587 unwind_output_sec = s->output_section;
4588 unwind_output_sec->contents
4589 = bfd_malloc (unwind_output_sec->size);
4590 if (unwind_output_sec->contents == NULL)
4591 return FALSE;
4595 /* Invoke the regular ELF backend linker to do all the work. */
4596 if (!bfd_elf_final_link (abfd, info))
4597 return FALSE;
4599 if (unwind_output_sec)
4601 elfNN_ia64_unwind_entry_compare_bfd = abfd;
4602 qsort (unwind_output_sec->contents,
4603 (size_t) (unwind_output_sec->size / 24),
4605 elfNN_ia64_unwind_entry_compare);
4607 if (! bfd_set_section_contents (abfd, unwind_output_sec,
4608 unwind_output_sec->contents, (bfd_vma) 0,
4609 unwind_output_sec->size))
4610 return FALSE;
4613 return TRUE;
4616 static bfd_boolean
4617 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
4618 contents, relocs, local_syms, local_sections)
4619 bfd *output_bfd;
4620 struct bfd_link_info *info;
4621 bfd *input_bfd;
4622 asection *input_section;
4623 bfd_byte *contents;
4624 Elf_Internal_Rela *relocs;
4625 Elf_Internal_Sym *local_syms;
4626 asection **local_sections;
4628 struct elfNN_ia64_link_hash_table *ia64_info;
4629 Elf_Internal_Shdr *symtab_hdr;
4630 Elf_Internal_Rela *rel;
4631 Elf_Internal_Rela *relend;
4632 asection *srel;
4633 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
4634 bfd_vma gp_val;
4636 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4637 ia64_info = elfNN_ia64_hash_table (info);
4639 /* Infect various flags from the input section to the output section. */
4640 if (info->relocatable)
4642 bfd_vma flags;
4644 flags = elf_section_data(input_section)->this_hdr.sh_flags;
4645 flags &= SHF_IA_64_NORECOV;
4647 elf_section_data(input_section->output_section)
4648 ->this_hdr.sh_flags |= flags;
4651 gp_val = _bfd_get_gp_value (output_bfd);
4652 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
4654 rel = relocs;
4655 relend = relocs + input_section->reloc_count;
4656 for (; rel < relend; ++rel)
4658 struct elf_link_hash_entry *h;
4659 struct elfNN_ia64_dyn_sym_info *dyn_i;
4660 bfd_reloc_status_type r;
4661 reloc_howto_type *howto;
4662 unsigned long r_symndx;
4663 Elf_Internal_Sym *sym;
4664 unsigned int r_type;
4665 bfd_vma value;
4666 asection *sym_sec;
4667 bfd_byte *hit_addr;
4668 bfd_boolean dynamic_symbol_p;
4669 bfd_boolean undef_weak_ref;
4671 r_type = ELFNN_R_TYPE (rel->r_info);
4672 if (r_type > R_IA64_MAX_RELOC_CODE)
4674 (*_bfd_error_handler)
4675 (_("%B: unknown relocation type %d"),
4676 input_bfd, (int) r_type);
4677 bfd_set_error (bfd_error_bad_value);
4678 ret_val = FALSE;
4679 continue;
4682 howto = lookup_howto (r_type);
4683 r_symndx = ELFNN_R_SYM (rel->r_info);
4684 h = NULL;
4685 sym = NULL;
4686 sym_sec = NULL;
4687 undef_weak_ref = FALSE;
4689 if (r_symndx < symtab_hdr->sh_info)
4691 /* Reloc against local symbol. */
4692 asection *msec;
4693 sym = local_syms + r_symndx;
4694 sym_sec = local_sections[r_symndx];
4695 msec = sym_sec;
4696 value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
4697 if (!info->relocatable
4698 && (sym_sec->flags & SEC_MERGE) != 0
4699 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
4700 && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
4702 struct elfNN_ia64_local_hash_entry *loc_h;
4704 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
4705 if (loc_h && ! loc_h->sec_merge_done)
4707 struct elfNN_ia64_dyn_sym_info *dynent;
4708 unsigned int count;
4710 for (count = loc_h->count, dynent = loc_h->info;
4711 count != 0;
4712 count--, dynent++)
4714 msec = sym_sec;
4715 dynent->addend =
4716 _bfd_merged_section_offset (output_bfd, &msec,
4717 elf_section_data (msec)->
4718 sec_info,
4719 sym->st_value
4720 + dynent->addend);
4721 dynent->addend -= sym->st_value;
4722 dynent->addend += msec->output_section->vma
4723 + msec->output_offset
4724 - sym_sec->output_section->vma
4725 - sym_sec->output_offset;
4728 /* We may have introduced duplicated entries. We need
4729 to remove them properly. */
4730 count = sort_dyn_sym_info (loc_h->info, loc_h->count);
4731 if (count != loc_h->count)
4733 loc_h->count = count;
4734 loc_h->sorted_count = count;
4737 loc_h->sec_merge_done = 1;
4741 else
4743 bfd_boolean unresolved_reloc;
4744 bfd_boolean warned;
4745 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
4747 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4748 r_symndx, symtab_hdr, sym_hashes,
4749 h, sym_sec, value,
4750 unresolved_reloc, warned);
4752 if (h->root.type == bfd_link_hash_undefweak)
4753 undef_weak_ref = TRUE;
4754 else if (warned)
4755 continue;
4758 /* For relocs against symbols from removed linkonce sections,
4759 or sections discarded by a linker script, we just want the
4760 section contents zeroed. Avoid any special processing. */
4761 if (sym_sec != NULL && elf_discarded_section (sym_sec))
4763 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
4764 rel->r_info = 0;
4765 rel->r_addend = 0;
4766 continue;
4769 if (info->relocatable)
4770 continue;
4772 hit_addr = contents + rel->r_offset;
4773 value += rel->r_addend;
4774 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
4776 switch (r_type)
4778 case R_IA64_NONE:
4779 case R_IA64_LDXMOV:
4780 continue;
4782 case R_IA64_IMM14:
4783 case R_IA64_IMM22:
4784 case R_IA64_IMM64:
4785 case R_IA64_DIR32MSB:
4786 case R_IA64_DIR32LSB:
4787 case R_IA64_DIR64MSB:
4788 case R_IA64_DIR64LSB:
4789 /* Install a dynamic relocation for this reloc. */
4790 if ((dynamic_symbol_p || info->shared)
4791 && r_symndx != 0
4792 && (input_section->flags & SEC_ALLOC) != 0)
4794 unsigned int dyn_r_type;
4795 long dynindx;
4796 bfd_vma addend;
4798 BFD_ASSERT (srel != NULL);
4800 switch (r_type)
4802 case R_IA64_IMM14:
4803 case R_IA64_IMM22:
4804 case R_IA64_IMM64:
4805 /* ??? People shouldn't be doing non-pic code in
4806 shared libraries nor dynamic executables. */
4807 (*_bfd_error_handler)
4808 (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4809 input_bfd,
4810 h ? h->root.root.string
4811 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4812 sym_sec));
4813 ret_val = FALSE;
4814 continue;
4816 default:
4817 break;
4820 /* If we don't need dynamic symbol lookup, find a
4821 matching RELATIVE relocation. */
4822 dyn_r_type = r_type;
4823 if (dynamic_symbol_p)
4825 dynindx = h->dynindx;
4826 addend = rel->r_addend;
4827 value = 0;
4829 else
4831 switch (r_type)
4833 case R_IA64_DIR32MSB:
4834 dyn_r_type = R_IA64_REL32MSB;
4835 break;
4836 case R_IA64_DIR32LSB:
4837 dyn_r_type = R_IA64_REL32LSB;
4838 break;
4839 case R_IA64_DIR64MSB:
4840 dyn_r_type = R_IA64_REL64MSB;
4841 break;
4842 case R_IA64_DIR64LSB:
4843 dyn_r_type = R_IA64_REL64LSB;
4844 break;
4846 default:
4847 break;
4849 dynindx = 0;
4850 addend = value;
4853 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4854 srel, rel->r_offset, dyn_r_type,
4855 dynindx, addend);
4857 /* Fall through. */
4859 case R_IA64_LTV32MSB:
4860 case R_IA64_LTV32LSB:
4861 case R_IA64_LTV64MSB:
4862 case R_IA64_LTV64LSB:
4863 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4864 break;
4866 case R_IA64_GPREL22:
4867 case R_IA64_GPREL64I:
4868 case R_IA64_GPREL32MSB:
4869 case R_IA64_GPREL32LSB:
4870 case R_IA64_GPREL64MSB:
4871 case R_IA64_GPREL64LSB:
4872 if (dynamic_symbol_p)
4874 (*_bfd_error_handler)
4875 (_("%B: @gprel relocation against dynamic symbol %s"),
4876 input_bfd,
4877 h ? h->root.root.string
4878 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4879 sym_sec));
4880 ret_val = FALSE;
4881 continue;
4883 value -= gp_val;
4884 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4885 break;
4887 case R_IA64_LTOFF22:
4888 case R_IA64_LTOFF22X:
4889 case R_IA64_LTOFF64I:
4890 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4891 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4892 rel->r_addend, value, R_IA64_DIRNNLSB);
4893 value -= gp_val;
4894 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4895 break;
4897 case R_IA64_PLTOFF22:
4898 case R_IA64_PLTOFF64I:
4899 case R_IA64_PLTOFF64MSB:
4900 case R_IA64_PLTOFF64LSB:
4901 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4902 value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4903 value -= gp_val;
4904 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4905 break;
4907 case R_IA64_FPTR64I:
4908 case R_IA64_FPTR32MSB:
4909 case R_IA64_FPTR32LSB:
4910 case R_IA64_FPTR64MSB:
4911 case R_IA64_FPTR64LSB:
4912 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4913 if (dyn_i->want_fptr)
4915 if (!undef_weak_ref)
4916 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4918 if (!dyn_i->want_fptr || info->pie)
4920 long dynindx;
4921 unsigned int dyn_r_type = r_type;
4922 bfd_vma addend = rel->r_addend;
4924 /* Otherwise, we expect the dynamic linker to create
4925 the entry. */
4927 if (dyn_i->want_fptr)
4929 if (r_type == R_IA64_FPTR64I)
4931 /* We can't represent this without a dynamic symbol.
4932 Adjust the relocation to be against an output
4933 section symbol, which are always present in the
4934 dynamic symbol table. */
4935 /* ??? People shouldn't be doing non-pic code in
4936 shared libraries. Hork. */
4937 (*_bfd_error_handler)
4938 (_("%B: linking non-pic code in a position independent executable"),
4939 input_bfd);
4940 ret_val = FALSE;
4941 continue;
4943 dynindx = 0;
4944 addend = value;
4945 dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
4947 else if (h)
4949 if (h->dynindx != -1)
4950 dynindx = h->dynindx;
4951 else
4952 dynindx = (_bfd_elf_link_lookup_local_dynindx
4953 (info, h->root.u.def.section->owner,
4954 global_sym_index (h)));
4955 value = 0;
4957 else
4959 dynindx = (_bfd_elf_link_lookup_local_dynindx
4960 (info, input_bfd, (long) r_symndx));
4961 value = 0;
4964 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4965 srel, rel->r_offset, dyn_r_type,
4966 dynindx, addend);
4969 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4970 break;
4972 case R_IA64_LTOFF_FPTR22:
4973 case R_IA64_LTOFF_FPTR64I:
4974 case R_IA64_LTOFF_FPTR32MSB:
4975 case R_IA64_LTOFF_FPTR32LSB:
4976 case R_IA64_LTOFF_FPTR64MSB:
4977 case R_IA64_LTOFF_FPTR64LSB:
4979 long dynindx;
4981 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4982 if (dyn_i->want_fptr)
4984 BFD_ASSERT (h == NULL || h->dynindx == -1);
4985 if (!undef_weak_ref)
4986 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4987 dynindx = -1;
4989 else
4991 /* Otherwise, we expect the dynamic linker to create
4992 the entry. */
4993 if (h)
4995 if (h->dynindx != -1)
4996 dynindx = h->dynindx;
4997 else
4998 dynindx = (_bfd_elf_link_lookup_local_dynindx
4999 (info, h->root.u.def.section->owner,
5000 global_sym_index (h)));
5002 else
5003 dynindx = (_bfd_elf_link_lookup_local_dynindx
5004 (info, input_bfd, (long) r_symndx));
5005 value = 0;
5008 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
5009 rel->r_addend, value, R_IA64_FPTRNNLSB);
5010 value -= gp_val;
5011 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5013 break;
5015 case R_IA64_PCREL32MSB:
5016 case R_IA64_PCREL32LSB:
5017 case R_IA64_PCREL64MSB:
5018 case R_IA64_PCREL64LSB:
5019 /* Install a dynamic relocation for this reloc. */
5020 if (dynamic_symbol_p && r_symndx != 0)
5022 BFD_ASSERT (srel != NULL);
5024 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
5025 srel, rel->r_offset, r_type,
5026 h->dynindx, rel->r_addend);
5028 goto finish_pcrel;
5030 case R_IA64_PCREL21B:
5031 case R_IA64_PCREL60B:
5032 /* We should have created a PLT entry for any dynamic symbol. */
5033 dyn_i = NULL;
5034 if (h)
5035 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
5037 if (dyn_i && dyn_i->want_plt2)
5039 /* Should have caught this earlier. */
5040 BFD_ASSERT (rel->r_addend == 0);
5042 value = (ia64_info->plt_sec->output_section->vma
5043 + ia64_info->plt_sec->output_offset
5044 + dyn_i->plt2_offset);
5046 else
5048 /* Since there's no PLT entry, Validate that this is
5049 locally defined. */
5050 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
5052 /* If the symbol is undef_weak, we shouldn't be trying
5053 to call it. There's every chance that we'd wind up
5054 with an out-of-range fixup here. Don't bother setting
5055 any value at all. */
5056 if (undef_weak_ref)
5057 continue;
5059 goto finish_pcrel;
5061 case R_IA64_PCREL21BI:
5062 case R_IA64_PCREL21F:
5063 case R_IA64_PCREL21M:
5064 case R_IA64_PCREL22:
5065 case R_IA64_PCREL64I:
5066 /* The PCREL21BI reloc is specifically not intended for use with
5067 dynamic relocs. PCREL21F and PCREL21M are used for speculation
5068 fixup code, and thus probably ought not be dynamic. The
5069 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
5070 if (dynamic_symbol_p)
5072 const char *msg;
5074 if (r_type == R_IA64_PCREL21BI)
5075 msg = _("%B: @internal branch to dynamic symbol %s");
5076 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
5077 msg = _("%B: speculation fixup to dynamic symbol %s");
5078 else
5079 msg = _("%B: @pcrel relocation against dynamic symbol %s");
5080 (*_bfd_error_handler) (msg, input_bfd,
5081 h ? h->root.root.string
5082 : bfd_elf_sym_name (input_bfd,
5083 symtab_hdr,
5084 sym,
5085 sym_sec));
5086 ret_val = FALSE;
5087 continue;
5089 goto finish_pcrel;
5091 finish_pcrel:
5092 /* Make pc-relative. */
5093 value -= (input_section->output_section->vma
5094 + input_section->output_offset
5095 + rel->r_offset) & ~ (bfd_vma) 0x3;
5096 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5097 break;
5099 case R_IA64_SEGREL32MSB:
5100 case R_IA64_SEGREL32LSB:
5101 case R_IA64_SEGREL64MSB:
5102 case R_IA64_SEGREL64LSB:
5104 struct elf_segment_map *m;
5105 Elf_Internal_Phdr *p;
5107 /* Find the segment that contains the output_section. */
5108 for (m = elf_tdata (output_bfd)->segment_map,
5109 p = elf_tdata (output_bfd)->phdr;
5110 m != NULL;
5111 m = m->next, p++)
5113 int i;
5114 for (i = m->count - 1; i >= 0; i--)
5115 if (m->sections[i] == input_section->output_section)
5116 break;
5117 if (i >= 0)
5118 break;
5121 if (m == NULL)
5123 r = bfd_reloc_notsupported;
5125 else
5127 /* The VMA of the segment is the vaddr of the associated
5128 program header. */
5129 if (value > p->p_vaddr)
5130 value -= p->p_vaddr;
5131 else
5132 value = 0;
5133 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5135 break;
5138 case R_IA64_SECREL32MSB:
5139 case R_IA64_SECREL32LSB:
5140 case R_IA64_SECREL64MSB:
5141 case R_IA64_SECREL64LSB:
5142 /* Make output-section relative to section where the symbol
5143 is defined. PR 475 */
5144 if (sym_sec)
5145 value -= sym_sec->output_section->vma;
5146 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5147 break;
5149 case R_IA64_IPLTMSB:
5150 case R_IA64_IPLTLSB:
5151 /* Install a dynamic relocation for this reloc. */
5152 if ((dynamic_symbol_p || info->shared)
5153 && (input_section->flags & SEC_ALLOC) != 0)
5155 BFD_ASSERT (srel != NULL);
5157 /* If we don't need dynamic symbol lookup, install two
5158 RELATIVE relocations. */
5159 if (!dynamic_symbol_p)
5161 unsigned int dyn_r_type;
5163 if (r_type == R_IA64_IPLTMSB)
5164 dyn_r_type = R_IA64_REL64MSB;
5165 else
5166 dyn_r_type = R_IA64_REL64LSB;
5168 elfNN_ia64_install_dyn_reloc (output_bfd, info,
5169 input_section,
5170 srel, rel->r_offset,
5171 dyn_r_type, 0, value);
5172 elfNN_ia64_install_dyn_reloc (output_bfd, info,
5173 input_section,
5174 srel, rel->r_offset + 8,
5175 dyn_r_type, 0, gp_val);
5177 else
5178 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
5179 srel, rel->r_offset, r_type,
5180 h->dynindx, rel->r_addend);
5183 if (r_type == R_IA64_IPLTMSB)
5184 r_type = R_IA64_DIR64MSB;
5185 else
5186 r_type = R_IA64_DIR64LSB;
5187 elfNN_ia64_install_value (hit_addr, value, r_type);
5188 r = elfNN_ia64_install_value (hit_addr + 8, gp_val, r_type);
5189 break;
5191 case R_IA64_TPREL14:
5192 case R_IA64_TPREL22:
5193 case R_IA64_TPREL64I:
5194 value -= elfNN_ia64_tprel_base (info);
5195 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5196 break;
5198 case R_IA64_DTPREL14:
5199 case R_IA64_DTPREL22:
5200 case R_IA64_DTPREL64I:
5201 case R_IA64_DTPREL32LSB:
5202 case R_IA64_DTPREL32MSB:
5203 case R_IA64_DTPREL64LSB:
5204 case R_IA64_DTPREL64MSB:
5205 value -= elfNN_ia64_dtprel_base (info);
5206 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5207 break;
5209 case R_IA64_LTOFF_TPREL22:
5210 case R_IA64_LTOFF_DTPMOD22:
5211 case R_IA64_LTOFF_DTPREL22:
5213 int got_r_type;
5214 long dynindx = h ? h->dynindx : -1;
5215 bfd_vma r_addend = rel->r_addend;
5217 switch (r_type)
5219 default:
5220 case R_IA64_LTOFF_TPREL22:
5221 if (!dynamic_symbol_p)
5223 if (!info->shared)
5224 value -= elfNN_ia64_tprel_base (info);
5225 else
5227 r_addend += value - elfNN_ia64_dtprel_base (info);
5228 dynindx = 0;
5231 got_r_type = R_IA64_TPREL64LSB;
5232 break;
5233 case R_IA64_LTOFF_DTPMOD22:
5234 if (!dynamic_symbol_p && !info->shared)
5235 value = 1;
5236 got_r_type = R_IA64_DTPMOD64LSB;
5237 break;
5238 case R_IA64_LTOFF_DTPREL22:
5239 if (!dynamic_symbol_p)
5240 value -= elfNN_ia64_dtprel_base (info);
5241 got_r_type = R_IA64_DTPRELNNLSB;
5242 break;
5244 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
5245 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
5246 value, got_r_type);
5247 value -= gp_val;
5248 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5250 break;
5252 default:
5253 r = bfd_reloc_notsupported;
5254 break;
5257 switch (r)
5259 case bfd_reloc_ok:
5260 break;
5262 case bfd_reloc_undefined:
5263 /* This can happen for global table relative relocs if
5264 __gp is undefined. This is a panic situation so we
5265 don't try to continue. */
5266 (*info->callbacks->undefined_symbol)
5267 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
5268 return FALSE;
5270 case bfd_reloc_notsupported:
5272 const char *name;
5274 if (h)
5275 name = h->root.root.string;
5276 else
5277 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5278 sym_sec);
5279 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
5280 name, input_bfd,
5281 input_section, rel->r_offset))
5282 return FALSE;
5283 ret_val = FALSE;
5285 break;
5287 case bfd_reloc_dangerous:
5288 case bfd_reloc_outofrange:
5289 case bfd_reloc_overflow:
5290 default:
5292 const char *name;
5294 if (h)
5295 name = h->root.root.string;
5296 else
5297 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5298 sym_sec);
5300 switch (r_type)
5302 case R_IA64_PCREL21B:
5303 case R_IA64_PCREL21BI:
5304 case R_IA64_PCREL21M:
5305 case R_IA64_PCREL21F:
5306 if (is_elf_hash_table (info->hash))
5308 /* Relaxtion is always performed for ELF output.
5309 Overflow failures for those relocations mean
5310 that the section is too big to relax. */
5311 (*_bfd_error_handler)
5312 (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
5313 input_bfd, input_section, howto->name, name,
5314 rel->r_offset, input_section->size);
5315 break;
5317 default:
5318 if (!(*info->callbacks->reloc_overflow) (info,
5319 &h->root,
5320 name,
5321 howto->name,
5322 (bfd_vma) 0,
5323 input_bfd,
5324 input_section,
5325 rel->r_offset))
5326 return FALSE;
5327 break;
5330 ret_val = FALSE;
5332 break;
5336 return ret_val;
5339 static bfd_boolean
5340 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
5341 bfd *output_bfd;
5342 struct bfd_link_info *info;
5343 struct elf_link_hash_entry *h;
5344 Elf_Internal_Sym *sym;
5346 struct elfNN_ia64_link_hash_table *ia64_info;
5347 struct elfNN_ia64_dyn_sym_info *dyn_i;
5349 ia64_info = elfNN_ia64_hash_table (info);
5350 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
5352 /* Fill in the PLT data, if required. */
5353 if (dyn_i && dyn_i->want_plt)
5355 Elf_Internal_Rela outrel;
5356 bfd_byte *loc;
5357 asection *plt_sec;
5358 bfd_vma plt_addr, pltoff_addr, gp_val, index;
5360 gp_val = _bfd_get_gp_value (output_bfd);
5362 /* Initialize the minimal PLT entry. */
5364 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
5365 plt_sec = ia64_info->plt_sec;
5366 loc = plt_sec->contents + dyn_i->plt_offset;
5368 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
5369 elfNN_ia64_install_value (loc, index, R_IA64_IMM22);
5370 elfNN_ia64_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
5372 plt_addr = (plt_sec->output_section->vma
5373 + plt_sec->output_offset
5374 + dyn_i->plt_offset);
5375 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
5377 /* Initialize the FULL PLT entry, if needed. */
5378 if (dyn_i->want_plt2)
5380 loc = plt_sec->contents + dyn_i->plt2_offset;
5382 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
5383 elfNN_ia64_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
5385 /* Mark the symbol as undefined, rather than as defined in the
5386 plt section. Leave the value alone. */
5387 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
5388 first place. But perhaps elflink.c did some for us. */
5389 if (!h->def_regular)
5390 sym->st_shndx = SHN_UNDEF;
5393 /* Create the dynamic relocation. */
5394 outrel.r_offset = pltoff_addr;
5395 if (bfd_little_endian (output_bfd))
5396 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
5397 else
5398 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
5399 outrel.r_addend = 0;
5401 /* This is fun. In the .IA_64.pltoff section, we've got entries
5402 that correspond both to real PLT entries, and those that
5403 happened to resolve to local symbols but need to be created
5404 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
5405 relocations for the real PLT should come at the end of the
5406 section, so that they can be indexed by plt entry at runtime.
5408 We emitted all of the relocations for the non-PLT @pltoff
5409 entries during relocate_section. So we can consider the
5410 existing sec->reloc_count to be the base of the array of
5411 PLT relocations. */
5413 loc = ia64_info->rel_pltoff_sec->contents;
5414 loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
5415 * sizeof (ElfNN_External_Rela));
5416 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
5419 /* Mark some specially defined symbols as absolute. */
5420 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
5421 || h == ia64_info->root.hgot
5422 || h == ia64_info->root.hplt)
5423 sym->st_shndx = SHN_ABS;
5425 return TRUE;
5428 static bfd_boolean
5429 elfNN_ia64_finish_dynamic_sections (abfd, info)
5430 bfd *abfd;
5431 struct bfd_link_info *info;
5433 struct elfNN_ia64_link_hash_table *ia64_info;
5434 bfd *dynobj;
5436 ia64_info = elfNN_ia64_hash_table (info);
5437 dynobj = ia64_info->root.dynobj;
5439 if (elf_hash_table (info)->dynamic_sections_created)
5441 ElfNN_External_Dyn *dyncon, *dynconend;
5442 asection *sdyn, *sgotplt;
5443 bfd_vma gp_val;
5445 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
5446 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
5447 BFD_ASSERT (sdyn != NULL);
5448 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
5449 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
5451 gp_val = _bfd_get_gp_value (abfd);
5453 for (; dyncon < dynconend; dyncon++)
5455 Elf_Internal_Dyn dyn;
5457 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
5459 switch (dyn.d_tag)
5461 case DT_PLTGOT:
5462 dyn.d_un.d_ptr = gp_val;
5463 break;
5465 case DT_PLTRELSZ:
5466 dyn.d_un.d_val = (ia64_info->minplt_entries
5467 * sizeof (ElfNN_External_Rela));
5468 break;
5470 case DT_JMPREL:
5471 /* See the comment above in finish_dynamic_symbol. */
5472 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
5473 + ia64_info->rel_pltoff_sec->output_offset
5474 + (ia64_info->rel_pltoff_sec->reloc_count
5475 * sizeof (ElfNN_External_Rela)));
5476 break;
5478 case DT_IA_64_PLT_RESERVE:
5479 dyn.d_un.d_ptr = (sgotplt->output_section->vma
5480 + sgotplt->output_offset);
5481 break;
5483 case DT_RELASZ:
5484 /* Do not have RELASZ include JMPREL. This makes things
5485 easier on ld.so. This is not what the rest of BFD set up. */
5486 dyn.d_un.d_val -= (ia64_info->minplt_entries
5487 * sizeof (ElfNN_External_Rela));
5488 break;
5491 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
5494 /* Initialize the PLT0 entry. */
5495 if (ia64_info->plt_sec)
5497 bfd_byte *loc = ia64_info->plt_sec->contents;
5498 bfd_vma pltres;
5500 memcpy (loc, plt_header, PLT_HEADER_SIZE);
5502 pltres = (sgotplt->output_section->vma
5503 + sgotplt->output_offset
5504 - gp_val);
5506 elfNN_ia64_install_value (loc+1, pltres, R_IA64_GPREL22);
5510 return TRUE;
5513 /* ELF file flag handling: */
5515 /* Function to keep IA-64 specific file flags. */
5516 static bfd_boolean
5517 elfNN_ia64_set_private_flags (abfd, flags)
5518 bfd *abfd;
5519 flagword flags;
5521 BFD_ASSERT (!elf_flags_init (abfd)
5522 || elf_elfheader (abfd)->e_flags == flags);
5524 elf_elfheader (abfd)->e_flags = flags;
5525 elf_flags_init (abfd) = TRUE;
5526 return TRUE;
5529 /* Merge backend specific data from an object file to the output
5530 object file when linking. */
5531 static bfd_boolean
5532 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
5533 bfd *ibfd, *obfd;
5535 flagword out_flags;
5536 flagword in_flags;
5537 bfd_boolean ok = TRUE;
5539 /* Don't even pretend to support mixed-format linking. */
5540 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
5541 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
5542 return FALSE;
5544 in_flags = elf_elfheader (ibfd)->e_flags;
5545 out_flags = elf_elfheader (obfd)->e_flags;
5547 if (! elf_flags_init (obfd))
5549 elf_flags_init (obfd) = TRUE;
5550 elf_elfheader (obfd)->e_flags = in_flags;
5552 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
5553 && bfd_get_arch_info (obfd)->the_default)
5555 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
5556 bfd_get_mach (ibfd));
5559 return TRUE;
5562 /* Check flag compatibility. */
5563 if (in_flags == out_flags)
5564 return TRUE;
5566 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
5567 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
5568 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
5570 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
5572 (*_bfd_error_handler)
5573 (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5574 ibfd);
5576 bfd_set_error (bfd_error_bad_value);
5577 ok = FALSE;
5579 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
5581 (*_bfd_error_handler)
5582 (_("%B: linking big-endian files with little-endian files"),
5583 ibfd);
5585 bfd_set_error (bfd_error_bad_value);
5586 ok = FALSE;
5588 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
5590 (*_bfd_error_handler)
5591 (_("%B: linking 64-bit files with 32-bit files"),
5592 ibfd);
5594 bfd_set_error (bfd_error_bad_value);
5595 ok = FALSE;
5597 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
5599 (*_bfd_error_handler)
5600 (_("%B: linking constant-gp files with non-constant-gp files"),
5601 ibfd);
5603 bfd_set_error (bfd_error_bad_value);
5604 ok = FALSE;
5606 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
5607 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
5609 (*_bfd_error_handler)
5610 (_("%B: linking auto-pic files with non-auto-pic files"),
5611 ibfd);
5613 bfd_set_error (bfd_error_bad_value);
5614 ok = FALSE;
5617 return ok;
5620 static bfd_boolean
5621 elfNN_ia64_print_private_bfd_data (abfd, ptr)
5622 bfd *abfd;
5623 PTR ptr;
5625 FILE *file = (FILE *) ptr;
5626 flagword flags = elf_elfheader (abfd)->e_flags;
5628 BFD_ASSERT (abfd != NULL && ptr != NULL);
5630 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
5631 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
5632 (flags & EF_IA_64_EXT) ? "EXT, " : "",
5633 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
5634 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
5635 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
5636 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
5637 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
5638 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
5640 _bfd_elf_print_private_bfd_data (abfd, ptr);
5641 return TRUE;
5644 static enum elf_reloc_type_class
5645 elfNN_ia64_reloc_type_class (rela)
5646 const Elf_Internal_Rela *rela;
5648 switch ((int) ELFNN_R_TYPE (rela->r_info))
5650 case R_IA64_REL32MSB:
5651 case R_IA64_REL32LSB:
5652 case R_IA64_REL64MSB:
5653 case R_IA64_REL64LSB:
5654 return reloc_class_relative;
5655 case R_IA64_IPLTMSB:
5656 case R_IA64_IPLTLSB:
5657 return reloc_class_plt;
5658 case R_IA64_COPY:
5659 return reloc_class_copy;
5660 default:
5661 return reloc_class_normal;
5665 static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
5667 { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5668 { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5669 { NULL, 0, 0, 0, 0 }
5672 static bfd_boolean
5673 elfNN_ia64_object_p (bfd *abfd)
5675 asection *sec;
5676 asection *group, *unwi, *unw;
5677 flagword flags;
5678 const char *name;
5679 char *unwi_name, *unw_name;
5680 bfd_size_type amt;
5682 if (abfd->flags & DYNAMIC)
5683 return TRUE;
5685 /* Flags for fake group section. */
5686 flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
5687 | SEC_EXCLUDE);
5689 /* We add a fake section group for each .gnu.linkonce.t.* section,
5690 which isn't in a section group, and its unwind sections. */
5691 for (sec = abfd->sections; sec != NULL; sec = sec->next)
5693 if (elf_sec_group (sec) == NULL
5694 && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
5695 == (SEC_LINK_ONCE | SEC_CODE))
5696 && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
5698 name = sec->name + 16;
5700 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
5701 unwi_name = bfd_alloc (abfd, amt);
5702 if (!unwi_name)
5703 return FALSE;
5705 strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
5706 unwi = bfd_get_section_by_name (abfd, unwi_name);
5708 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
5709 unw_name = bfd_alloc (abfd, amt);
5710 if (!unw_name)
5711 return FALSE;
5713 strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
5714 unw = bfd_get_section_by_name (abfd, unw_name);
5716 /* We need to create a fake group section for it and its
5717 unwind sections. */
5718 group = bfd_make_section_anyway_with_flags (abfd, name,
5719 flags);
5720 if (group == NULL)
5721 return FALSE;
5723 /* Move the fake group section to the beginning. */
5724 bfd_section_list_remove (abfd, group);
5725 bfd_section_list_prepend (abfd, group);
5727 elf_next_in_group (group) = sec;
5729 elf_group_name (sec) = name;
5730 elf_next_in_group (sec) = sec;
5731 elf_sec_group (sec) = group;
5733 if (unwi)
5735 elf_group_name (unwi) = name;
5736 elf_next_in_group (unwi) = sec;
5737 elf_next_in_group (sec) = unwi;
5738 elf_sec_group (unwi) = group;
5741 if (unw)
5743 elf_group_name (unw) = name;
5744 if (unwi)
5746 elf_next_in_group (unw) = elf_next_in_group (unwi);
5747 elf_next_in_group (unwi) = unw;
5749 else
5751 elf_next_in_group (unw) = sec;
5752 elf_next_in_group (sec) = unw;
5754 elf_sec_group (unw) = group;
5757 /* Fake SHT_GROUP section header. */
5758 elf_section_data (group)->this_hdr.bfd_section = group;
5759 elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
5762 return TRUE;
5765 static bfd_boolean
5766 elfNN_ia64_hpux_vec (const bfd_target *vec)
5768 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
5769 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
5772 static void
5773 elfNN_hpux_post_process_headers (abfd, info)
5774 bfd *abfd;
5775 struct bfd_link_info *info ATTRIBUTE_UNUSED;
5777 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5779 i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
5780 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
5783 bfd_boolean
5784 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
5785 bfd *abfd ATTRIBUTE_UNUSED;
5786 asection *sec;
5787 int *retval;
5789 if (bfd_is_com_section (sec))
5791 *retval = SHN_IA_64_ANSI_COMMON;
5792 return TRUE;
5794 return FALSE;
5797 static void
5798 elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5799 asymbol *asym)
5801 elf_symbol_type *elfsym = (elf_symbol_type *) asym;
5803 switch (elfsym->internal_elf_sym.st_shndx)
5805 case SHN_IA_64_ANSI_COMMON:
5806 asym->section = bfd_com_section_ptr;
5807 asym->value = elfsym->internal_elf_sym.st_size;
5808 asym->flags &= ~BSF_GLOBAL;
5809 break;
5814 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
5815 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
5816 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
5817 #define TARGET_BIG_NAME "elfNN-ia64-big"
5818 #define ELF_ARCH bfd_arch_ia64
5819 #define ELF_MACHINE_CODE EM_IA_64
5820 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
5821 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
5822 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
5823 #define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
5825 #define elf_backend_section_from_shdr \
5826 elfNN_ia64_section_from_shdr
5827 #define elf_backend_section_flags \
5828 elfNN_ia64_section_flags
5829 #define elf_backend_fake_sections \
5830 elfNN_ia64_fake_sections
5831 #define elf_backend_final_write_processing \
5832 elfNN_ia64_final_write_processing
5833 #define elf_backend_add_symbol_hook \
5834 elfNN_ia64_add_symbol_hook
5835 #define elf_backend_additional_program_headers \
5836 elfNN_ia64_additional_program_headers
5837 #define elf_backend_modify_segment_map \
5838 elfNN_ia64_modify_segment_map
5839 #define elf_backend_modify_program_headers \
5840 elfNN_ia64_modify_program_headers
5841 #define elf_info_to_howto \
5842 elfNN_ia64_info_to_howto
5844 #define bfd_elfNN_bfd_reloc_type_lookup \
5845 elfNN_ia64_reloc_type_lookup
5846 #define bfd_elfNN_bfd_reloc_name_lookup \
5847 elfNN_ia64_reloc_name_lookup
5848 #define bfd_elfNN_bfd_is_local_label_name \
5849 elfNN_ia64_is_local_label_name
5850 #define bfd_elfNN_bfd_relax_section \
5851 elfNN_ia64_relax_section
5853 #define elf_backend_object_p \
5854 elfNN_ia64_object_p
5856 /* Stuff for the BFD linker: */
5857 #define bfd_elfNN_bfd_link_hash_table_create \
5858 elfNN_ia64_hash_table_create
5859 #define bfd_elfNN_bfd_link_hash_table_free \
5860 elfNN_ia64_hash_table_free
5861 #define elf_backend_create_dynamic_sections \
5862 elfNN_ia64_create_dynamic_sections
5863 #define elf_backend_check_relocs \
5864 elfNN_ia64_check_relocs
5865 #define elf_backend_adjust_dynamic_symbol \
5866 elfNN_ia64_adjust_dynamic_symbol
5867 #define elf_backend_size_dynamic_sections \
5868 elfNN_ia64_size_dynamic_sections
5869 #define elf_backend_omit_section_dynsym \
5870 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
5871 #define elf_backend_relocate_section \
5872 elfNN_ia64_relocate_section
5873 #define elf_backend_finish_dynamic_symbol \
5874 elfNN_ia64_finish_dynamic_symbol
5875 #define elf_backend_finish_dynamic_sections \
5876 elfNN_ia64_finish_dynamic_sections
5877 #define bfd_elfNN_bfd_final_link \
5878 elfNN_ia64_final_link
5880 #define bfd_elfNN_bfd_merge_private_bfd_data \
5881 elfNN_ia64_merge_private_bfd_data
5882 #define bfd_elfNN_bfd_set_private_flags \
5883 elfNN_ia64_set_private_flags
5884 #define bfd_elfNN_bfd_print_private_bfd_data \
5885 elfNN_ia64_print_private_bfd_data
5887 #define elf_backend_plt_readonly 1
5888 #define elf_backend_want_plt_sym 0
5889 #define elf_backend_plt_alignment 5
5890 #define elf_backend_got_header_size 0
5891 #define elf_backend_want_got_plt 1
5892 #define elf_backend_may_use_rel_p 1
5893 #define elf_backend_may_use_rela_p 1
5894 #define elf_backend_default_use_rela_p 1
5895 #define elf_backend_want_dynbss 0
5896 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5897 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
5898 #define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
5899 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
5900 #define elf_backend_rela_normal 1
5901 #define elf_backend_special_sections elfNN_ia64_special_sections
5902 #define elf_backend_default_execstack 0
5904 /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5905 SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
5906 We don't want to flood users with so many error messages. We turn
5907 off the warning for now. It will be turned on later when the Intel
5908 compiler is fixed. */
5909 #define elf_backend_link_order_error_handler NULL
5911 #include "elfNN-target.h"
5913 /* HPUX-specific vectors. */
5915 #undef TARGET_LITTLE_SYM
5916 #undef TARGET_LITTLE_NAME
5917 #undef TARGET_BIG_SYM
5918 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
5919 #undef TARGET_BIG_NAME
5920 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
5922 /* These are HP-UX specific functions. */
5924 #undef elf_backend_post_process_headers
5925 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5927 #undef elf_backend_section_from_bfd_section
5928 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5930 #undef elf_backend_symbol_processing
5931 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5933 #undef elf_backend_want_p_paddr_set_to_zero
5934 #define elf_backend_want_p_paddr_set_to_zero 1
5936 #undef ELF_MAXPAGESIZE
5937 #define ELF_MAXPAGESIZE 0x1000 /* 4K */
5938 #undef ELF_COMMONPAGESIZE
5939 #undef ELF_OSABI
5940 #define ELF_OSABI ELFOSABI_HPUX
5942 #undef elfNN_bed
5943 #define elfNN_bed elfNN_ia64_hpux_bed
5945 #include "elfNN-target.h"
5947 #undef elf_backend_want_p_paddr_set_to_zero