Revert Adam Nemet's THUMB PLT patch
[binutils.git] / bfd / elfxx-ia64.c
blob4de90dffc424cc7684d04f440ad1354d1760e95f
1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "opcode/ia64.h"
26 #include "elf/ia64.h"
28 /* THE RULES for all the stuff the linker creates --
30 GOT Entries created in response to LTOFF or LTOFF_FPTR
31 relocations. Dynamic relocs created for dynamic
32 symbols in an application; REL relocs for locals
33 in a shared library.
35 FPTR The canonical function descriptor. Created for local
36 symbols in applications. Descriptors for dynamic symbols
37 and local symbols in shared libraries are created by
38 ld.so. Thus there are no dynamic relocs against these
39 objects. The FPTR relocs for such _are_ passed through
40 to the dynamic relocation tables.
42 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
43 Requires the creation of a PLTOFF entry. This does not
44 require any dynamic relocations.
46 PLTOFF Created by PLTOFF relocations. For local symbols, this
47 is an alternate function descriptor, and in shared libraries
48 requires two REL relocations. Note that this cannot be
49 transformed into an FPTR relocation, since it must be in
50 range of the GP. For dynamic symbols, this is a function
51 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
53 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
54 does not reqire dynamic relocations. */
56 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
58 typedef struct bfd_hash_entry *(*new_hash_entry_func)
59 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
61 /* In dynamically (linker-) created sections, we generally need to keep track
62 of the place a symbol or expression got allocated to. This is done via hash
63 tables that store entries of the following type. */
65 struct elfNN_ia64_dyn_sym_info
67 /* The addend for which this entry is relevant. */
68 bfd_vma addend;
70 /* Next addend in the list. */
71 struct elfNN_ia64_dyn_sym_info *next;
73 bfd_vma got_offset;
74 bfd_vma fptr_offset;
75 bfd_vma pltoff_offset;
76 bfd_vma plt_offset;
77 bfd_vma plt2_offset;
78 bfd_vma tprel_offset;
79 bfd_vma dtpmod_offset;
80 bfd_vma dtprel_offset;
82 /* The symbol table entry, if any, that this was derrived from. */
83 struct elf_link_hash_entry *h;
85 /* Used to count non-got, non-plt relocations for delayed sizing
86 of relocation sections. */
87 struct elfNN_ia64_dyn_reloc_entry
89 struct elfNN_ia64_dyn_reloc_entry *next;
90 asection *srel;
91 int type;
92 int count;
93 } *reloc_entries;
95 /* True when the section contents have been updated. */
96 unsigned got_done : 1;
97 unsigned fptr_done : 1;
98 unsigned pltoff_done : 1;
99 unsigned tprel_done : 1;
100 unsigned dtpmod_done : 1;
101 unsigned dtprel_done : 1;
103 /* True for the different kinds of linker data we want created. */
104 unsigned want_got : 1;
105 unsigned want_fptr : 1;
106 unsigned want_ltoff_fptr : 1;
107 unsigned want_plt : 1;
108 unsigned want_plt2 : 1;
109 unsigned want_pltoff : 1;
110 unsigned want_tprel : 1;
111 unsigned want_dtpmod : 1;
112 unsigned want_dtprel : 1;
115 struct elfNN_ia64_local_hash_entry
117 struct bfd_hash_entry root;
118 struct elfNN_ia64_dyn_sym_info *info;
120 /* True if this hash entry's addends was translated for
121 SHF_MERGE optimization. */
122 unsigned sec_merge_done : 1;
125 struct elfNN_ia64_local_hash_table
127 struct bfd_hash_table root;
128 /* No additional fields for now. */
131 struct elfNN_ia64_link_hash_entry
133 struct elf_link_hash_entry root;
134 struct elfNN_ia64_dyn_sym_info *info;
137 struct elfNN_ia64_link_hash_table
139 /* The main hash table. */
140 struct elf_link_hash_table root;
142 asection *got_sec; /* the linkage table section (or NULL) */
143 asection *rel_got_sec; /* dynamic relocation section for same */
144 asection *fptr_sec; /* function descriptor table (or NULL) */
145 asection *plt_sec; /* the primary plt section (or NULL) */
146 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
147 asection *rel_pltoff_sec; /* dynamic relocation section for same */
149 bfd_size_type minplt_entries; /* number of minplt entries */
150 unsigned reltext : 1; /* are there relocs against readonly sections? */
152 struct elfNN_ia64_local_hash_table loc_hash_table;
155 #define elfNN_ia64_hash_table(p) \
156 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
158 static bfd_reloc_status_type elfNN_ia64_reloc
159 PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
160 asection *input_section, bfd *output_bfd, char **error_message));
161 static reloc_howto_type * lookup_howto
162 PARAMS ((unsigned int rtype));
163 static reloc_howto_type *elfNN_ia64_reloc_type_lookup
164 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
165 static void elfNN_ia64_info_to_howto
166 PARAMS ((bfd *abfd, arelent *bfd_reloc, ElfNN_Internal_Rela *elf_reloc));
167 static boolean elfNN_ia64_relax_section
168 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
169 boolean *again));
170 static boolean is_unwind_section_name
171 PARAMS ((bfd *abfd, const char *));
172 static boolean elfNN_ia64_section_from_shdr
173 PARAMS ((bfd *, ElfNN_Internal_Shdr *, const char *));
174 static boolean elfNN_ia64_section_flags
175 PARAMS ((flagword *, ElfNN_Internal_Shdr *));
176 static boolean elfNN_ia64_fake_sections
177 PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec));
178 static void elfNN_ia64_final_write_processing
179 PARAMS ((bfd *abfd, boolean linker));
180 static boolean elfNN_ia64_add_symbol_hook
181 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
182 const char **namep, flagword *flagsp, asection **secp,
183 bfd_vma *valp));
184 static boolean elfNN_ia64_aix_vec
185 PARAMS ((const bfd_target *vec));
186 static boolean elfNN_ia64_aix_add_symbol_hook
187 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
188 const char **namep, flagword *flagsp, asection **secp,
189 bfd_vma *valp));
190 static boolean elfNN_ia64_aix_link_add_symbols
191 PARAMS ((bfd *abfd, struct bfd_link_info *info));
192 static int elfNN_ia64_additional_program_headers
193 PARAMS ((bfd *abfd));
194 static boolean elfNN_ia64_modify_segment_map
195 PARAMS ((bfd *));
196 static boolean elfNN_ia64_is_local_label_name
197 PARAMS ((bfd *abfd, const char *name));
198 static boolean elfNN_ia64_dynamic_symbol_p
199 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
200 static boolean elfNN_ia64_local_hash_table_init
201 PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
202 new_hash_entry_func new));
203 static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
204 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
205 const char *string));
206 static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
207 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
208 const char *string));
209 static void elfNN_ia64_hash_copy_indirect
210 PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
211 static void elfNN_ia64_hash_hide_symbol
212 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
213 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
214 PARAMS ((bfd *abfd));
215 static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
216 PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
217 boolean create, boolean copy));
218 static boolean elfNN_ia64_global_dyn_sym_thunk
219 PARAMS ((struct bfd_hash_entry *, PTR));
220 static boolean elfNN_ia64_local_dyn_sym_thunk
221 PARAMS ((struct bfd_hash_entry *, PTR));
222 static void elfNN_ia64_dyn_sym_traverse
223 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
224 boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
225 PTR info));
226 static boolean elfNN_ia64_create_dynamic_sections
227 PARAMS ((bfd *abfd, struct bfd_link_info *info));
228 static struct elfNN_ia64_local_hash_entry * get_local_sym_hash
229 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
230 bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
231 static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
232 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
233 struct elf_link_hash_entry *h,
234 bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
235 static asection *get_got
236 PARAMS ((bfd *abfd, struct bfd_link_info *info,
237 struct elfNN_ia64_link_hash_table *ia64_info));
238 static asection *get_fptr
239 PARAMS ((bfd *abfd, struct bfd_link_info *info,
240 struct elfNN_ia64_link_hash_table *ia64_info));
241 static asection *get_pltoff
242 PARAMS ((bfd *abfd, struct bfd_link_info *info,
243 struct elfNN_ia64_link_hash_table *ia64_info));
244 static asection *get_reloc_section
245 PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
246 asection *sec, boolean create));
247 static boolean count_dyn_reloc
248 PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
249 asection *srel, int type));
250 static boolean elfNN_ia64_check_relocs
251 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
252 const Elf_Internal_Rela *relocs));
253 static boolean elfNN_ia64_adjust_dynamic_symbol
254 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
255 static long global_sym_index
256 PARAMS ((struct elf_link_hash_entry *h));
257 static boolean allocate_fptr
258 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
259 static boolean allocate_global_data_got
260 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
261 static boolean allocate_global_fptr_got
262 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
263 static boolean allocate_local_got
264 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
265 static boolean allocate_pltoff_entries
266 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
267 static boolean allocate_plt_entries
268 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
269 static boolean allocate_plt2_entries
270 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
271 static boolean allocate_dynrel_entries
272 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
273 static boolean elfNN_ia64_size_dynamic_sections
274 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
275 static bfd_reloc_status_type elfNN_ia64_install_value
276 PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
277 static void elfNN_ia64_install_dyn_reloc
278 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
279 asection *srel, bfd_vma offset, unsigned int type,
280 long dynindx, bfd_vma addend));
281 static bfd_vma set_got_entry
282 PARAMS ((bfd *abfd, struct bfd_link_info *info,
283 struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
284 bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
285 static bfd_vma set_fptr_entry
286 PARAMS ((bfd *abfd, struct bfd_link_info *info,
287 struct elfNN_ia64_dyn_sym_info *dyn_i,
288 bfd_vma value));
289 static bfd_vma set_pltoff_entry
290 PARAMS ((bfd *abfd, struct bfd_link_info *info,
291 struct elfNN_ia64_dyn_sym_info *dyn_i,
292 bfd_vma value, boolean));
293 static bfd_vma elfNN_ia64_tprel_base
294 PARAMS ((struct bfd_link_info *info));
295 static bfd_vma elfNN_ia64_dtprel_base
296 PARAMS ((struct bfd_link_info *info));
297 static int elfNN_ia64_unwind_entry_compare
298 PARAMS ((const PTR, const PTR));
299 static boolean elfNN_ia64_final_link
300 PARAMS ((bfd *abfd, struct bfd_link_info *info));
301 static boolean elfNN_ia64_relocate_section
302 PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
303 asection *input_section, bfd_byte *contents,
304 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
305 asection **local_sections));
306 static boolean elfNN_ia64_finish_dynamic_symbol
307 PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
308 struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
309 static boolean elfNN_ia64_finish_dynamic_sections
310 PARAMS ((bfd *abfd, struct bfd_link_info *info));
311 static boolean elfNN_ia64_set_private_flags
312 PARAMS ((bfd *abfd, flagword flags));
313 static boolean elfNN_ia64_merge_private_bfd_data
314 PARAMS ((bfd *ibfd, bfd *obfd));
315 static boolean elfNN_ia64_print_private_bfd_data
316 PARAMS ((bfd *abfd, PTR ptr));
317 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
318 PARAMS ((const Elf_Internal_Rela *));
319 static boolean elfNN_ia64_hpux_vec
320 PARAMS ((const bfd_target *vec));
321 static void elfNN_hpux_post_process_headers
322 PARAMS ((bfd *abfd, struct bfd_link_info *info));
323 boolean elfNN_hpux_backend_section_from_bfd_section
324 PARAMS ((bfd *abfd, asection *sec, int *retval));
326 /* ia64-specific relocation. */
328 /* Perform a relocation. Not much to do here as all the hard work is
329 done in elfNN_ia64_final_link_relocate. */
330 static bfd_reloc_status_type
331 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
332 output_bfd, error_message)
333 bfd *abfd ATTRIBUTE_UNUSED;
334 arelent *reloc;
335 asymbol *sym ATTRIBUTE_UNUSED;
336 PTR data ATTRIBUTE_UNUSED;
337 asection *input_section;
338 bfd *output_bfd;
339 char **error_message;
341 if (output_bfd)
343 reloc->address += input_section->output_offset;
344 return bfd_reloc_ok;
346 *error_message = "Unsupported call to elfNN_ia64_reloc";
347 return bfd_reloc_notsupported;
350 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
351 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
352 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
354 /* This table has to be sorted according to increasing number of the
355 TYPE field. */
356 static reloc_howto_type ia64_howto_table[] =
358 IA64_HOWTO (R_IA64_NONE, "NONE", 0, false, true),
360 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, false, true),
361 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, false, true),
362 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, false, true),
363 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, false, true),
364 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, false, true),
365 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, false, true),
366 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, false, true),
368 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, false, true),
369 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, false, true),
370 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, false, true),
371 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, false, true),
372 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, false, true),
373 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, false, true),
375 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, false, true),
376 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, false, true),
378 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, false, true),
379 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, false, true),
380 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, false, true),
381 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, false, true),
383 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, false, true),
384 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, false, true),
385 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, false, true),
386 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, false, true),
387 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, false, true),
389 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, true, true),
390 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, true, true),
391 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, true, true),
392 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, true, true),
393 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, true, true),
394 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, true, true),
395 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, true, true),
396 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, true, true),
398 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true),
399 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true),
400 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, false, true),
401 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, false, true),
402 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
403 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
405 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
406 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
407 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
408 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, false, true),
410 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, false, true),
411 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, false, true),
412 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, false, true),
413 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, false, true),
415 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, false, true),
416 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, false, true),
417 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, false, true),
418 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, false, true),
420 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, false, true),
421 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, false, true),
422 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, false, true),
423 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, false, true),
425 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, true, true),
426 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, true, true),
427 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, true, true),
429 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, false, true),
430 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, false, true),
431 IA64_HOWTO (R_IA64_COPY, "COPY", 4, false, true),
432 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, false, true),
433 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, false, true),
435 IA64_HOWTO (R_IA64_TPREL14, "TPREL14", 0, false, false),
436 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, false, false),
437 IA64_HOWTO (R_IA64_TPREL64I, "TPREL64I", 0, false, false),
438 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 8, false, false),
439 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 8, false, false),
440 IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, false, false),
442 IA64_HOWTO (R_IA64_DTPMOD64MSB, "TPREL64MSB", 8, false, false),
443 IA64_HOWTO (R_IA64_DTPMOD64LSB, "TPREL64LSB", 8, false, false),
444 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, false, false),
446 IA64_HOWTO (R_IA64_DTPREL14, "DTPREL14", 0, false, false),
447 IA64_HOWTO (R_IA64_DTPREL22, "DTPREL22", 0, false, false),
448 IA64_HOWTO (R_IA64_DTPREL64I, "DTPREL64I", 0, false, false),
449 IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 4, false, false),
450 IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 4, false, false),
451 IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 8, false, false),
452 IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 8, false, false),
453 IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, false, false),
456 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
458 /* Given a BFD reloc type, return the matching HOWTO structure. */
460 static reloc_howto_type *
461 lookup_howto (rtype)
462 unsigned int rtype;
464 static int inited = 0;
465 int i;
467 if (!inited)
469 inited = 1;
471 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
472 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
473 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
476 BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
477 i = elf_code_to_howto_index[rtype];
478 if (i >= NELEMS (ia64_howto_table))
479 return 0;
480 return ia64_howto_table + i;
483 static reloc_howto_type*
484 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
485 bfd *abfd ATTRIBUTE_UNUSED;
486 bfd_reloc_code_real_type bfd_code;
488 unsigned int rtype;
490 switch (bfd_code)
492 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
494 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
495 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
496 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
498 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
499 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
500 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
501 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
503 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
504 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
505 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
506 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
507 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
508 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
510 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
511 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
513 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
514 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
515 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
516 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
517 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
518 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
519 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
520 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
521 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
523 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
524 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
525 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
526 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
527 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
528 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
529 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
530 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
531 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
532 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
533 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
535 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
536 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
537 case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
538 case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
539 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
540 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
542 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
543 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
544 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
545 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
547 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
548 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
549 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
550 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
552 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
553 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
554 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
555 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
557 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
558 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
559 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
560 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
562 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
563 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
564 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
565 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
566 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
568 case BFD_RELOC_IA64_TPREL14: rtype = R_IA64_TPREL14; break;
569 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
570 case BFD_RELOC_IA64_TPREL64I: rtype = R_IA64_TPREL64I; break;
571 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
572 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
573 case BFD_RELOC_IA64_LTOFF_TPREL22: rtype = R_IA64_LTOFF_TPREL22; break;
575 case BFD_RELOC_IA64_DTPMOD64MSB: rtype = R_IA64_DTPMOD64MSB; break;
576 case BFD_RELOC_IA64_DTPMOD64LSB: rtype = R_IA64_DTPMOD64LSB; break;
577 case BFD_RELOC_IA64_LTOFF_DTPMOD22: rtype = R_IA64_LTOFF_DTPMOD22; break;
579 case BFD_RELOC_IA64_DTPREL14: rtype = R_IA64_DTPREL14; break;
580 case BFD_RELOC_IA64_DTPREL22: rtype = R_IA64_DTPREL22; break;
581 case BFD_RELOC_IA64_DTPREL64I: rtype = R_IA64_DTPREL64I; break;
582 case BFD_RELOC_IA64_DTPREL32MSB: rtype = R_IA64_DTPREL32MSB; break;
583 case BFD_RELOC_IA64_DTPREL32LSB: rtype = R_IA64_DTPREL32LSB; break;
584 case BFD_RELOC_IA64_DTPREL64MSB: rtype = R_IA64_DTPREL64MSB; break;
585 case BFD_RELOC_IA64_DTPREL64LSB: rtype = R_IA64_DTPREL64LSB; break;
586 case BFD_RELOC_IA64_LTOFF_DTPREL22: rtype = R_IA64_LTOFF_DTPREL22; break;
588 default: return 0;
590 return lookup_howto (rtype);
593 /* Given a ELF reloc, return the matching HOWTO structure. */
595 static void
596 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
597 bfd *abfd ATTRIBUTE_UNUSED;
598 arelent *bfd_reloc;
599 ElfNN_Internal_Rela *elf_reloc;
601 bfd_reloc->howto
602 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
605 #define PLT_HEADER_SIZE (3 * 16)
606 #define PLT_MIN_ENTRY_SIZE (1 * 16)
607 #define PLT_FULL_ENTRY_SIZE (2 * 16)
608 #define PLT_RESERVED_WORDS 3
610 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
612 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
613 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
614 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
615 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
616 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
617 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
618 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
619 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
620 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
623 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
625 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
626 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
627 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
630 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
632 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
633 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
634 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
635 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
636 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
637 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
640 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
641 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
642 #define DYNAMIC_INTERPRETER(abfd) \
643 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
645 /* Select out of range branch fixup type. Note that Itanium does
646 not support brl, and so it gets emulated by the kernel. */
647 #undef USE_BRL
649 static const bfd_byte oor_brl[16] =
651 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
653 0x00, 0x00, 0x00, 0xc0
656 static const bfd_byte oor_ip[48] =
658 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
659 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
660 0x01, 0x00, 0x00, 0x60,
661 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
662 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
663 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
664 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
665 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
666 0x60, 0x00, 0x80, 0x00 /* br b6;; */
669 /* These functions do relaxation for IA-64 ELF.
671 This is primarily to support branches to targets out of range;
672 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
674 static boolean
675 elfNN_ia64_relax_section (abfd, sec, link_info, again)
676 bfd *abfd;
677 asection *sec;
678 struct bfd_link_info *link_info;
679 boolean *again;
681 struct one_fixup
683 struct one_fixup *next;
684 asection *tsec;
685 bfd_vma toff;
686 bfd_vma trampoff;
689 Elf_Internal_Shdr *symtab_hdr;
690 Elf_Internal_Rela *internal_relocs;
691 Elf_Internal_Rela *irel, *irelend;
692 bfd_byte *contents;
693 Elf_Internal_Sym *isymbuf = NULL;
694 struct elfNN_ia64_link_hash_table *ia64_info;
695 struct one_fixup *fixups = NULL;
696 boolean changed_contents = false;
697 boolean changed_relocs = false;
699 /* Assume we're not going to change any sizes, and we'll only need
700 one pass. */
701 *again = false;
703 /* Nothing to do if there are no relocations. */
704 if ((sec->flags & SEC_RELOC) == 0
705 || sec->reloc_count == 0)
706 return true;
708 /* If this is the first time we have been called for this section,
709 initialize the cooked size. */
710 if (sec->_cooked_size == 0)
711 sec->_cooked_size = sec->_raw_size;
713 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
715 /* Load the relocations for this section. */
716 internal_relocs = (_bfd_elfNN_link_read_relocs
717 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
718 link_info->keep_memory));
719 if (internal_relocs == NULL)
720 return false;
722 ia64_info = elfNN_ia64_hash_table (link_info);
723 irelend = internal_relocs + sec->reloc_count;
725 for (irel = internal_relocs; irel < irelend; irel++)
726 if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
727 break;
729 /* No branch-type relocations. */
730 if (irel == irelend)
732 if (elf_section_data (sec)->relocs != internal_relocs)
733 free (internal_relocs);
734 return true;
737 /* Get the section contents. */
738 if (elf_section_data (sec)->this_hdr.contents != NULL)
739 contents = elf_section_data (sec)->this_hdr.contents;
740 else
742 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
743 if (contents == NULL)
744 goto error_return;
746 if (! bfd_get_section_contents (abfd, sec, contents,
747 (file_ptr) 0, sec->_raw_size))
748 goto error_return;
751 for (; irel < irelend; irel++)
753 bfd_vma symaddr, reladdr, trampoff, toff, roff;
754 asection *tsec;
755 struct one_fixup *f;
756 bfd_size_type amt;
758 if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
759 continue;
761 /* Get the value of the symbol referred to by the reloc. */
762 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
764 /* A local symbol. */
765 Elf_Internal_Sym *isym;
767 /* Read this BFD's local symbols. */
768 if (isymbuf == NULL)
770 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
771 if (isymbuf == NULL)
772 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
773 symtab_hdr->sh_info, 0,
774 NULL, NULL, NULL);
775 if (isymbuf == 0)
776 goto error_return;
779 isym = isymbuf + ELF64_R_SYM (irel->r_info);
780 if (isym->st_shndx == SHN_UNDEF)
781 continue; /* We can't do anthing with undefined symbols. */
782 else if (isym->st_shndx == SHN_ABS)
783 tsec = bfd_abs_section_ptr;
784 else if (isym->st_shndx == SHN_COMMON)
785 tsec = bfd_com_section_ptr;
786 else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
787 tsec = bfd_com_section_ptr;
788 else
789 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
791 toff = isym->st_value;
793 else
795 unsigned long indx;
796 struct elf_link_hash_entry *h;
797 struct elfNN_ia64_dyn_sym_info *dyn_i;
799 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
800 h = elf_sym_hashes (abfd)[indx];
801 BFD_ASSERT (h != NULL);
803 while (h->root.type == bfd_link_hash_indirect
804 || h->root.type == bfd_link_hash_warning)
805 h = (struct elf_link_hash_entry *) h->root.u.i.link;
807 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
809 /* For branches to dynamic symbols, we're interested instead
810 in a branch to the PLT entry. */
811 if (dyn_i && dyn_i->want_plt2)
813 tsec = ia64_info->plt_sec;
814 toff = dyn_i->plt2_offset;
816 else
818 /* We can't do anthing with undefined symbols. */
819 if (h->root.type == bfd_link_hash_undefined
820 || h->root.type == bfd_link_hash_undefweak)
821 continue;
823 tsec = h->root.u.def.section;
824 toff = h->root.u.def.value;
828 symaddr = (tsec->output_section->vma
829 + tsec->output_offset
830 + toff
831 + irel->r_addend);
833 roff = irel->r_offset;
834 reladdr = (sec->output_section->vma
835 + sec->output_offset
836 + roff) & (bfd_vma) -4;
838 /* If the branch is in range, no need to do anything. */
839 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
840 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
841 continue;
843 /* If the branch and target are in the same section, you've
844 got one honking big section and we can't help you. You'll
845 get an error message later. */
846 if (tsec == sec)
847 continue;
849 /* Look for an existing fixup to this address. */
850 for (f = fixups; f ; f = f->next)
851 if (f->tsec == tsec && f->toff == toff)
852 break;
854 if (f == NULL)
856 /* Two alternatives: If it's a branch to a PLT entry, we can
857 make a copy of the FULL_PLT entry. Otherwise, we'll have
858 to use a `brl' insn to get where we're going. */
860 size_t size;
862 if (tsec == ia64_info->plt_sec)
863 size = sizeof (plt_full_entry);
864 else
866 #ifdef USE_BRL
867 size = sizeof (oor_brl);
868 #else
869 size = sizeof (oor_ip);
870 #endif
873 /* Resize the current section to make room for the new branch. */
874 trampoff = (sec->_cooked_size + 15) & (bfd_vma) -16;
875 amt = trampoff + size;
876 contents = (bfd_byte *) bfd_realloc (contents, amt);
877 if (contents == NULL)
878 goto error_return;
879 sec->_cooked_size = amt;
881 if (tsec == ia64_info->plt_sec)
883 memcpy (contents + trampoff, plt_full_entry, size);
885 /* Hijack the old relocation for use as the PLTOFF reloc. */
886 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
887 R_IA64_PLTOFF22);
888 irel->r_offset = trampoff;
890 else
892 #ifdef USE_BRL
893 memcpy (contents + trampoff, oor_brl, size);
894 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
895 R_IA64_PCREL60B);
896 irel->r_offset = trampoff + 2;
897 #else
898 memcpy (contents + trampoff, oor_ip, size);
899 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
900 R_IA64_PCREL64I);
901 irel->r_addend -= 16;
902 irel->r_offset = trampoff + 2;
903 #endif
906 /* Record the fixup so we don't do it again this section. */
907 f = (struct one_fixup *) bfd_malloc ((bfd_size_type) sizeof (*f));
908 f->next = fixups;
909 f->tsec = tsec;
910 f->toff = toff;
911 f->trampoff = trampoff;
912 fixups = f;
914 else
916 /* Nop out the reloc, since we're finalizing things here. */
917 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
920 /* Fix up the existing branch to hit the trampoline. Hope like
921 hell this doesn't overflow too. */
922 if (elfNN_ia64_install_value (abfd, contents + roff,
923 f->trampoff - (roff & (bfd_vma) -4),
924 R_IA64_PCREL21B) != bfd_reloc_ok)
925 goto error_return;
927 changed_contents = true;
928 changed_relocs = true;
931 /* Clean up and go home. */
932 while (fixups)
934 struct one_fixup *f = fixups;
935 fixups = fixups->next;
936 free (f);
939 if (isymbuf != NULL
940 && symtab_hdr->contents != (unsigned char *) isymbuf)
942 if (! link_info->keep_memory)
943 free (isymbuf);
944 else
946 /* Cache the symbols for elf_link_input_bfd. */
947 symtab_hdr->contents = (unsigned char *) isymbuf;
951 if (contents != NULL
952 && elf_section_data (sec)->this_hdr.contents != contents)
954 if (!changed_contents && !link_info->keep_memory)
955 free (contents);
956 else
958 /* Cache the section contents for elf_link_input_bfd. */
959 elf_section_data (sec)->this_hdr.contents = contents;
963 if (elf_section_data (sec)->relocs != internal_relocs)
965 if (!changed_relocs)
966 free (internal_relocs);
967 else
968 elf_section_data (sec)->relocs = internal_relocs;
971 *again = changed_contents || changed_relocs;
972 return true;
974 error_return:
975 if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
976 free (isymbuf);
977 if (contents != NULL
978 && elf_section_data (sec)->this_hdr.contents != contents)
979 free (contents);
980 if (internal_relocs != NULL
981 && elf_section_data (sec)->relocs != internal_relocs)
982 free (internal_relocs);
983 return false;
986 /* Return true if NAME is an unwind table section name. */
988 static inline boolean
989 is_unwind_section_name (abfd, name)
990 bfd *abfd;
991 const char *name;
993 size_t len1, len2, len3;
995 if (elfNN_ia64_hpux_vec (abfd->xvec)
996 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
997 return false;
999 len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
1000 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
1001 len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
1002 return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
1003 && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
1004 || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
1007 /* Handle an IA-64 specific section when reading an object file. This
1008 is called when elfcode.h finds a section with an unknown type. */
1010 static boolean
1011 elfNN_ia64_section_from_shdr (abfd, hdr, name)
1012 bfd *abfd;
1013 ElfNN_Internal_Shdr *hdr;
1014 const char *name;
1016 asection *newsect;
1018 /* There ought to be a place to keep ELF backend specific flags, but
1019 at the moment there isn't one. We just keep track of the
1020 sections by their name, instead. Fortunately, the ABI gives
1021 suggested names for all the MIPS specific sections, so we will
1022 probably get away with this. */
1023 switch (hdr->sh_type)
1025 case SHT_IA_64_UNWIND:
1026 case SHT_IA_64_HP_OPT_ANOT:
1027 break;
1029 case SHT_IA_64_EXT:
1030 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1031 return false;
1032 break;
1034 default:
1035 return false;
1038 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
1039 return false;
1040 newsect = hdr->bfd_section;
1042 return true;
1045 /* Convert IA-64 specific section flags to bfd internal section flags. */
1047 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1048 flag. */
1050 static boolean
1051 elfNN_ia64_section_flags (flags, hdr)
1052 flagword *flags;
1053 ElfNN_Internal_Shdr *hdr;
1055 if (hdr->sh_flags & SHF_IA_64_SHORT)
1056 *flags |= SEC_SMALL_DATA;
1058 return true;
1061 /* Set the correct type for an IA-64 ELF section. We do this by the
1062 section name, which is a hack, but ought to work. */
1064 static boolean
1065 elfNN_ia64_fake_sections (abfd, hdr, sec)
1066 bfd *abfd ATTRIBUTE_UNUSED;
1067 ElfNN_Internal_Shdr *hdr;
1068 asection *sec;
1070 register const char *name;
1072 name = bfd_get_section_name (abfd, sec);
1074 if (is_unwind_section_name (abfd, name))
1076 /* We don't have the sections numbered at this point, so sh_info
1077 is set later, in elfNN_ia64_final_write_processing. */
1078 hdr->sh_type = SHT_IA_64_UNWIND;
1079 hdr->sh_flags |= SHF_LINK_ORDER;
1081 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1082 hdr->sh_type = SHT_IA_64_EXT;
1083 else if (strcmp (name, ".HP.opt_annot") == 0)
1084 hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
1085 else if (strcmp (name, ".reloc") == 0)
1086 /* This is an ugly, but unfortunately necessary hack that is
1087 needed when producing EFI binaries on IA-64. It tells
1088 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1089 containing ELF relocation info. We need this hack in order to
1090 be able to generate ELF binaries that can be translated into
1091 EFI applications (which are essentially COFF objects). Those
1092 files contain a COFF ".reloc" section inside an ELFNN object,
1093 which would normally cause BFD to segfault because it would
1094 attempt to interpret this section as containing relocation
1095 entries for section "oc". With this hack enabled, ".reloc"
1096 will be treated as a normal data section, which will avoid the
1097 segfault. However, you won't be able to create an ELFNN binary
1098 with a section named "oc" that needs relocations, but that's
1099 the kind of ugly side-effects you get when detecting section
1100 types based on their names... In practice, this limitation is
1101 unlikely to bite. */
1102 hdr->sh_type = SHT_PROGBITS;
1104 if (sec->flags & SEC_SMALL_DATA)
1105 hdr->sh_flags |= SHF_IA_64_SHORT;
1107 return true;
1110 /* The final processing done just before writing out an IA-64 ELF
1111 object file. */
1113 static void
1114 elfNN_ia64_final_write_processing (abfd, linker)
1115 bfd *abfd;
1116 boolean linker ATTRIBUTE_UNUSED;
1118 Elf_Internal_Shdr *hdr;
1119 const char *sname;
1120 asection *text_sect, *s;
1121 size_t len;
1123 for (s = abfd->sections; s; s = s->next)
1125 hdr = &elf_section_data (s)->this_hdr;
1126 switch (hdr->sh_type)
1128 case SHT_IA_64_UNWIND:
1129 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1130 have to do this. */
1131 sname = bfd_get_section_name (abfd, s);
1132 len = sizeof (ELF_STRING_ia64_unwind) - 1;
1133 if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0)
1135 sname += len;
1137 if (sname[0] == '\0')
1138 /* .IA_64.unwind -> .text */
1139 text_sect = bfd_get_section_by_name (abfd, ".text");
1140 else
1141 /* .IA_64.unwindFOO -> FOO */
1142 text_sect = bfd_get_section_by_name (abfd, sname);
1144 else if (sname
1145 && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
1146 strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
1148 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1149 size_t len2 = sizeof (".gnu.linkonce.t.") - 1;
1150 char *once_name = bfd_malloc (len2 + strlen (sname + len) + 1);
1152 if (once_name != NULL)
1154 memcpy (once_name, ".gnu.linkonce.t.", len2);
1155 strcpy (once_name + len2, sname + len);
1156 text_sect = bfd_get_section_by_name (abfd, once_name);
1157 free (once_name);
1159 else
1160 /* Should only happen if we run out of memory, in
1161 which case we're probably toast anyway. Try to
1162 cope by finding the section the slow way. */
1163 for (text_sect = abfd->sections;
1164 text_sect != NULL;
1165 text_sect = text_sect->next)
1167 if (strncmp (bfd_section_name (abfd, text_sect),
1168 ".gnu.linkonce.t.", len2) == 0
1169 && strcmp (bfd_section_name (abfd, text_sect) + len2,
1170 sname + len) == 0)
1171 break;
1174 else
1175 /* last resort: fall back on .text */
1176 text_sect = bfd_get_section_by_name (abfd, ".text");
1178 if (text_sect)
1180 /* The IA-64 processor-specific ABI requires setting
1181 sh_link to the unwind section, whereas HP-UX requires
1182 sh_info to do so. For maximum compatibility, we'll
1183 set both for now... */
1184 hdr->sh_link = elf_section_data (text_sect)->this_idx;
1185 hdr->sh_info = elf_section_data (text_sect)->this_idx;
1187 break;
1191 if (! elf_flags_init (abfd))
1193 unsigned long flags = 0;
1195 if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
1196 flags |= EF_IA_64_BE;
1197 if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
1198 flags |= EF_IA_64_ABI64;
1200 elf_elfheader(abfd)->e_flags = flags;
1201 elf_flags_init (abfd) = true;
1205 /* Hook called by the linker routine which adds symbols from an object
1206 file. We use it to put .comm items in .sbss, and not .bss. */
1208 static boolean
1209 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1210 bfd *abfd;
1211 struct bfd_link_info *info;
1212 const Elf_Internal_Sym *sym;
1213 const char **namep ATTRIBUTE_UNUSED;
1214 flagword *flagsp ATTRIBUTE_UNUSED;
1215 asection **secp;
1216 bfd_vma *valp;
1218 if (sym->st_shndx == SHN_COMMON
1219 && !info->relocateable
1220 && sym->st_size <= elf_gp_size (abfd))
1222 /* Common symbols less than or equal to -G nn bytes are
1223 automatically put into .sbss. */
1225 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1227 if (scomm == NULL)
1229 scomm = bfd_make_section (abfd, ".scommon");
1230 if (scomm == NULL
1231 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1232 | SEC_IS_COMMON
1233 | SEC_LINKER_CREATED)))
1234 return false;
1237 *secp = scomm;
1238 *valp = sym->st_size;
1241 return true;
1244 static boolean
1245 elfNN_ia64_aix_vec (const bfd_target *vec)
1247 extern const bfd_target bfd_elfNN_ia64_aix_little_vec;
1248 extern const bfd_target bfd_elfNN_ia64_aix_big_vec;
1250 return (/**/vec == & bfd_elfNN_ia64_aix_little_vec
1251 || vec == & bfd_elfNN_ia64_aix_big_vec);
1254 /* Hook called by the linker routine which adds symbols from an object
1255 file. We use it to handle OS-specific symbols. */
1257 static boolean
1258 elfNN_ia64_aix_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1259 bfd *abfd;
1260 struct bfd_link_info *info;
1261 const Elf_Internal_Sym *sym;
1262 const char **namep;
1263 flagword *flagsp;
1264 asection **secp;
1265 bfd_vma *valp;
1267 if (strcmp (*namep, "__GLOB_DATA_PTR") == 0)
1269 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1270 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1271 no one else should use it b/c it is undocumented. */
1272 struct elf_link_hash_entry *h;
1274 h = elf_link_hash_lookup (elf_hash_table (info), *namep,
1275 false, false, false);
1276 if (h == NULL)
1278 struct elf_backend_data *bed;
1279 struct elfNN_ia64_link_hash_table *ia64_info;
1281 bed = get_elf_backend_data (abfd);
1282 ia64_info = elfNN_ia64_hash_table (info);
1284 if (!(_bfd_generic_link_add_one_symbol
1285 (info, abfd, *namep, BSF_GLOBAL,
1286 bfd_get_section_by_name (abfd, ".bss"),
1287 bed->got_symbol_offset, (const char *) NULL, false,
1288 bed->collect, (struct bfd_link_hash_entry **) &h)))
1289 return false;
1291 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1292 h->type = STT_OBJECT;
1294 if (! _bfd_elf_link_record_dynamic_symbol (info, h))
1295 return false;
1298 return true;
1300 else if (sym->st_shndx == SHN_LOOS)
1302 unsigned int i;
1304 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1305 is only relevant when compiling code for extended system calls.
1306 Replace the "special" section with .text, if possible.
1307 Note that these symbols are always assumed to be in .text. */
1308 for (i = 1; i < elf_numsections (abfd); i++)
1310 asection * sec = bfd_section_from_elf_index (abfd, i);
1312 if (sec && strcmp (sec->name, ".text") == 0)
1314 *secp = sec;
1315 break;
1319 if (*secp == NULL)
1320 *secp = bfd_abs_section_ptr;
1322 *valp = sym->st_size;
1324 return true;
1326 else
1328 return elfNN_ia64_add_symbol_hook (abfd, info, sym,
1329 namep, flagsp, secp, valp);
1333 boolean
1334 elfNN_ia64_aix_link_add_symbols (abfd, info)
1335 bfd *abfd;
1336 struct bfd_link_info *info;
1338 /* Make sure dynamic sections are always created. */
1339 if (! elf_hash_table (info)->dynamic_sections_created
1340 && abfd->xvec == info->hash->creator)
1342 if (! bfd_elfNN_link_create_dynamic_sections (abfd, info))
1343 return false;
1346 /* Now do the standard call. */
1347 return bfd_elfNN_bfd_link_add_symbols (abfd, info);
1350 /* Return the number of additional phdrs we will need. */
1352 static int
1353 elfNN_ia64_additional_program_headers (abfd)
1354 bfd *abfd;
1356 asection *s;
1357 int ret = 0;
1359 /* See if we need a PT_IA_64_ARCHEXT segment. */
1360 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1361 if (s && (s->flags & SEC_LOAD))
1362 ++ret;
1364 /* Count how many PT_IA_64_UNWIND segments we need. */
1365 for (s = abfd->sections; s; s = s->next)
1366 if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1367 ++ret;
1369 return ret;
1372 static boolean
1373 elfNN_ia64_modify_segment_map (abfd)
1374 bfd *abfd;
1376 struct elf_segment_map *m, **pm;
1377 Elf_Internal_Shdr *hdr;
1378 asection *s;
1380 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1381 all PT_LOAD segments. */
1382 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1383 if (s && (s->flags & SEC_LOAD))
1385 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1386 if (m->p_type == PT_IA_64_ARCHEXT)
1387 break;
1388 if (m == NULL)
1390 m = ((struct elf_segment_map *)
1391 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1392 if (m == NULL)
1393 return false;
1395 m->p_type = PT_IA_64_ARCHEXT;
1396 m->count = 1;
1397 m->sections[0] = s;
1399 /* We want to put it after the PHDR and INTERP segments. */
1400 pm = &elf_tdata (abfd)->segment_map;
1401 while (*pm != NULL
1402 && ((*pm)->p_type == PT_PHDR
1403 || (*pm)->p_type == PT_INTERP))
1404 pm = &(*pm)->next;
1406 m->next = *pm;
1407 *pm = m;
1411 /* Install PT_IA_64_UNWIND segments, if needed. */
1412 for (s = abfd->sections; s; s = s->next)
1414 hdr = &elf_section_data (s)->this_hdr;
1415 if (hdr->sh_type != SHT_IA_64_UNWIND)
1416 continue;
1418 if (s && (s->flags & SEC_LOAD))
1420 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1421 if (m->p_type == PT_IA_64_UNWIND)
1423 int i;
1425 /* Look through all sections in the unwind segment
1426 for a match since there may be multiple sections
1427 to a segment. */
1428 for (i = m->count - 1; i >= 0; --i)
1429 if (m->sections[i] == s)
1430 break;
1432 if (i >= 0)
1433 break;
1436 if (m == NULL)
1438 m = ((struct elf_segment_map *)
1439 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1440 if (m == NULL)
1441 return false;
1443 m->p_type = PT_IA_64_UNWIND;
1444 m->count = 1;
1445 m->sections[0] = s;
1446 m->next = NULL;
1448 /* We want to put it last. */
1449 pm = &elf_tdata (abfd)->segment_map;
1450 while (*pm != NULL)
1451 pm = &(*pm)->next;
1452 *pm = m;
1457 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1458 the input sections for each output section in the segment and testing
1459 for SHF_IA_64_NORECOV on each. */
1460 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1461 if (m->p_type == PT_LOAD)
1463 int i;
1464 for (i = m->count - 1; i >= 0; --i)
1466 struct bfd_link_order *order = m->sections[i]->link_order_head;
1467 while (order)
1469 if (order->type == bfd_indirect_link_order)
1471 asection *is = order->u.indirect.section;
1472 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1473 if (flags & SHF_IA_64_NORECOV)
1475 m->p_flags |= PF_IA_64_NORECOV;
1476 goto found;
1479 order = order->next;
1482 found:;
1485 return true;
1488 /* According to the Tahoe assembler spec, all labels starting with a
1489 '.' are local. */
1491 static boolean
1492 elfNN_ia64_is_local_label_name (abfd, name)
1493 bfd *abfd ATTRIBUTE_UNUSED;
1494 const char *name;
1496 return name[0] == '.';
1499 /* Should we do dynamic things to this symbol? */
1501 static boolean
1502 elfNN_ia64_dynamic_symbol_p (h, info)
1503 struct elf_link_hash_entry *h;
1504 struct bfd_link_info *info;
1506 if (h == NULL)
1507 return false;
1509 while (h->root.type == bfd_link_hash_indirect
1510 || h->root.type == bfd_link_hash_warning)
1511 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1513 if (h->dynindx == -1)
1514 return false;
1515 switch (ELF_ST_VISIBILITY (h->other))
1517 case STV_INTERNAL:
1518 case STV_HIDDEN:
1519 return false;
1520 default:
1521 break;
1524 if (h->root.type == bfd_link_hash_undefweak
1525 || h->root.type == bfd_link_hash_defweak)
1526 return true;
1528 if ((info->shared && (!info->symbolic || info->allow_shlib_undefined))
1529 || ((h->elf_link_hash_flags
1530 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1531 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1532 return true;
1534 return false;
1537 static boolean
1538 elfNN_ia64_local_hash_table_init (ht, abfd, new)
1539 struct elfNN_ia64_local_hash_table *ht;
1540 bfd *abfd ATTRIBUTE_UNUSED;
1541 new_hash_entry_func new;
1543 memset (ht, 0, sizeof (*ht));
1544 return bfd_hash_table_init (&ht->root, new);
1547 static struct bfd_hash_entry*
1548 elfNN_ia64_new_loc_hash_entry (entry, table, string)
1549 struct bfd_hash_entry *entry;
1550 struct bfd_hash_table *table;
1551 const char *string;
1553 struct elfNN_ia64_local_hash_entry *ret;
1554 ret = (struct elfNN_ia64_local_hash_entry *) entry;
1556 /* Allocate the structure if it has not already been allocated by a
1557 subclass. */
1558 if (!ret)
1559 ret = bfd_hash_allocate (table, sizeof (*ret));
1561 if (!ret)
1562 return 0;
1564 /* Initialize our local data. All zeros, and definitely easier
1565 than setting a handful of bit fields. */
1566 memset (ret, 0, sizeof (*ret));
1568 /* Call the allocation method of the superclass. */
1569 ret = ((struct elfNN_ia64_local_hash_entry *)
1570 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1572 return (struct bfd_hash_entry *) ret;
1575 static struct bfd_hash_entry*
1576 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1577 struct bfd_hash_entry *entry;
1578 struct bfd_hash_table *table;
1579 const char *string;
1581 struct elfNN_ia64_link_hash_entry *ret;
1582 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1584 /* Allocate the structure if it has not already been allocated by a
1585 subclass. */
1586 if (!ret)
1587 ret = bfd_hash_allocate (table, sizeof (*ret));
1589 if (!ret)
1590 return 0;
1592 /* Initialize our local data. All zeros, and definitely easier
1593 than setting a handful of bit fields. */
1594 memset (ret, 0, sizeof (*ret));
1596 /* Call the allocation method of the superclass. */
1597 ret = ((struct elfNN_ia64_link_hash_entry *)
1598 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1599 table, string));
1601 return (struct bfd_hash_entry *) ret;
1604 static void
1605 elfNN_ia64_hash_copy_indirect (xdir, xind)
1606 struct elf_link_hash_entry *xdir, *xind;
1608 struct elfNN_ia64_link_hash_entry *dir, *ind;
1610 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1611 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1613 /* Copy down any references that we may have already seen to the
1614 symbol which just became indirect. */
1616 dir->root.elf_link_hash_flags |=
1617 (ind->root.elf_link_hash_flags
1618 & (ELF_LINK_HASH_REF_DYNAMIC
1619 | ELF_LINK_HASH_REF_REGULAR
1620 | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1622 if (ind->root.root.type != bfd_link_hash_indirect)
1623 return;
1625 /* Copy over the got and plt data. This would have been done
1626 by check_relocs. */
1628 if (dir->info == NULL)
1630 struct elfNN_ia64_dyn_sym_info *dyn_i;
1632 dir->info = dyn_i = ind->info;
1633 ind->info = NULL;
1635 /* Fix up the dyn_sym_info pointers to the global symbol. */
1636 for (; dyn_i; dyn_i = dyn_i->next)
1637 dyn_i->h = &dir->root;
1639 BFD_ASSERT (ind->info == NULL);
1641 /* Copy over the dynindx. */
1643 if (dir->root.dynindx == -1)
1645 dir->root.dynindx = ind->root.dynindx;
1646 dir->root.dynstr_index = ind->root.dynstr_index;
1647 ind->root.dynindx = -1;
1648 ind->root.dynstr_index = 0;
1650 BFD_ASSERT (ind->root.dynindx == -1);
1653 static void
1654 elfNN_ia64_hash_hide_symbol (info, xh, force_local)
1655 struct bfd_link_info *info;
1656 struct elf_link_hash_entry *xh;
1657 boolean force_local;
1659 struct elfNN_ia64_link_hash_entry *h;
1660 struct elfNN_ia64_dyn_sym_info *dyn_i;
1662 h = (struct elfNN_ia64_link_hash_entry *)xh;
1664 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1666 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1667 dyn_i->want_plt2 = 0;
1670 /* Create the derived linker hash table. The IA-64 ELF port uses this
1671 derived hash table to keep information specific to the IA-64 ElF
1672 linker (without using static variables). */
1674 static struct bfd_link_hash_table*
1675 elfNN_ia64_hash_table_create (abfd)
1676 bfd *abfd;
1678 struct elfNN_ia64_link_hash_table *ret;
1680 ret = bfd_zalloc (abfd, (bfd_size_type) sizeof (*ret));
1681 if (!ret)
1682 return 0;
1683 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1684 elfNN_ia64_new_elf_hash_entry))
1686 bfd_release (abfd, ret);
1687 return 0;
1690 if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1691 elfNN_ia64_new_loc_hash_entry))
1692 return 0;
1693 return &ret->root.root;
1696 /* Look up an entry in a Alpha ELF linker hash table. */
1698 static INLINE struct elfNN_ia64_local_hash_entry *
1699 elfNN_ia64_local_hash_lookup(table, string, create, copy)
1700 struct elfNN_ia64_local_hash_table *table;
1701 const char *string;
1702 boolean create, copy;
1704 return ((struct elfNN_ia64_local_hash_entry *)
1705 bfd_hash_lookup (&table->root, string, create, copy));
1708 /* Traverse both local and global hash tables. */
1710 struct elfNN_ia64_dyn_sym_traverse_data
1712 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1713 PTR data;
1716 static boolean
1717 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1718 struct bfd_hash_entry *xentry;
1719 PTR xdata;
1721 struct elfNN_ia64_link_hash_entry *entry
1722 = (struct elfNN_ia64_link_hash_entry *) xentry;
1723 struct elfNN_ia64_dyn_sym_traverse_data *data
1724 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1725 struct elfNN_ia64_dyn_sym_info *dyn_i;
1727 if (entry->root.root.type == bfd_link_hash_warning)
1728 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1730 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1731 if (! (*data->func) (dyn_i, data->data))
1732 return false;
1733 return true;
1736 static boolean
1737 elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1738 struct bfd_hash_entry *xentry;
1739 PTR xdata;
1741 struct elfNN_ia64_local_hash_entry *entry
1742 = (struct elfNN_ia64_local_hash_entry *) xentry;
1743 struct elfNN_ia64_dyn_sym_traverse_data *data
1744 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1745 struct elfNN_ia64_dyn_sym_info *dyn_i;
1747 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1748 if (! (*data->func) (dyn_i, data->data))
1749 return false;
1750 return true;
1753 static void
1754 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1755 struct elfNN_ia64_link_hash_table *ia64_info;
1756 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1757 PTR data;
1759 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1761 xdata.func = func;
1762 xdata.data = data;
1764 elf_link_hash_traverse (&ia64_info->root,
1765 elfNN_ia64_global_dyn_sym_thunk, &xdata);
1766 bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1767 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1770 static boolean
1771 elfNN_ia64_create_dynamic_sections (abfd, info)
1772 bfd *abfd;
1773 struct bfd_link_info *info;
1775 struct elfNN_ia64_link_hash_table *ia64_info;
1776 asection *s;
1778 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1779 return false;
1781 ia64_info = elfNN_ia64_hash_table (info);
1783 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1784 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1787 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1788 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1791 if (!get_pltoff (abfd, info, ia64_info))
1792 return false;
1794 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1795 if (s == NULL
1796 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1797 | SEC_HAS_CONTENTS
1798 | SEC_IN_MEMORY
1799 | SEC_LINKER_CREATED
1800 | SEC_READONLY))
1801 || !bfd_set_section_alignment (abfd, s, 3))
1802 return false;
1803 ia64_info->rel_pltoff_sec = s;
1805 s = bfd_make_section(abfd, ".rela.got");
1806 if (s == NULL
1807 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1808 | SEC_HAS_CONTENTS
1809 | SEC_IN_MEMORY
1810 | SEC_LINKER_CREATED
1811 | SEC_READONLY))
1812 || !bfd_set_section_alignment (abfd, s, 3))
1813 return false;
1814 ia64_info->rel_got_sec = s;
1816 return true;
1819 /* Find and/or create a hash entry for local symbol. */
1820 static struct elfNN_ia64_local_hash_entry *
1821 get_local_sym_hash (ia64_info, abfd, rel, create)
1822 struct elfNN_ia64_link_hash_table *ia64_info;
1823 bfd *abfd;
1824 const Elf_Internal_Rela *rel;
1825 boolean create;
1827 char *addr_name;
1828 size_t len;
1829 struct elfNN_ia64_local_hash_entry *ret;
1831 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1832 name describes what was once anonymous memory. */
1834 len = sizeof (void*)*2 + 1 + sizeof (bfd_vma)*4 + 1 + 1;
1835 len += 10; /* %p slop */
1837 addr_name = bfd_malloc (len);
1838 if (addr_name == NULL)
1839 return 0;
1840 sprintf (addr_name, "%p:%lx",
1841 (void *) abfd, (unsigned long) ELFNN_R_SYM (rel->r_info));
1843 /* Collect the canonical entry data for this address. */
1844 ret = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1845 addr_name, create, create);
1846 free (addr_name);
1847 return ret;
1850 /* Find and/or create a descriptor for dynamic symbol info. This will
1851 vary based on global or local symbol, and the addend to the reloc. */
1853 static struct elfNN_ia64_dyn_sym_info *
1854 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1855 struct elfNN_ia64_link_hash_table *ia64_info;
1856 struct elf_link_hash_entry *h;
1857 bfd *abfd;
1858 const Elf_Internal_Rela *rel;
1859 boolean create;
1861 struct elfNN_ia64_dyn_sym_info **pp;
1862 struct elfNN_ia64_dyn_sym_info *dyn_i;
1863 bfd_vma addend = rel ? rel->r_addend : 0;
1865 if (h)
1866 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1867 else
1869 struct elfNN_ia64_local_hash_entry *loc_h;
1871 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1872 BFD_ASSERT (loc_h);
1874 pp = &loc_h->info;
1877 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1878 pp = &dyn_i->next;
1880 if (dyn_i == NULL && create)
1882 dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
1883 bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
1884 *pp = dyn_i;
1885 dyn_i->addend = addend;
1888 return dyn_i;
1891 static asection *
1892 get_got (abfd, info, ia64_info)
1893 bfd *abfd;
1894 struct bfd_link_info *info;
1895 struct elfNN_ia64_link_hash_table *ia64_info;
1897 asection *got;
1898 bfd *dynobj;
1900 got = ia64_info->got_sec;
1901 if (!got)
1903 flagword flags;
1905 dynobj = ia64_info->root.dynobj;
1906 if (!dynobj)
1907 ia64_info->root.dynobj = dynobj = abfd;
1908 if (!_bfd_elf_create_got_section (dynobj, info))
1909 return 0;
1911 got = bfd_get_section_by_name (dynobj, ".got");
1912 BFD_ASSERT (got);
1913 ia64_info->got_sec = got;
1915 flags = bfd_get_section_flags (abfd, got);
1916 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1919 return got;
1922 /* Create function descriptor section (.opd). This section is called .opd
1923 because it contains "official prodecure descriptors". The "official"
1924 refers to the fact that these descriptors are used when taking the address
1925 of a procedure, thus ensuring a unique address for each procedure. */
1927 static asection *
1928 get_fptr (abfd, info, ia64_info)
1929 bfd *abfd;
1930 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1931 struct elfNN_ia64_link_hash_table *ia64_info;
1933 asection *fptr;
1934 bfd *dynobj;
1936 fptr = ia64_info->fptr_sec;
1937 if (!fptr)
1939 dynobj = ia64_info->root.dynobj;
1940 if (!dynobj)
1941 ia64_info->root.dynobj = dynobj = abfd;
1943 fptr = bfd_make_section (dynobj, ".opd");
1944 if (!fptr
1945 || !bfd_set_section_flags (dynobj, fptr,
1946 (SEC_ALLOC
1947 | SEC_LOAD
1948 | SEC_HAS_CONTENTS
1949 | SEC_IN_MEMORY
1950 | SEC_READONLY
1951 | SEC_LINKER_CREATED))
1952 || !bfd_set_section_alignment (abfd, fptr, 4))
1954 BFD_ASSERT (0);
1955 return NULL;
1958 ia64_info->fptr_sec = fptr;
1961 return fptr;
1964 static asection *
1965 get_pltoff (abfd, info, ia64_info)
1966 bfd *abfd;
1967 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1968 struct elfNN_ia64_link_hash_table *ia64_info;
1970 asection *pltoff;
1971 bfd *dynobj;
1973 pltoff = ia64_info->pltoff_sec;
1974 if (!pltoff)
1976 dynobj = ia64_info->root.dynobj;
1977 if (!dynobj)
1978 ia64_info->root.dynobj = dynobj = abfd;
1980 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
1981 if (!pltoff
1982 || !bfd_set_section_flags (dynobj, pltoff,
1983 (SEC_ALLOC
1984 | SEC_LOAD
1985 | SEC_HAS_CONTENTS
1986 | SEC_IN_MEMORY
1987 | SEC_SMALL_DATA
1988 | SEC_LINKER_CREATED))
1989 || !bfd_set_section_alignment (abfd, pltoff, 4))
1991 BFD_ASSERT (0);
1992 return NULL;
1995 ia64_info->pltoff_sec = pltoff;
1998 return pltoff;
2001 static asection *
2002 get_reloc_section (abfd, ia64_info, sec, create)
2003 bfd *abfd;
2004 struct elfNN_ia64_link_hash_table *ia64_info;
2005 asection *sec;
2006 boolean create;
2008 const char *srel_name;
2009 asection *srel;
2010 bfd *dynobj;
2012 srel_name = (bfd_elf_string_from_elf_section
2013 (abfd, elf_elfheader(abfd)->e_shstrndx,
2014 elf_section_data(sec)->rel_hdr.sh_name));
2015 if (srel_name == NULL)
2016 return NULL;
2018 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2019 && strcmp (bfd_get_section_name (abfd, sec),
2020 srel_name+5) == 0)
2021 || (strncmp (srel_name, ".rel", 4) == 0
2022 && strcmp (bfd_get_section_name (abfd, sec),
2023 srel_name+4) == 0));
2025 dynobj = ia64_info->root.dynobj;
2026 if (!dynobj)
2027 ia64_info->root.dynobj = dynobj = abfd;
2029 srel = bfd_get_section_by_name (dynobj, srel_name);
2030 if (srel == NULL && create)
2032 srel = bfd_make_section (dynobj, srel_name);
2033 if (srel == NULL
2034 || !bfd_set_section_flags (dynobj, srel,
2035 (SEC_ALLOC
2036 | SEC_LOAD
2037 | SEC_HAS_CONTENTS
2038 | SEC_IN_MEMORY
2039 | SEC_LINKER_CREATED
2040 | SEC_READONLY))
2041 || !bfd_set_section_alignment (dynobj, srel, 3))
2042 return NULL;
2045 if (sec->flags & SEC_READONLY)
2046 ia64_info->reltext = 1;
2048 return srel;
2051 static boolean
2052 count_dyn_reloc (abfd, dyn_i, srel, type)
2053 bfd *abfd;
2054 struct elfNN_ia64_dyn_sym_info *dyn_i;
2055 asection *srel;
2056 int type;
2058 struct elfNN_ia64_dyn_reloc_entry *rent;
2060 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2061 if (rent->srel == srel && rent->type == type)
2062 break;
2064 if (!rent)
2066 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2067 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2068 if (!rent)
2069 return false;
2071 rent->next = dyn_i->reloc_entries;
2072 rent->srel = srel;
2073 rent->type = type;
2074 rent->count = 0;
2075 dyn_i->reloc_entries = rent;
2077 rent->count++;
2079 return true;
2082 static boolean
2083 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2084 bfd *abfd;
2085 struct bfd_link_info *info;
2086 asection *sec;
2087 const Elf_Internal_Rela *relocs;
2089 struct elfNN_ia64_link_hash_table *ia64_info;
2090 const Elf_Internal_Rela *relend;
2091 Elf_Internal_Shdr *symtab_hdr;
2092 const Elf_Internal_Rela *rel;
2093 asection *got, *fptr, *srel;
2095 if (info->relocateable)
2096 return true;
2098 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2099 ia64_info = elfNN_ia64_hash_table (info);
2101 got = fptr = srel = NULL;
2103 relend = relocs + sec->reloc_count;
2104 for (rel = relocs; rel < relend; ++rel)
2106 enum {
2107 NEED_GOT = 1,
2108 NEED_FPTR = 2,
2109 NEED_PLTOFF = 4,
2110 NEED_MIN_PLT = 8,
2111 NEED_FULL_PLT = 16,
2112 NEED_DYNREL = 32,
2113 NEED_LTOFF_FPTR = 64,
2114 NEED_TPREL = 128,
2115 NEED_DTPMOD = 256,
2116 NEED_DTPREL = 512
2119 struct elf_link_hash_entry *h = NULL;
2120 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2121 struct elfNN_ia64_dyn_sym_info *dyn_i;
2122 int need_entry;
2123 boolean maybe_dynamic;
2124 int dynrel_type = R_IA64_NONE;
2126 if (r_symndx >= symtab_hdr->sh_info)
2128 /* We're dealing with a global symbol -- find its hash entry
2129 and mark it as being referenced. */
2130 long indx = r_symndx - symtab_hdr->sh_info;
2131 h = elf_sym_hashes (abfd)[indx];
2132 while (h->root.type == bfd_link_hash_indirect
2133 || h->root.type == bfd_link_hash_warning)
2134 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2136 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2139 /* We can only get preliminary data on whether a symbol is
2140 locally or externally defined, as not all of the input files
2141 have yet been processed. Do something with what we know, as
2142 this may help reduce memory usage and processing time later. */
2143 maybe_dynamic = false;
2144 if (h && ((info->shared
2145 && (!info->symbolic || info->allow_shlib_undefined))
2146 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
2147 || h->root.type == bfd_link_hash_defweak
2148 || elfNN_ia64_aix_vec (abfd->xvec)))
2149 maybe_dynamic = true;
2151 need_entry = 0;
2152 switch (ELFNN_R_TYPE (rel->r_info))
2154 case R_IA64_TPREL64MSB:
2155 case R_IA64_TPREL64LSB:
2156 if (info->shared || maybe_dynamic)
2157 need_entry = NEED_DYNREL;
2158 dynrel_type = R_IA64_TPREL64LSB;
2159 if (info->shared)
2160 info->flags |= DF_STATIC_TLS;
2161 break;
2163 case R_IA64_LTOFF_TPREL22:
2164 need_entry = NEED_TPREL;
2165 if (info->shared)
2166 info->flags |= DF_STATIC_TLS;
2167 break;
2169 case R_IA64_DTPREL64MSB:
2170 case R_IA64_DTPREL64LSB:
2171 if (info->shared || maybe_dynamic)
2172 need_entry = NEED_DYNREL;
2173 dynrel_type = R_IA64_DTPREL64LSB;
2174 break;
2176 case R_IA64_LTOFF_DTPREL22:
2177 need_entry = NEED_DTPREL;
2178 break;
2180 case R_IA64_DTPMOD64MSB:
2181 case R_IA64_DTPMOD64LSB:
2182 if (info->shared || maybe_dynamic)
2183 need_entry = NEED_DYNREL;
2184 dynrel_type = R_IA64_DTPMOD64LSB;
2185 break;
2187 case R_IA64_LTOFF_DTPMOD22:
2188 need_entry = NEED_DTPMOD;
2189 break;
2191 case R_IA64_LTOFF_FPTR22:
2192 case R_IA64_LTOFF_FPTR64I:
2193 case R_IA64_LTOFF_FPTR32MSB:
2194 case R_IA64_LTOFF_FPTR32LSB:
2195 case R_IA64_LTOFF_FPTR64MSB:
2196 case R_IA64_LTOFF_FPTR64LSB:
2197 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2198 break;
2200 case R_IA64_FPTR64I:
2201 case R_IA64_FPTR32MSB:
2202 case R_IA64_FPTR32LSB:
2203 case R_IA64_FPTR64MSB:
2204 case R_IA64_FPTR64LSB:
2205 if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
2206 need_entry = NEED_FPTR | NEED_DYNREL;
2207 else
2208 need_entry = NEED_FPTR;
2209 dynrel_type = R_IA64_FPTR64LSB;
2210 break;
2212 case R_IA64_LTOFF22:
2213 case R_IA64_LTOFF22X:
2214 case R_IA64_LTOFF64I:
2215 need_entry = NEED_GOT;
2216 break;
2218 case R_IA64_PLTOFF22:
2219 case R_IA64_PLTOFF64I:
2220 case R_IA64_PLTOFF64MSB:
2221 case R_IA64_PLTOFF64LSB:
2222 need_entry = NEED_PLTOFF;
2223 if (h)
2225 if (maybe_dynamic)
2226 need_entry |= NEED_MIN_PLT;
2228 else
2230 (*info->callbacks->warning)
2231 (info, _("@pltoff reloc against local symbol"), 0,
2232 abfd, 0, (bfd_vma) 0);
2234 break;
2236 case R_IA64_PCREL21B:
2237 case R_IA64_PCREL60B:
2238 /* Depending on where this symbol is defined, we may or may not
2239 need a full plt entry. Only skip if we know we'll not need
2240 the entry -- static or symbolic, and the symbol definition
2241 has already been seen. */
2242 if (maybe_dynamic && rel->r_addend == 0)
2243 need_entry = NEED_FULL_PLT;
2244 break;
2246 case R_IA64_IMM14:
2247 case R_IA64_IMM22:
2248 case R_IA64_IMM64:
2249 case R_IA64_DIR32MSB:
2250 case R_IA64_DIR32LSB:
2251 case R_IA64_DIR64MSB:
2252 case R_IA64_DIR64LSB:
2253 /* Shared objects will always need at least a REL relocation. */
2254 if (info->shared || maybe_dynamic
2255 || (elfNN_ia64_aix_vec (abfd->xvec)
2256 && (!h || strcmp (h->root.root.string,
2257 "__GLOB_DATA_PTR") != 0)))
2258 need_entry = NEED_DYNREL;
2259 dynrel_type = R_IA64_DIR64LSB;
2260 break;
2262 case R_IA64_IPLTMSB:
2263 case R_IA64_IPLTLSB:
2264 /* Shared objects will always need at least a REL relocation. */
2265 if (info->shared || maybe_dynamic)
2266 need_entry = NEED_DYNREL;
2267 dynrel_type = R_IA64_IPLTLSB;
2268 break;
2270 case R_IA64_PCREL22:
2271 case R_IA64_PCREL64I:
2272 case R_IA64_PCREL32MSB:
2273 case R_IA64_PCREL32LSB:
2274 case R_IA64_PCREL64MSB:
2275 case R_IA64_PCREL64LSB:
2276 if (maybe_dynamic)
2277 need_entry = NEED_DYNREL;
2278 dynrel_type = R_IA64_PCREL64LSB;
2279 break;
2282 if (!need_entry)
2283 continue;
2285 if ((need_entry & NEED_FPTR) != 0
2286 && rel->r_addend)
2288 (*info->callbacks->warning)
2289 (info, _("non-zero addend in @fptr reloc"), 0,
2290 abfd, 0, (bfd_vma) 0);
2293 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
2295 /* Record whether or not this is a local symbol. */
2296 dyn_i->h = h;
2298 /* Create what's needed. */
2299 if (need_entry & (NEED_GOT | NEED_TPREL | NEED_DTPMOD | NEED_DTPREL))
2301 if (!got)
2303 got = get_got (abfd, info, ia64_info);
2304 if (!got)
2305 return false;
2307 if (need_entry & NEED_GOT)
2308 dyn_i->want_got = 1;
2309 if (need_entry & NEED_TPREL)
2310 dyn_i->want_tprel = 1;
2311 if (need_entry & NEED_DTPMOD)
2312 dyn_i->want_dtpmod = 1;
2313 if (need_entry & NEED_DTPREL)
2314 dyn_i->want_dtprel = 1;
2316 if (need_entry & NEED_FPTR)
2318 if (!fptr)
2320 fptr = get_fptr (abfd, info, ia64_info);
2321 if (!fptr)
2322 return false;
2325 /* FPTRs for shared libraries are allocated by the dynamic
2326 linker. Make sure this local symbol will appear in the
2327 dynamic symbol table. */
2328 if (!h && (info->shared
2329 /* AIX also needs one */
2330 || elfNN_ia64_aix_vec (abfd->xvec)))
2332 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2333 (info, abfd, (long) r_symndx)))
2334 return false;
2337 dyn_i->want_fptr = 1;
2339 if (need_entry & NEED_LTOFF_FPTR)
2340 dyn_i->want_ltoff_fptr = 1;
2341 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2343 if (!ia64_info->root.dynobj)
2344 ia64_info->root.dynobj = abfd;
2345 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2346 dyn_i->want_plt = 1;
2348 if (need_entry & NEED_FULL_PLT)
2349 dyn_i->want_plt2 = 1;
2350 if (need_entry & NEED_PLTOFF)
2351 dyn_i->want_pltoff = 1;
2352 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2354 if (!srel)
2356 srel = get_reloc_section (abfd, ia64_info, sec, true);
2357 if (!srel)
2358 return false;
2360 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2361 return false;
2365 return true;
2368 struct elfNN_ia64_allocate_data
2370 struct bfd_link_info *info;
2371 bfd_size_type ofs;
2374 /* For cleanliness, and potentially faster dynamic loading, allocate
2375 external GOT entries first. */
2377 static boolean
2378 allocate_global_data_got (dyn_i, data)
2379 struct elfNN_ia64_dyn_sym_info *dyn_i;
2380 PTR data;
2382 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2384 if (dyn_i->want_got
2385 && ! dyn_i->want_fptr
2386 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2387 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2388 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2389 "__GLOB_DATA_PTR") != 0))))
2391 dyn_i->got_offset = x->ofs;
2392 x->ofs += 8;
2394 if (dyn_i->want_tprel)
2396 dyn_i->tprel_offset = x->ofs;
2397 x->ofs += 8;
2399 if (dyn_i->want_dtpmod)
2401 dyn_i->dtpmod_offset = x->ofs;
2402 x->ofs += 8;
2404 if (dyn_i->want_dtprel)
2406 dyn_i->dtprel_offset = x->ofs;
2407 x->ofs += 8;
2409 return true;
2412 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2414 static boolean
2415 allocate_global_fptr_got (dyn_i, data)
2416 struct elfNN_ia64_dyn_sym_info *dyn_i;
2417 PTR data;
2419 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2421 if (dyn_i->want_got
2422 && dyn_i->want_fptr
2423 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2424 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2426 dyn_i->got_offset = x->ofs;
2427 x->ofs += 8;
2429 return true;
2432 /* Lastly, allocate all the GOT entries for local data. */
2434 static boolean
2435 allocate_local_got (dyn_i, data)
2436 struct elfNN_ia64_dyn_sym_info *dyn_i;
2437 PTR data;
2439 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2441 if (dyn_i->want_got
2442 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2443 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2445 dyn_i->got_offset = x->ofs;
2446 x->ofs += 8;
2448 return true;
2451 /* Search for the index of a global symbol in it's defining object file. */
2453 static long
2454 global_sym_index (h)
2455 struct elf_link_hash_entry *h;
2457 struct elf_link_hash_entry **p;
2458 bfd *obj;
2460 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2461 || h->root.type == bfd_link_hash_defweak);
2463 obj = h->root.u.def.section->owner;
2464 for (p = elf_sym_hashes (obj); *p != h; ++p)
2465 continue;
2467 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2470 /* Allocate function descriptors. We can do these for every function
2471 in a main executable that is not exported. */
2473 static boolean
2474 allocate_fptr (dyn_i, data)
2475 struct elfNN_ia64_dyn_sym_info *dyn_i;
2476 PTR data;
2478 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2480 if (dyn_i->want_fptr)
2482 struct elf_link_hash_entry *h = dyn_i->h;
2484 if (h)
2485 while (h->root.type == bfd_link_hash_indirect
2486 || h->root.type == bfd_link_hash_warning)
2487 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2489 if (x->info->shared
2490 /* AIX needs an FPTR in this case. */
2491 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2492 && (!h
2493 || h->root.type == bfd_link_hash_defined
2494 || h->root.type == bfd_link_hash_defweak)))
2496 if (h && h->dynindx == -1)
2498 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2499 || (h->root.type == bfd_link_hash_defweak));
2501 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2502 (x->info, h->root.u.def.section->owner,
2503 global_sym_index (h)))
2504 return false;
2507 dyn_i->want_fptr = 0;
2509 else if (h == NULL || h->dynindx == -1)
2511 dyn_i->fptr_offset = x->ofs;
2512 x->ofs += 16;
2514 else
2515 dyn_i->want_fptr = 0;
2517 return true;
2520 /* Allocate all the minimal PLT entries. */
2522 static boolean
2523 allocate_plt_entries (dyn_i, data)
2524 struct elfNN_ia64_dyn_sym_info *dyn_i;
2525 PTR data;
2527 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2529 if (dyn_i->want_plt)
2531 struct elf_link_hash_entry *h = dyn_i->h;
2533 if (h)
2534 while (h->root.type == bfd_link_hash_indirect
2535 || h->root.type == bfd_link_hash_warning)
2536 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2538 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2539 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2541 bfd_size_type offset = x->ofs;
2542 if (offset == 0)
2543 offset = PLT_HEADER_SIZE;
2544 dyn_i->plt_offset = offset;
2545 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2547 dyn_i->want_pltoff = 1;
2549 else
2551 dyn_i->want_plt = 0;
2552 dyn_i->want_plt2 = 0;
2555 return true;
2558 /* Allocate all the full PLT entries. */
2560 static boolean
2561 allocate_plt2_entries (dyn_i, data)
2562 struct elfNN_ia64_dyn_sym_info *dyn_i;
2563 PTR data;
2565 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2567 if (dyn_i->want_plt2)
2569 struct elf_link_hash_entry *h = dyn_i->h;
2570 bfd_size_type ofs = x->ofs;
2572 dyn_i->plt2_offset = ofs;
2573 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2575 while (h->root.type == bfd_link_hash_indirect
2576 || h->root.type == bfd_link_hash_warning)
2577 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2578 dyn_i->h->plt.offset = ofs;
2580 return true;
2583 /* Allocate all the PLTOFF entries requested by relocations and
2584 plt entries. We can't share space with allocated FPTR entries,
2585 because the latter are not necessarily addressable by the GP.
2586 ??? Relaxation might be able to determine that they are. */
2588 static boolean
2589 allocate_pltoff_entries (dyn_i, data)
2590 struct elfNN_ia64_dyn_sym_info *dyn_i;
2591 PTR data;
2593 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2595 if (dyn_i->want_pltoff)
2597 dyn_i->pltoff_offset = x->ofs;
2598 x->ofs += 16;
2600 return true;
2603 /* Allocate dynamic relocations for those symbols that turned out
2604 to be dynamic. */
2606 static boolean
2607 allocate_dynrel_entries (dyn_i, data)
2608 struct elfNN_ia64_dyn_sym_info *dyn_i;
2609 PTR data;
2611 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2612 struct elfNN_ia64_link_hash_table *ia64_info;
2613 struct elfNN_ia64_dyn_reloc_entry *rent;
2614 boolean dynamic_symbol, shared;
2616 ia64_info = elfNN_ia64_hash_table (x->info);
2617 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2618 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2619 /* Don't allocate an entry for __GLOB_DATA_PTR */
2620 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2621 "__GLOB_DATA_PTR") != 0));
2622 shared = x->info->shared;
2624 /* Take care of the normal data relocations. */
2626 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2628 int count = rent->count;
2630 switch (rent->type)
2632 case R_IA64_FPTR64LSB:
2633 /* Allocate one iff !want_fptr, which by this point will
2634 be true only if we're actually allocating one statically
2635 in the main executable. */
2636 if (dyn_i->want_fptr)
2637 continue;
2638 break;
2639 case R_IA64_PCREL64LSB:
2640 if (!dynamic_symbol)
2641 continue;
2642 break;
2643 case R_IA64_DIR64LSB:
2644 if (!dynamic_symbol && !shared)
2645 continue;
2646 break;
2647 case R_IA64_IPLTLSB:
2648 if (!dynamic_symbol && !shared)
2649 continue;
2650 /* Use two REL relocations for IPLT relocations
2651 against local symbols. */
2652 if (!dynamic_symbol)
2653 count *= 2;
2654 break;
2655 case R_IA64_TPREL64LSB:
2656 case R_IA64_DTPREL64LSB:
2657 case R_IA64_DTPMOD64LSB:
2658 break;
2659 default:
2660 abort ();
2662 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2665 /* Take care of the GOT and PLT relocations. */
2667 if (((dynamic_symbol || shared) && dyn_i->want_got)
2668 || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2669 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2670 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2671 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2672 if ((dynamic_symbol || shared) && dyn_i->want_dtpmod)
2673 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2674 if (dynamic_symbol && dyn_i->want_dtprel)
2675 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2677 if (dyn_i->want_pltoff)
2679 bfd_size_type t = 0;
2681 /* Dynamic symbols get one IPLT relocation. Local symbols in
2682 shared libraries get two REL relocations. Local symbols in
2683 main applications get nothing. */
2684 if (dynamic_symbol)
2685 t = sizeof (ElfNN_External_Rela);
2686 else if (shared)
2687 t = 2 * sizeof (ElfNN_External_Rela);
2689 ia64_info->rel_pltoff_sec->_raw_size += t;
2692 return true;
2695 static boolean
2696 elfNN_ia64_adjust_dynamic_symbol (info, h)
2697 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2698 struct elf_link_hash_entry *h;
2700 /* ??? Undefined symbols with PLT entries should be re-defined
2701 to be the PLT entry. */
2703 /* If this is a weak symbol, and there is a real definition, the
2704 processor independent code will have arranged for us to see the
2705 real definition first, and we can just use the same value. */
2706 if (h->weakdef != NULL)
2708 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2709 || h->weakdef->root.type == bfd_link_hash_defweak);
2710 h->root.u.def.section = h->weakdef->root.u.def.section;
2711 h->root.u.def.value = h->weakdef->root.u.def.value;
2712 return true;
2715 /* If this is a reference to a symbol defined by a dynamic object which
2716 is not a function, we might allocate the symbol in our .dynbss section
2717 and allocate a COPY dynamic relocation.
2719 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2720 of hackery. */
2722 return true;
2725 static boolean
2726 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2727 bfd *output_bfd;
2728 struct bfd_link_info *info;
2730 struct elfNN_ia64_allocate_data data;
2731 struct elfNN_ia64_link_hash_table *ia64_info;
2732 asection *sec;
2733 bfd *dynobj;
2734 boolean relplt = false;
2736 dynobj = elf_hash_table(info)->dynobj;
2737 ia64_info = elfNN_ia64_hash_table (info);
2738 BFD_ASSERT(dynobj != NULL);
2739 data.info = info;
2741 /* Set the contents of the .interp section to the interpreter. */
2742 if (ia64_info->root.dynamic_sections_created
2743 && !info->shared)
2745 sec = bfd_get_section_by_name (dynobj, ".interp");
2746 BFD_ASSERT (sec != NULL);
2747 sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd);
2748 sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1;
2751 /* Allocate the GOT entries. */
2753 if (ia64_info->got_sec)
2755 data.ofs = 0;
2756 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2757 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2758 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2759 ia64_info->got_sec->_raw_size = data.ofs;
2762 /* Allocate the FPTR entries. */
2764 if (ia64_info->fptr_sec)
2766 data.ofs = 0;
2767 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2768 ia64_info->fptr_sec->_raw_size = data.ofs;
2771 /* Now that we've seen all of the input files, we can decide which
2772 symbols need plt entries. Allocate the minimal PLT entries first.
2773 We do this even though dynamic_sections_created may be false, because
2774 this has the side-effect of clearing want_plt and want_plt2. */
2776 data.ofs = 0;
2777 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2779 ia64_info->minplt_entries = 0;
2780 if (data.ofs)
2782 ia64_info->minplt_entries
2783 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2786 /* Align the pointer for the plt2 entries. */
2787 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2789 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2790 if (data.ofs != 0)
2792 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2794 ia64_info->plt_sec->_raw_size = data.ofs;
2796 /* If we've got a .plt, we need some extra memory for the dynamic
2797 linker. We stuff these in .got.plt. */
2798 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2799 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2802 /* Allocate the PLTOFF entries. */
2804 if (ia64_info->pltoff_sec)
2806 data.ofs = 0;
2807 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2808 ia64_info->pltoff_sec->_raw_size = data.ofs;
2811 if (ia64_info->root.dynamic_sections_created)
2813 /* Allocate space for the dynamic relocations that turned out to be
2814 required. */
2816 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2819 /* We have now determined the sizes of the various dynamic sections.
2820 Allocate memory for them. */
2821 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2823 boolean strip;
2825 if (!(sec->flags & SEC_LINKER_CREATED))
2826 continue;
2828 /* If we don't need this section, strip it from the output file.
2829 There were several sections primarily related to dynamic
2830 linking that must be create before the linker maps input
2831 sections to output sections. The linker does that before
2832 bfd_elf_size_dynamic_sections is called, and it is that
2833 function which decides whether anything needs to go into
2834 these sections. */
2836 strip = (sec->_raw_size == 0);
2838 if (sec == ia64_info->got_sec)
2839 strip = false;
2840 else if (sec == ia64_info->rel_got_sec)
2842 if (strip)
2843 ia64_info->rel_got_sec = NULL;
2844 else
2845 /* We use the reloc_count field as a counter if we need to
2846 copy relocs into the output file. */
2847 sec->reloc_count = 0;
2849 else if (sec == ia64_info->fptr_sec)
2851 if (strip)
2852 ia64_info->fptr_sec = NULL;
2854 else if (sec == ia64_info->plt_sec)
2856 if (strip)
2857 ia64_info->plt_sec = NULL;
2859 else if (sec == ia64_info->pltoff_sec)
2861 if (strip)
2862 ia64_info->pltoff_sec = NULL;
2864 else if (sec == ia64_info->rel_pltoff_sec)
2866 if (strip)
2867 ia64_info->rel_pltoff_sec = NULL;
2868 else
2870 relplt = true;
2871 /* We use the reloc_count field as a counter if we need to
2872 copy relocs into the output file. */
2873 sec->reloc_count = 0;
2876 else
2878 const char *name;
2880 /* It's OK to base decisions on the section name, because none
2881 of the dynobj section names depend upon the input files. */
2882 name = bfd_get_section_name (dynobj, sec);
2884 if (strcmp (name, ".got.plt") == 0)
2885 strip = false;
2886 else if (strncmp (name, ".rel", 4) == 0)
2888 if (!strip)
2890 /* We use the reloc_count field as a counter if we need to
2891 copy relocs into the output file. */
2892 sec->reloc_count = 0;
2895 else
2896 continue;
2899 if (strip)
2900 _bfd_strip_section_from_output (info, sec);
2901 else
2903 /* Allocate memory for the section contents. */
2904 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
2905 if (sec->contents == NULL && sec->_raw_size != 0)
2906 return false;
2910 if (elf_hash_table (info)->dynamic_sections_created)
2912 /* Add some entries to the .dynamic section. We fill in the values
2913 later (in finish_dynamic_sections) but we must add the entries now
2914 so that we get the correct size for the .dynamic section. */
2916 if (!info->shared)
2918 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2919 by the debugger. */
2920 #define add_dynamic_entry(TAG, VAL) \
2921 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
2923 if (!add_dynamic_entry (DT_DEBUG, 0))
2924 return false;
2927 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
2928 return false;
2929 if (!add_dynamic_entry (DT_PLTGOT, 0))
2930 return false;
2932 if (relplt)
2934 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
2935 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2936 || !add_dynamic_entry (DT_JMPREL, 0))
2937 return false;
2940 if (!add_dynamic_entry (DT_RELA, 0)
2941 || !add_dynamic_entry (DT_RELASZ, 0)
2942 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
2943 return false;
2945 if (ia64_info->reltext)
2947 if (!add_dynamic_entry (DT_TEXTREL, 0))
2948 return false;
2949 info->flags |= DF_TEXTREL;
2953 /* ??? Perhaps force __gp local. */
2955 return true;
2958 static bfd_reloc_status_type
2959 elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
2960 bfd *abfd;
2961 bfd_byte *hit_addr;
2962 bfd_vma v;
2963 unsigned int r_type;
2965 const struct ia64_operand *op;
2966 int bigendian = 0, shift = 0;
2967 bfd_vma t0, t1, insn, dword;
2968 enum ia64_opnd opnd;
2969 const char *err;
2970 size_t size = 8;
2971 #ifdef BFD_HOST_U_64_BIT
2972 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
2973 #else
2974 bfd_vma val = v;
2975 #endif
2977 opnd = IA64_OPND_NIL;
2978 switch (r_type)
2980 case R_IA64_NONE:
2981 case R_IA64_LDXMOV:
2982 return bfd_reloc_ok;
2984 /* Instruction relocations. */
2986 case R_IA64_IMM14:
2987 case R_IA64_TPREL14:
2988 case R_IA64_DTPREL14:
2989 opnd = IA64_OPND_IMM14;
2990 break;
2992 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
2993 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
2994 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
2995 case R_IA64_PCREL21B:
2996 case R_IA64_PCREL21BI:
2997 opnd = IA64_OPND_TGT25c;
2998 break;
3000 case R_IA64_IMM22:
3001 case R_IA64_GPREL22:
3002 case R_IA64_LTOFF22:
3003 case R_IA64_LTOFF22X:
3004 case R_IA64_PLTOFF22:
3005 case R_IA64_PCREL22:
3006 case R_IA64_LTOFF_FPTR22:
3007 case R_IA64_TPREL22:
3008 case R_IA64_DTPREL22:
3009 case R_IA64_LTOFF_TPREL22:
3010 case R_IA64_LTOFF_DTPMOD22:
3011 case R_IA64_LTOFF_DTPREL22:
3012 opnd = IA64_OPND_IMM22;
3013 break;
3015 case R_IA64_IMM64:
3016 case R_IA64_GPREL64I:
3017 case R_IA64_LTOFF64I:
3018 case R_IA64_PLTOFF64I:
3019 case R_IA64_PCREL64I:
3020 case R_IA64_FPTR64I:
3021 case R_IA64_LTOFF_FPTR64I:
3022 case R_IA64_TPREL64I:
3023 case R_IA64_DTPREL64I:
3024 opnd = IA64_OPND_IMMU64;
3025 break;
3027 /* Data relocations. */
3029 case R_IA64_DIR32MSB:
3030 case R_IA64_GPREL32MSB:
3031 case R_IA64_FPTR32MSB:
3032 case R_IA64_PCREL32MSB:
3033 case R_IA64_LTOFF_FPTR32MSB:
3034 case R_IA64_SEGREL32MSB:
3035 case R_IA64_SECREL32MSB:
3036 case R_IA64_LTV32MSB:
3037 case R_IA64_DTPREL32MSB:
3038 size = 4; bigendian = 1;
3039 break;
3041 case R_IA64_DIR32LSB:
3042 case R_IA64_GPREL32LSB:
3043 case R_IA64_FPTR32LSB:
3044 case R_IA64_PCREL32LSB:
3045 case R_IA64_LTOFF_FPTR32LSB:
3046 case R_IA64_SEGREL32LSB:
3047 case R_IA64_SECREL32LSB:
3048 case R_IA64_LTV32LSB:
3049 case R_IA64_DTPREL32LSB:
3050 size = 4; bigendian = 0;
3051 break;
3053 case R_IA64_DIR64MSB:
3054 case R_IA64_GPREL64MSB:
3055 case R_IA64_PLTOFF64MSB:
3056 case R_IA64_FPTR64MSB:
3057 case R_IA64_PCREL64MSB:
3058 case R_IA64_LTOFF_FPTR64MSB:
3059 case R_IA64_SEGREL64MSB:
3060 case R_IA64_SECREL64MSB:
3061 case R_IA64_LTV64MSB:
3062 case R_IA64_TPREL64MSB:
3063 case R_IA64_DTPMOD64MSB:
3064 case R_IA64_DTPREL64MSB:
3065 size = 8; bigendian = 1;
3066 break;
3068 case R_IA64_DIR64LSB:
3069 case R_IA64_GPREL64LSB:
3070 case R_IA64_PLTOFF64LSB:
3071 case R_IA64_FPTR64LSB:
3072 case R_IA64_PCREL64LSB:
3073 case R_IA64_LTOFF_FPTR64LSB:
3074 case R_IA64_SEGREL64LSB:
3075 case R_IA64_SECREL64LSB:
3076 case R_IA64_LTV64LSB:
3077 case R_IA64_TPREL64LSB:
3078 case R_IA64_DTPMOD64LSB:
3079 case R_IA64_DTPREL64LSB:
3080 size = 8; bigendian = 0;
3081 break;
3083 /* Unsupported / Dynamic relocations. */
3084 default:
3085 return bfd_reloc_notsupported;
3088 switch (opnd)
3090 case IA64_OPND_IMMU64:
3091 hit_addr -= (long) hit_addr & 0x3;
3092 t0 = bfd_get_64 (abfd, hit_addr);
3093 t1 = bfd_get_64 (abfd, hit_addr + 8);
3095 /* tmpl/s: bits 0.. 5 in t0
3096 slot 0: bits 5..45 in t0
3097 slot 1: bits 46..63 in t0, bits 0..22 in t1
3098 slot 2: bits 23..63 in t1 */
3100 /* First, clear the bits that form the 64 bit constant. */
3101 t0 &= ~(0x3ffffLL << 46);
3102 t1 &= ~(0x7fffffLL
3103 | (( (0x07fLL << 13) | (0x1ffLL << 27)
3104 | (0x01fLL << 22) | (0x001LL << 21)
3105 | (0x001LL << 36)) << 23));
3107 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
3108 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
3109 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
3110 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
3111 | (((val >> 16) & 0x01f) << 22) /* imm5c */
3112 | (((val >> 21) & 0x001) << 21) /* ic */
3113 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
3115 bfd_put_64 (abfd, t0, hit_addr);
3116 bfd_put_64 (abfd, t1, hit_addr + 8);
3117 break;
3119 case IA64_OPND_TGT64:
3120 hit_addr -= (long) hit_addr & 0x3;
3121 t0 = bfd_get_64 (abfd, hit_addr);
3122 t1 = bfd_get_64 (abfd, hit_addr + 8);
3124 /* tmpl/s: bits 0.. 5 in t0
3125 slot 0: bits 5..45 in t0
3126 slot 1: bits 46..63 in t0, bits 0..22 in t1
3127 slot 2: bits 23..63 in t1 */
3129 /* First, clear the bits that form the 64 bit constant. */
3130 t0 &= ~(0x3ffffLL << 46);
3131 t1 &= ~(0x7fffffLL
3132 | ((1LL << 36 | 0xfffffLL << 13) << 23));
3134 val >>= 4;
3135 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
3136 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
3137 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
3138 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
3140 bfd_put_64 (abfd, t0, hit_addr);
3141 bfd_put_64 (abfd, t1, hit_addr + 8);
3142 break;
3144 default:
3145 switch ((long) hit_addr & 0x3)
3147 case 0: shift = 5; break;
3148 case 1: shift = 14; hit_addr += 3; break;
3149 case 2: shift = 23; hit_addr += 6; break;
3150 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
3152 dword = bfd_get_64 (abfd, hit_addr);
3153 insn = (dword >> shift) & 0x1ffffffffffLL;
3155 op = elf64_ia64_operands + opnd;
3156 err = (*op->insert) (op, val, (ia64_insn *)& insn);
3157 if (err)
3158 return bfd_reloc_overflow;
3160 dword &= ~(0x1ffffffffffLL << shift);
3161 dword |= (insn << shift);
3162 bfd_put_64 (abfd, dword, hit_addr);
3163 break;
3165 case IA64_OPND_NIL:
3166 /* A data relocation. */
3167 if (bigendian)
3168 if (size == 4)
3169 bfd_putb32 (val, hit_addr);
3170 else
3171 bfd_putb64 (val, hit_addr);
3172 else
3173 if (size == 4)
3174 bfd_putl32 (val, hit_addr);
3175 else
3176 bfd_putl64 (val, hit_addr);
3177 break;
3180 return bfd_reloc_ok;
3183 static void
3184 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3185 dynindx, addend)
3186 bfd *abfd;
3187 struct bfd_link_info *info;
3188 asection *sec;
3189 asection *srel;
3190 bfd_vma offset;
3191 unsigned int type;
3192 long dynindx;
3193 bfd_vma addend;
3195 Elf_Internal_Rela outrel;
3197 offset += sec->output_section->vma + sec->output_offset;
3199 BFD_ASSERT (dynindx != -1);
3200 outrel.r_info = ELFNN_R_INFO (dynindx, type);
3201 outrel.r_addend = addend;
3202 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3203 if ((outrel.r_offset | 1) == (bfd_vma) -1)
3205 /* Run for the hills. We shouldn't be outputting a relocation
3206 for this. So do what everyone else does and output a no-op. */
3207 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3208 outrel.r_addend = 0;
3209 outrel.r_offset = 0;
3212 bfd_elfNN_swap_reloca_out (abfd, &outrel,
3213 ((ElfNN_External_Rela *) srel->contents
3214 + srel->reloc_count++));
3215 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3216 <= srel->_cooked_size);
3219 /* Store an entry for target address TARGET_ADDR in the linkage table
3220 and return the gp-relative address of the linkage table entry. */
3222 static bfd_vma
3223 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3224 bfd *abfd;
3225 struct bfd_link_info *info;
3226 struct elfNN_ia64_dyn_sym_info *dyn_i;
3227 long dynindx;
3228 bfd_vma addend;
3229 bfd_vma value;
3230 unsigned int dyn_r_type;
3232 struct elfNN_ia64_link_hash_table *ia64_info;
3233 asection *got_sec;
3234 boolean done;
3235 bfd_vma got_offset;
3237 ia64_info = elfNN_ia64_hash_table (info);
3238 got_sec = ia64_info->got_sec;
3240 switch (dyn_r_type)
3242 case R_IA64_TPREL64LSB:
3243 done = dyn_i->tprel_done;
3244 dyn_i->tprel_done = true;
3245 got_offset = dyn_i->tprel_offset;
3246 break;
3247 case R_IA64_DTPMOD64LSB:
3248 done = dyn_i->dtpmod_done;
3249 dyn_i->dtpmod_done = true;
3250 got_offset = dyn_i->dtpmod_offset;
3251 break;
3252 case R_IA64_DTPREL64LSB:
3253 done = dyn_i->dtprel_done;
3254 dyn_i->dtprel_done = true;
3255 got_offset = dyn_i->dtprel_offset;
3256 break;
3257 default:
3258 done = dyn_i->got_done;
3259 dyn_i->got_done = true;
3260 got_offset = dyn_i->got_offset;
3261 break;
3264 BFD_ASSERT ((got_offset & 7) == 0);
3266 if (! done)
3268 /* Store the target address in the linkage table entry. */
3269 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3271 /* Install a dynamic relocation if needed. */
3272 if ((info->shared && dyn_r_type != R_IA64_DTPREL64LSB)
3273 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
3274 || elfNN_ia64_aix_vec (abfd->xvec)
3275 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3277 if (dynindx == -1
3278 && dyn_r_type != R_IA64_TPREL64LSB
3279 && dyn_r_type != R_IA64_DTPMOD64LSB
3280 && dyn_r_type != R_IA64_DTPREL64LSB)
3282 dyn_r_type = R_IA64_REL64LSB;
3283 dynindx = 0;
3284 addend = value;
3287 if (bfd_big_endian (abfd))
3289 switch (dyn_r_type)
3291 case R_IA64_REL64LSB:
3292 dyn_r_type = R_IA64_REL64MSB;
3293 break;
3294 case R_IA64_DIR64LSB:
3295 dyn_r_type = R_IA64_DIR64MSB;
3296 break;
3297 case R_IA64_FPTR64LSB:
3298 dyn_r_type = R_IA64_FPTR64MSB;
3299 break;
3300 case R_IA64_TPREL64LSB:
3301 dyn_r_type = R_IA64_TPREL64MSB;
3302 break;
3303 case R_IA64_DTPMOD64LSB:
3304 dyn_r_type = R_IA64_DTPMOD64MSB;
3305 break;
3306 case R_IA64_DTPREL64LSB:
3307 dyn_r_type = R_IA64_DTPREL64MSB;
3308 break;
3309 default:
3310 BFD_ASSERT (false);
3311 break;
3315 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3316 ia64_info->rel_got_sec,
3317 got_offset, dyn_r_type,
3318 dynindx, addend);
3322 /* Return the address of the linkage table entry. */
3323 value = (got_sec->output_section->vma
3324 + got_sec->output_offset
3325 + got_offset);
3327 return value;
3330 /* Fill in a function descriptor consisting of the function's code
3331 address and its global pointer. Return the descriptor's address. */
3333 static bfd_vma
3334 set_fptr_entry (abfd, info, dyn_i, value)
3335 bfd *abfd;
3336 struct bfd_link_info *info;
3337 struct elfNN_ia64_dyn_sym_info *dyn_i;
3338 bfd_vma value;
3340 struct elfNN_ia64_link_hash_table *ia64_info;
3341 asection *fptr_sec;
3343 ia64_info = elfNN_ia64_hash_table (info);
3344 fptr_sec = ia64_info->fptr_sec;
3346 if (!dyn_i->fptr_done)
3348 dyn_i->fptr_done = 1;
3350 /* Fill in the function descriptor. */
3351 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3352 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3353 fptr_sec->contents + dyn_i->fptr_offset + 8);
3356 /* Return the descriptor's address. */
3357 value = (fptr_sec->output_section->vma
3358 + fptr_sec->output_offset
3359 + dyn_i->fptr_offset);
3361 return value;
3364 /* Fill in a PLTOFF entry consisting of the function's code address
3365 and its global pointer. Return the descriptor's address. */
3367 static bfd_vma
3368 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3369 bfd *abfd;
3370 struct bfd_link_info *info;
3371 struct elfNN_ia64_dyn_sym_info *dyn_i;
3372 bfd_vma value;
3373 boolean is_plt;
3375 struct elfNN_ia64_link_hash_table *ia64_info;
3376 asection *pltoff_sec;
3378 ia64_info = elfNN_ia64_hash_table (info);
3379 pltoff_sec = ia64_info->pltoff_sec;
3381 /* Don't do anything if this symbol uses a real PLT entry. In
3382 that case, we'll fill this in during finish_dynamic_symbol. */
3383 if ((! dyn_i->want_plt || is_plt)
3384 && !dyn_i->pltoff_done)
3386 bfd_vma gp = _bfd_get_gp_value (abfd);
3388 /* Fill in the function descriptor. */
3389 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3390 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3392 /* Install dynamic relocations if needed. */
3393 if (!is_plt && info->shared)
3395 unsigned int dyn_r_type;
3397 if (bfd_big_endian (abfd))
3398 dyn_r_type = R_IA64_REL64MSB;
3399 else
3400 dyn_r_type = R_IA64_REL64LSB;
3402 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3403 ia64_info->rel_pltoff_sec,
3404 dyn_i->pltoff_offset,
3405 dyn_r_type, 0, value);
3406 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3407 ia64_info->rel_pltoff_sec,
3408 dyn_i->pltoff_offset + 8,
3409 dyn_r_type, 0, gp);
3412 dyn_i->pltoff_done = 1;
3415 /* Return the descriptor's address. */
3416 value = (pltoff_sec->output_section->vma
3417 + pltoff_sec->output_offset
3418 + dyn_i->pltoff_offset);
3420 return value;
3423 /* Return the base VMA address which should be subtracted from real addresses
3424 when resolving @tprel() relocation.
3425 Main program TLS (whose template starts at PT_TLS p_vaddr)
3426 is assigned offset round(16, PT_TLS p_align). */
3428 static bfd_vma
3429 elfNN_ia64_tprel_base (info)
3430 struct bfd_link_info *info;
3432 struct elf_link_tls_segment *tls_segment
3433 = elf_hash_table (info)->tls_segment;
3435 BFD_ASSERT (tls_segment != NULL);
3436 return (tls_segment->start
3437 - align_power ((bfd_vma) 16, tls_segment->align));
3440 /* Return the base VMA address which should be subtracted from real addresses
3441 when resolving @dtprel() relocation.
3442 This is PT_TLS segment p_vaddr. */
3444 static bfd_vma
3445 elfNN_ia64_dtprel_base (info)
3446 struct bfd_link_info *info;
3448 BFD_ASSERT (elf_hash_table (info)->tls_segment != NULL);
3449 return elf_hash_table (info)->tls_segment->start;
3452 /* Called through qsort to sort the .IA_64.unwind section during a
3453 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3454 to the output bfd so we can do proper endianness frobbing. */
3456 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3458 static int
3459 elfNN_ia64_unwind_entry_compare (a, b)
3460 const PTR a;
3461 const PTR b;
3463 bfd_vma av, bv;
3465 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3466 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3468 return (av < bv ? -1 : av > bv ? 1 : 0);
3471 static boolean
3472 elfNN_ia64_final_link (abfd, info)
3473 bfd *abfd;
3474 struct bfd_link_info *info;
3476 struct elfNN_ia64_link_hash_table *ia64_info;
3477 asection *unwind_output_sec;
3479 ia64_info = elfNN_ia64_hash_table (info);
3481 /* Make sure we've got ourselves a nice fat __gp value. */
3482 if (!info->relocateable)
3484 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3485 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3486 struct elf_link_hash_entry *gp;
3487 bfd_vma gp_val;
3488 asection *os;
3490 /* Find the min and max vma of all sections marked short. Also
3491 collect min and max vma of any type, for use in selecting a
3492 nice gp. */
3493 for (os = abfd->sections; os ; os = os->next)
3495 bfd_vma lo, hi;
3497 if ((os->flags & SEC_ALLOC) == 0)
3498 continue;
3500 lo = os->vma;
3501 hi = os->vma + os->_raw_size;
3502 if (hi < lo)
3503 hi = (bfd_vma) -1;
3505 if (min_vma > lo)
3506 min_vma = lo;
3507 if (max_vma < hi)
3508 max_vma = hi;
3509 if (os->flags & SEC_SMALL_DATA)
3511 if (min_short_vma > lo)
3512 min_short_vma = lo;
3513 if (max_short_vma < hi)
3514 max_short_vma = hi;
3518 /* See if the user wants to force a value. */
3519 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
3520 false, false);
3522 if (gp
3523 && (gp->root.type == bfd_link_hash_defined
3524 || gp->root.type == bfd_link_hash_defweak))
3526 asection *gp_sec = gp->root.u.def.section;
3527 gp_val = (gp->root.u.def.value
3528 + gp_sec->output_section->vma
3529 + gp_sec->output_offset);
3531 else
3533 /* Pick a sensible value. */
3535 asection *got_sec = ia64_info->got_sec;
3537 /* Start with just the address of the .got. */
3538 if (got_sec)
3539 gp_val = got_sec->output_section->vma;
3540 else if (max_short_vma != 0)
3541 gp_val = min_short_vma;
3542 else
3543 gp_val = min_vma;
3545 /* If it is possible to address the entire image, but we
3546 don't with the choice above, adjust. */
3547 if (max_vma - min_vma < 0x400000
3548 && max_vma - gp_val <= 0x200000
3549 && gp_val - min_vma > 0x200000)
3550 gp_val = min_vma + 0x200000;
3551 else if (max_short_vma != 0)
3553 /* If we don't cover all the short data, adjust. */
3554 if (max_short_vma - gp_val >= 0x200000)
3555 gp_val = min_short_vma + 0x200000;
3557 /* If we're addressing stuff past the end, adjust back. */
3558 if (gp_val > max_vma)
3559 gp_val = max_vma - 0x200000 + 8;
3563 /* Validate whether all SHF_IA_64_SHORT sections are within
3564 range of the chosen GP. */
3566 if (max_short_vma != 0)
3568 if (max_short_vma - min_short_vma >= 0x400000)
3570 (*_bfd_error_handler)
3571 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3572 bfd_get_filename (abfd),
3573 (unsigned long) (max_short_vma - min_short_vma));
3574 return false;
3576 else if ((gp_val > min_short_vma
3577 && gp_val - min_short_vma > 0x200000)
3578 || (gp_val < max_short_vma
3579 && max_short_vma - gp_val >= 0x200000))
3581 (*_bfd_error_handler)
3582 (_("%s: __gp does not cover short data segment"),
3583 bfd_get_filename (abfd));
3584 return false;
3588 _bfd_set_gp_value (abfd, gp_val);
3590 if (gp)
3592 gp->root.type = bfd_link_hash_defined;
3593 gp->root.u.def.value = gp_val;
3594 gp->root.u.def.section = bfd_abs_section_ptr;
3598 /* If we're producing a final executable, we need to sort the contents
3599 of the .IA_64.unwind section. Force this section to be relocated
3600 into memory rather than written immediately to the output file. */
3601 unwind_output_sec = NULL;
3602 if (!info->relocateable)
3604 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3605 if (s)
3607 unwind_output_sec = s->output_section;
3608 unwind_output_sec->contents
3609 = bfd_malloc (unwind_output_sec->_raw_size);
3610 if (unwind_output_sec->contents == NULL)
3611 return false;
3615 /* Invoke the regular ELF backend linker to do all the work. */
3616 if (!bfd_elfNN_bfd_final_link (abfd, info))
3617 return false;
3619 if (unwind_output_sec)
3621 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3622 qsort (unwind_output_sec->contents,
3623 (size_t) (unwind_output_sec->_raw_size / 24),
3625 elfNN_ia64_unwind_entry_compare);
3627 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3628 unwind_output_sec->contents, (bfd_vma) 0,
3629 unwind_output_sec->_raw_size))
3630 return false;
3633 return true;
3636 static boolean
3637 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3638 contents, relocs, local_syms, local_sections)
3639 bfd *output_bfd;
3640 struct bfd_link_info *info;
3641 bfd *input_bfd;
3642 asection *input_section;
3643 bfd_byte *contents;
3644 Elf_Internal_Rela *relocs;
3645 Elf_Internal_Sym *local_syms;
3646 asection **local_sections;
3648 struct elfNN_ia64_link_hash_table *ia64_info;
3649 Elf_Internal_Shdr *symtab_hdr;
3650 Elf_Internal_Rela *rel;
3651 Elf_Internal_Rela *relend;
3652 asection *srel;
3653 boolean ret_val = true; /* for non-fatal errors */
3654 bfd_vma gp_val;
3656 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3657 ia64_info = elfNN_ia64_hash_table (info);
3659 /* Infect various flags from the input section to the output section. */
3660 if (info->relocateable)
3662 bfd_vma flags;
3664 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3665 flags &= SHF_IA_64_NORECOV;
3667 elf_section_data(input_section->output_section)
3668 ->this_hdr.sh_flags |= flags;
3669 return true;
3672 gp_val = _bfd_get_gp_value (output_bfd);
3673 srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3675 rel = relocs;
3676 relend = relocs + input_section->reloc_count;
3677 for (; rel < relend; ++rel)
3679 struct elf_link_hash_entry *h;
3680 struct elfNN_ia64_dyn_sym_info *dyn_i;
3681 bfd_reloc_status_type r;
3682 reloc_howto_type *howto;
3683 unsigned long r_symndx;
3684 Elf_Internal_Sym *sym;
3685 unsigned int r_type;
3686 bfd_vma value;
3687 asection *sym_sec;
3688 bfd_byte *hit_addr;
3689 boolean dynamic_symbol_p;
3690 boolean undef_weak_ref;
3692 r_type = ELFNN_R_TYPE (rel->r_info);
3693 if (r_type > R_IA64_MAX_RELOC_CODE)
3695 (*_bfd_error_handler)
3696 (_("%s: unknown relocation type %d"),
3697 bfd_archive_filename (input_bfd), (int)r_type);
3698 bfd_set_error (bfd_error_bad_value);
3699 ret_val = false;
3700 continue;
3703 howto = lookup_howto (r_type);
3704 r_symndx = ELFNN_R_SYM (rel->r_info);
3705 h = NULL;
3706 sym = NULL;
3707 sym_sec = NULL;
3708 undef_weak_ref = false;
3710 if (r_symndx < symtab_hdr->sh_info)
3712 /* Reloc against local symbol. */
3713 sym = local_syms + r_symndx;
3714 sym_sec = local_sections[r_symndx];
3715 value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel);
3716 if ((sym_sec->flags & SEC_MERGE)
3717 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3718 && (elf_section_data (sym_sec)->sec_info_type
3719 == ELF_INFO_TYPE_MERGE))
3721 struct elfNN_ia64_local_hash_entry *loc_h;
3723 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, false);
3724 if (loc_h && ! loc_h->sec_merge_done)
3726 struct elfNN_ia64_dyn_sym_info *dynent;
3727 asection *msec;
3729 for (dynent = loc_h->info; dynent; dynent = dynent->next)
3731 msec = sym_sec;
3732 dynent->addend =
3733 _bfd_merged_section_offset (output_bfd, &msec,
3734 elf_section_data (msec)->
3735 sec_info,
3736 sym->st_value
3737 + dynent->addend,
3738 (bfd_vma) 0);
3739 dynent->addend -= sym->st_value;
3740 dynent->addend += msec->output_section->vma
3741 + msec->output_offset
3742 - sym_sec->output_section->vma
3743 - sym_sec->output_offset;
3745 loc_h->sec_merge_done = 1;
3749 else
3751 long indx;
3753 /* Reloc against global symbol. */
3754 indx = r_symndx - symtab_hdr->sh_info;
3755 h = elf_sym_hashes (input_bfd)[indx];
3756 while (h->root.type == bfd_link_hash_indirect
3757 || h->root.type == bfd_link_hash_warning)
3758 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3760 value = 0;
3761 if (h->root.type == bfd_link_hash_defined
3762 || h->root.type == bfd_link_hash_defweak)
3764 sym_sec = h->root.u.def.section;
3766 /* Detect the cases that sym_sec->output_section is
3767 expected to be NULL -- all cases in which the symbol
3768 is defined in another shared module. This includes
3769 PLT relocs for which we've created a PLT entry and
3770 other relocs for which we're prepared to create
3771 dynamic relocations. */
3772 /* ??? Just accept it NULL and continue. */
3774 if (sym_sec->output_section != NULL)
3776 value = (h->root.u.def.value
3777 + sym_sec->output_section->vma
3778 + sym_sec->output_offset);
3781 else if (h->root.type == bfd_link_hash_undefweak)
3782 undef_weak_ref = true;
3783 else if (info->shared
3784 && (!info->symbolic || info->allow_shlib_undefined)
3785 && !info->no_undefined
3786 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3788 else
3790 if (! ((*info->callbacks->undefined_symbol)
3791 (info, h->root.root.string, input_bfd,
3792 input_section, rel->r_offset,
3793 (!info->shared || info->no_undefined
3794 || ELF_ST_VISIBILITY (h->other)))))
3795 return false;
3796 ret_val = false;
3797 continue;
3801 hit_addr = contents + rel->r_offset;
3802 value += rel->r_addend;
3803 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3805 switch (r_type)
3807 case R_IA64_NONE:
3808 case R_IA64_LDXMOV:
3809 continue;
3811 case R_IA64_IMM14:
3812 case R_IA64_IMM22:
3813 case R_IA64_IMM64:
3814 case R_IA64_DIR32MSB:
3815 case R_IA64_DIR32LSB:
3816 case R_IA64_DIR64MSB:
3817 case R_IA64_DIR64LSB:
3818 /* Install a dynamic relocation for this reloc. */
3819 if ((dynamic_symbol_p || info->shared
3820 || (elfNN_ia64_aix_vec (info->hash->creator)
3821 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3822 && (!h || strcmp (h->root.root.string,
3823 "__GLOB_DATA_PTR") != 0)))
3824 && r_symndx != 0
3825 && (input_section->flags & SEC_ALLOC) != 0)
3827 unsigned int dyn_r_type;
3828 long dynindx;
3829 bfd_vma addend;
3831 BFD_ASSERT (srel != NULL);
3833 /* If we don't need dynamic symbol lookup, find a
3834 matching RELATIVE relocation. */
3835 dyn_r_type = r_type;
3836 if (dynamic_symbol_p)
3838 dynindx = h->dynindx;
3839 addend = rel->r_addend;
3840 value = 0;
3842 else
3844 switch (r_type)
3846 case R_IA64_DIR32MSB:
3847 dyn_r_type = R_IA64_REL32MSB;
3848 break;
3849 case R_IA64_DIR32LSB:
3850 dyn_r_type = R_IA64_REL32LSB;
3851 break;
3852 case R_IA64_DIR64MSB:
3853 dyn_r_type = R_IA64_REL64MSB;
3854 break;
3855 case R_IA64_DIR64LSB:
3856 dyn_r_type = R_IA64_REL64LSB;
3857 break;
3859 default:
3860 /* We can't represent this without a dynamic symbol.
3861 Adjust the relocation to be against an output
3862 section symbol, which are always present in the
3863 dynamic symbol table. */
3864 /* ??? People shouldn't be doing non-pic code in
3865 shared libraries. Hork. */
3866 (*_bfd_error_handler)
3867 (_("%s: linking non-pic code in a shared library"),
3868 bfd_archive_filename (input_bfd));
3869 ret_val = false;
3870 continue;
3872 dynindx = 0;
3873 addend = value;
3876 if (elfNN_ia64_aix_vec (info->hash->creator))
3877 rel->r_addend = value;
3878 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3879 srel, rel->r_offset, dyn_r_type,
3880 dynindx, addend);
3882 /* FALLTHRU */
3884 case R_IA64_LTV32MSB:
3885 case R_IA64_LTV32LSB:
3886 case R_IA64_LTV64MSB:
3887 case R_IA64_LTV64LSB:
3888 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3889 break;
3891 case R_IA64_GPREL22:
3892 case R_IA64_GPREL64I:
3893 case R_IA64_GPREL32MSB:
3894 case R_IA64_GPREL32LSB:
3895 case R_IA64_GPREL64MSB:
3896 case R_IA64_GPREL64LSB:
3897 if (dynamic_symbol_p)
3899 (*_bfd_error_handler)
3900 (_("%s: @gprel relocation against dynamic symbol %s"),
3901 bfd_archive_filename (input_bfd), h->root.root.string);
3902 ret_val = false;
3903 continue;
3905 value -= gp_val;
3906 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3907 break;
3909 case R_IA64_LTOFF22:
3910 case R_IA64_LTOFF22X:
3911 case R_IA64_LTOFF64I:
3912 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3913 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
3914 rel->r_addend, value, R_IA64_DIR64LSB);
3915 value -= gp_val;
3916 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3917 break;
3919 case R_IA64_PLTOFF22:
3920 case R_IA64_PLTOFF64I:
3921 case R_IA64_PLTOFF64MSB:
3922 case R_IA64_PLTOFF64LSB:
3923 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3924 value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
3925 value -= gp_val;
3926 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3927 break;
3929 case R_IA64_FPTR64I:
3930 case R_IA64_FPTR32MSB:
3931 case R_IA64_FPTR32LSB:
3932 case R_IA64_FPTR64MSB:
3933 case R_IA64_FPTR64LSB:
3934 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3935 if (dyn_i->want_fptr)
3937 if (!undef_weak_ref)
3938 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3940 else
3942 long dynindx;
3944 /* Otherwise, we expect the dynamic linker to create
3945 the entry. */
3947 if (h)
3949 if (h->dynindx != -1)
3950 dynindx = h->dynindx;
3951 else
3952 dynindx = (_bfd_elf_link_lookup_local_dynindx
3953 (info, h->root.u.def.section->owner,
3954 global_sym_index (h)));
3956 else
3958 dynindx = (_bfd_elf_link_lookup_local_dynindx
3959 (info, input_bfd, (long) r_symndx));
3962 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3963 srel, rel->r_offset, r_type,
3964 dynindx, rel->r_addend);
3965 value = 0;
3968 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3969 break;
3971 case R_IA64_LTOFF_FPTR22:
3972 case R_IA64_LTOFF_FPTR64I:
3973 case R_IA64_LTOFF_FPTR32MSB:
3974 case R_IA64_LTOFF_FPTR32LSB:
3975 case R_IA64_LTOFF_FPTR64MSB:
3976 case R_IA64_LTOFF_FPTR64LSB:
3978 long dynindx;
3980 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3981 if (dyn_i->want_fptr)
3983 BFD_ASSERT (h == NULL || h->dynindx == -1)
3984 if (!undef_weak_ref)
3985 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3986 dynindx = -1;
3988 else
3990 /* Otherwise, we expect the dynamic linker to create
3991 the entry. */
3992 if (h)
3994 if (h->dynindx != -1)
3995 dynindx = h->dynindx;
3996 else
3997 dynindx = (_bfd_elf_link_lookup_local_dynindx
3998 (info, h->root.u.def.section->owner,
3999 global_sym_index (h)));
4001 else
4002 dynindx = (_bfd_elf_link_lookup_local_dynindx
4003 (info, input_bfd, (long) r_symndx));
4004 value = 0;
4007 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4008 rel->r_addend, value, R_IA64_FPTR64LSB);
4009 value -= gp_val;
4010 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4012 break;
4014 case R_IA64_PCREL32MSB:
4015 case R_IA64_PCREL32LSB:
4016 case R_IA64_PCREL64MSB:
4017 case R_IA64_PCREL64LSB:
4018 /* Install a dynamic relocation for this reloc. */
4019 if ((dynamic_symbol_p
4020 || elfNN_ia64_aix_vec (info->hash->creator))
4021 && r_symndx != 0)
4023 BFD_ASSERT (srel != NULL);
4025 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4026 srel, rel->r_offset, r_type,
4027 h->dynindx, rel->r_addend);
4029 goto finish_pcrel;
4031 case R_IA64_PCREL21BI:
4032 case R_IA64_PCREL21F:
4033 case R_IA64_PCREL21M:
4034 /* ??? These two are only used for speculation fixup code.
4035 They should never be dynamic. */
4036 if (dynamic_symbol_p)
4038 (*_bfd_error_handler)
4039 (_("%s: dynamic relocation against speculation fixup"),
4040 bfd_archive_filename (input_bfd));
4041 ret_val = false;
4042 continue;
4044 if (undef_weak_ref)
4046 (*_bfd_error_handler)
4047 (_("%s: speculation fixup against undefined weak symbol"),
4048 bfd_archive_filename (input_bfd));
4049 ret_val = false;
4050 continue;
4052 goto finish_pcrel;
4054 case R_IA64_PCREL21B:
4055 case R_IA64_PCREL60B:
4056 /* We should have created a PLT entry for any dynamic symbol. */
4057 dyn_i = NULL;
4058 if (h)
4059 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
4061 if (dyn_i && dyn_i->want_plt2)
4063 /* Should have caught this earlier. */
4064 BFD_ASSERT (rel->r_addend == 0);
4066 value = (ia64_info->plt_sec->output_section->vma
4067 + ia64_info->plt_sec->output_offset
4068 + dyn_i->plt2_offset);
4070 else
4072 /* Since there's no PLT entry, Validate that this is
4073 locally defined. */
4074 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4076 /* If the symbol is undef_weak, we shouldn't be trying
4077 to call it. There's every chance that we'd wind up
4078 with an out-of-range fixup here. Don't bother setting
4079 any value at all. */
4080 if (undef_weak_ref)
4081 continue;
4083 goto finish_pcrel;
4085 case R_IA64_PCREL22:
4086 case R_IA64_PCREL64I:
4087 finish_pcrel:
4088 /* Make pc-relative. */
4089 value -= (input_section->output_section->vma
4090 + input_section->output_offset
4091 + rel->r_offset) & ~ (bfd_vma) 0x3;
4092 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4093 break;
4095 case R_IA64_SEGREL32MSB:
4096 case R_IA64_SEGREL32LSB:
4097 case R_IA64_SEGREL64MSB:
4098 case R_IA64_SEGREL64LSB:
4099 if (r_symndx == 0)
4101 /* If the input section was discarded from the output, then
4102 do nothing. */
4103 r = bfd_reloc_ok;
4105 else
4107 struct elf_segment_map *m;
4108 Elf_Internal_Phdr *p;
4110 /* Find the segment that contains the output_section. */
4111 for (m = elf_tdata (output_bfd)->segment_map,
4112 p = elf_tdata (output_bfd)->phdr;
4113 m != NULL;
4114 m = m->next, p++)
4116 int i;
4117 for (i = m->count - 1; i >= 0; i--)
4118 if (m->sections[i] == sym_sec->output_section)
4119 break;
4120 if (i >= 0)
4121 break;
4124 if (m == NULL)
4126 r = bfd_reloc_notsupported;
4128 else
4130 /* The VMA of the segment is the vaddr of the associated
4131 program header. */
4132 if (value > p->p_vaddr)
4133 value -= p->p_vaddr;
4134 else
4135 value = 0;
4136 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4137 r_type);
4139 break;
4142 case R_IA64_SECREL32MSB:
4143 case R_IA64_SECREL32LSB:
4144 case R_IA64_SECREL64MSB:
4145 case R_IA64_SECREL64LSB:
4146 /* Make output-section relative. */
4147 if (value > input_section->output_section->vma)
4148 value -= input_section->output_section->vma;
4149 else
4150 value = 0;
4151 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4152 break;
4154 case R_IA64_IPLTMSB:
4155 case R_IA64_IPLTLSB:
4156 /* Install a dynamic relocation for this reloc. */
4157 if ((dynamic_symbol_p || info->shared)
4158 && (input_section->flags & SEC_ALLOC) != 0)
4160 BFD_ASSERT (srel != NULL);
4162 /* If we don't need dynamic symbol lookup, install two
4163 RELATIVE relocations. */
4164 if (! dynamic_symbol_p)
4166 unsigned int dyn_r_type;
4168 if (r_type == R_IA64_IPLTMSB)
4169 dyn_r_type = R_IA64_REL64MSB;
4170 else
4171 dyn_r_type = R_IA64_REL64LSB;
4173 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4174 input_section,
4175 srel, rel->r_offset,
4176 dyn_r_type, 0, value);
4177 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4178 input_section,
4179 srel, rel->r_offset + 8,
4180 dyn_r_type, 0, gp_val);
4182 else
4183 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4184 srel, rel->r_offset, r_type,
4185 h->dynindx, rel->r_addend);
4188 if (r_type == R_IA64_IPLTMSB)
4189 r_type = R_IA64_DIR64MSB;
4190 else
4191 r_type = R_IA64_DIR64LSB;
4192 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4193 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
4194 r_type);
4195 break;
4197 case R_IA64_TPREL14:
4198 case R_IA64_TPREL22:
4199 case R_IA64_TPREL64I:
4200 value -= elfNN_ia64_tprel_base (info);
4201 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4202 break;
4204 case R_IA64_DTPREL14:
4205 case R_IA64_DTPREL22:
4206 case R_IA64_DTPREL64I:
4207 value -= elfNN_ia64_dtprel_base (info);
4208 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4209 break;
4211 case R_IA64_LTOFF_TPREL22:
4212 case R_IA64_LTOFF_DTPMOD22:
4213 case R_IA64_LTOFF_DTPREL22:
4215 int got_r_type;
4217 switch (r_type)
4219 default:
4220 case R_IA64_LTOFF_TPREL22:
4221 if (!dynamic_symbol_p && !info->shared)
4222 value -= elfNN_ia64_tprel_base (info);
4223 got_r_type = R_IA64_TPREL64LSB;
4224 break;
4225 case R_IA64_LTOFF_DTPMOD22:
4226 if (!dynamic_symbol_p && !info->shared)
4227 value = 1;
4228 got_r_type = R_IA64_DTPMOD64LSB;
4229 break;
4230 case R_IA64_LTOFF_DTPREL22:
4231 if (!dynamic_symbol_p)
4232 value -= elfNN_ia64_dtprel_base (info);
4233 got_r_type = R_IA64_DTPREL64LSB;
4234 break;
4236 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
4237 value = set_got_entry (input_bfd, info, dyn_i,
4238 (h ? h->dynindx : -1), rel->r_addend,
4239 value, got_r_type);
4240 value -= gp_val;
4241 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4242 r_type);
4244 break;
4246 default:
4247 r = bfd_reloc_notsupported;
4248 break;
4251 switch (r)
4253 case bfd_reloc_ok:
4254 break;
4256 case bfd_reloc_undefined:
4257 /* This can happen for global table relative relocs if
4258 __gp is undefined. This is a panic situation so we
4259 don't try to continue. */
4260 (*info->callbacks->undefined_symbol)
4261 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4262 return false;
4264 case bfd_reloc_notsupported:
4266 const char *name;
4268 if (h)
4269 name = h->root.root.string;
4270 else
4272 name = bfd_elf_string_from_elf_section (input_bfd,
4273 symtab_hdr->sh_link,
4274 sym->st_name);
4275 if (name == NULL)
4276 return false;
4277 if (*name == '\0')
4278 name = bfd_section_name (input_bfd, input_section);
4280 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4281 name, input_bfd,
4282 input_section, rel->r_offset))
4283 return false;
4284 ret_val = false;
4286 break;
4288 case bfd_reloc_dangerous:
4289 case bfd_reloc_outofrange:
4290 case bfd_reloc_overflow:
4291 default:
4293 const char *name;
4295 if (h)
4296 name = h->root.root.string;
4297 else
4299 name = bfd_elf_string_from_elf_section (input_bfd,
4300 symtab_hdr->sh_link,
4301 sym->st_name);
4302 if (name == NULL)
4303 return false;
4304 if (*name == '\0')
4305 name = bfd_section_name (input_bfd, input_section);
4307 if (!(*info->callbacks->reloc_overflow) (info, name,
4308 howto->name,
4309 (bfd_vma) 0,
4310 input_bfd,
4311 input_section,
4312 rel->r_offset))
4313 return false;
4314 ret_val = false;
4316 break;
4320 return ret_val;
4323 static boolean
4324 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4325 bfd *output_bfd;
4326 struct bfd_link_info *info;
4327 struct elf_link_hash_entry *h;
4328 Elf_Internal_Sym *sym;
4330 struct elfNN_ia64_link_hash_table *ia64_info;
4331 struct elfNN_ia64_dyn_sym_info *dyn_i;
4333 ia64_info = elfNN_ia64_hash_table (info);
4334 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
4336 /* Fill in the PLT data, if required. */
4337 if (dyn_i && dyn_i->want_plt)
4339 Elf_Internal_Rela outrel;
4340 bfd_byte *loc;
4341 asection *plt_sec;
4342 bfd_vma plt_addr, pltoff_addr, gp_val, index;
4343 ElfNN_External_Rela *rel;
4345 gp_val = _bfd_get_gp_value (output_bfd);
4347 /* Initialize the minimal PLT entry. */
4349 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4350 plt_sec = ia64_info->plt_sec;
4351 loc = plt_sec->contents + dyn_i->plt_offset;
4353 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4354 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4355 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4356 R_IA64_PCREL21B);
4358 plt_addr = (plt_sec->output_section->vma
4359 + plt_sec->output_offset
4360 + dyn_i->plt_offset);
4361 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
4363 /* Initialize the FULL PLT entry, if needed. */
4364 if (dyn_i->want_plt2)
4366 loc = plt_sec->contents + dyn_i->plt2_offset;
4368 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4369 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4370 R_IA64_IMM22);
4372 /* Mark the symbol as undefined, rather than as defined in the
4373 plt section. Leave the value alone. */
4374 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4375 first place. But perhaps elflink.h did some for us. */
4376 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4377 sym->st_shndx = SHN_UNDEF;
4380 /* Create the dynamic relocation. */
4381 outrel.r_offset = pltoff_addr;
4382 if (bfd_little_endian (output_bfd))
4383 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4384 else
4385 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4386 outrel.r_addend = 0;
4388 /* This is fun. In the .IA_64.pltoff section, we've got entries
4389 that correspond both to real PLT entries, and those that
4390 happened to resolve to local symbols but need to be created
4391 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4392 relocations for the real PLT should come at the end of the
4393 section, so that they can be indexed by plt entry at runtime.
4395 We emitted all of the relocations for the non-PLT @pltoff
4396 entries during relocate_section. So we can consider the
4397 existing sec->reloc_count to be the base of the array of
4398 PLT relocations. */
4400 rel = (ElfNN_External_Rela *)ia64_info->rel_pltoff_sec->contents;
4401 rel += ia64_info->rel_pltoff_sec->reloc_count;
4403 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, rel + index);
4406 /* Mark some specially defined symbols as absolute. */
4407 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4408 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4409 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4410 sym->st_shndx = SHN_ABS;
4412 return true;
4415 static boolean
4416 elfNN_ia64_finish_dynamic_sections (abfd, info)
4417 bfd *abfd;
4418 struct bfd_link_info *info;
4420 struct elfNN_ia64_link_hash_table *ia64_info;
4421 bfd *dynobj;
4423 ia64_info = elfNN_ia64_hash_table (info);
4424 dynobj = ia64_info->root.dynobj;
4426 if (elf_hash_table (info)->dynamic_sections_created)
4428 ElfNN_External_Dyn *dyncon, *dynconend;
4429 asection *sdyn, *sgotplt;
4430 bfd_vma gp_val;
4432 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4433 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4434 BFD_ASSERT (sdyn != NULL);
4435 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4436 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4438 gp_val = _bfd_get_gp_value (abfd);
4440 for (; dyncon < dynconend; dyncon++)
4442 Elf_Internal_Dyn dyn;
4444 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4446 switch (dyn.d_tag)
4448 case DT_PLTGOT:
4449 dyn.d_un.d_ptr = gp_val;
4450 break;
4452 case DT_PLTRELSZ:
4453 dyn.d_un.d_val = (ia64_info->minplt_entries
4454 * sizeof (ElfNN_External_Rela));
4455 break;
4457 case DT_JMPREL:
4458 /* See the comment above in finish_dynamic_symbol. */
4459 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4460 + ia64_info->rel_pltoff_sec->output_offset
4461 + (ia64_info->rel_pltoff_sec->reloc_count
4462 * sizeof (ElfNN_External_Rela)));
4463 break;
4465 case DT_IA_64_PLT_RESERVE:
4466 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4467 + sgotplt->output_offset);
4468 break;
4470 case DT_RELASZ:
4471 /* Do not have RELASZ include JMPREL. This makes things
4472 easier on ld.so. This is not what the rest of BFD set up. */
4473 dyn.d_un.d_val -= (ia64_info->minplt_entries
4474 * sizeof (ElfNN_External_Rela));
4475 break;
4478 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4481 /* Initialize the PLT0 entry */
4482 if (ia64_info->plt_sec)
4484 bfd_byte *loc = ia64_info->plt_sec->contents;
4485 bfd_vma pltres;
4487 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4489 pltres = (sgotplt->output_section->vma
4490 + sgotplt->output_offset
4491 - gp_val);
4493 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4497 return true;
4500 /* ELF file flag handling: */
4502 /* Function to keep IA-64 specific file flags. */
4503 static boolean
4504 elfNN_ia64_set_private_flags (abfd, flags)
4505 bfd *abfd;
4506 flagword flags;
4508 BFD_ASSERT (!elf_flags_init (abfd)
4509 || elf_elfheader (abfd)->e_flags == flags);
4511 elf_elfheader (abfd)->e_flags = flags;
4512 elf_flags_init (abfd) = true;
4513 return true;
4516 /* Merge backend specific data from an object file to the output
4517 object file when linking. */
4518 static boolean
4519 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4520 bfd *ibfd, *obfd;
4522 flagword out_flags;
4523 flagword in_flags;
4524 boolean ok = true;
4526 /* Don't even pretend to support mixed-format linking. */
4527 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4528 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4529 return false;
4531 in_flags = elf_elfheader (ibfd)->e_flags;
4532 out_flags = elf_elfheader (obfd)->e_flags;
4534 if (! elf_flags_init (obfd))
4536 elf_flags_init (obfd) = true;
4537 elf_elfheader (obfd)->e_flags = in_flags;
4539 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4540 && bfd_get_arch_info (obfd)->the_default)
4542 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4543 bfd_get_mach (ibfd));
4546 return true;
4549 /* Check flag compatibility. */
4550 if (in_flags == out_flags)
4551 return true;
4553 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4554 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4555 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4557 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4559 (*_bfd_error_handler)
4560 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4561 bfd_archive_filename (ibfd));
4563 bfd_set_error (bfd_error_bad_value);
4564 ok = false;
4566 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4568 (*_bfd_error_handler)
4569 (_("%s: linking big-endian files with little-endian files"),
4570 bfd_archive_filename (ibfd));
4572 bfd_set_error (bfd_error_bad_value);
4573 ok = false;
4575 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4577 (*_bfd_error_handler)
4578 (_("%s: linking 64-bit files with 32-bit files"),
4579 bfd_archive_filename (ibfd));
4581 bfd_set_error (bfd_error_bad_value);
4582 ok = false;
4584 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4586 (*_bfd_error_handler)
4587 (_("%s: linking constant-gp files with non-constant-gp files"),
4588 bfd_archive_filename (ibfd));
4590 bfd_set_error (bfd_error_bad_value);
4591 ok = false;
4593 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4594 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4596 (*_bfd_error_handler)
4597 (_("%s: linking auto-pic files with non-auto-pic files"),
4598 bfd_archive_filename (ibfd));
4600 bfd_set_error (bfd_error_bad_value);
4601 ok = false;
4604 return ok;
4607 static boolean
4608 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4609 bfd *abfd;
4610 PTR ptr;
4612 FILE *file = (FILE *) ptr;
4613 flagword flags = elf_elfheader (abfd)->e_flags;
4615 BFD_ASSERT (abfd != NULL && ptr != NULL);
4617 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4618 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4619 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4620 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4621 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4622 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4623 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4624 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4625 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4627 _bfd_elf_print_private_bfd_data (abfd, ptr);
4628 return true;
4631 static enum elf_reloc_type_class
4632 elfNN_ia64_reloc_type_class (rela)
4633 const Elf_Internal_Rela *rela;
4635 switch ((int) ELFNN_R_TYPE (rela->r_info))
4637 case R_IA64_REL32MSB:
4638 case R_IA64_REL32LSB:
4639 case R_IA64_REL64MSB:
4640 case R_IA64_REL64LSB:
4641 return reloc_class_relative;
4642 case R_IA64_IPLTMSB:
4643 case R_IA64_IPLTLSB:
4644 return reloc_class_plt;
4645 case R_IA64_COPY:
4646 return reloc_class_copy;
4647 default:
4648 return reloc_class_normal;
4652 static boolean
4653 elfNN_ia64_hpux_vec (const bfd_target *vec)
4655 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4656 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4659 static void
4660 elfNN_hpux_post_process_headers (abfd, info)
4661 bfd *abfd;
4662 struct bfd_link_info *info ATTRIBUTE_UNUSED;
4664 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4666 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4667 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4670 boolean
4671 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
4672 bfd *abfd ATTRIBUTE_UNUSED;
4673 asection *sec;
4674 int *retval;
4676 if (bfd_is_com_section (sec))
4678 *retval = SHN_IA_64_ANSI_COMMON;
4679 return true;
4681 return false;
4684 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4685 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4686 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4687 #define TARGET_BIG_NAME "elfNN-ia64-big"
4688 #define ELF_ARCH bfd_arch_ia64
4689 #define ELF_MACHINE_CODE EM_IA_64
4690 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4691 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4692 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4694 #define elf_backend_section_from_shdr \
4695 elfNN_ia64_section_from_shdr
4696 #define elf_backend_section_flags \
4697 elfNN_ia64_section_flags
4698 #define elf_backend_fake_sections \
4699 elfNN_ia64_fake_sections
4700 #define elf_backend_final_write_processing \
4701 elfNN_ia64_final_write_processing
4702 #define elf_backend_add_symbol_hook \
4703 elfNN_ia64_add_symbol_hook
4704 #define elf_backend_additional_program_headers \
4705 elfNN_ia64_additional_program_headers
4706 #define elf_backend_modify_segment_map \
4707 elfNN_ia64_modify_segment_map
4708 #define elf_info_to_howto \
4709 elfNN_ia64_info_to_howto
4711 #define bfd_elfNN_bfd_reloc_type_lookup \
4712 elfNN_ia64_reloc_type_lookup
4713 #define bfd_elfNN_bfd_is_local_label_name \
4714 elfNN_ia64_is_local_label_name
4715 #define bfd_elfNN_bfd_relax_section \
4716 elfNN_ia64_relax_section
4718 /* Stuff for the BFD linker: */
4719 #define bfd_elfNN_bfd_link_hash_table_create \
4720 elfNN_ia64_hash_table_create
4721 #define elf_backend_create_dynamic_sections \
4722 elfNN_ia64_create_dynamic_sections
4723 #define elf_backend_check_relocs \
4724 elfNN_ia64_check_relocs
4725 #define elf_backend_adjust_dynamic_symbol \
4726 elfNN_ia64_adjust_dynamic_symbol
4727 #define elf_backend_size_dynamic_sections \
4728 elfNN_ia64_size_dynamic_sections
4729 #define elf_backend_relocate_section \
4730 elfNN_ia64_relocate_section
4731 #define elf_backend_finish_dynamic_symbol \
4732 elfNN_ia64_finish_dynamic_symbol
4733 #define elf_backend_finish_dynamic_sections \
4734 elfNN_ia64_finish_dynamic_sections
4735 #define bfd_elfNN_bfd_final_link \
4736 elfNN_ia64_final_link
4738 #define bfd_elfNN_bfd_merge_private_bfd_data \
4739 elfNN_ia64_merge_private_bfd_data
4740 #define bfd_elfNN_bfd_set_private_flags \
4741 elfNN_ia64_set_private_flags
4742 #define bfd_elfNN_bfd_print_private_bfd_data \
4743 elfNN_ia64_print_private_bfd_data
4745 #define elf_backend_plt_readonly 1
4746 #define elf_backend_want_plt_sym 0
4747 #define elf_backend_plt_alignment 5
4748 #define elf_backend_got_header_size 0
4749 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4750 #define elf_backend_want_got_plt 1
4751 #define elf_backend_may_use_rel_p 1
4752 #define elf_backend_may_use_rela_p 1
4753 #define elf_backend_default_use_rela_p 1
4754 #define elf_backend_want_dynbss 0
4755 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4756 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4757 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4758 #define elf_backend_rela_normal 1
4760 #include "elfNN-target.h"
4762 /* AIX-specific vectors. */
4764 #undef TARGET_LITTLE_SYM
4765 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4766 #undef TARGET_LITTLE_NAME
4767 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4768 #undef TARGET_BIG_SYM
4769 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4770 #undef TARGET_BIG_NAME
4771 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4773 #undef elf_backend_add_symbol_hook
4774 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4776 #undef bfd_elfNN_bfd_link_add_symbols
4777 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4779 #define elfNN_bed elfNN_ia64_aix_bed
4781 #include "elfNN-target.h"
4783 /* HPUX-specific vectors. */
4785 #undef TARGET_LITTLE_SYM
4786 #undef TARGET_LITTLE_NAME
4787 #undef TARGET_BIG_SYM
4788 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4789 #undef TARGET_BIG_NAME
4790 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4792 /* We need to undo the AIX specific functions. */
4794 #undef elf_backend_add_symbol_hook
4795 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
4797 #undef bfd_elfNN_bfd_link_add_symbols
4798 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
4800 /* These are HP-UX specific functions. */
4802 #undef elf_backend_post_process_headers
4803 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4805 #undef elf_backend_section_from_bfd_section
4806 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4808 #undef elf_backend_want_p_paddr_set_to_zero
4809 #define elf_backend_want_p_paddr_set_to_zero 1
4811 #undef ELF_MAXPAGESIZE
4812 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4814 #undef elfNN_bed
4815 #define elfNN_bed elfNN_ia64_hpux_bed
4817 #include "elfNN-target.h"
4819 #undef elf_backend_want_p_paddr_set_to_zero