* elf32-m68hc11.c (elf_m68hc11_howto_table): Add the new relocs;
[deliverable/binutils-gdb.git] / bfd / elfxx-ia64.c
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>
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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. */
20
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"
27
28 /* THE RULES for all the stuff the linker creates --
29
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.
34
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.
41
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.
45
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.
52
53 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
54 does not reqire dynamic relocations. */
55
56 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
57
58 typedef struct bfd_hash_entry *(*new_hash_entry_func)
59 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
60
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. */
64
65 struct elfNN_ia64_dyn_sym_info
66 {
67 /* The addend for which this entry is relevant. */
68 bfd_vma addend;
69
70 /* Next addend in the list. */
71 struct elfNN_ia64_dyn_sym_info *next;
72
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;
81
82 /* The symbol table entry, if any, that this was derrived from. */
83 struct elf_link_hash_entry *h;
84
85 /* Used to count non-got, non-plt relocations for delayed sizing
86 of relocation sections. */
87 struct elfNN_ia64_dyn_reloc_entry
88 {
89 struct elfNN_ia64_dyn_reloc_entry *next;
90 asection *srel;
91 int type;
92 int count;
93 } *reloc_entries;
94
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;
102
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;
113 };
114
115 struct elfNN_ia64_local_hash_entry
116 {
117 struct bfd_hash_entry root;
118 struct elfNN_ia64_dyn_sym_info *info;
119
120 /* True if this hash entry's addends was translated for
121 SHF_MERGE optimization. */
122 unsigned sec_merge_done : 1;
123 };
124
125 struct elfNN_ia64_local_hash_table
126 {
127 struct bfd_hash_table root;
128 /* No additional fields for now. */
129 };
130
131 struct elfNN_ia64_link_hash_entry
132 {
133 struct elf_link_hash_entry root;
134 struct elfNN_ia64_dyn_sym_info *info;
135 };
136
137 struct elfNN_ia64_link_hash_table
138 {
139 /* The main hash table. */
140 struct elf_link_hash_table root;
141
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 */
148
149 bfd_size_type minplt_entries; /* number of minplt entries */
150 unsigned reltext : 1; /* are there relocs against readonly sections? */
151
152 struct elfNN_ia64_local_hash_table loc_hash_table;
153 };
154
155 #define elfNN_ia64_hash_table(p) \
156 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
157
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));
325 \f
326 /* ia64-specific relocation. */
327
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;
340 {
341 if (output_bfd)
342 {
343 reloc->address += input_section->output_offset;
344 return bfd_reloc_ok;
345 }
346 *error_message = "Unsupported call to elfNN_ia64_reloc";
347 return bfd_reloc_notsupported;
348 }
349
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)
353
354 /* This table has to be sorted according to increasing number of the
355 TYPE field. */
356 static reloc_howto_type ia64_howto_table[] =
357 {
358 IA64_HOWTO (R_IA64_NONE, "NONE", 0, false, true),
359
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),
367
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),
374
375 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, false, true),
376 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, false, true),
377
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),
382
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),
388
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),
397
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),
404
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),
409
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),
414
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),
419
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),
424
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),
428
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),
434
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),
441
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),
445
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),
454 };
455
456 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
457
458 /* Given a BFD reloc type, return the matching HOWTO structure. */
459
460 static reloc_howto_type *
461 lookup_howto (rtype)
462 unsigned int rtype;
463 {
464 static int inited = 0;
465 int i;
466
467 if (!inited)
468 {
469 inited = 1;
470
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;
474 }
475
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;
481 }
482
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;
487 {
488 unsigned int rtype;
489
490 switch (bfd_code)
491 {
492 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
493
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;
497
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;
502
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;
509
510 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
511 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
512
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;
522
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;
534
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;
541
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;
546
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;
551
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;
556
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;
561
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;
567
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;
574
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;
578
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;
587
588 default: return 0;
589 }
590 return lookup_howto (rtype);
591 }
592
593 /* Given a ELF reloc, return the matching HOWTO structure. */
594
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;
600 {
601 bfd_reloc->howto
602 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
603 }
604 \f
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
609
610 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
611 {
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;; */
621 };
622
623 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
624 {
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>;; */
628 };
629
630 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
631 {
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;; */
638 };
639
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)
644
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
648
649 static const bfd_byte oor_brl[16] =
650 {
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
654 };
655
656 static const bfd_byte oor_ip[48] =
657 {
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;; */
667 };
668 \f
669 /* These functions do relaxation for IA-64 ELF.
670
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. */
673
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;
680 {
681 struct one_fixup
682 {
683 struct one_fixup *next;
684 asection *tsec;
685 bfd_vma toff;
686 bfd_vma trampoff;
687 };
688
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;
698
699 /* Assume we're not going to change any sizes, and we'll only need
700 one pass. */
701 *again = false;
702
703 /* Nothing to do if there are no relocations. */
704 if ((sec->flags & SEC_RELOC) == 0
705 || sec->reloc_count == 0)
706 return true;
707
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;
712
713 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
714
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;
721
722 ia64_info = elfNN_ia64_hash_table (link_info);
723 irelend = internal_relocs + sec->reloc_count;
724
725 for (irel = internal_relocs; irel < irelend; irel++)
726 if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
727 break;
728
729 /* No branch-type relocations. */
730 if (irel == irelend)
731 {
732 if (elf_section_data (sec)->relocs != internal_relocs)
733 free (internal_relocs);
734 return true;
735 }
736
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
741 {
742 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
743 if (contents == NULL)
744 goto error_return;
745
746 if (! bfd_get_section_contents (abfd, sec, contents,
747 (file_ptr) 0, sec->_raw_size))
748 goto error_return;
749 }
750
751 for (; irel < irelend; irel++)
752 {
753 bfd_vma symaddr, reladdr, trampoff, toff, roff;
754 asection *tsec;
755 struct one_fixup *f;
756 bfd_size_type amt;
757
758 if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
759 continue;
760
761 /* Get the value of the symbol referred to by the reloc. */
762 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
763 {
764 /* A local symbol. */
765 Elf_Internal_Sym *isym;
766
767 /* Read this BFD's local symbols. */
768 if (isymbuf == NULL)
769 {
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;
777 }
778
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);
790
791 toff = isym->st_value;
792 }
793 else
794 {
795 unsigned long indx;
796 struct elf_link_hash_entry *h;
797 struct elfNN_ia64_dyn_sym_info *dyn_i;
798
799 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
800 h = elf_sym_hashes (abfd)[indx];
801 BFD_ASSERT (h != NULL);
802
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;
806
807 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
808
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)
812 {
813 tsec = ia64_info->plt_sec;
814 toff = dyn_i->plt2_offset;
815 }
816 else
817 {
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;
822
823 tsec = h->root.u.def.section;
824 toff = h->root.u.def.value;
825 }
826 }
827
828 symaddr = (tsec->output_section->vma
829 + tsec->output_offset
830 + toff
831 + irel->r_addend);
832
833 roff = irel->r_offset;
834 reladdr = (sec->output_section->vma
835 + sec->output_offset
836 + roff) & (bfd_vma) -4;
837
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;
842
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;
848
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;
853
854 if (f == NULL)
855 {
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. */
859
860 size_t size;
861
862 if (tsec == ia64_info->plt_sec)
863 size = sizeof (plt_full_entry);
864 else
865 {
866 #ifdef USE_BRL
867 size = sizeof (oor_brl);
868 #else
869 size = sizeof (oor_ip);
870 #endif
871 }
872
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;
880
881 if (tsec == ia64_info->plt_sec)
882 {
883 memcpy (contents + trampoff, plt_full_entry, size);
884
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;
889 }
890 else
891 {
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
904 }
905
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;
913 }
914 else
915 {
916 /* Nop out the reloc, since we're finalizing things here. */
917 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
918 }
919
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;
926
927 changed_contents = true;
928 changed_relocs = true;
929 }
930
931 /* Clean up and go home. */
932 while (fixups)
933 {
934 struct one_fixup *f = fixups;
935 fixups = fixups->next;
936 free (f);
937 }
938
939 if (isymbuf != NULL
940 && symtab_hdr->contents != (unsigned char *) isymbuf)
941 {
942 if (! link_info->keep_memory)
943 free (isymbuf);
944 else
945 {
946 /* Cache the symbols for elf_link_input_bfd. */
947 symtab_hdr->contents = (unsigned char *) isymbuf;
948 }
949 }
950
951 if (contents != NULL
952 && elf_section_data (sec)->this_hdr.contents != contents)
953 {
954 if (!changed_contents && !link_info->keep_memory)
955 free (contents);
956 else
957 {
958 /* Cache the section contents for elf_link_input_bfd. */
959 elf_section_data (sec)->this_hdr.contents = contents;
960 }
961 }
962
963 if (elf_section_data (sec)->relocs != internal_relocs)
964 {
965 if (!changed_relocs)
966 free (internal_relocs);
967 else
968 elf_section_data (sec)->relocs = internal_relocs;
969 }
970
971 *again = changed_contents || changed_relocs;
972 return true;
973
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;
984 }
985 \f
986 /* Return true if NAME is an unwind table section name. */
987
988 static inline boolean
989 is_unwind_section_name (abfd, name)
990 bfd *abfd;
991 const char *name;
992 {
993 size_t len1, len2, len3;
994
995 if (elfNN_ia64_hpux_vec (abfd->xvec)
996 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
997 return false;
998
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);
1005 }
1006
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. */
1009
1010 static boolean
1011 elfNN_ia64_section_from_shdr (abfd, hdr, name)
1012 bfd *abfd;
1013 ElfNN_Internal_Shdr *hdr;
1014 const char *name;
1015 {
1016 asection *newsect;
1017
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)
1024 {
1025 case SHT_IA_64_UNWIND:
1026 case SHT_IA_64_HP_OPT_ANOT:
1027 break;
1028
1029 case SHT_IA_64_EXT:
1030 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1031 return false;
1032 break;
1033
1034 default:
1035 return false;
1036 }
1037
1038 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
1039 return false;
1040 newsect = hdr->bfd_section;
1041
1042 return true;
1043 }
1044
1045 /* Convert IA-64 specific section flags to bfd internal section flags. */
1046
1047 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1048 flag. */
1049
1050 static boolean
1051 elfNN_ia64_section_flags (flags, hdr)
1052 flagword *flags;
1053 ElfNN_Internal_Shdr *hdr;
1054 {
1055 if (hdr->sh_flags & SHF_IA_64_SHORT)
1056 *flags |= SEC_SMALL_DATA;
1057
1058 return true;
1059 }
1060
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. */
1063
1064 static boolean
1065 elfNN_ia64_fake_sections (abfd, hdr, sec)
1066 bfd *abfd ATTRIBUTE_UNUSED;
1067 ElfNN_Internal_Shdr *hdr;
1068 asection *sec;
1069 {
1070 register const char *name;
1071
1072 name = bfd_get_section_name (abfd, sec);
1073
1074 if (is_unwind_section_name (abfd, name))
1075 {
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;
1080 }
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;
1103
1104 if (sec->flags & SEC_SMALL_DATA)
1105 hdr->sh_flags |= SHF_IA_64_SHORT;
1106
1107 return true;
1108 }
1109
1110 /* The final processing done just before writing out an IA-64 ELF
1111 object file. */
1112
1113 static void
1114 elfNN_ia64_final_write_processing (abfd, linker)
1115 bfd *abfd;
1116 boolean linker ATTRIBUTE_UNUSED;
1117 {
1118 Elf_Internal_Shdr *hdr;
1119 const char *sname;
1120 asection *text_sect, *s;
1121 size_t len;
1122
1123 for (s = abfd->sections; s; s = s->next)
1124 {
1125 hdr = &elf_section_data (s)->this_hdr;
1126 switch (hdr->sh_type)
1127 {
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)
1134 {
1135 sname += len;
1136
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);
1143 }
1144 else if (sname
1145 && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
1146 strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
1147 {
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);
1151
1152 if (once_name != NULL)
1153 {
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);
1158 }
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)
1166 {
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;
1172 }
1173 }
1174 else
1175 /* last resort: fall back on .text */
1176 text_sect = bfd_get_section_by_name (abfd, ".text");
1177
1178 if (text_sect)
1179 {
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;
1186 }
1187 break;
1188 }
1189 }
1190
1191 if (! elf_flags_init (abfd))
1192 {
1193 unsigned long flags = 0;
1194
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;
1199
1200 elf_elfheader(abfd)->e_flags = flags;
1201 elf_flags_init (abfd) = true;
1202 }
1203 }
1204
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. */
1207
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;
1217 {
1218 if (sym->st_shndx == SHN_COMMON
1219 && !info->relocateable
1220 && sym->st_size <= elf_gp_size (abfd))
1221 {
1222 /* Common symbols less than or equal to -G nn bytes are
1223 automatically put into .sbss. */
1224
1225 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1226
1227 if (scomm == NULL)
1228 {
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;
1235 }
1236
1237 *secp = scomm;
1238 *valp = sym->st_size;
1239 }
1240
1241 return true;
1242 }
1243
1244 static boolean
1245 elfNN_ia64_aix_vec (const bfd_target *vec)
1246 {
1247 extern const bfd_target bfd_elfNN_ia64_aix_little_vec;
1248 extern const bfd_target bfd_elfNN_ia64_aix_big_vec;
1249
1250 return (/**/vec == & bfd_elfNN_ia64_aix_little_vec
1251 || vec == & bfd_elfNN_ia64_aix_big_vec);
1252 }
1253
1254 /* Hook called by the linker routine which adds symbols from an object
1255 file. We use it to handle OS-specific symbols. */
1256
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;
1266 {
1267 if (strcmp (*namep, "__GLOB_DATA_PTR") == 0)
1268 {
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;
1273
1274 h = elf_link_hash_lookup (elf_hash_table (info), *namep,
1275 false, false, false);
1276 if (h == NULL)
1277 {
1278 struct elf_backend_data *bed;
1279 struct elfNN_ia64_link_hash_table *ia64_info;
1280
1281 bed = get_elf_backend_data (abfd);
1282 ia64_info = elfNN_ia64_hash_table (info);
1283
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;
1290
1291 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1292 h->type = STT_OBJECT;
1293
1294 if (! _bfd_elf_link_record_dynamic_symbol (info, h))
1295 return false;
1296 }
1297
1298 return true;
1299 }
1300 else if (sym->st_shndx == SHN_LOOS)
1301 {
1302 unsigned int i;
1303
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++)
1309 {
1310 asection * sec = bfd_section_from_elf_index (abfd, i);
1311
1312 if (sec && strcmp (sec->name, ".text") == 0)
1313 {
1314 *secp = sec;
1315 break;
1316 }
1317 }
1318
1319 if (*secp == NULL)
1320 *secp = bfd_abs_section_ptr;
1321
1322 *valp = sym->st_size;
1323
1324 return true;
1325 }
1326 else
1327 {
1328 return elfNN_ia64_add_symbol_hook (abfd, info, sym,
1329 namep, flagsp, secp, valp);
1330 }
1331 }
1332
1333 boolean
1334 elfNN_ia64_aix_link_add_symbols (abfd, info)
1335 bfd *abfd;
1336 struct bfd_link_info *info;
1337 {
1338 /* Make sure dynamic sections are always created. */
1339 if (! elf_hash_table (info)->dynamic_sections_created
1340 && abfd->xvec == info->hash->creator)
1341 {
1342 if (! bfd_elfNN_link_create_dynamic_sections (abfd, info))
1343 return false;
1344 }
1345
1346 /* Now do the standard call. */
1347 return bfd_elfNN_bfd_link_add_symbols (abfd, info);
1348 }
1349
1350 /* Return the number of additional phdrs we will need. */
1351
1352 static int
1353 elfNN_ia64_additional_program_headers (abfd)
1354 bfd *abfd;
1355 {
1356 asection *s;
1357 int ret = 0;
1358
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;
1363
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;
1368
1369 return ret;
1370 }
1371
1372 static boolean
1373 elfNN_ia64_modify_segment_map (abfd)
1374 bfd *abfd;
1375 {
1376 struct elf_segment_map *m, **pm;
1377 Elf_Internal_Shdr *hdr;
1378 asection *s;
1379
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))
1384 {
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)
1389 {
1390 m = ((struct elf_segment_map *)
1391 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1392 if (m == NULL)
1393 return false;
1394
1395 m->p_type = PT_IA_64_ARCHEXT;
1396 m->count = 1;
1397 m->sections[0] = s;
1398
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;
1405
1406 m->next = *pm;
1407 *pm = m;
1408 }
1409 }
1410
1411 /* Install PT_IA_64_UNWIND segments, if needed. */
1412 for (s = abfd->sections; s; s = s->next)
1413 {
1414 hdr = &elf_section_data (s)->this_hdr;
1415 if (hdr->sh_type != SHT_IA_64_UNWIND)
1416 continue;
1417
1418 if (s && (s->flags & SEC_LOAD))
1419 {
1420 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1421 if (m->p_type == PT_IA_64_UNWIND)
1422 {
1423 int i;
1424
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;
1431
1432 if (i >= 0)
1433 break;
1434 }
1435
1436 if (m == NULL)
1437 {
1438 m = ((struct elf_segment_map *)
1439 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1440 if (m == NULL)
1441 return false;
1442
1443 m->p_type = PT_IA_64_UNWIND;
1444 m->count = 1;
1445 m->sections[0] = s;
1446 m->next = NULL;
1447
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;
1453 }
1454 }
1455 }
1456
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)
1462 {
1463 int i;
1464 for (i = m->count - 1; i >= 0; --i)
1465 {
1466 struct bfd_link_order *order = m->sections[i]->link_order_head;
1467 while (order)
1468 {
1469 if (order->type == bfd_indirect_link_order)
1470 {
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)
1474 {
1475 m->p_flags |= PF_IA_64_NORECOV;
1476 goto found;
1477 }
1478 }
1479 order = order->next;
1480 }
1481 }
1482 found:;
1483 }
1484
1485 return true;
1486 }
1487
1488 /* According to the Tahoe assembler spec, all labels starting with a
1489 '.' are local. */
1490
1491 static boolean
1492 elfNN_ia64_is_local_label_name (abfd, name)
1493 bfd *abfd ATTRIBUTE_UNUSED;
1494 const char *name;
1495 {
1496 return name[0] == '.';
1497 }
1498
1499 /* Should we do dynamic things to this symbol? */
1500
1501 static boolean
1502 elfNN_ia64_dynamic_symbol_p (h, info)
1503 struct elf_link_hash_entry *h;
1504 struct bfd_link_info *info;
1505 {
1506 if (h == NULL)
1507 return false;
1508
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;
1512
1513 if (h->dynindx == -1)
1514 return false;
1515 switch (ELF_ST_VISIBILITY (h->other))
1516 {
1517 case STV_INTERNAL:
1518 case STV_HIDDEN:
1519 return false;
1520 default:
1521 break;
1522 }
1523
1524 if (h->root.type == bfd_link_hash_undefweak
1525 || h->root.type == bfd_link_hash_defweak)
1526 return true;
1527
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;
1533
1534 return false;
1535 }
1536 \f
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;
1542 {
1543 memset (ht, 0, sizeof (*ht));
1544 return bfd_hash_table_init (&ht->root, new);
1545 }
1546
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;
1552 {
1553 struct elfNN_ia64_local_hash_entry *ret;
1554 ret = (struct elfNN_ia64_local_hash_entry *) entry;
1555
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));
1560
1561 if (!ret)
1562 return 0;
1563
1564 /* Initialize our local data. All zeros, and definitely easier
1565 than setting a handful of bit fields. */
1566 memset (ret, 0, sizeof (*ret));
1567
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));
1571
1572 return (struct bfd_hash_entry *) ret;
1573 }
1574
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;
1580 {
1581 struct elfNN_ia64_link_hash_entry *ret;
1582 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1583
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));
1588
1589 if (!ret)
1590 return 0;
1591
1592 /* Initialize our local data. All zeros, and definitely easier
1593 than setting a handful of bit fields. */
1594 memset (ret, 0, sizeof (*ret));
1595
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));
1600
1601 return (struct bfd_hash_entry *) ret;
1602 }
1603
1604 static void
1605 elfNN_ia64_hash_copy_indirect (xdir, xind)
1606 struct elf_link_hash_entry *xdir, *xind;
1607 {
1608 struct elfNN_ia64_link_hash_entry *dir, *ind;
1609
1610 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1611 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1612
1613 /* Copy down any references that we may have already seen to the
1614 symbol which just became indirect. */
1615
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));
1621
1622 if (ind->root.root.type != bfd_link_hash_indirect)
1623 return;
1624
1625 /* Copy over the got and plt data. This would have been done
1626 by check_relocs. */
1627
1628 if (dir->info == NULL)
1629 {
1630 struct elfNN_ia64_dyn_sym_info *dyn_i;
1631
1632 dir->info = dyn_i = ind->info;
1633 ind->info = NULL;
1634
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;
1638 }
1639 BFD_ASSERT (ind->info == NULL);
1640
1641 /* Copy over the dynindx. */
1642
1643 if (dir->root.dynindx == -1)
1644 {
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;
1649 }
1650 BFD_ASSERT (ind->root.dynindx == -1);
1651 }
1652
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;
1658 {
1659 struct elfNN_ia64_link_hash_entry *h;
1660 struct elfNN_ia64_dyn_sym_info *dyn_i;
1661
1662 h = (struct elfNN_ia64_link_hash_entry *)xh;
1663
1664 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1665
1666 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1667 dyn_i->want_plt2 = 0;
1668 }
1669
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). */
1673
1674 static struct bfd_link_hash_table*
1675 elfNN_ia64_hash_table_create (abfd)
1676 bfd *abfd;
1677 {
1678 struct elfNN_ia64_link_hash_table *ret;
1679
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))
1685 {
1686 bfd_release (abfd, ret);
1687 return 0;
1688 }
1689
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;
1694 }
1695
1696 /* Look up an entry in a Alpha ELF linker hash table. */
1697
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;
1703 {
1704 return ((struct elfNN_ia64_local_hash_entry *)
1705 bfd_hash_lookup (&table->root, string, create, copy));
1706 }
1707
1708 /* Traverse both local and global hash tables. */
1709
1710 struct elfNN_ia64_dyn_sym_traverse_data
1711 {
1712 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1713 PTR data;
1714 };
1715
1716 static boolean
1717 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1718 struct bfd_hash_entry *xentry;
1719 PTR xdata;
1720 {
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;
1726
1727 if (entry->root.root.type == bfd_link_hash_warning)
1728 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1729
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;
1734 }
1735
1736 static boolean
1737 elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1738 struct bfd_hash_entry *xentry;
1739 PTR xdata;
1740 {
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;
1746
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;
1751 }
1752
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;
1758 {
1759 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1760
1761 xdata.func = func;
1762 xdata.data = data;
1763
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);
1768 }
1769 \f
1770 static boolean
1771 elfNN_ia64_create_dynamic_sections (abfd, info)
1772 bfd *abfd;
1773 struct bfd_link_info *info;
1774 {
1775 struct elfNN_ia64_link_hash_table *ia64_info;
1776 asection *s;
1777
1778 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1779 return false;
1780
1781 ia64_info = elfNN_ia64_hash_table (info);
1782
1783 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1784 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1785
1786 {
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);
1789 }
1790
1791 if (!get_pltoff (abfd, info, ia64_info))
1792 return false;
1793
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;
1804
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;
1815
1816 return true;
1817 }
1818
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;
1826 {
1827 char *addr_name;
1828 size_t len;
1829 struct elfNN_ia64_local_hash_entry *ret;
1830
1831 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1832 name describes what was once anonymous memory. */
1833
1834 len = sizeof (void*)*2 + 1 + sizeof (bfd_vma)*4 + 1 + 1;
1835 len += 10; /* %p slop */
1836
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));
1842
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;
1848 }
1849
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. */
1852
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;
1860 {
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;
1864
1865 if (h)
1866 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1867 else
1868 {
1869 struct elfNN_ia64_local_hash_entry *loc_h;
1870
1871 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1872 BFD_ASSERT (loc_h);
1873
1874 pp = &loc_h->info;
1875 }
1876
1877 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1878 pp = &dyn_i->next;
1879
1880 if (dyn_i == NULL && create)
1881 {
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;
1886 }
1887
1888 return dyn_i;
1889 }
1890
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;
1896 {
1897 asection *got;
1898 bfd *dynobj;
1899
1900 got = ia64_info->got_sec;
1901 if (!got)
1902 {
1903 flagword flags;
1904
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;
1910
1911 got = bfd_get_section_by_name (dynobj, ".got");
1912 BFD_ASSERT (got);
1913 ia64_info->got_sec = got;
1914
1915 flags = bfd_get_section_flags (abfd, got);
1916 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1917 }
1918
1919 return got;
1920 }
1921
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. */
1926
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;
1932 {
1933 asection *fptr;
1934 bfd *dynobj;
1935
1936 fptr = ia64_info->fptr_sec;
1937 if (!fptr)
1938 {
1939 dynobj = ia64_info->root.dynobj;
1940 if (!dynobj)
1941 ia64_info->root.dynobj = dynobj = abfd;
1942
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))
1953 {
1954 BFD_ASSERT (0);
1955 return NULL;
1956 }
1957
1958 ia64_info->fptr_sec = fptr;
1959 }
1960
1961 return fptr;
1962 }
1963
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;
1969 {
1970 asection *pltoff;
1971 bfd *dynobj;
1972
1973 pltoff = ia64_info->pltoff_sec;
1974 if (!pltoff)
1975 {
1976 dynobj = ia64_info->root.dynobj;
1977 if (!dynobj)
1978 ia64_info->root.dynobj = dynobj = abfd;
1979
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))
1990 {
1991 BFD_ASSERT (0);
1992 return NULL;
1993 }
1994
1995 ia64_info->pltoff_sec = pltoff;
1996 }
1997
1998 return pltoff;
1999 }
2000
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;
2007 {
2008 const char *srel_name;
2009 asection *srel;
2010 bfd *dynobj;
2011
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;
2017
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));
2024
2025 dynobj = ia64_info->root.dynobj;
2026 if (!dynobj)
2027 ia64_info->root.dynobj = dynobj = abfd;
2028
2029 srel = bfd_get_section_by_name (dynobj, srel_name);
2030 if (srel == NULL && create)
2031 {
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;
2043 }
2044
2045 if (sec->flags & SEC_READONLY)
2046 ia64_info->reltext = 1;
2047
2048 return srel;
2049 }
2050
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;
2057 {
2058 struct elfNN_ia64_dyn_reloc_entry *rent;
2059
2060 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2061 if (rent->srel == srel && rent->type == type)
2062 break;
2063
2064 if (!rent)
2065 {
2066 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2067 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2068 if (!rent)
2069 return false;
2070
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;
2076 }
2077 rent->count++;
2078
2079 return true;
2080 }
2081
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;
2088 {
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;
2094
2095 if (info->relocateable)
2096 return true;
2097
2098 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2099 ia64_info = elfNN_ia64_hash_table (info);
2100
2101 got = fptr = srel = NULL;
2102
2103 relend = relocs + sec->reloc_count;
2104 for (rel = relocs; rel < relend; ++rel)
2105 {
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
2117 };
2118
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;
2125
2126 if (r_symndx >= symtab_hdr->sh_info)
2127 {
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;
2135
2136 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2137 }
2138
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;
2150
2151 need_entry = 0;
2152 switch (ELFNN_R_TYPE (rel->r_info))
2153 {
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;
2162
2163 case R_IA64_LTOFF_TPREL22:
2164 need_entry = NEED_TPREL;
2165 if (info->shared)
2166 info->flags |= DF_STATIC_TLS;
2167 break;
2168
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;
2175
2176 case R_IA64_LTOFF_DTPREL22:
2177 need_entry = NEED_DTPREL;
2178 break;
2179
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;
2186
2187 case R_IA64_LTOFF_DTPMOD22:
2188 need_entry = NEED_DTPMOD;
2189 break;
2190
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;
2199
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;
2211
2212 case R_IA64_LTOFF22:
2213 case R_IA64_LTOFF22X:
2214 case R_IA64_LTOFF64I:
2215 need_entry = NEED_GOT;
2216 break;
2217
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)
2224 {
2225 if (maybe_dynamic)
2226 need_entry |= NEED_MIN_PLT;
2227 }
2228 else
2229 {
2230 (*info->callbacks->warning)
2231 (info, _("@pltoff reloc against local symbol"), 0,
2232 abfd, 0, (bfd_vma) 0);
2233 }
2234 break;
2235
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;
2245
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;
2261
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;
2269
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;
2280 }
2281
2282 if (!need_entry)
2283 continue;
2284
2285 if ((need_entry & NEED_FPTR) != 0
2286 && rel->r_addend)
2287 {
2288 (*info->callbacks->warning)
2289 (info, _("non-zero addend in @fptr reloc"), 0,
2290 abfd, 0, (bfd_vma) 0);
2291 }
2292
2293 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
2294
2295 /* Record whether or not this is a local symbol. */
2296 dyn_i->h = h;
2297
2298 /* Create what's needed. */
2299 if (need_entry & (NEED_GOT | NEED_TPREL | NEED_DTPMOD | NEED_DTPREL))
2300 {
2301 if (!got)
2302 {
2303 got = get_got (abfd, info, ia64_info);
2304 if (!got)
2305 return false;
2306 }
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;
2315 }
2316 if (need_entry & NEED_FPTR)
2317 {
2318 if (!fptr)
2319 {
2320 fptr = get_fptr (abfd, info, ia64_info);
2321 if (!fptr)
2322 return false;
2323 }
2324
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)))
2331 {
2332 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2333 (info, abfd, (long) r_symndx)))
2334 return false;
2335 }
2336
2337 dyn_i->want_fptr = 1;
2338 }
2339 if (need_entry & NEED_LTOFF_FPTR)
2340 dyn_i->want_ltoff_fptr = 1;
2341 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2342 {
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;
2347 }
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))
2353 {
2354 if (!srel)
2355 {
2356 srel = get_reloc_section (abfd, ia64_info, sec, true);
2357 if (!srel)
2358 return false;
2359 }
2360 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2361 return false;
2362 }
2363 }
2364
2365 return true;
2366 }
2367
2368 struct elfNN_ia64_allocate_data
2369 {
2370 struct bfd_link_info *info;
2371 bfd_size_type ofs;
2372 };
2373
2374 /* For cleanliness, and potentially faster dynamic loading, allocate
2375 external GOT entries first. */
2376
2377 static boolean
2378 allocate_global_data_got (dyn_i, data)
2379 struct elfNN_ia64_dyn_sym_info *dyn_i;
2380 PTR data;
2381 {
2382 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2383
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))))
2390 {
2391 dyn_i->got_offset = x->ofs;
2392 x->ofs += 8;
2393 }
2394 if (dyn_i->want_tprel)
2395 {
2396 dyn_i->tprel_offset = x->ofs;
2397 x->ofs += 8;
2398 }
2399 if (dyn_i->want_dtpmod)
2400 {
2401 dyn_i->dtpmod_offset = x->ofs;
2402 x->ofs += 8;
2403 }
2404 if (dyn_i->want_dtprel)
2405 {
2406 dyn_i->dtprel_offset = x->ofs;
2407 x->ofs += 8;
2408 }
2409 return true;
2410 }
2411
2412 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2413
2414 static boolean
2415 allocate_global_fptr_got (dyn_i, data)
2416 struct elfNN_ia64_dyn_sym_info *dyn_i;
2417 PTR data;
2418 {
2419 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2420
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)))
2425 {
2426 dyn_i->got_offset = x->ofs;
2427 x->ofs += 8;
2428 }
2429 return true;
2430 }
2431
2432 /* Lastly, allocate all the GOT entries for local data. */
2433
2434 static boolean
2435 allocate_local_got (dyn_i, data)
2436 struct elfNN_ia64_dyn_sym_info *dyn_i;
2437 PTR data;
2438 {
2439 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2440
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)))
2444 {
2445 dyn_i->got_offset = x->ofs;
2446 x->ofs += 8;
2447 }
2448 return true;
2449 }
2450
2451 /* Search for the index of a global symbol in it's defining object file. */
2452
2453 static long
2454 global_sym_index (h)
2455 struct elf_link_hash_entry *h;
2456 {
2457 struct elf_link_hash_entry **p;
2458 bfd *obj;
2459
2460 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2461 || h->root.type == bfd_link_hash_defweak);
2462
2463 obj = h->root.u.def.section->owner;
2464 for (p = elf_sym_hashes (obj); *p != h; ++p)
2465 continue;
2466
2467 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2468 }
2469
2470 /* Allocate function descriptors. We can do these for every function
2471 in a main executable that is not exported. */
2472
2473 static boolean
2474 allocate_fptr (dyn_i, data)
2475 struct elfNN_ia64_dyn_sym_info *dyn_i;
2476 PTR data;
2477 {
2478 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2479
2480 if (dyn_i->want_fptr)
2481 {
2482 struct elf_link_hash_entry *h = dyn_i->h;
2483
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;
2488
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)))
2495 {
2496 if (h && h->dynindx == -1)
2497 {
2498 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2499 || (h->root.type == bfd_link_hash_defweak));
2500
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;
2505 }
2506
2507 dyn_i->want_fptr = 0;
2508 }
2509 else if (h == NULL || h->dynindx == -1)
2510 {
2511 dyn_i->fptr_offset = x->ofs;
2512 x->ofs += 16;
2513 }
2514 else
2515 dyn_i->want_fptr = 0;
2516 }
2517 return true;
2518 }
2519
2520 /* Allocate all the minimal PLT entries. */
2521
2522 static boolean
2523 allocate_plt_entries (dyn_i, data)
2524 struct elfNN_ia64_dyn_sym_info *dyn_i;
2525 PTR data;
2526 {
2527 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2528
2529 if (dyn_i->want_plt)
2530 {
2531 struct elf_link_hash_entry *h = dyn_i->h;
2532
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;
2537
2538 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2539 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2540 {
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;
2546
2547 dyn_i->want_pltoff = 1;
2548 }
2549 else
2550 {
2551 dyn_i->want_plt = 0;
2552 dyn_i->want_plt2 = 0;
2553 }
2554 }
2555 return true;
2556 }
2557
2558 /* Allocate all the full PLT entries. */
2559
2560 static boolean
2561 allocate_plt2_entries (dyn_i, data)
2562 struct elfNN_ia64_dyn_sym_info *dyn_i;
2563 PTR data;
2564 {
2565 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2566
2567 if (dyn_i->want_plt2)
2568 {
2569 struct elf_link_hash_entry *h = dyn_i->h;
2570 bfd_size_type ofs = x->ofs;
2571
2572 dyn_i->plt2_offset = ofs;
2573 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2574
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;
2579 }
2580 return true;
2581 }
2582
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. */
2587
2588 static boolean
2589 allocate_pltoff_entries (dyn_i, data)
2590 struct elfNN_ia64_dyn_sym_info *dyn_i;
2591 PTR data;
2592 {
2593 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2594
2595 if (dyn_i->want_pltoff)
2596 {
2597 dyn_i->pltoff_offset = x->ofs;
2598 x->ofs += 16;
2599 }
2600 return true;
2601 }
2602
2603 /* Allocate dynamic relocations for those symbols that turned out
2604 to be dynamic. */
2605
2606 static boolean
2607 allocate_dynrel_entries (dyn_i, data)
2608 struct elfNN_ia64_dyn_sym_info *dyn_i;
2609 PTR data;
2610 {
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;
2615
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;
2623
2624 /* Take care of the normal data relocations. */
2625
2626 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2627 {
2628 int count = rent->count;
2629
2630 switch (rent->type)
2631 {
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 ();
2661 }
2662 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2663 }
2664
2665 /* Take care of the GOT and PLT relocations. */
2666
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);
2676
2677 if (dyn_i->want_pltoff)
2678 {
2679 bfd_size_type t = 0;
2680
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);
2688
2689 ia64_info->rel_pltoff_sec->_raw_size += t;
2690 }
2691
2692 return true;
2693 }
2694
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;
2699 {
2700 /* ??? Undefined symbols with PLT entries should be re-defined
2701 to be the PLT entry. */
2702
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)
2707 {
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;
2713 }
2714
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.
2718
2719 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2720 of hackery. */
2721
2722 return true;
2723 }
2724
2725 static boolean
2726 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2727 bfd *output_bfd;
2728 struct bfd_link_info *info;
2729 {
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;
2735
2736 dynobj = elf_hash_table(info)->dynobj;
2737 ia64_info = elfNN_ia64_hash_table (info);
2738 BFD_ASSERT(dynobj != NULL);
2739 data.info = info;
2740
2741 /* Set the contents of the .interp section to the interpreter. */
2742 if (ia64_info->root.dynamic_sections_created
2743 && !info->shared)
2744 {
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;
2749 }
2750
2751 /* Allocate the GOT entries. */
2752
2753 if (ia64_info->got_sec)
2754 {
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;
2760 }
2761
2762 /* Allocate the FPTR entries. */
2763
2764 if (ia64_info->fptr_sec)
2765 {
2766 data.ofs = 0;
2767 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2768 ia64_info->fptr_sec->_raw_size = data.ofs;
2769 }
2770
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. */
2775
2776 data.ofs = 0;
2777 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2778
2779 ia64_info->minplt_entries = 0;
2780 if (data.ofs)
2781 {
2782 ia64_info->minplt_entries
2783 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2784 }
2785
2786 /* Align the pointer for the plt2 entries. */
2787 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2788
2789 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2790 if (data.ofs != 0)
2791 {
2792 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2793
2794 ia64_info->plt_sec->_raw_size = data.ofs;
2795
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;
2800 }
2801
2802 /* Allocate the PLTOFF entries. */
2803
2804 if (ia64_info->pltoff_sec)
2805 {
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;
2809 }
2810
2811 if (ia64_info->root.dynamic_sections_created)
2812 {
2813 /* Allocate space for the dynamic relocations that turned out to be
2814 required. */
2815
2816 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2817 }
2818
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)
2822 {
2823 boolean strip;
2824
2825 if (!(sec->flags & SEC_LINKER_CREATED))
2826 continue;
2827
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. */
2835
2836 strip = (sec->_raw_size == 0);
2837
2838 if (sec == ia64_info->got_sec)
2839 strip = false;
2840 else if (sec == ia64_info->rel_got_sec)
2841 {
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;
2848 }
2849 else if (sec == ia64_info->fptr_sec)
2850 {
2851 if (strip)
2852 ia64_info->fptr_sec = NULL;
2853 }
2854 else if (sec == ia64_info->plt_sec)
2855 {
2856 if (strip)
2857 ia64_info->plt_sec = NULL;
2858 }
2859 else if (sec == ia64_info->pltoff_sec)
2860 {
2861 if (strip)
2862 ia64_info->pltoff_sec = NULL;
2863 }
2864 else if (sec == ia64_info->rel_pltoff_sec)
2865 {
2866 if (strip)
2867 ia64_info->rel_pltoff_sec = NULL;
2868 else
2869 {
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;
2874 }
2875 }
2876 else
2877 {
2878 const char *name;
2879
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);
2883
2884 if (strcmp (name, ".got.plt") == 0)
2885 strip = false;
2886 else if (strncmp (name, ".rel", 4) == 0)
2887 {
2888 if (!strip)
2889 {
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;
2893 }
2894 }
2895 else
2896 continue;
2897 }
2898
2899 if (strip)
2900 _bfd_strip_section_from_output (info, sec);
2901 else
2902 {
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;
2907 }
2908 }
2909
2910 if (elf_hash_table (info)->dynamic_sections_created)
2911 {
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. */
2915
2916 if (!info->shared)
2917 {
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))
2922
2923 if (!add_dynamic_entry (DT_DEBUG, 0))
2924 return false;
2925 }
2926
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;
2931
2932 if (relplt)
2933 {
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;
2938 }
2939
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;
2944
2945 if (ia64_info->reltext)
2946 {
2947 if (!add_dynamic_entry (DT_TEXTREL, 0))
2948 return false;
2949 info->flags |= DF_TEXTREL;
2950 }
2951 }
2952
2953 /* ??? Perhaps force __gp local. */
2954
2955 return true;
2956 }
2957
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;
2964 {
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
2976
2977 opnd = IA64_OPND_NIL;
2978 switch (r_type)
2979 {
2980 case R_IA64_NONE:
2981 case R_IA64_LDXMOV:
2982 return bfd_reloc_ok;
2983
2984 /* Instruction relocations. */
2985
2986 case R_IA64_IMM14:
2987 case R_IA64_TPREL14:
2988 case R_IA64_DTPREL14:
2989 opnd = IA64_OPND_IMM14;
2990 break;
2991
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;
2999
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;
3014
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;
3026
3027 /* Data relocations. */
3028
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;
3040
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;
3052
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;
3067
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;
3082
3083 /* Unsupported / Dynamic relocations. */
3084 default:
3085 return bfd_reloc_notsupported;
3086 }
3087
3088 switch (opnd)
3089 {
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);
3094
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 */
3099
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));
3106
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 */
3114
3115 bfd_put_64 (abfd, t0, hit_addr);
3116 bfd_put_64 (abfd, t1, hit_addr + 8);
3117 break;
3118
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);
3123
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 */
3128
3129 /* First, clear the bits that form the 64 bit constant. */
3130 t0 &= ~(0x3ffffLL << 46);
3131 t1 &= ~(0x7fffffLL
3132 | ((1LL << 36 | 0xfffffLL << 13) << 23));
3133
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 */
3139
3140 bfd_put_64 (abfd, t0, hit_addr);
3141 bfd_put_64 (abfd, t1, hit_addr + 8);
3142 break;
3143
3144 default:
3145 switch ((long) hit_addr & 0x3)
3146 {
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... */
3151 }
3152 dword = bfd_get_64 (abfd, hit_addr);
3153 insn = (dword >> shift) & 0x1ffffffffffLL;
3154
3155 op = elf64_ia64_operands + opnd;
3156 err = (*op->insert) (op, val, (ia64_insn *)& insn);
3157 if (err)
3158 return bfd_reloc_overflow;
3159
3160 dword &= ~(0x1ffffffffffLL << shift);
3161 dword |= (insn << shift);
3162 bfd_put_64 (abfd, dword, hit_addr);
3163 break;
3164
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;
3178 }
3179
3180 return bfd_reloc_ok;
3181 }
3182
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;
3194 {
3195 Elf_Internal_Rela outrel;
3196
3197 offset += sec->output_section->vma + sec->output_offset;
3198
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)
3204 {
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;
3210 }
3211
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);
3217 }
3218
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. */
3221
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;
3231 {
3232 struct elfNN_ia64_link_hash_table *ia64_info;
3233 asection *got_sec;
3234 boolean done;
3235 bfd_vma got_offset;
3236
3237 ia64_info = elfNN_ia64_hash_table (info);
3238 got_sec = ia64_info->got_sec;
3239
3240 switch (dyn_r_type)
3241 {
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;
3262 }
3263
3264 BFD_ASSERT ((got_offset & 7) == 0);
3265
3266 if (! done)
3267 {
3268 /* Store the target address in the linkage table entry. */
3269 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3270
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))
3276 {
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)
3281 {
3282 dyn_r_type = R_IA64_REL64LSB;
3283 dynindx = 0;
3284 addend = value;
3285 }
3286
3287 if (bfd_big_endian (abfd))
3288 {
3289 switch (dyn_r_type)
3290 {
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;
3312 }
3313 }
3314
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);
3319 }
3320 }
3321
3322 /* Return the address of the linkage table entry. */
3323 value = (got_sec->output_section->vma
3324 + got_sec->output_offset
3325 + got_offset);
3326
3327 return value;
3328 }
3329
3330 /* Fill in a function descriptor consisting of the function's code
3331 address and its global pointer. Return the descriptor's address. */
3332
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;
3339 {
3340 struct elfNN_ia64_link_hash_table *ia64_info;
3341 asection *fptr_sec;
3342
3343 ia64_info = elfNN_ia64_hash_table (info);
3344 fptr_sec = ia64_info->fptr_sec;
3345
3346 if (!dyn_i->fptr_done)
3347 {
3348 dyn_i->fptr_done = 1;
3349
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);
3354 }
3355
3356 /* Return the descriptor's address. */
3357 value = (fptr_sec->output_section->vma
3358 + fptr_sec->output_offset
3359 + dyn_i->fptr_offset);
3360
3361 return value;
3362 }
3363
3364 /* Fill in a PLTOFF entry consisting of the function's code address
3365 and its global pointer. Return the descriptor's address. */
3366
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;
3374 {
3375 struct elfNN_ia64_link_hash_table *ia64_info;
3376 asection *pltoff_sec;
3377
3378 ia64_info = elfNN_ia64_hash_table (info);
3379 pltoff_sec = ia64_info->pltoff_sec;
3380
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)
3385 {
3386 bfd_vma gp = _bfd_get_gp_value (abfd);
3387
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);
3391
3392 /* Install dynamic relocations if needed. */
3393 if (!is_plt && info->shared)
3394 {
3395 unsigned int dyn_r_type;
3396
3397 if (bfd_big_endian (abfd))
3398 dyn_r_type = R_IA64_REL64MSB;
3399 else
3400 dyn_r_type = R_IA64_REL64LSB;
3401
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);
3410 }
3411
3412 dyn_i->pltoff_done = 1;
3413 }
3414
3415 /* Return the descriptor's address. */
3416 value = (pltoff_sec->output_section->vma
3417 + pltoff_sec->output_offset
3418 + dyn_i->pltoff_offset);
3419
3420 return value;
3421 }
3422
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). */
3427
3428 static bfd_vma
3429 elfNN_ia64_tprel_base (info)
3430 struct bfd_link_info *info;
3431 {
3432 struct elf_link_tls_segment *tls_segment
3433 = elf_hash_table (info)->tls_segment;
3434
3435 BFD_ASSERT (tls_segment != NULL);
3436 return (tls_segment->start
3437 - align_power ((bfd_vma) 16, tls_segment->align));
3438 }
3439
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. */
3443
3444 static bfd_vma
3445 elfNN_ia64_dtprel_base (info)
3446 struct bfd_link_info *info;
3447 {
3448 BFD_ASSERT (elf_hash_table (info)->tls_segment != NULL);
3449 return elf_hash_table (info)->tls_segment->start;
3450 }
3451
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. */
3455
3456 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3457
3458 static int
3459 elfNN_ia64_unwind_entry_compare (a, b)
3460 const PTR a;
3461 const PTR b;
3462 {
3463 bfd_vma av, bv;
3464
3465 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3466 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3467
3468 return (av < bv ? -1 : av > bv ? 1 : 0);
3469 }
3470
3471 static boolean
3472 elfNN_ia64_final_link (abfd, info)
3473 bfd *abfd;
3474 struct bfd_link_info *info;
3475 {
3476 struct elfNN_ia64_link_hash_table *ia64_info;
3477 asection *unwind_output_sec;
3478
3479 ia64_info = elfNN_ia64_hash_table (info);
3480
3481 /* Make sure we've got ourselves a nice fat __gp value. */
3482 if (!info->relocateable)
3483 {
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;
3489
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)
3494 {
3495 bfd_vma lo, hi;
3496
3497 if ((os->flags & SEC_ALLOC) == 0)
3498 continue;
3499
3500 lo = os->vma;
3501 hi = os->vma + os->_raw_size;
3502 if (hi < lo)
3503 hi = (bfd_vma) -1;
3504
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)
3510 {
3511 if (min_short_vma > lo)
3512 min_short_vma = lo;
3513 if (max_short_vma < hi)
3514 max_short_vma = hi;
3515 }
3516 }
3517
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);
3521
3522 if (gp
3523 && (gp->root.type == bfd_link_hash_defined
3524 || gp->root.type == bfd_link_hash_defweak))
3525 {
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);
3530 }
3531 else
3532 {
3533 /* Pick a sensible value. */
3534
3535 asection *got_sec = ia64_info->got_sec;
3536
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;
3544
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)
3552 {
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;
3556
3557 /* If we're addressing stuff past the end, adjust back. */
3558 if (gp_val > max_vma)
3559 gp_val = max_vma - 0x200000 + 8;
3560 }
3561 }
3562
3563 /* Validate whether all SHF_IA_64_SHORT sections are within
3564 range of the chosen GP. */
3565
3566 if (max_short_vma != 0)
3567 {
3568 if (max_short_vma - min_short_vma >= 0x400000)
3569 {
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;
3575 }
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))
3580 {
3581 (*_bfd_error_handler)
3582 (_("%s: __gp does not cover short data segment"),
3583 bfd_get_filename (abfd));
3584 return false;
3585 }
3586 }
3587
3588 _bfd_set_gp_value (abfd, gp_val);
3589
3590 if (gp)
3591 {
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;
3595 }
3596 }
3597
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)
3603 {
3604 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3605 if (s)
3606 {
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;
3612 }
3613 }
3614
3615 /* Invoke the regular ELF backend linker to do all the work. */
3616 if (!bfd_elfNN_bfd_final_link (abfd, info))
3617 return false;
3618
3619 if (unwind_output_sec)
3620 {
3621 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3622 qsort (unwind_output_sec->contents,
3623 (size_t) (unwind_output_sec->_raw_size / 24),
3624 24,
3625 elfNN_ia64_unwind_entry_compare);
3626
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;
3631 }
3632
3633 return true;
3634 }
3635
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;
3647 {
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;
3655
3656 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3657 ia64_info = elfNN_ia64_hash_table (info);
3658
3659 /* Infect various flags from the input section to the output section. */
3660 if (info->relocateable)
3661 {
3662 bfd_vma flags;
3663
3664 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3665 flags &= SHF_IA_64_NORECOV;
3666
3667 elf_section_data(input_section->output_section)
3668 ->this_hdr.sh_flags |= flags;
3669 return true;
3670 }
3671
3672 gp_val = _bfd_get_gp_value (output_bfd);
3673 srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3674
3675 rel = relocs;
3676 relend = relocs + input_section->reloc_count;
3677 for (; rel < relend; ++rel)
3678 {
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;
3691
3692 r_type = ELFNN_R_TYPE (rel->r_info);
3693 if (r_type > R_IA64_MAX_RELOC_CODE)
3694 {
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;
3701 }
3702
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;
3709
3710 if (r_symndx < symtab_hdr->sh_info)
3711 {
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))
3720 {
3721 struct elfNN_ia64_local_hash_entry *loc_h;
3722
3723 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, false);
3724 if (loc_h && ! loc_h->sec_merge_done)
3725 {
3726 struct elfNN_ia64_dyn_sym_info *dynent;
3727 asection *msec;
3728
3729 for (dynent = loc_h->info; dynent; dynent = dynent->next)
3730 {
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;
3744 }
3745 loc_h->sec_merge_done = 1;
3746 }
3747 }
3748 }
3749 else
3750 {
3751 long indx;
3752
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;
3759
3760 value = 0;
3761 if (h->root.type == bfd_link_hash_defined
3762 || h->root.type == bfd_link_hash_defweak)
3763 {
3764 sym_sec = h->root.u.def.section;
3765
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. */
3773
3774 if (sym_sec->output_section != NULL)
3775 {
3776 value = (h->root.u.def.value
3777 + sym_sec->output_section->vma
3778 + sym_sec->output_offset);
3779 }
3780 }
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)
3787 ;
3788 else
3789 {
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;
3798 }
3799 }
3800
3801 hit_addr = contents + rel->r_offset;
3802 value += rel->r_addend;
3803 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3804
3805 switch (r_type)
3806 {
3807 case R_IA64_NONE:
3808 case R_IA64_LDXMOV:
3809 continue;
3810
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)
3826 {
3827 unsigned int dyn_r_type;
3828 long dynindx;
3829 bfd_vma addend;
3830
3831 BFD_ASSERT (srel != NULL);
3832
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)
3837 {
3838 dynindx = h->dynindx;
3839 addend = rel->r_addend;
3840 value = 0;
3841 }
3842 else
3843 {
3844 switch (r_type)
3845 {
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;
3858
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;
3871 }
3872 dynindx = 0;
3873 addend = value;
3874 }
3875
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);
3881 }
3882 /* FALLTHRU */
3883
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;
3890
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)
3898 {
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;
3904 }
3905 value -= gp_val;
3906 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3907 break;
3908
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;
3918
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;
3928
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)
3936 {
3937 if (!undef_weak_ref)
3938 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3939 }
3940 else
3941 {
3942 long dynindx;
3943
3944 /* Otherwise, we expect the dynamic linker to create
3945 the entry. */
3946
3947 if (h)
3948 {
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)));
3955 }
3956 else
3957 {
3958 dynindx = (_bfd_elf_link_lookup_local_dynindx
3959 (info, input_bfd, (long) r_symndx));
3960 }
3961
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;
3966 }
3967
3968 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3969 break;
3970
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:
3977 {
3978 long dynindx;
3979
3980 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3981 if (dyn_i->want_fptr)
3982 {
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;
3987 }
3988 else
3989 {
3990 /* Otherwise, we expect the dynamic linker to create
3991 the entry. */
3992 if (h)
3993 {
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)));
4000 }
4001 else
4002 dynindx = (_bfd_elf_link_lookup_local_dynindx
4003 (info, input_bfd, (long) r_symndx));
4004 value = 0;
4005 }
4006
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);
4011 }
4012 break;
4013
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)
4022 {
4023 BFD_ASSERT (srel != NULL);
4024
4025 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4026 srel, rel->r_offset, r_type,
4027 h->dynindx, rel->r_addend);
4028 }
4029 goto finish_pcrel;
4030
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)
4037 {
4038 (*_bfd_error_handler)
4039 (_("%s: dynamic relocation against speculation fixup"),
4040 bfd_archive_filename (input_bfd));
4041 ret_val = false;
4042 continue;
4043 }
4044 if (undef_weak_ref)
4045 {
4046 (*_bfd_error_handler)
4047 (_("%s: speculation fixup against undefined weak symbol"),
4048 bfd_archive_filename (input_bfd));
4049 ret_val = false;
4050 continue;
4051 }
4052 goto finish_pcrel;
4053
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);
4060
4061 if (dyn_i && dyn_i->want_plt2)
4062 {
4063 /* Should have caught this earlier. */
4064 BFD_ASSERT (rel->r_addend == 0);
4065
4066 value = (ia64_info->plt_sec->output_section->vma
4067 + ia64_info->plt_sec->output_offset
4068 + dyn_i->plt2_offset);
4069 }
4070 else
4071 {
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);
4075
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;
4082 }
4083 goto finish_pcrel;
4084
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;
4094
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)
4100 {
4101 /* If the input section was discarded from the output, then
4102 do nothing. */
4103 r = bfd_reloc_ok;
4104 }
4105 else
4106 {
4107 struct elf_segment_map *m;
4108 Elf_Internal_Phdr *p;
4109
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++)
4115 {
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;
4122 }
4123
4124 if (m == NULL)
4125 {
4126 r = bfd_reloc_notsupported;
4127 }
4128 else
4129 {
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);
4138 }
4139 break;
4140 }
4141
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;
4153
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)
4159 {
4160 BFD_ASSERT (srel != NULL);
4161
4162 /* If we don't need dynamic symbol lookup, install two
4163 RELATIVE relocations. */
4164 if (! dynamic_symbol_p)
4165 {
4166 unsigned int dyn_r_type;
4167
4168 if (r_type == R_IA64_IPLTMSB)
4169 dyn_r_type = R_IA64_REL64MSB;
4170 else
4171 dyn_r_type = R_IA64_REL64LSB;
4172
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);
4181 }
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);
4186 }
4187
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;
4196
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;
4203
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;
4210
4211 case R_IA64_LTOFF_TPREL22:
4212 case R_IA64_LTOFF_DTPMOD22:
4213 case R_IA64_LTOFF_DTPREL22:
4214 {
4215 int got_r_type;
4216
4217 switch (r_type)
4218 {
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;
4235 }
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);
4243 }
4244 break;
4245
4246 default:
4247 r = bfd_reloc_notsupported;
4248 break;
4249 }
4250
4251 switch (r)
4252 {
4253 case bfd_reloc_ok:
4254 break;
4255
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;
4263
4264 case bfd_reloc_notsupported:
4265 {
4266 const char *name;
4267
4268 if (h)
4269 name = h->root.root.string;
4270 else
4271 {
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);
4279 }
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;
4285 }
4286 break;
4287
4288 case bfd_reloc_dangerous:
4289 case bfd_reloc_outofrange:
4290 case bfd_reloc_overflow:
4291 default:
4292 {
4293 const char *name;
4294
4295 if (h)
4296 name = h->root.root.string;
4297 else
4298 {
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);
4306 }
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;
4315 }
4316 break;
4317 }
4318 }
4319
4320 return ret_val;
4321 }
4322
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;
4329 {
4330 struct elfNN_ia64_link_hash_table *ia64_info;
4331 struct elfNN_ia64_dyn_sym_info *dyn_i;
4332
4333 ia64_info = elfNN_ia64_hash_table (info);
4334 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
4335
4336 /* Fill in the PLT data, if required. */
4337 if (dyn_i && dyn_i->want_plt)
4338 {
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;
4344
4345 gp_val = _bfd_get_gp_value (output_bfd);
4346
4347 /* Initialize the minimal PLT entry. */
4348
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;
4352
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);
4357
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);
4362
4363 /* Initialize the FULL PLT entry, if needed. */
4364 if (dyn_i->want_plt2)
4365 {
4366 loc = plt_sec->contents + dyn_i->plt2_offset;
4367
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);
4371
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;
4378 }
4379
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;
4387
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.
4394
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. */
4399
4400 rel = (ElfNN_External_Rela *)ia64_info->rel_pltoff_sec->contents;
4401 rel += ia64_info->rel_pltoff_sec->reloc_count;
4402
4403 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, rel + index);
4404 }
4405
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;
4411
4412 return true;
4413 }
4414
4415 static boolean
4416 elfNN_ia64_finish_dynamic_sections (abfd, info)
4417 bfd *abfd;
4418 struct bfd_link_info *info;
4419 {
4420 struct elfNN_ia64_link_hash_table *ia64_info;
4421 bfd *dynobj;
4422
4423 ia64_info = elfNN_ia64_hash_table (info);
4424 dynobj = ia64_info->root.dynobj;
4425
4426 if (elf_hash_table (info)->dynamic_sections_created)
4427 {
4428 ElfNN_External_Dyn *dyncon, *dynconend;
4429 asection *sdyn, *sgotplt;
4430 bfd_vma gp_val;
4431
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);
4437
4438 gp_val = _bfd_get_gp_value (abfd);
4439
4440 for (; dyncon < dynconend; dyncon++)
4441 {
4442 Elf_Internal_Dyn dyn;
4443
4444 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4445
4446 switch (dyn.d_tag)
4447 {
4448 case DT_PLTGOT:
4449 dyn.d_un.d_ptr = gp_val;
4450 break;
4451
4452 case DT_PLTRELSZ:
4453 dyn.d_un.d_val = (ia64_info->minplt_entries
4454 * sizeof (ElfNN_External_Rela));
4455 break;
4456
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;
4464
4465 case DT_IA_64_PLT_RESERVE:
4466 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4467 + sgotplt->output_offset);
4468 break;
4469
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;
4476 }
4477
4478 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4479 }
4480
4481 /* Initialize the PLT0 entry */
4482 if (ia64_info->plt_sec)
4483 {
4484 bfd_byte *loc = ia64_info->plt_sec->contents;
4485 bfd_vma pltres;
4486
4487 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4488
4489 pltres = (sgotplt->output_section->vma
4490 + sgotplt->output_offset
4491 - gp_val);
4492
4493 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4494 }
4495 }
4496
4497 return true;
4498 }
4499 \f
4500 /* ELF file flag handling: */
4501
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;
4507 {
4508 BFD_ASSERT (!elf_flags_init (abfd)
4509 || elf_elfheader (abfd)->e_flags == flags);
4510
4511 elf_elfheader (abfd)->e_flags = flags;
4512 elf_flags_init (abfd) = true;
4513 return true;
4514 }
4515
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;
4521 {
4522 flagword out_flags;
4523 flagword in_flags;
4524 boolean ok = true;
4525
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;
4530
4531 in_flags = elf_elfheader (ibfd)->e_flags;
4532 out_flags = elf_elfheader (obfd)->e_flags;
4533
4534 if (! elf_flags_init (obfd))
4535 {
4536 elf_flags_init (obfd) = true;
4537 elf_elfheader (obfd)->e_flags = in_flags;
4538
4539 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4540 && bfd_get_arch_info (obfd)->the_default)
4541 {
4542 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4543 bfd_get_mach (ibfd));
4544 }
4545
4546 return true;
4547 }
4548
4549 /* Check flag compatibility. */
4550 if (in_flags == out_flags)
4551 return true;
4552
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;
4556
4557 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4558 {
4559 (*_bfd_error_handler)
4560 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4561 bfd_archive_filename (ibfd));
4562
4563 bfd_set_error (bfd_error_bad_value);
4564 ok = false;
4565 }
4566 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4567 {
4568 (*_bfd_error_handler)
4569 (_("%s: linking big-endian files with little-endian files"),
4570 bfd_archive_filename (ibfd));
4571
4572 bfd_set_error (bfd_error_bad_value);
4573 ok = false;
4574 }
4575 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4576 {
4577 (*_bfd_error_handler)
4578 (_("%s: linking 64-bit files with 32-bit files"),
4579 bfd_archive_filename (ibfd));
4580
4581 bfd_set_error (bfd_error_bad_value);
4582 ok = false;
4583 }
4584 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4585 {
4586 (*_bfd_error_handler)
4587 (_("%s: linking constant-gp files with non-constant-gp files"),
4588 bfd_archive_filename (ibfd));
4589
4590 bfd_set_error (bfd_error_bad_value);
4591 ok = false;
4592 }
4593 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4594 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4595 {
4596 (*_bfd_error_handler)
4597 (_("%s: linking auto-pic files with non-auto-pic files"),
4598 bfd_archive_filename (ibfd));
4599
4600 bfd_set_error (bfd_error_bad_value);
4601 ok = false;
4602 }
4603
4604 return ok;
4605 }
4606
4607 static boolean
4608 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4609 bfd *abfd;
4610 PTR ptr;
4611 {
4612 FILE *file = (FILE *) ptr;
4613 flagword flags = elf_elfheader (abfd)->e_flags;
4614
4615 BFD_ASSERT (abfd != NULL && ptr != NULL);
4616
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");
4626
4627 _bfd_elf_print_private_bfd_data (abfd, ptr);
4628 return true;
4629 }
4630
4631 static enum elf_reloc_type_class
4632 elfNN_ia64_reloc_type_class (rela)
4633 const Elf_Internal_Rela *rela;
4634 {
4635 switch ((int) ELFNN_R_TYPE (rela->r_info))
4636 {
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;
4649 }
4650 }
4651
4652 static boolean
4653 elfNN_ia64_hpux_vec (const bfd_target *vec)
4654 {
4655 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4656 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4657 }
4658
4659 static void
4660 elfNN_hpux_post_process_headers (abfd, info)
4661 bfd *abfd;
4662 struct bfd_link_info *info ATTRIBUTE_UNUSED;
4663 {
4664 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4665
4666 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4667 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4668 }
4669
4670 boolean
4671 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
4672 bfd *abfd ATTRIBUTE_UNUSED;
4673 asection *sec;
4674 int *retval;
4675 {
4676 if (bfd_is_com_section (sec))
4677 {
4678 *retval = SHN_IA_64_ANSI_COMMON;
4679 return true;
4680 }
4681 return false;
4682 }
4683 \f
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 */
4693
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
4710
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
4717
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
4737
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
4744
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
4759
4760 #include "elfNN-target.h"
4761
4762 /* AIX-specific vectors. */
4763
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"
4772
4773 #undef elf_backend_add_symbol_hook
4774 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4775
4776 #undef bfd_elfNN_bfd_link_add_symbols
4777 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4778
4779 #define elfNN_bed elfNN_ia64_aix_bed
4780
4781 #include "elfNN-target.h"
4782
4783 /* HPUX-specific vectors. */
4784
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"
4791
4792 /* We need to undo the AIX specific functions. */
4793
4794 #undef elf_backend_add_symbol_hook
4795 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
4796
4797 #undef bfd_elfNN_bfd_link_add_symbols
4798 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
4799
4800 /* These are HP-UX specific functions. */
4801
4802 #undef elf_backend_post_process_headers
4803 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4804
4805 #undef elf_backend_section_from_bfd_section
4806 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4807
4808 #undef elf_backend_want_p_paddr_set_to_zero
4809 #define elf_backend_want_p_paddr_set_to_zero 1
4810
4811 #undef ELF_MAXPAGESIZE
4812 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4813
4814 #undef elfNN_bed
4815 #define elfNN_bed elfNN_ia64_hpux_bed
4816
4817 #include "elfNN-target.h"
4818
4819 #undef elf_backend_want_p_paddr_set_to_zero
This page took 0.184898 seconds and 4 git commands to generate.