* coffcode.h (coff_write_object_contents): Add ATTRIBUTE_UNUSED to
[deliverable/binutils-gdb.git] / bfd / elfxx-ia64.c
1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
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 /*
29 * THE RULES for all the stuff the linker creates --
30 *
31 * GOT Entries created in response to LTOFF or LTOFF_FPTR
32 * relocations. Dynamic relocs created for dynamic
33 * symbols in an application; REL relocs for locals
34 * in a shared library.
35 *
36 * FPTR The canonical function descriptor. Created for local
37 * symbols in applications. Descriptors for dynamic symbols
38 * and local symbols in shared libraries are created by
39 * ld.so. Thus there are no dynamic relocs against these
40 * objects. The FPTR relocs for such _are_ passed through
41 * to the dynamic relocation tables.
42 *
43 * FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
44 * Requires the creation of a PLTOFF entry. This does not
45 * require any dynamic relocations.
46 *
47 * PLTOFF Created by PLTOFF relocations. For local symbols, this
48 * is an alternate function descriptor, and in shared libraries
49 * requires two REL relocations. Note that this cannot be
50 * transformed into an FPTR relocation, since it must be in
51 * range of the GP. For dynamic symbols, this is a function
52 * descriptor for a MIN_PLT entry, and requires one IPLT reloc.
53 *
54 * MIN_PLT Created by PLTOFF entries against dynamic symbols. This
55 * does not reqire dynamic relocations.
56 */
57
58 #define USE_RELA /* we want RELA relocs, not REL */
59
60 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
61
62 typedef struct bfd_hash_entry *(*new_hash_entry_func)
63 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
64
65 /* In dynamically (linker-) created sections, we generally need to keep track
66 of the place a symbol or expression got allocated to. This is done via hash
67 tables that store entries of the following type. */
68
69 struct elfNN_ia64_dyn_sym_info
70 {
71 /* The addend for which this entry is relevant. */
72 bfd_vma addend;
73
74 /* Next addend in the list. */
75 struct elfNN_ia64_dyn_sym_info *next;
76
77 bfd_vma got_offset;
78 bfd_vma fptr_offset;
79 bfd_vma pltoff_offset;
80 bfd_vma plt_offset;
81 bfd_vma plt2_offset;
82
83 /* The symbol table entry, if any, that this was derrived from. */
84 struct elf_link_hash_entry *h;
85
86 /* Used to count non-got, non-plt relocations for delayed sizing
87 of relocation sections. */
88 struct elfNN_ia64_dyn_reloc_entry
89 {
90 struct elfNN_ia64_dyn_reloc_entry *next;
91 asection *srel;
92 int type;
93 int count;
94 } *reloc_entries;
95
96 /* True when the section contents have been updated. */
97 unsigned got_done : 1;
98 unsigned fptr_done : 1;
99 unsigned pltoff_done : 1;
100
101 /* True for the different kinds of linker data we want created. */
102 unsigned want_got : 1;
103 unsigned want_fptr : 1;
104 unsigned want_ltoff_fptr : 1;
105 unsigned want_plt : 1;
106 unsigned want_plt2 : 1;
107 unsigned want_pltoff : 1;
108 };
109
110 struct elfNN_ia64_local_hash_entry
111 {
112 struct bfd_hash_entry root;
113 struct elfNN_ia64_dyn_sym_info *info;
114 };
115
116 struct elfNN_ia64_local_hash_table
117 {
118 struct bfd_hash_table root;
119 /* No additional fields for now. */
120 };
121
122 struct elfNN_ia64_link_hash_entry
123 {
124 struct elf_link_hash_entry root;
125 struct elfNN_ia64_dyn_sym_info *info;
126 };
127
128 struct elfNN_ia64_link_hash_table
129 {
130 /* The main hash table */
131 struct elf_link_hash_table root;
132
133 asection *got_sec; /* the linkage table section (or NULL) */
134 asection *rel_got_sec; /* dynamic relocation section for same */
135 asection *fptr_sec; /* function descriptor table (or NULL) */
136 asection *plt_sec; /* the primary plt section (or NULL) */
137 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
138 asection *rel_pltoff_sec; /* dynamic relocation section for same */
139
140 bfd_size_type minplt_entries; /* number of minplt entries */
141
142 struct elfNN_ia64_local_hash_table loc_hash_table;
143 };
144
145 #define elfNN_ia64_hash_table(p) \
146 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
147
148 static bfd_reloc_status_type elfNN_ia64_reloc
149 PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
150 asection *input_section, bfd *output_bfd, char **error_message));
151 static reloc_howto_type * lookup_howto
152 PARAMS ((unsigned int rtype));
153 static reloc_howto_type *elfNN_ia64_reloc_type_lookup
154 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
155 static void elfNN_ia64_info_to_howto
156 PARAMS ((bfd *abfd, arelent *bfd_reloc, ElfNN_Internal_Rela *elf_reloc));
157 static boolean elfNN_ia64_relax_section
158 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
159 boolean *again));
160 static boolean is_unwind_section_name
161 PARAMS ((const char *));
162 static boolean elfNN_ia64_section_from_shdr
163 PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *));
164 static boolean elfNN_ia64_section_flags
165 PARAMS ((flagword *, ElfNN_Internal_Shdr *));
166 static boolean elfNN_ia64_fake_sections
167 PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec));
168 static void elfNN_ia64_final_write_processing
169 PARAMS ((bfd *abfd, boolean linker));
170 static boolean elfNN_ia64_add_symbol_hook
171 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
172 const char **namep, flagword *flagsp, asection **secp,
173 bfd_vma *valp));
174 static boolean elfNN_ia64_aix_vec
175 PARAMS ((const bfd_target *vec));
176 static boolean elfNN_ia64_aix_add_symbol_hook
177 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
178 const char **namep, flagword *flagsp, asection **secp,
179 bfd_vma *valp));
180 static boolean elfNN_ia64_aix_link_add_symbols
181 PARAMS ((bfd *abfd, struct bfd_link_info *info));
182 static int elfNN_ia64_additional_program_headers
183 PARAMS ((bfd *abfd));
184 static boolean elfNN_ia64_modify_segment_map
185 PARAMS ((bfd *));
186 static boolean elfNN_ia64_is_local_label_name
187 PARAMS ((bfd *abfd, const char *name));
188 static boolean elfNN_ia64_dynamic_symbol_p
189 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
190 static boolean elfNN_ia64_local_hash_table_init
191 PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
192 new_hash_entry_func new));
193 static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
194 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
195 const char *string));
196 static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
197 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
198 const char *string));
199 static void elfNN_ia64_hash_copy_indirect
200 PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
201 static void elfNN_ia64_hash_hide_symbol
202 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
203 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
204 PARAMS ((bfd *abfd));
205 static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
206 PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
207 boolean create, boolean copy));
208 static boolean elfNN_ia64_global_dyn_sym_thunk
209 PARAMS ((struct bfd_hash_entry *, PTR));
210 static boolean elfNN_ia64_local_dyn_sym_thunk
211 PARAMS ((struct bfd_hash_entry *, PTR));
212 static void elfNN_ia64_dyn_sym_traverse
213 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
214 boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
215 PTR info));
216 static boolean elfNN_ia64_create_dynamic_sections
217 PARAMS ((bfd *abfd, struct bfd_link_info *info));
218 static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
219 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
220 struct elf_link_hash_entry *h,
221 bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
222 static asection *get_got
223 PARAMS ((bfd *abfd, struct bfd_link_info *info,
224 struct elfNN_ia64_link_hash_table *ia64_info));
225 static asection *get_fptr
226 PARAMS ((bfd *abfd, struct bfd_link_info *info,
227 struct elfNN_ia64_link_hash_table *ia64_info));
228 static asection *get_pltoff
229 PARAMS ((bfd *abfd, struct bfd_link_info *info,
230 struct elfNN_ia64_link_hash_table *ia64_info));
231 static asection *get_reloc_section
232 PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
233 asection *sec, boolean create));
234 static boolean count_dyn_reloc
235 PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
236 asection *srel, int type));
237 static boolean elfNN_ia64_check_relocs
238 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
239 const Elf_Internal_Rela *relocs));
240 static boolean elfNN_ia64_adjust_dynamic_symbol
241 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
242 static unsigned long global_sym_index
243 PARAMS ((struct elf_link_hash_entry *h));
244 static boolean allocate_fptr
245 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
246 static boolean allocate_global_data_got
247 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
248 static boolean allocate_global_fptr_got
249 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
250 static boolean allocate_local_got
251 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
252 static boolean allocate_pltoff_entries
253 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
254 static boolean allocate_plt_entries
255 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
256 static boolean allocate_plt2_entries
257 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
258 static boolean allocate_dynrel_entries
259 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
260 static boolean elfNN_ia64_size_dynamic_sections
261 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
262 static bfd_reloc_status_type elfNN_ia64_install_value
263 PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
264 static void elfNN_ia64_install_dyn_reloc
265 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
266 asection *srel, bfd_vma offset, unsigned int type,
267 long dynindx, bfd_vma addend));
268 static bfd_vma set_got_entry
269 PARAMS ((bfd *abfd, struct bfd_link_info *info,
270 struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
271 bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
272 static bfd_vma set_fptr_entry
273 PARAMS ((bfd *abfd, struct bfd_link_info *info,
274 struct elfNN_ia64_dyn_sym_info *dyn_i,
275 bfd_vma value));
276 static bfd_vma set_pltoff_entry
277 PARAMS ((bfd *abfd, struct bfd_link_info *info,
278 struct elfNN_ia64_dyn_sym_info *dyn_i,
279 bfd_vma value, boolean));
280 static int elfNN_ia64_unwind_entry_compare
281 PARAMS ((const PTR, const PTR));
282 static boolean elfNN_ia64_final_link
283 PARAMS ((bfd *abfd, struct bfd_link_info *info));
284 static boolean elfNN_ia64_relocate_section
285 PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
286 asection *input_section, bfd_byte *contents,
287 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
288 asection **local_sections));
289 static boolean elfNN_ia64_finish_dynamic_symbol
290 PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
291 struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
292 static boolean elfNN_ia64_finish_dynamic_sections
293 PARAMS ((bfd *abfd, struct bfd_link_info *info));
294 static boolean elfNN_ia64_set_private_flags
295 PARAMS ((bfd *abfd, flagword flags));
296 static boolean elfNN_ia64_copy_private_bfd_data
297 PARAMS ((bfd *ibfd, bfd *obfd));
298 static boolean elfNN_ia64_merge_private_bfd_data
299 PARAMS ((bfd *ibfd, bfd *obfd));
300 static boolean elfNN_ia64_print_private_bfd_data
301 PARAMS ((bfd *abfd, PTR ptr));
302 \f
303 /* ia64-specific relocation */
304
305 /* Perform a relocation. Not much to do here as all the hard work is
306 done in elfNN_ia64_final_link_relocate. */
307 static bfd_reloc_status_type
308 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
309 output_bfd, error_message)
310 bfd *abfd ATTRIBUTE_UNUSED;
311 arelent *reloc;
312 asymbol *sym ATTRIBUTE_UNUSED;
313 PTR data ATTRIBUTE_UNUSED;
314 asection *input_section;
315 bfd *output_bfd;
316 char **error_message;
317 {
318 if (output_bfd)
319 {
320 reloc->address += input_section->output_offset;
321 return bfd_reloc_ok;
322 }
323 *error_message = "Unsupported call to elfNN_ia64_reloc";
324 return bfd_reloc_notsupported;
325 }
326
327 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
328 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
329 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
330
331 /* This table has to be sorted according to increasing number of the
332 TYPE field. */
333 static reloc_howto_type ia64_howto_table[] =
334 {
335 IA64_HOWTO (R_IA64_NONE, "NONE", 0, false, true),
336
337 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, false, true),
338 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, false, true),
339 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, false, true),
340 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, false, true),
341 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, false, true),
342 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, false, true),
343 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, false, true),
344
345 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, false, true),
346 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, false, true),
347 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, false, true),
348 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, false, true),
349 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, false, true),
350 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, false, true),
351
352 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, false, true),
353 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, false, true),
354
355 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, false, true),
356 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, false, true),
357 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, false, true),
358 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, false, true),
359
360 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, false, true),
361 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, false, true),
362 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, false, true),
363 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, false, true),
364 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, false, true),
365
366 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, true, true),
367 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, true, true),
368 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, true, true),
369 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, true, true),
370 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, true, true),
371 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, true, true),
372 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, true, true),
373 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, true, true),
374
375 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true),
376 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true),
377 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, false, true),
378 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, false, true),
379 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
380 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
381
382 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
383 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
384 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
385 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, false, true),
386
387 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, false, true),
388 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, false, true),
389 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, false, true),
390 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, false, true),
391
392 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, false, true),
393 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, false, true),
394 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, false, true),
395 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, false, true),
396
397 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, false, true),
398 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, false, true),
399 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, false, true),
400 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, false, true),
401
402 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, true, true),
403 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, true, true),
404 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, true, true),
405
406 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, false, true),
407 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, false, true),
408 IA64_HOWTO (R_IA64_COPY, "COPY", 4, false, true),
409 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, false, true),
410 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, false, true),
411
412 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, false, false),
413 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 8, false, false),
414 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 8, false, false),
415 IA64_HOWTO (R_IA64_LTOFF_TP22, "LTOFF_TP22", 0, false, false),
416 };
417
418 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
419
420 /* Given a BFD reloc type, return the matching HOWTO structure. */
421
422 static reloc_howto_type*
423 lookup_howto (rtype)
424 unsigned int rtype;
425 {
426 static int inited = 0;
427 int i;
428
429 if (!inited)
430 {
431 inited = 1;
432
433 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
434 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
435 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
436 }
437
438 BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
439 i = elf_code_to_howto_index[rtype];
440 if (i >= NELEMS (ia64_howto_table))
441 return 0;
442 return ia64_howto_table + i;
443 }
444
445 static reloc_howto_type*
446 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
447 bfd *abfd ATTRIBUTE_UNUSED;
448 bfd_reloc_code_real_type bfd_code;
449 {
450 unsigned int rtype;
451
452 switch (bfd_code)
453 {
454 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
455
456 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
457 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
458 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
459
460 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
461 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
462 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
463 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
464
465 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
466 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
467 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
468 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
469 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
470 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
471
472 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
473 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
474
475 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
476 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
477 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
478 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
479 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
480 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
481 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
482 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
483 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
484
485 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
486 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
487 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
488 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
489 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
490 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
491 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
492 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
493 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
494 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
495 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
496
497 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
498 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
499 case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
500 case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
501 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
502 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
503
504 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
505 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
506 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
507 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
508
509 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
510 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
511 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
512 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
513
514 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
515 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
516 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
517 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
518
519 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
520 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
521 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
522 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
523
524 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
525 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
526 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
527 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
528 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
529
530 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
531 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
532 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
533 case BFD_RELOC_IA64_LTOFF_TP22: rtype = R_IA64_LTOFF_TP22; break;
534
535 default: return 0;
536 }
537 return lookup_howto (rtype);
538 }
539
540 /* Given a ELF reloc, return the matching HOWTO structure. */
541
542 static void
543 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
544 bfd *abfd ATTRIBUTE_UNUSED;
545 arelent *bfd_reloc;
546 ElfNN_Internal_Rela *elf_reloc;
547 {
548 bfd_reloc->howto = lookup_howto (ELFNN_R_TYPE (elf_reloc->r_info));
549 }
550 \f
551 #define PLT_HEADER_SIZE (3 * 16)
552 #define PLT_MIN_ENTRY_SIZE (1 * 16)
553 #define PLT_FULL_ENTRY_SIZE (2 * 16)
554 #define PLT_RESERVED_WORDS 3
555
556 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
557 {
558 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
559 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
560 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
561 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
562 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
563 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
564 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
565 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
566 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
567 };
568
569 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
570 {
571 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
572 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
573 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
574 };
575
576 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
577 {
578 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
579 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
580 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
581 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
582 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
583 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
584 };
585
586 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
587 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
588 #define DYNAMIC_INTERPRETER(abfd) \
589 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
590
591 /* Select out of range branch fixup type. Note that Itanium does
592 not support brl, and so it gets emulated by the kernel. */
593 #undef USE_BRL
594
595 static const bfd_byte oor_brl[16] =
596 {
597 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
599 0x00, 0x00, 0x00, 0xc0
600 };
601
602 static const bfd_byte oor_ip[48] =
603 {
604 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
605 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
606 0x01, 0x00, 0x00, 0x60,
607 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
608 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
609 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
610 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
611 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
612 0x60, 0x00, 0x80, 0x00 /* br b6;; */
613 };
614 \f
615 /* These functions do relaxation for IA-64 ELF.
616
617 This is primarily to support branches to targets out of range;
618 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
619
620 static boolean
621 elfNN_ia64_relax_section (abfd, sec, link_info, again)
622 bfd *abfd;
623 asection *sec;
624 struct bfd_link_info *link_info;
625 boolean *again;
626 {
627 struct one_fixup
628 {
629 struct one_fixup *next;
630 asection *tsec;
631 bfd_vma toff;
632 bfd_vma trampoff;
633 };
634
635 Elf_Internal_Shdr *symtab_hdr;
636 Elf_Internal_Rela *internal_relocs;
637 Elf_Internal_Rela *free_relocs = NULL;
638 Elf_Internal_Rela *irel, *irelend;
639 bfd_byte *contents;
640 bfd_byte *free_contents = NULL;
641 ElfNN_External_Sym *extsyms;
642 ElfNN_External_Sym *free_extsyms = NULL;
643 struct elfNN_ia64_link_hash_table *ia64_info;
644 struct one_fixup *fixups = NULL;
645 boolean changed_contents = false;
646 boolean changed_relocs = false;
647
648 /* Assume we're not going to change any sizes, and we'll only need
649 one pass. */
650 *again = false;
651
652 /* Nothing to do if there are no relocations. */
653 if ((sec->flags & SEC_RELOC) == 0
654 || sec->reloc_count == 0)
655 return true;
656
657 /* If this is the first time we have been called for this section,
658 initialize the cooked size. */
659 if (sec->_cooked_size == 0)
660 sec->_cooked_size = sec->_raw_size;
661
662 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
663
664 /* Load the relocations for this section. */
665 internal_relocs = (_bfd_elfNN_link_read_relocs
666 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
667 link_info->keep_memory));
668 if (internal_relocs == NULL)
669 goto error_return;
670
671 if (! link_info->keep_memory)
672 free_relocs = internal_relocs;
673
674 ia64_info = elfNN_ia64_hash_table (link_info);
675 irelend = internal_relocs + sec->reloc_count;
676
677 for (irel = internal_relocs; irel < irelend; irel++)
678 if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
679 break;
680
681 /* No branch-type relocations. */
682 if (irel == irelend)
683 {
684 if (free_relocs != NULL)
685 free (free_relocs);
686 return true;
687 }
688
689 /* Get the section contents. */
690 if (elf_section_data (sec)->this_hdr.contents != NULL)
691 contents = elf_section_data (sec)->this_hdr.contents;
692 else
693 {
694 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
695 if (contents == NULL)
696 goto error_return;
697 free_contents = contents;
698
699 if (! bfd_get_section_contents (abfd, sec, contents,
700 (file_ptr) 0, sec->_raw_size))
701 goto error_return;
702 }
703
704 /* Read this BFD's symbols. */
705 if (symtab_hdr->contents != NULL)
706 extsyms = (ElfNN_External_Sym *) symtab_hdr->contents;
707 else
708 {
709 extsyms = (ElfNN_External_Sym *) bfd_malloc (symtab_hdr->sh_size);
710 if (extsyms == NULL)
711 goto error_return;
712 free_extsyms = extsyms;
713 if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
714 || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
715 != symtab_hdr->sh_size))
716 goto error_return;
717 }
718
719 for (; irel < irelend; irel++)
720 {
721 bfd_vma symaddr, reladdr, trampoff, toff, roff;
722 Elf_Internal_Sym isym;
723 asection *tsec;
724 struct one_fixup *f;
725
726 if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
727 continue;
728
729 /* Get the value of the symbol referred to by the reloc. */
730 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
731 {
732 /* A local symbol. */
733 bfd_elfNN_swap_symbol_in (abfd,
734 extsyms + ELFNN_R_SYM (irel->r_info),
735 &isym);
736 if (isym.st_shndx == SHN_UNDEF)
737 continue; /* We can't do anthing with undefined symbols. */
738 else if (isym.st_shndx == SHN_ABS)
739 tsec = bfd_abs_section_ptr;
740 else if (isym.st_shndx == SHN_COMMON)
741 tsec = bfd_com_section_ptr;
742 else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
743 tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
744 else
745 continue; /* who knows. */
746
747 toff = isym.st_value;
748 }
749 else
750 {
751 unsigned long indx;
752 struct elf_link_hash_entry *h;
753 struct elfNN_ia64_dyn_sym_info *dyn_i;
754
755 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
756 h = elf_sym_hashes (abfd)[indx];
757 BFD_ASSERT (h != NULL);
758
759 while (h->root.type == bfd_link_hash_indirect
760 || h->root.type == bfd_link_hash_warning)
761 h = (struct elf_link_hash_entry *) h->root.u.i.link;
762
763 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
764
765 /* For branches to dynamic symbols, we're interested instead
766 in a branch to the PLT entry. */
767 if (dyn_i && dyn_i->want_plt2)
768 {
769 tsec = ia64_info->plt_sec;
770 toff = dyn_i->plt2_offset;
771 }
772 else
773 {
774 /* We can't do anthing with undefined symbols. */
775 if (h->root.type == bfd_link_hash_undefined
776 || h->root.type == bfd_link_hash_undefweak)
777 continue;
778
779 tsec = h->root.u.def.section;
780 toff = h->root.u.def.value;
781 }
782 }
783
784 symaddr = (tsec->output_section->vma
785 + tsec->output_offset
786 + toff
787 + irel->r_addend);
788
789 roff = irel->r_offset;
790 reladdr = (sec->output_section->vma
791 + sec->output_offset
792 + roff) & -4;
793
794 /* If the branch is in range, no need to do anything. */
795 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
796 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
797 continue;
798
799 /* If the branch and target are in the same section, you've
800 got one honking big section and we can't help you. You'll
801 get an error message later. */
802 if (tsec == sec)
803 continue;
804
805 /* Look for an existing fixup to this address. */
806 for (f = fixups; f ; f = f->next)
807 if (f->tsec == tsec && f->toff == toff)
808 break;
809
810 if (f == NULL)
811 {
812 /* Two alternatives: If it's a branch to a PLT entry, we can
813 make a copy of the FULL_PLT entry. Otherwise, we'll have
814 to use a `brl' insn to get where we're going. */
815
816 int size;
817
818 if (tsec == ia64_info->plt_sec)
819 size = sizeof (plt_full_entry);
820 else
821 {
822 #ifdef USE_BRL
823 size = sizeof (oor_brl);
824 #else
825 size = sizeof (oor_ip);
826 #endif
827 }
828
829 /* Resize the current section to make room for the new branch. */
830 trampoff = (sec->_cooked_size + 15) & -16;
831 contents = (bfd_byte *) bfd_realloc (contents, trampoff + size);
832 if (contents == NULL)
833 goto error_return;
834 sec->_cooked_size = trampoff + size;
835
836 if (tsec == ia64_info->plt_sec)
837 {
838 memcpy (contents + trampoff, plt_full_entry, size);
839
840 /* Hijack the old relocation for use as the PLTOFF reloc. */
841 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
842 R_IA64_PLTOFF22);
843 irel->r_offset = trampoff;
844 }
845 else
846 {
847 #ifdef USE_BRL
848 memcpy (contents + trampoff, oor_brl, size);
849 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
850 R_IA64_PCREL60B);
851 irel->r_offset = trampoff + 2;
852 #else
853 memcpy (contents + trampoff, oor_ip, size);
854 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
855 R_IA64_PCREL64I);
856 irel->r_addend -= 16;
857 irel->r_offset = trampoff + 2;
858 #endif
859 }
860
861 /* Record the fixup so we don't do it again this section. */
862 f = (struct one_fixup *) bfd_malloc (sizeof (*f));
863 f->next = fixups;
864 f->tsec = tsec;
865 f->toff = toff;
866 f->trampoff = trampoff;
867 fixups = f;
868 }
869 else
870 {
871 /* Nop out the reloc, since we're finalizing things here. */
872 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
873 }
874
875 /* Fix up the existing branch to hit the trampoline. Hope like
876 hell this doesn't overflow too. */
877 if (elfNN_ia64_install_value (abfd, contents + roff,
878 f->trampoff - (roff & -4),
879 R_IA64_PCREL21B) != bfd_reloc_ok)
880 goto error_return;
881
882 changed_contents = true;
883 changed_relocs = true;
884 }
885
886 /* Clean up and go home. */
887 while (fixups)
888 {
889 struct one_fixup *f = fixups;
890 fixups = fixups->next;
891 free (f);
892 }
893
894 if (changed_relocs)
895 elf_section_data (sec)->relocs = internal_relocs;
896 else if (free_relocs != NULL)
897 free (free_relocs);
898
899 if (changed_contents)
900 elf_section_data (sec)->this_hdr.contents = contents;
901 else if (free_contents != NULL)
902 {
903 if (! link_info->keep_memory)
904 free (free_contents);
905 else
906 {
907 /* Cache the section contents for elf_link_input_bfd. */
908 elf_section_data (sec)->this_hdr.contents = contents;
909 }
910 }
911
912 if (free_extsyms != NULL)
913 {
914 if (! link_info->keep_memory)
915 free (free_extsyms);
916 else
917 {
918 /* Cache the symbols for elf_link_input_bfd. */
919 symtab_hdr->contents = extsyms;
920 }
921 }
922
923 *again = changed_contents || changed_relocs;
924 return true;
925
926 error_return:
927 if (free_relocs != NULL)
928 free (free_relocs);
929 if (free_contents != NULL)
930 free (free_contents);
931 if (free_extsyms != NULL)
932 free (free_extsyms);
933 return false;
934 }
935 \f
936 /* Return true if NAME is an unwind table section name. */
937
938 static inline boolean
939 is_unwind_section_name (name)
940 const char *name;
941 {
942 size_t len1, len2, len3;
943
944 len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
945 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
946 len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
947 return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
948 && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
949 || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
950 }
951
952 /* Handle an IA-64 specific section when reading an object file. This
953 is called when elfcode.h finds a section with an unknown type. */
954
955 static boolean
956 elfNN_ia64_section_from_shdr (abfd, hdr, name)
957 bfd *abfd;
958 ElfNN_Internal_Shdr *hdr;
959 char *name;
960 {
961 asection *newsect;
962
963 /* There ought to be a place to keep ELF backend specific flags, but
964 at the moment there isn't one. We just keep track of the
965 sections by their name, instead. Fortunately, the ABI gives
966 suggested names for all the MIPS specific sections, so we will
967 probably get away with this. */
968 switch (hdr->sh_type)
969 {
970 case SHT_IA_64_UNWIND:
971 break;
972
973 case SHT_IA_64_EXT:
974 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
975 return false;
976 break;
977
978 default:
979 return false;
980 }
981
982 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
983 return false;
984 newsect = hdr->bfd_section;
985
986 return true;
987 }
988
989 /* Convert IA-64 specific section flags to bfd internal section flags. */
990
991 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
992 flag. */
993
994 static boolean
995 elfNN_ia64_section_flags (flags, hdr)
996 flagword *flags;
997 ElfNN_Internal_Shdr *hdr;
998 {
999 if (hdr->sh_flags & SHF_IA_64_SHORT)
1000 *flags |= SEC_SMALL_DATA;
1001
1002 return true;
1003 }
1004
1005 /* Set the correct type for an IA-64 ELF section. We do this by the
1006 section name, which is a hack, but ought to work. */
1007
1008 static boolean
1009 elfNN_ia64_fake_sections (abfd, hdr, sec)
1010 bfd *abfd ATTRIBUTE_UNUSED;
1011 ElfNN_Internal_Shdr *hdr;
1012 asection *sec;
1013 {
1014 register const char *name;
1015
1016 name = bfd_get_section_name (abfd, sec);
1017
1018 if (is_unwind_section_name (name))
1019 {
1020 /* We don't have the sections numbered at this point, so sh_info
1021 is set later, in elfNN_ia64_final_write_processing. */
1022 hdr->sh_type = SHT_IA_64_UNWIND;
1023 hdr->sh_flags |= SHF_LINK_ORDER;
1024 }
1025 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1026 hdr->sh_type = SHT_IA_64_EXT;
1027 else if (strcmp (name, ".reloc") == 0)
1028 /*
1029 * This is an ugly, but unfortunately necessary hack that is
1030 * needed when producing EFI binaries on IA-64. It tells
1031 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1032 * containing ELF relocation info. We need this hack in order to
1033 * be able to generate ELF binaries that can be translated into
1034 * EFI applications (which are essentially COFF objects). Those
1035 * files contain a COFF ".reloc" section inside an ELFNN object,
1036 * which would normally cause BFD to segfault because it would
1037 * attempt to interpret this section as containing relocation
1038 * entries for section "oc". With this hack enabled, ".reloc"
1039 * will be treated as a normal data section, which will avoid the
1040 * segfault. However, you won't be able to create an ELFNN binary
1041 * with a section named "oc" that needs relocations, but that's
1042 * the kind of ugly side-effects you get when detecting section
1043 * types based on their names... In practice, this limitation is
1044 * unlikely to bite.
1045 */
1046 hdr->sh_type = SHT_PROGBITS;
1047
1048 if (sec->flags & SEC_SMALL_DATA)
1049 hdr->sh_flags |= SHF_IA_64_SHORT;
1050
1051 return true;
1052 }
1053
1054 /* The final processing done just before writing out an IA-64 ELF
1055 object file. */
1056
1057 static void
1058 elfNN_ia64_final_write_processing (abfd, linker)
1059 bfd *abfd;
1060 boolean linker ATTRIBUTE_UNUSED;
1061 {
1062 Elf_Internal_Shdr *hdr;
1063 const char *sname;
1064 asection *text_sect, *s;
1065 size_t len;
1066
1067 for (s = abfd->sections; s; s = s->next)
1068 {
1069 hdr = &elf_section_data (s)->this_hdr;
1070 switch (hdr->sh_type)
1071 {
1072 case SHT_IA_64_UNWIND:
1073 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1074 have to do this. */
1075 sname = bfd_get_section_name (abfd, s);
1076 len = sizeof (ELF_STRING_ia64_unwind) - 1;
1077 if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0)
1078 {
1079 sname += len;
1080
1081 if (sname[0] == '\0')
1082 /* .IA_64.unwind -> .text */
1083 text_sect = bfd_get_section_by_name (abfd, ".text");
1084 else
1085 /* .IA_64.unwindFOO -> FOO */
1086 text_sect = bfd_get_section_by_name (abfd, sname);
1087 }
1088 else if (sname
1089 && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
1090 strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
1091 {
1092 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1093 size_t len2 = sizeof (".gnu.linkonce.t.") - 1;
1094 char *once_name = alloca (len2 + strlen (sname) - len + 1);
1095
1096 memcpy (once_name, ".gnu.linkonce.t.", len2);
1097 strcpy (once_name + len2, sname + len);
1098 text_sect = bfd_get_section_by_name (abfd, once_name);
1099 }
1100 else
1101 /* last resort: fall back on .text */
1102 text_sect = bfd_get_section_by_name (abfd, ".text");
1103
1104 if (text_sect)
1105 {
1106 /* The IA-64 processor-specific ABI requires setting
1107 sh_link to the unwind section, whereas HP-UX requires
1108 sh_info to do so. For maximum compatibility, we'll
1109 set both for now... */
1110 hdr->sh_link = elf_section_data (text_sect)->this_idx;
1111 hdr->sh_info = elf_section_data (text_sect)->this_idx;
1112 }
1113 break;
1114 }
1115 }
1116 }
1117
1118 /* Hook called by the linker routine which adds symbols from an object
1119 file. We use it to put .comm items in .sbss, and not .bss. */
1120
1121 static boolean
1122 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1123 bfd *abfd;
1124 struct bfd_link_info *info;
1125 const Elf_Internal_Sym *sym;
1126 const char **namep ATTRIBUTE_UNUSED;
1127 flagword *flagsp ATTRIBUTE_UNUSED;
1128 asection **secp;
1129 bfd_vma *valp;
1130 {
1131 if (sym->st_shndx == SHN_COMMON
1132 && !info->relocateable
1133 && sym->st_size <= (unsigned) bfd_get_gp_size (abfd))
1134 {
1135 /* Common symbols less than or equal to -G nn bytes are
1136 automatically put into .sbss. */
1137
1138 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1139
1140 if (scomm == NULL)
1141 {
1142 scomm = bfd_make_section (abfd, ".scommon");
1143 if (scomm == NULL
1144 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1145 | SEC_IS_COMMON
1146 | SEC_LINKER_CREATED)))
1147 return false;
1148 }
1149
1150 *secp = scomm;
1151 *valp = sym->st_size;
1152 }
1153
1154 return true;
1155 }
1156
1157 static boolean
1158 elfNN_ia64_aix_vec (const bfd_target *vec)
1159 {
1160 extern const bfd_target bfd_elfNN_ia64_aix_little_vec;
1161 extern const bfd_target bfd_elfNN_ia64_aix_big_vec;
1162
1163 return (/**/vec == & bfd_elfNN_ia64_aix_little_vec
1164 || vec == & bfd_elfNN_ia64_aix_big_vec);
1165 }
1166
1167 /* Hook called by the linker routine which adds symbols from an object
1168 file. We use it to handle OS-specific symbols. */
1169
1170 static boolean
1171 elfNN_ia64_aix_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1172 bfd *abfd;
1173 struct bfd_link_info *info;
1174 const Elf_Internal_Sym *sym;
1175 const char **namep;
1176 flagword *flagsp;
1177 asection **secp;
1178 bfd_vma *valp;
1179 {
1180 if (strcmp (*namep, "__GLOB_DATA_PTR") == 0)
1181 {
1182 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1183 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1184 no one else should use it b/c it is undocumented. */
1185 struct elf_link_hash_entry *h;
1186
1187 h = (struct elf_link_hash_entry *) bfd_link_hash_lookup (info->hash, *namep, false, false, false);
1188 if (h == NULL)
1189 {
1190 struct elf_backend_data *bed;
1191 struct elfNN_ia64_link_hash_table *ia64_info;
1192
1193 bed = get_elf_backend_data (abfd);
1194 ia64_info = elfNN_ia64_hash_table (info);
1195
1196 if (!(_bfd_generic_link_add_one_symbol
1197 (info, abfd, *namep, BSF_GLOBAL,
1198 bfd_get_section_by_name (abfd, ".bss"),
1199 bed->got_symbol_offset, (const char *) NULL, false,
1200 bed->collect, (struct bfd_link_hash_entry **) &h)))
1201 return false;
1202
1203 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1204 h->type = STT_OBJECT;
1205
1206 if (! _bfd_elf_link_record_dynamic_symbol (info, h))
1207 return false;
1208 }
1209
1210 return true;
1211 }
1212 else if (sym->st_shndx == SHN_LOOS)
1213 {
1214 int i;
1215
1216 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1217 is only relevant when compiling code for extended system calls.
1218 Replace the "special" section with .text, if possible.
1219 Note that these symbols are always assumed to be in .text. */
1220 for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++)
1221 {
1222 asection * sec = bfd_section_from_elf_index (abfd, i);
1223
1224 if (sec && strcmp (sec->name, ".text") == 0)
1225 {
1226 *secp = sec;
1227 break;
1228 }
1229 }
1230
1231 if (*secp == NULL)
1232 *secp = bfd_abs_section_ptr;
1233
1234 *valp = sym->st_size;
1235
1236 return true;
1237 }
1238 else
1239 {
1240 return elfNN_ia64_add_symbol_hook (abfd, info, sym,
1241 namep, flagsp, secp, valp);
1242 }
1243 }
1244
1245 boolean
1246 elfNN_ia64_aix_link_add_symbols (abfd, info)
1247 bfd *abfd;
1248 struct bfd_link_info *info;
1249 {
1250 /* Make sure dynamic sections are always created. */
1251 if (! elf_hash_table (info)->dynamic_sections_created
1252 && abfd->xvec == info->hash->creator)
1253 {
1254 if (! bfd_elfNN_link_create_dynamic_sections (abfd, info))
1255 return false;
1256 }
1257
1258 /* Now do the standard call. */
1259 return bfd_elfNN_bfd_link_add_symbols (abfd, info);
1260 }
1261
1262 /* Return the number of additional phdrs we will need. */
1263
1264 static int
1265 elfNN_ia64_additional_program_headers (abfd)
1266 bfd *abfd;
1267 {
1268 asection *s;
1269 int ret = 0;
1270
1271 /* See if we need a PT_IA_64_ARCHEXT segment. */
1272 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1273 if (s && (s->flags & SEC_LOAD))
1274 ++ret;
1275
1276 /* Count how many PT_IA_64_UNWIND segments we need. */
1277 for (s = abfd->sections; s; s = s->next)
1278 if (is_unwind_section_name(s->name) && (s->flags & SEC_LOAD))
1279 ++ret;
1280
1281 return ret;
1282 }
1283
1284 static boolean
1285 elfNN_ia64_modify_segment_map (abfd)
1286 bfd *abfd;
1287 {
1288 struct elf_segment_map *m, **pm;
1289 Elf_Internal_Shdr *hdr;
1290 asection *s;
1291
1292 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1293 all PT_LOAD segments. */
1294 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1295 if (s && (s->flags & SEC_LOAD))
1296 {
1297 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1298 if (m->p_type == PT_IA_64_ARCHEXT)
1299 break;
1300 if (m == NULL)
1301 {
1302 m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1303 if (m == NULL)
1304 return false;
1305
1306 m->p_type = PT_IA_64_ARCHEXT;
1307 m->count = 1;
1308 m->sections[0] = s;
1309
1310 /* We want to put it after the PHDR and INTERP segments. */
1311 pm = &elf_tdata (abfd)->segment_map;
1312 while (*pm != NULL
1313 && ((*pm)->p_type == PT_PHDR
1314 || (*pm)->p_type == PT_INTERP))
1315 pm = &(*pm)->next;
1316
1317 m->next = *pm;
1318 *pm = m;
1319 }
1320 }
1321
1322 /* Install PT_IA_64_UNWIND segments, if needed. */
1323 for (s = abfd->sections; s; s = s->next)
1324 {
1325 hdr = &elf_section_data (s)->this_hdr;
1326 if (hdr->sh_type != SHT_IA_64_UNWIND)
1327 continue;
1328
1329 if (s && (s->flags & SEC_LOAD))
1330 {
1331 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1332 if (m->p_type == PT_IA_64_UNWIND && m->sections[0] == s)
1333 break;
1334
1335 if (m == NULL)
1336 {
1337 m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1338 if (m == NULL)
1339 return false;
1340
1341 m->p_type = PT_IA_64_UNWIND;
1342 m->count = 1;
1343 m->sections[0] = s;
1344 m->next = NULL;
1345
1346 /* We want to put it last. */
1347 pm = &elf_tdata (abfd)->segment_map;
1348 while (*pm != NULL)
1349 pm = &(*pm)->next;
1350 *pm = m;
1351 }
1352 }
1353 }
1354
1355 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1356 the input sections for each output section in the segment and testing
1357 for SHF_IA_64_NORECOV on each. */
1358 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1359 if (m->p_type == PT_LOAD)
1360 {
1361 int i;
1362 for (i = m->count - 1; i >= 0; --i)
1363 {
1364 struct bfd_link_order *order = m->sections[i]->link_order_head;
1365 while (order)
1366 {
1367 if (order->type == bfd_indirect_link_order)
1368 {
1369 asection *is = order->u.indirect.section;
1370 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1371 if (flags & SHF_IA_64_NORECOV)
1372 {
1373 m->p_flags |= PF_IA_64_NORECOV;
1374 goto found;
1375 }
1376 }
1377 order = order->next;
1378 }
1379 }
1380 found:;
1381 }
1382
1383 return true;
1384 }
1385
1386 /* According to the Tahoe assembler spec, all labels starting with a
1387 '.' are local. */
1388
1389 static boolean
1390 elfNN_ia64_is_local_label_name (abfd, name)
1391 bfd *abfd ATTRIBUTE_UNUSED;
1392 const char *name;
1393 {
1394 return name[0] == '.';
1395 }
1396
1397 /* Should we do dynamic things to this symbol? */
1398
1399 static boolean
1400 elfNN_ia64_dynamic_symbol_p (h, info)
1401 struct elf_link_hash_entry *h;
1402 struct bfd_link_info *info;
1403 {
1404 if (h == NULL)
1405 return false;
1406
1407 while (h->root.type == bfd_link_hash_indirect
1408 || h->root.type == bfd_link_hash_warning)
1409 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1410
1411 if (h->dynindx == -1)
1412 return false;
1413 switch (ELF_ST_VISIBILITY (h->other))
1414 {
1415 case STV_INTERNAL:
1416 case STV_HIDDEN:
1417 return false;
1418 }
1419
1420 if (h->root.type == bfd_link_hash_undefweak
1421 || h->root.type == bfd_link_hash_defweak)
1422 return true;
1423
1424 if ((info->shared && !info->symbolic)
1425 || ((h->elf_link_hash_flags
1426 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1427 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1428 return true;
1429
1430 return false;
1431 }
1432 \f
1433 static boolean
1434 elfNN_ia64_local_hash_table_init (ht, abfd, new)
1435 struct elfNN_ia64_local_hash_table *ht;
1436 bfd *abfd ATTRIBUTE_UNUSED;
1437 new_hash_entry_func new;
1438 {
1439 memset (ht, 0, sizeof (*ht));
1440 return bfd_hash_table_init (&ht->root, new);
1441 }
1442
1443 static struct bfd_hash_entry*
1444 elfNN_ia64_new_loc_hash_entry (entry, table, string)
1445 struct bfd_hash_entry *entry;
1446 struct bfd_hash_table *table;
1447 const char *string;
1448 {
1449 struct elfNN_ia64_local_hash_entry *ret;
1450 ret = (struct elfNN_ia64_local_hash_entry *) entry;
1451
1452 /* Allocate the structure if it has not already been allocated by a
1453 subclass. */
1454 if (!ret)
1455 ret = bfd_hash_allocate (table, sizeof (*ret));
1456
1457 if (!ret)
1458 return 0;
1459
1460 /* Initialize our local data. All zeros, and definitely easier
1461 than setting a handful of bit fields. */
1462 memset (ret, 0, sizeof (*ret));
1463
1464 /* Call the allocation method of the superclass. */
1465 ret = ((struct elfNN_ia64_local_hash_entry *)
1466 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1467
1468 return (struct bfd_hash_entry *) ret;
1469 }
1470
1471 static struct bfd_hash_entry*
1472 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1473 struct bfd_hash_entry *entry;
1474 struct bfd_hash_table *table;
1475 const char *string;
1476 {
1477 struct elfNN_ia64_link_hash_entry *ret;
1478 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1479
1480 /* Allocate the structure if it has not already been allocated by a
1481 subclass. */
1482 if (!ret)
1483 ret = bfd_hash_allocate (table, sizeof (*ret));
1484
1485 if (!ret)
1486 return 0;
1487
1488 /* Initialize our local data. All zeros, and definitely easier
1489 than setting a handful of bit fields. */
1490 memset (ret, 0, sizeof (*ret));
1491
1492 /* Call the allocation method of the superclass. */
1493 ret = ((struct elfNN_ia64_link_hash_entry *)
1494 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1495 table, string));
1496
1497 return (struct bfd_hash_entry *) ret;
1498 }
1499
1500 static void
1501 elfNN_ia64_hash_copy_indirect (xdir, xind)
1502 struct elf_link_hash_entry *xdir, *xind;
1503 {
1504 struct elfNN_ia64_link_hash_entry *dir, *ind;
1505
1506 dir = (struct elfNN_ia64_link_hash_entry *)xdir;
1507 ind = (struct elfNN_ia64_link_hash_entry *)xind;
1508
1509 /* Copy down any references that we may have already seen to the
1510 symbol which just became indirect. */
1511
1512 dir->root.elf_link_hash_flags |=
1513 (ind->root.elf_link_hash_flags
1514 & (ELF_LINK_HASH_REF_DYNAMIC
1515 | ELF_LINK_HASH_REF_REGULAR
1516 | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1517
1518 /* Copy over the got and plt data. This would have been done
1519 by check_relocs. */
1520
1521 if (dir->info == NULL)
1522 {
1523 struct elfNN_ia64_dyn_sym_info *dyn_i;
1524
1525 dir->info = dyn_i = ind->info;
1526 ind->info = NULL;
1527
1528 /* Fix up the dyn_sym_info pointers to the global symbol. */
1529 for (; dyn_i; dyn_i = dyn_i->next)
1530 dyn_i->h = &dir->root;
1531 }
1532 BFD_ASSERT (ind->info == NULL);
1533
1534 /* Copy over the dynindx. */
1535
1536 if (dir->root.dynindx == -1)
1537 {
1538 dir->root.dynindx = ind->root.dynindx;
1539 dir->root.dynstr_index = ind->root.dynstr_index;
1540 ind->root.dynindx = -1;
1541 ind->root.dynstr_index = 0;
1542 }
1543 BFD_ASSERT (ind->root.dynindx == -1);
1544 }
1545
1546 static void
1547 elfNN_ia64_hash_hide_symbol (info, xh)
1548 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1549 struct elf_link_hash_entry *xh;
1550 {
1551 struct elfNN_ia64_link_hash_entry *h;
1552 struct elfNN_ia64_dyn_sym_info *dyn_i;
1553
1554 h = (struct elfNN_ia64_link_hash_entry *)xh;
1555
1556 h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
1557 if ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
1558 h->root.dynindx = -1;
1559
1560 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1561 dyn_i->want_plt2 = 0;
1562 }
1563
1564 /* Create the derived linker hash table. The IA-64 ELF port uses this
1565 derived hash table to keep information specific to the IA-64 ElF
1566 linker (without using static variables). */
1567
1568 static struct bfd_link_hash_table*
1569 elfNN_ia64_hash_table_create (abfd)
1570 bfd *abfd;
1571 {
1572 struct elfNN_ia64_link_hash_table *ret;
1573
1574 ret = bfd_alloc (abfd, sizeof (*ret));
1575 if (!ret)
1576 return 0;
1577 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1578 elfNN_ia64_new_elf_hash_entry))
1579 {
1580 bfd_release (abfd, ret);
1581 return 0;
1582 }
1583
1584 if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1585 elfNN_ia64_new_loc_hash_entry))
1586 return 0;
1587 return &ret->root.root;
1588 }
1589
1590 /* Look up an entry in a Alpha ELF linker hash table. */
1591
1592 static INLINE struct elfNN_ia64_local_hash_entry *
1593 elfNN_ia64_local_hash_lookup(table, string, create, copy)
1594 struct elfNN_ia64_local_hash_table *table;
1595 const char *string;
1596 boolean create, copy;
1597 {
1598 return ((struct elfNN_ia64_local_hash_entry *)
1599 bfd_hash_lookup (&table->root, string, create, copy));
1600 }
1601
1602 /* Traverse both local and global hash tables. */
1603
1604 struct elfNN_ia64_dyn_sym_traverse_data
1605 {
1606 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1607 PTR data;
1608 };
1609
1610 static boolean
1611 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1612 struct bfd_hash_entry *xentry;
1613 PTR xdata;
1614 {
1615 struct elfNN_ia64_link_hash_entry *entry
1616 = (struct elfNN_ia64_link_hash_entry *) xentry;
1617 struct elfNN_ia64_dyn_sym_traverse_data *data
1618 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1619 struct elfNN_ia64_dyn_sym_info *dyn_i;
1620
1621 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1622 if (! (*data->func) (dyn_i, data->data))
1623 return false;
1624 return true;
1625 }
1626
1627 static boolean
1628 elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1629 struct bfd_hash_entry *xentry;
1630 PTR xdata;
1631 {
1632 struct elfNN_ia64_local_hash_entry *entry
1633 = (struct elfNN_ia64_local_hash_entry *) xentry;
1634 struct elfNN_ia64_dyn_sym_traverse_data *data
1635 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1636 struct elfNN_ia64_dyn_sym_info *dyn_i;
1637
1638 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1639 if (! (*data->func) (dyn_i, data->data))
1640 return false;
1641 return true;
1642 }
1643
1644 static void
1645 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1646 struct elfNN_ia64_link_hash_table *ia64_info;
1647 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1648 PTR data;
1649 {
1650 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1651
1652 xdata.func = func;
1653 xdata.data = data;
1654
1655 elf_link_hash_traverse (&ia64_info->root,
1656 elfNN_ia64_global_dyn_sym_thunk, &xdata);
1657 bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1658 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1659 }
1660 \f
1661 static boolean
1662 elfNN_ia64_create_dynamic_sections (abfd, info)
1663 bfd *abfd;
1664 struct bfd_link_info *info;
1665 {
1666 struct elfNN_ia64_link_hash_table *ia64_info;
1667 asection *s;
1668
1669 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1670 return false;
1671
1672 ia64_info = elfNN_ia64_hash_table (info);
1673
1674 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1675 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1676
1677 {
1678 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1679 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1680 }
1681
1682 if (!get_pltoff (abfd, info, ia64_info))
1683 return false;
1684
1685 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1686 if (s == NULL
1687 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1688 | SEC_HAS_CONTENTS
1689 | SEC_IN_MEMORY
1690 | SEC_LINKER_CREATED
1691 | SEC_READONLY))
1692 || !bfd_set_section_alignment (abfd, s, 3))
1693 return false;
1694 ia64_info->rel_pltoff_sec = s;
1695
1696 s = bfd_make_section(abfd, ".rela.got");
1697 if (s == NULL
1698 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1699 | SEC_HAS_CONTENTS
1700 | SEC_IN_MEMORY
1701 | SEC_LINKER_CREATED
1702 | SEC_READONLY))
1703 || !bfd_set_section_alignment (abfd, s, 3))
1704 return false;
1705 ia64_info->rel_got_sec = s;
1706
1707 return true;
1708 }
1709
1710 /* Find and/or create a descriptor for dynamic symbol info. This will
1711 vary based on global or local symbol, and the addend to the reloc. */
1712
1713 static struct elfNN_ia64_dyn_sym_info *
1714 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1715 struct elfNN_ia64_link_hash_table *ia64_info;
1716 struct elf_link_hash_entry *h;
1717 bfd *abfd;
1718 const Elf_Internal_Rela *rel;
1719 boolean create;
1720 {
1721 struct elfNN_ia64_dyn_sym_info **pp;
1722 struct elfNN_ia64_dyn_sym_info *dyn_i;
1723 bfd_vma addend = rel ? rel->r_addend : 0;
1724
1725 if (h)
1726 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1727 else
1728 {
1729 struct elfNN_ia64_local_hash_entry *loc_h;
1730 char *addr_name;
1731 size_t len;
1732
1733 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1734 The name describes what was once anonymous memory. */
1735
1736 len = sizeof (void*)*2 + 1 + sizeof (bfd_vma)*4 + 1 + 1;
1737 len += 10; /* %p slop */
1738
1739 addr_name = alloca (len);
1740 sprintf (addr_name, "%p:%lx",
1741 (void *) abfd, (unsigned long) ELFNN_R_SYM (rel->r_info));
1742
1743 /* Collect the canonical entry data for this address. */
1744 loc_h = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1745 addr_name, create, create);
1746 BFD_ASSERT (loc_h);
1747
1748 pp = &loc_h->info;
1749 }
1750
1751 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1752 pp = &dyn_i->next;
1753
1754 if (dyn_i == NULL && create)
1755 {
1756 dyn_i = (struct elfNN_ia64_dyn_sym_info *)
1757 bfd_zalloc (abfd, sizeof *dyn_i);
1758 *pp = dyn_i;
1759 dyn_i->addend = addend;
1760 }
1761
1762 return dyn_i;
1763 }
1764
1765 static asection *
1766 get_got (abfd, info, ia64_info)
1767 bfd *abfd;
1768 struct bfd_link_info *info;
1769 struct elfNN_ia64_link_hash_table *ia64_info;
1770 {
1771 asection *got;
1772 bfd *dynobj;
1773
1774 got = ia64_info->got_sec;
1775 if (!got)
1776 {
1777 flagword flags;
1778
1779 dynobj = ia64_info->root.dynobj;
1780 if (!dynobj)
1781 ia64_info->root.dynobj = dynobj = abfd;
1782 if (!_bfd_elf_create_got_section (dynobj, info))
1783 return 0;
1784
1785 got = bfd_get_section_by_name (dynobj, ".got");
1786 BFD_ASSERT (got);
1787 ia64_info->got_sec = got;
1788
1789 flags = bfd_get_section_flags (abfd, got);
1790 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1791 }
1792
1793 return got;
1794 }
1795
1796 /* Create function descriptor section (.opd). This section is called .opd
1797 because it contains "official prodecure descriptors". The "official"
1798 refers to the fact that these descriptors are used when taking the address
1799 of a procedure, thus ensuring a unique address for each procedure. */
1800
1801 static asection *
1802 get_fptr (abfd, info, ia64_info)
1803 bfd *abfd;
1804 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1805 struct elfNN_ia64_link_hash_table *ia64_info;
1806 {
1807 asection *fptr;
1808 bfd *dynobj;
1809
1810 fptr = ia64_info->fptr_sec;
1811 if (!fptr)
1812 {
1813 dynobj = ia64_info->root.dynobj;
1814 if (!dynobj)
1815 ia64_info->root.dynobj = dynobj = abfd;
1816
1817 fptr = bfd_make_section (dynobj, ".opd");
1818 if (!fptr
1819 || !bfd_set_section_flags (dynobj, fptr,
1820 (SEC_ALLOC
1821 | SEC_LOAD
1822 | SEC_HAS_CONTENTS
1823 | SEC_IN_MEMORY
1824 | SEC_READONLY
1825 | SEC_LINKER_CREATED))
1826 || !bfd_set_section_alignment (abfd, fptr, 4))
1827 {
1828 BFD_ASSERT (0);
1829 return NULL;
1830 }
1831
1832 ia64_info->fptr_sec = fptr;
1833 }
1834
1835 return fptr;
1836 }
1837
1838 static asection *
1839 get_pltoff (abfd, info, ia64_info)
1840 bfd *abfd;
1841 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1842 struct elfNN_ia64_link_hash_table *ia64_info;
1843 {
1844 asection *pltoff;
1845 bfd *dynobj;
1846
1847 pltoff = ia64_info->pltoff_sec;
1848 if (!pltoff)
1849 {
1850 dynobj = ia64_info->root.dynobj;
1851 if (!dynobj)
1852 ia64_info->root.dynobj = dynobj = abfd;
1853
1854 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
1855 if (!pltoff
1856 || !bfd_set_section_flags (dynobj, pltoff,
1857 (SEC_ALLOC
1858 | SEC_LOAD
1859 | SEC_HAS_CONTENTS
1860 | SEC_IN_MEMORY
1861 | SEC_SMALL_DATA
1862 | SEC_LINKER_CREATED))
1863 || !bfd_set_section_alignment (abfd, pltoff, 4))
1864 {
1865 BFD_ASSERT (0);
1866 return NULL;
1867 }
1868
1869 ia64_info->pltoff_sec = pltoff;
1870 }
1871
1872 return pltoff;
1873 }
1874
1875 static asection *
1876 get_reloc_section (abfd, ia64_info, sec, create)
1877 bfd *abfd;
1878 struct elfNN_ia64_link_hash_table *ia64_info;
1879 asection *sec;
1880 boolean create;
1881 {
1882 const char *srel_name;
1883 asection *srel;
1884 bfd *dynobj;
1885
1886 srel_name = (bfd_elf_string_from_elf_section
1887 (abfd, elf_elfheader(abfd)->e_shstrndx,
1888 elf_section_data(sec)->rel_hdr.sh_name));
1889 if (srel_name == NULL)
1890 return NULL;
1891
1892 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
1893 && strcmp (bfd_get_section_name (abfd, sec),
1894 srel_name+5) == 0)
1895 || (strncmp (srel_name, ".rel", 4) == 0
1896 && strcmp (bfd_get_section_name (abfd, sec),
1897 srel_name+4) == 0));
1898
1899 dynobj = ia64_info->root.dynobj;
1900 if (!dynobj)
1901 ia64_info->root.dynobj = dynobj = abfd;
1902
1903 srel = bfd_get_section_by_name (dynobj, srel_name);
1904 if (srel == NULL && create)
1905 {
1906 srel = bfd_make_section (dynobj, srel_name);
1907 if (srel == NULL
1908 || !bfd_set_section_flags (dynobj, srel,
1909 (SEC_ALLOC
1910 | SEC_LOAD
1911 | SEC_HAS_CONTENTS
1912 | SEC_IN_MEMORY
1913 | SEC_LINKER_CREATED
1914 | SEC_READONLY))
1915 || !bfd_set_section_alignment (dynobj, srel, 3))
1916 return NULL;
1917 }
1918
1919 return srel;
1920 }
1921
1922 static boolean
1923 count_dyn_reloc (abfd, dyn_i, srel, type)
1924 bfd *abfd;
1925 struct elfNN_ia64_dyn_sym_info *dyn_i;
1926 asection *srel;
1927 int type;
1928 {
1929 struct elfNN_ia64_dyn_reloc_entry *rent;
1930
1931 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
1932 if (rent->srel == srel && rent->type == type)
1933 break;
1934
1935 if (!rent)
1936 {
1937 rent = (struct elfNN_ia64_dyn_reloc_entry *)
1938 bfd_alloc (abfd, sizeof (*rent));
1939 if (!rent)
1940 return false;
1941
1942 rent->next = dyn_i->reloc_entries;
1943 rent->srel = srel;
1944 rent->type = type;
1945 rent->count = 0;
1946 dyn_i->reloc_entries = rent;
1947 }
1948 rent->count++;
1949
1950 return true;
1951 }
1952
1953 static boolean
1954 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
1955 bfd *abfd;
1956 struct bfd_link_info *info;
1957 asection *sec;
1958 const Elf_Internal_Rela *relocs;
1959 {
1960 struct elfNN_ia64_link_hash_table *ia64_info;
1961 const Elf_Internal_Rela *relend;
1962 Elf_Internal_Shdr *symtab_hdr;
1963 const Elf_Internal_Rela *rel;
1964 asection *got, *fptr, *srel;
1965
1966 if (info->relocateable)
1967 return true;
1968
1969 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1970 ia64_info = elfNN_ia64_hash_table (info);
1971
1972 got = fptr = srel = NULL;
1973
1974 relend = relocs + sec->reloc_count;
1975 for (rel = relocs; rel < relend; ++rel)
1976 {
1977 enum {
1978 NEED_GOT = 1,
1979 NEED_FPTR = 2,
1980 NEED_PLTOFF = 4,
1981 NEED_MIN_PLT = 8,
1982 NEED_FULL_PLT = 16,
1983 NEED_DYNREL = 32,
1984 NEED_LTOFF_FPTR = 64,
1985 };
1986
1987 struct elf_link_hash_entry *h = NULL;
1988 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
1989 struct elfNN_ia64_dyn_sym_info *dyn_i;
1990 int need_entry;
1991 boolean maybe_dynamic;
1992 int dynrel_type = R_IA64_NONE;
1993
1994 if (r_symndx >= symtab_hdr->sh_info)
1995 {
1996 /* We're dealing with a global symbol -- find its hash entry
1997 and mark it as being referenced. */
1998 long indx = r_symndx - symtab_hdr->sh_info;
1999 h = elf_sym_hashes (abfd)[indx];
2000 while (h->root.type == bfd_link_hash_indirect
2001 || h->root.type == bfd_link_hash_warning)
2002 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2003
2004 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2005 }
2006
2007 /* We can only get preliminary data on whether a symbol is
2008 locally or externally defined, as not all of the input files
2009 have yet been processed. Do something with what we know, as
2010 this may help reduce memory usage and processing time later. */
2011 maybe_dynamic = false;
2012 if (h && ((info->shared && ! info->symbolic)
2013 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
2014 || h->root.type == bfd_link_hash_defweak
2015 || elfNN_ia64_aix_vec (abfd->xvec)))
2016 maybe_dynamic = true;
2017
2018 need_entry = 0;
2019 switch (ELFNN_R_TYPE (rel->r_info))
2020 {
2021 case R_IA64_TPREL22:
2022 case R_IA64_TPREL64MSB:
2023 case R_IA64_TPREL64LSB:
2024 case R_IA64_LTOFF_TP22:
2025 return false;
2026
2027 case R_IA64_LTOFF_FPTR22:
2028 case R_IA64_LTOFF_FPTR64I:
2029 case R_IA64_LTOFF_FPTR32MSB:
2030 case R_IA64_LTOFF_FPTR32LSB:
2031 case R_IA64_LTOFF_FPTR64MSB:
2032 case R_IA64_LTOFF_FPTR64LSB:
2033 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2034 break;
2035
2036 case R_IA64_FPTR64I:
2037 case R_IA64_FPTR32MSB:
2038 case R_IA64_FPTR32LSB:
2039 case R_IA64_FPTR64MSB:
2040 case R_IA64_FPTR64LSB:
2041 if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
2042 need_entry = NEED_FPTR | NEED_DYNREL;
2043 else
2044 need_entry = NEED_FPTR;
2045 dynrel_type = R_IA64_FPTR64LSB;
2046 break;
2047
2048 case R_IA64_LTOFF22:
2049 case R_IA64_LTOFF22X:
2050 case R_IA64_LTOFF64I:
2051 need_entry = NEED_GOT;
2052 break;
2053
2054 case R_IA64_PLTOFF22:
2055 case R_IA64_PLTOFF64I:
2056 case R_IA64_PLTOFF64MSB:
2057 case R_IA64_PLTOFF64LSB:
2058 need_entry = NEED_PLTOFF;
2059 if (h)
2060 {
2061 if (maybe_dynamic)
2062 need_entry |= NEED_MIN_PLT;
2063 }
2064 else
2065 {
2066 (*info->callbacks->warning)
2067 (info, _("@pltoff reloc against local symbol"), 0,
2068 abfd, 0, 0);
2069 }
2070 break;
2071
2072 case R_IA64_PCREL21B:
2073 case R_IA64_PCREL60B:
2074 /* Depending on where this symbol is defined, we may or may not
2075 need a full plt entry. Only skip if we know we'll not need
2076 the entry -- static or symbolic, and the symbol definition
2077 has already been seen. */
2078 if (maybe_dynamic && rel->r_addend == 0)
2079 need_entry = NEED_FULL_PLT;
2080 break;
2081
2082 case R_IA64_IMM14:
2083 case R_IA64_IMM22:
2084 case R_IA64_IMM64:
2085 case R_IA64_DIR32MSB:
2086 case R_IA64_DIR32LSB:
2087 case R_IA64_DIR64MSB:
2088 case R_IA64_DIR64LSB:
2089 /* Shared objects will always need at least a REL relocation. */
2090 if (info->shared || maybe_dynamic
2091 || (elfNN_ia64_aix_vec (abfd->xvec)
2092 && (!h || strcmp (h->root.root.string,
2093 "__GLOB_DATA_PTR") != 0)))
2094 need_entry = NEED_DYNREL;
2095 dynrel_type = R_IA64_DIR64LSB;
2096 break;
2097
2098 case R_IA64_IPLTMSB:
2099 case R_IA64_IPLTLSB:
2100 /* Shared objects will always need at least a REL relocation. */
2101 if (info->shared || maybe_dynamic)
2102 need_entry = NEED_DYNREL;
2103 dynrel_type = R_IA64_IPLTLSB;
2104 break;
2105
2106 case R_IA64_PCREL22:
2107 case R_IA64_PCREL64I:
2108 case R_IA64_PCREL32MSB:
2109 case R_IA64_PCREL32LSB:
2110 case R_IA64_PCREL64MSB:
2111 case R_IA64_PCREL64LSB:
2112 if (maybe_dynamic)
2113 need_entry = NEED_DYNREL;
2114 dynrel_type = R_IA64_PCREL64LSB;
2115 break;
2116 }
2117
2118 if (!need_entry)
2119 continue;
2120
2121 if ((need_entry & NEED_FPTR) != 0
2122 && rel->r_addend)
2123 {
2124 (*info->callbacks->warning)
2125 (info, _("non-zero addend in @fptr reloc"), 0,
2126 abfd, 0, 0);
2127 }
2128
2129 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
2130
2131 /* Record whether or not this is a local symbol. */
2132 dyn_i->h = h;
2133
2134 /* Create what's needed. */
2135 if (need_entry & NEED_GOT)
2136 {
2137 if (!got)
2138 {
2139 got = get_got (abfd, info, ia64_info);
2140 if (!got)
2141 return false;
2142 }
2143 dyn_i->want_got = 1;
2144 }
2145 if (need_entry & NEED_FPTR)
2146 {
2147 if (!fptr)
2148 {
2149 fptr = get_fptr (abfd, info, ia64_info);
2150 if (!fptr)
2151 return false;
2152 }
2153
2154 /* FPTRs for shared libraries are allocated by the dynamic
2155 linker. Make sure this local symbol will appear in the
2156 dynamic symbol table. */
2157 if (!h && (info->shared
2158 /* AIX also needs one */
2159 || elfNN_ia64_aix_vec (abfd->xvec)))
2160 {
2161 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2162 (info, abfd, r_symndx)))
2163 return false;
2164 }
2165
2166 dyn_i->want_fptr = 1;
2167 }
2168 if (need_entry & NEED_LTOFF_FPTR)
2169 dyn_i->want_ltoff_fptr = 1;
2170 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2171 {
2172 if (!ia64_info->root.dynobj)
2173 ia64_info->root.dynobj = abfd;
2174 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2175 dyn_i->want_plt = 1;
2176 }
2177 if (need_entry & NEED_FULL_PLT)
2178 dyn_i->want_plt2 = 1;
2179 if (need_entry & NEED_PLTOFF)
2180 dyn_i->want_pltoff = 1;
2181 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2182 {
2183 if (!srel)
2184 {
2185 srel = get_reloc_section (abfd, ia64_info, sec, true);
2186 if (!srel)
2187 return false;
2188 }
2189 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2190 return false;
2191 }
2192 }
2193
2194 return true;
2195 }
2196
2197 struct elfNN_ia64_allocate_data
2198 {
2199 struct bfd_link_info *info;
2200 bfd_size_type ofs;
2201 };
2202
2203 /* For cleanliness, and potentially faster dynamic loading, allocate
2204 external GOT entries first. */
2205
2206 static boolean
2207 allocate_global_data_got (dyn_i, data)
2208 struct elfNN_ia64_dyn_sym_info *dyn_i;
2209 PTR data;
2210 {
2211 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2212
2213 if (dyn_i->want_got
2214 && ! dyn_i->want_fptr
2215 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2216 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2217 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2218 "__GLOB_DATA_PTR") != 0))))
2219 {
2220 dyn_i->got_offset = x->ofs;
2221 x->ofs += 8;
2222 }
2223 return true;
2224 }
2225
2226 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2227
2228 static boolean
2229 allocate_global_fptr_got (dyn_i, data)
2230 struct elfNN_ia64_dyn_sym_info *dyn_i;
2231 PTR data;
2232 {
2233 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2234
2235 if (dyn_i->want_got
2236 && dyn_i->want_fptr
2237 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2238 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2239 {
2240 dyn_i->got_offset = x->ofs;
2241 x->ofs += 8;
2242 }
2243 return true;
2244 }
2245
2246 /* Lastly, allocate all the GOT entries for local data. */
2247
2248 static boolean
2249 allocate_local_got (dyn_i, data)
2250 struct elfNN_ia64_dyn_sym_info *dyn_i;
2251 PTR data;
2252 {
2253 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2254
2255 if (dyn_i->want_got
2256 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2257 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2258 {
2259 dyn_i->got_offset = x->ofs;
2260 x->ofs += 8;
2261 }
2262 return true;
2263 }
2264
2265 /* Search for the index of a global symbol in it's defining object file. */
2266
2267 static unsigned long
2268 global_sym_index (h)
2269 struct elf_link_hash_entry *h;
2270 {
2271 struct elf_link_hash_entry **p;
2272 bfd *obj;
2273
2274 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2275 || h->root.type == bfd_link_hash_defweak);
2276
2277 obj = h->root.u.def.section->owner;
2278 for (p = elf_sym_hashes (obj); *p != h; ++p)
2279 continue;
2280
2281 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2282 }
2283
2284 /* Allocate function descriptors. We can do these for every function
2285 in a main executable that is not exported. */
2286
2287 static boolean
2288 allocate_fptr (dyn_i, data)
2289 struct elfNN_ia64_dyn_sym_info *dyn_i;
2290 PTR data;
2291 {
2292 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2293
2294 if (dyn_i->want_fptr)
2295 {
2296 struct elf_link_hash_entry *h = dyn_i->h;
2297
2298 if (h)
2299 while (h->root.type == bfd_link_hash_indirect
2300 || h->root.type == bfd_link_hash_warning)
2301 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2302
2303 if (x->info->shared
2304 /* AIX needs an FPTR in this case. */
2305 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2306 && (!h
2307 || h->root.type == bfd_link_hash_defined
2308 || h->root.type == bfd_link_hash_defweak)))
2309 {
2310 if (h && h->dynindx == -1)
2311 {
2312 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2313 || (h->root.type == bfd_link_hash_defweak));
2314
2315 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2316 (x->info, h->root.u.def.section->owner,
2317 global_sym_index (h)))
2318 return false;
2319 }
2320
2321 dyn_i->want_fptr = 0;
2322 }
2323 else if (h == NULL || h->dynindx == -1)
2324 {
2325 dyn_i->fptr_offset = x->ofs;
2326 x->ofs += 16;
2327 }
2328 else
2329 dyn_i->want_fptr = 0;
2330 }
2331 return true;
2332 }
2333
2334 /* Allocate all the minimal PLT entries. */
2335
2336 static boolean
2337 allocate_plt_entries (dyn_i, data)
2338 struct elfNN_ia64_dyn_sym_info *dyn_i;
2339 PTR data;
2340 {
2341 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2342
2343 if (dyn_i->want_plt)
2344 {
2345 struct elf_link_hash_entry *h = dyn_i->h;
2346
2347 if (h)
2348 while (h->root.type == bfd_link_hash_indirect
2349 || h->root.type == bfd_link_hash_warning)
2350 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2351
2352 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2353 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2354 {
2355 bfd_size_type offset = x->ofs;
2356 if (offset == 0)
2357 offset = PLT_HEADER_SIZE;
2358 dyn_i->plt_offset = offset;
2359 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2360
2361 dyn_i->want_pltoff = 1;
2362 }
2363 else
2364 {
2365 dyn_i->want_plt = 0;
2366 dyn_i->want_plt2 = 0;
2367 }
2368 }
2369 return true;
2370 }
2371
2372 /* Allocate all the full PLT entries. */
2373
2374 static boolean
2375 allocate_plt2_entries (dyn_i, data)
2376 struct elfNN_ia64_dyn_sym_info *dyn_i;
2377 PTR data;
2378 {
2379 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2380
2381 if (dyn_i->want_plt2)
2382 {
2383 struct elf_link_hash_entry *h = dyn_i->h;
2384 bfd_size_type ofs = x->ofs;
2385
2386 dyn_i->plt2_offset = ofs;
2387 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2388
2389 while (h->root.type == bfd_link_hash_indirect
2390 || h->root.type == bfd_link_hash_warning)
2391 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2392 dyn_i->h->plt.offset = ofs;
2393 }
2394 return true;
2395 }
2396
2397 /* Allocate all the PLTOFF entries requested by relocations and
2398 plt entries. We can't share space with allocated FPTR entries,
2399 because the latter are not necessarily addressable by the GP.
2400 ??? Relaxation might be able to determine that they are. */
2401
2402 static boolean
2403 allocate_pltoff_entries (dyn_i, data)
2404 struct elfNN_ia64_dyn_sym_info *dyn_i;
2405 PTR data;
2406 {
2407 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2408
2409 if (dyn_i->want_pltoff)
2410 {
2411 dyn_i->pltoff_offset = x->ofs;
2412 x->ofs += 16;
2413 }
2414 return true;
2415 }
2416
2417 /* Allocate dynamic relocations for those symbols that turned out
2418 to be dynamic. */
2419
2420 static boolean
2421 allocate_dynrel_entries (dyn_i, data)
2422 struct elfNN_ia64_dyn_sym_info *dyn_i;
2423 PTR data;
2424 {
2425 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2426 struct elfNN_ia64_link_hash_table *ia64_info;
2427 struct elfNN_ia64_dyn_reloc_entry *rent;
2428 boolean dynamic_symbol, shared;
2429
2430 ia64_info = elfNN_ia64_hash_table (x->info);
2431 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2432 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2433 /* Don't allocate an entry for __GLOB_DATA_PTR */
2434 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2435 "__GLOB_DATA_PTR") != 0));
2436 shared = x->info->shared;
2437
2438 /* Take care of the normal data relocations. */
2439
2440 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2441 {
2442 int count = rent->count;
2443
2444 switch (rent->type)
2445 {
2446 case R_IA64_FPTR64LSB:
2447 /* Allocate one iff !want_fptr, which by this point will
2448 be true only if we're actually allocating one statically
2449 in the main executable. */
2450 if (dyn_i->want_fptr)
2451 continue;
2452 break;
2453 case R_IA64_PCREL64LSB:
2454 if (!dynamic_symbol)
2455 continue;
2456 break;
2457 case R_IA64_DIR64LSB:
2458 if (!dynamic_symbol && !shared)
2459 continue;
2460 break;
2461 case R_IA64_IPLTLSB:
2462 if (!dynamic_symbol && !shared)
2463 continue;
2464 /* Use two REL relocations for IPLT relocations
2465 against local symbols. */
2466 if (!dynamic_symbol)
2467 count *= 2;
2468 break;
2469 default:
2470 abort ();
2471 }
2472 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2473 }
2474
2475 /* Take care of the GOT and PLT relocations. */
2476
2477 if (((dynamic_symbol || shared) && dyn_i->want_got)
2478 || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2479 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2480
2481 if (dyn_i->want_pltoff)
2482 {
2483 bfd_size_type t = 0;
2484
2485 /* Dynamic symbols get one IPLT relocation. Local symbols in
2486 shared libraries get two REL relocations. Local symbols in
2487 main applications get nothing. */
2488 if (dynamic_symbol)
2489 t = sizeof (ElfNN_External_Rela);
2490 else if (shared)
2491 t = 2 * sizeof (ElfNN_External_Rela);
2492
2493 ia64_info->rel_pltoff_sec->_raw_size += t;
2494 }
2495
2496 return true;
2497 }
2498
2499 static boolean
2500 elfNN_ia64_adjust_dynamic_symbol (info, h)
2501 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2502 struct elf_link_hash_entry *h;
2503 {
2504 /* ??? Undefined symbols with PLT entries should be re-defined
2505 to be the PLT entry. */
2506
2507 /* If this is a weak symbol, and there is a real definition, the
2508 processor independent code will have arranged for us to see the
2509 real definition first, and we can just use the same value. */
2510 if (h->weakdef != NULL)
2511 {
2512 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2513 || h->weakdef->root.type == bfd_link_hash_defweak);
2514 h->root.u.def.section = h->weakdef->root.u.def.section;
2515 h->root.u.def.value = h->weakdef->root.u.def.value;
2516 return true;
2517 }
2518
2519 /* If this is a reference to a symbol defined by a dynamic object which
2520 is not a function, we might allocate the symbol in our .dynbss section
2521 and allocate a COPY dynamic relocation.
2522
2523 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2524 of hackery. */
2525
2526 return true;
2527 }
2528
2529 static boolean
2530 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2531 bfd *output_bfd;
2532 struct bfd_link_info *info;
2533 {
2534 struct elfNN_ia64_allocate_data data;
2535 struct elfNN_ia64_link_hash_table *ia64_info;
2536 asection *sec;
2537 bfd *dynobj;
2538 boolean reltext = false;
2539 boolean relplt = false;
2540
2541 dynobj = elf_hash_table(info)->dynobj;
2542 ia64_info = elfNN_ia64_hash_table (info);
2543 BFD_ASSERT(dynobj != NULL);
2544 data.info = info;
2545
2546 /* Set the contents of the .interp section to the interpreter. */
2547 if (ia64_info->root.dynamic_sections_created
2548 && !info->shared)
2549 {
2550 sec = bfd_get_section_by_name (dynobj, ".interp");
2551 BFD_ASSERT (sec != NULL);
2552 sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd);
2553 sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1;
2554 }
2555
2556 /* Allocate the GOT entries. */
2557
2558 if (ia64_info->got_sec)
2559 {
2560 data.ofs = 0;
2561 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2562 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2563 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2564 ia64_info->got_sec->_raw_size = data.ofs;
2565 }
2566
2567 /* Allocate the FPTR entries. */
2568
2569 if (ia64_info->fptr_sec)
2570 {
2571 data.ofs = 0;
2572 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2573 ia64_info->fptr_sec->_raw_size = data.ofs;
2574 }
2575
2576 /* Now that we've seen all of the input files, we can decide which
2577 symbols need plt entries. Allocate the minimal PLT entries first.
2578 We do this even though dynamic_sections_created may be false, because
2579 this has the side-effect of clearing want_plt and want_plt2. */
2580
2581 data.ofs = 0;
2582 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2583
2584 ia64_info->minplt_entries = 0;
2585 if (data.ofs)
2586 {
2587 ia64_info->minplt_entries
2588 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2589 }
2590
2591 /* Align the pointer for the plt2 entries. */
2592 data.ofs = (data.ofs + 31) & -32;
2593
2594 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2595 if (data.ofs != 0)
2596 {
2597 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2598
2599 ia64_info->plt_sec->_raw_size = data.ofs;
2600
2601 /* If we've got a .plt, we need some extra memory for the dynamic
2602 linker. We stuff these in .got.plt. */
2603 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2604 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2605 }
2606
2607 /* Allocate the PLTOFF entries. */
2608
2609 if (ia64_info->pltoff_sec)
2610 {
2611 data.ofs = 0;
2612 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2613 ia64_info->pltoff_sec->_raw_size = data.ofs;
2614 }
2615
2616 if (ia64_info->root.dynamic_sections_created)
2617 {
2618 /* Allocate space for the dynamic relocations that turned out to be
2619 required. */
2620
2621 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2622 }
2623
2624 /* We have now determined the sizes of the various dynamic sections.
2625 Allocate memory for them. */
2626 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2627 {
2628 boolean strip;
2629
2630 if (!(sec->flags & SEC_LINKER_CREATED))
2631 continue;
2632
2633 /* If we don't need this section, strip it from the output file.
2634 There were several sections primarily related to dynamic
2635 linking that must be create before the linker maps input
2636 sections to output sections. The linker does that before
2637 bfd_elf_size_dynamic_sections is called, and it is that
2638 function which decides whether anything needs to go into
2639 these sections. */
2640
2641 strip = (sec->_raw_size == 0);
2642
2643 if (sec == ia64_info->got_sec)
2644 strip = false;
2645 else if (sec == ia64_info->rel_got_sec)
2646 {
2647 if (strip)
2648 ia64_info->rel_got_sec = NULL;
2649 else
2650 /* We use the reloc_count field as a counter if we need to
2651 copy relocs into the output file. */
2652 sec->reloc_count = 0;
2653 }
2654 else if (sec == ia64_info->fptr_sec)
2655 {
2656 if (strip)
2657 ia64_info->fptr_sec = NULL;
2658 }
2659 else if (sec == ia64_info->plt_sec)
2660 {
2661 if (strip)
2662 ia64_info->plt_sec = NULL;
2663 }
2664 else if (sec == ia64_info->pltoff_sec)
2665 {
2666 if (strip)
2667 ia64_info->pltoff_sec = NULL;
2668 }
2669 else if (sec == ia64_info->rel_pltoff_sec)
2670 {
2671 if (strip)
2672 ia64_info->rel_pltoff_sec = NULL;
2673 else
2674 {
2675 relplt = true;
2676 /* We use the reloc_count field as a counter if we need to
2677 copy relocs into the output file. */
2678 sec->reloc_count = 0;
2679 }
2680 }
2681 else
2682 {
2683 const char *name;
2684
2685 /* It's OK to base decisions on the section name, because none
2686 of the dynobj section names depend upon the input files. */
2687 name = bfd_get_section_name (dynobj, sec);
2688
2689 if (strcmp (name, ".got.plt") == 0)
2690 strip = false;
2691 else if (strncmp (name, ".rel", 4) == 0)
2692 {
2693 if (!strip)
2694 {
2695 const char *outname;
2696 asection *target;
2697
2698 /* If this relocation section applies to a read only
2699 section, then we probably need a DT_TEXTREL entry. */
2700 outname = bfd_get_section_name (output_bfd,
2701 sec->output_section);
2702 if (outname[4] == 'a')
2703 outname += 5;
2704 else
2705 outname += 4;
2706
2707 target = bfd_get_section_by_name (output_bfd, outname);
2708 if (target != NULL
2709 && (target->flags & SEC_READONLY) != 0
2710 && (target->flags & SEC_ALLOC) != 0)
2711 reltext = true;
2712
2713 /* We use the reloc_count field as a counter if we need to
2714 copy relocs into the output file. */
2715 sec->reloc_count = 0;
2716 }
2717 }
2718 else
2719 continue;
2720 }
2721
2722 if (strip)
2723 _bfd_strip_section_from_output (info, sec);
2724 else
2725 {
2726 /* Allocate memory for the section contents. */
2727 sec->contents = (bfd_byte *) bfd_zalloc(dynobj, sec->_raw_size);
2728 if (sec->contents == NULL && sec->_raw_size != 0)
2729 return false;
2730 }
2731 }
2732
2733 if (elf_hash_table (info)->dynamic_sections_created)
2734 {
2735 /* Add some entries to the .dynamic section. We fill in the values
2736 later (in finish_dynamic_sections) but we must add the entries now
2737 so that we get the correct size for the .dynamic section. */
2738
2739 if (!info->shared)
2740 {
2741 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2742 by the debugger. */
2743 if (!bfd_elfNN_add_dynamic_entry (info, DT_DEBUG, 0))
2744 return false;
2745 }
2746
2747 if (! bfd_elfNN_add_dynamic_entry (info, DT_IA_64_PLT_RESERVE, 0))
2748 return false;
2749 if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTGOT, 0))
2750 return false;
2751
2752 if (relplt)
2753 {
2754 if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2755 || ! bfd_elfNN_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2756 || ! bfd_elfNN_add_dynamic_entry (info, DT_JMPREL, 0))
2757 return false;
2758 }
2759
2760 if (! bfd_elfNN_add_dynamic_entry (info, DT_RELA, 0)
2761 || ! bfd_elfNN_add_dynamic_entry (info, DT_RELASZ, 0)
2762 || ! bfd_elfNN_add_dynamic_entry (info, DT_RELAENT,
2763 sizeof (ElfNN_External_Rela)))
2764 return false;
2765
2766 if (reltext)
2767 {
2768 if (! bfd_elfNN_add_dynamic_entry (info, DT_TEXTREL, 0))
2769 return false;
2770 info->flags |= DF_TEXTREL;
2771 }
2772 }
2773
2774 /* ??? Perhaps force __gp local. */
2775
2776 return true;
2777 }
2778
2779 static bfd_reloc_status_type
2780 elfNN_ia64_install_value (abfd, hit_addr, val, r_type)
2781 bfd *abfd;
2782 bfd_byte *hit_addr;
2783 bfd_vma val;
2784 unsigned int r_type;
2785 {
2786 const struct ia64_operand *op;
2787 int bigendian = 0, shift = 0;
2788 bfd_vma t0, t1, insn, dword;
2789 enum ia64_opnd opnd;
2790 const char *err;
2791 size_t size = 8;
2792
2793 opnd = IA64_OPND_NIL;
2794 switch (r_type)
2795 {
2796 case R_IA64_NONE:
2797 case R_IA64_LDXMOV:
2798 return bfd_reloc_ok;
2799
2800 /* Instruction relocations. */
2801
2802 case R_IA64_IMM14: opnd = IA64_OPND_IMM14; break;
2803
2804 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
2805 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
2806 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
2807 case R_IA64_PCREL21B:
2808 case R_IA64_PCREL21BI:
2809 opnd = IA64_OPND_TGT25c;
2810 break;
2811
2812 case R_IA64_IMM22:
2813 case R_IA64_GPREL22:
2814 case R_IA64_LTOFF22:
2815 case R_IA64_LTOFF22X:
2816 case R_IA64_PLTOFF22:
2817 case R_IA64_PCREL22:
2818 case R_IA64_LTOFF_FPTR22:
2819 opnd = IA64_OPND_IMM22;
2820 break;
2821
2822 case R_IA64_IMM64:
2823 case R_IA64_GPREL64I:
2824 case R_IA64_LTOFF64I:
2825 case R_IA64_PLTOFF64I:
2826 case R_IA64_PCREL64I:
2827 case R_IA64_FPTR64I:
2828 case R_IA64_LTOFF_FPTR64I:
2829 opnd = IA64_OPND_IMMU64;
2830 break;
2831
2832 /* Data relocations. */
2833
2834 case R_IA64_DIR32MSB:
2835 case R_IA64_GPREL32MSB:
2836 case R_IA64_FPTR32MSB:
2837 case R_IA64_PCREL32MSB:
2838 case R_IA64_LTOFF_FPTR32MSB:
2839 case R_IA64_SEGREL32MSB:
2840 case R_IA64_SECREL32MSB:
2841 case R_IA64_LTV32MSB:
2842 size = 4; bigendian = 1;
2843 break;
2844
2845 case R_IA64_DIR32LSB:
2846 case R_IA64_GPREL32LSB:
2847 case R_IA64_FPTR32LSB:
2848 case R_IA64_PCREL32LSB:
2849 case R_IA64_LTOFF_FPTR32LSB:
2850 case R_IA64_SEGREL32LSB:
2851 case R_IA64_SECREL32LSB:
2852 case R_IA64_LTV32LSB:
2853 size = 4; bigendian = 0;
2854 break;
2855
2856 case R_IA64_DIR64MSB:
2857 case R_IA64_GPREL64MSB:
2858 case R_IA64_PLTOFF64MSB:
2859 case R_IA64_FPTR64MSB:
2860 case R_IA64_PCREL64MSB:
2861 case R_IA64_LTOFF_FPTR64MSB:
2862 case R_IA64_SEGREL64MSB:
2863 case R_IA64_SECREL64MSB:
2864 case R_IA64_LTV64MSB:
2865 size = 8; bigendian = 1;
2866 break;
2867
2868 case R_IA64_DIR64LSB:
2869 case R_IA64_GPREL64LSB:
2870 case R_IA64_PLTOFF64LSB:
2871 case R_IA64_FPTR64LSB:
2872 case R_IA64_PCREL64LSB:
2873 case R_IA64_LTOFF_FPTR64LSB:
2874 case R_IA64_SEGREL64LSB:
2875 case R_IA64_SECREL64LSB:
2876 case R_IA64_LTV64LSB:
2877 size = 8; bigendian = 0;
2878 break;
2879
2880 /* Unsupported / Dynamic relocations. */
2881 default:
2882 return bfd_reloc_notsupported;
2883 }
2884
2885 switch (opnd)
2886 {
2887 case IA64_OPND_IMMU64:
2888 hit_addr -= (long) hit_addr & 0x3;
2889 t0 = bfd_get_64 (abfd, hit_addr);
2890 t1 = bfd_get_64 (abfd, hit_addr + 8);
2891
2892 /* tmpl/s: bits 0.. 5 in t0
2893 slot 0: bits 5..45 in t0
2894 slot 1: bits 46..63 in t0, bits 0..22 in t1
2895 slot 2: bits 23..63 in t1 */
2896
2897 /* First, clear the bits that form the 64 bit constant. */
2898 t0 &= ~(0x3ffffLL << 46);
2899 t1 &= ~(0x7fffffLL
2900 | (( (0x07fLL << 13) | (0x1ffLL << 27)
2901 | (0x01fLL << 22) | (0x001LL << 21)
2902 | (0x001LL << 36)) << 23));
2903
2904 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
2905 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
2906 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
2907 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
2908 | (((val >> 16) & 0x01f) << 22) /* imm5c */
2909 | (((val >> 21) & 0x001) << 21) /* ic */
2910 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
2911
2912 bfd_put_64 (abfd, t0, hit_addr);
2913 bfd_put_64 (abfd, t1, hit_addr + 8);
2914 break;
2915
2916 case IA64_OPND_TGT64:
2917 hit_addr -= (long) hit_addr & 0x3;
2918 t0 = bfd_get_64 (abfd, hit_addr);
2919 t1 = bfd_get_64 (abfd, hit_addr + 8);
2920
2921 /* tmpl/s: bits 0.. 5 in t0
2922 slot 0: bits 5..45 in t0
2923 slot 1: bits 46..63 in t0, bits 0..22 in t1
2924 slot 2: bits 23..63 in t1 */
2925
2926 /* First, clear the bits that form the 64 bit constant. */
2927 t0 &= ~(0x3ffffLL << 46);
2928 t1 &= ~(0x7fffffLL
2929 | ((1LL << 36 | 0xfffffLL << 13) << 23));
2930
2931 val >>= 4;
2932 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
2933 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
2934 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
2935 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
2936
2937 bfd_put_64 (abfd, t0, hit_addr);
2938 bfd_put_64 (abfd, t1, hit_addr + 8);
2939 break;
2940
2941 default:
2942 switch ((long) hit_addr & 0x3)
2943 {
2944 case 0: shift = 5; break;
2945 case 1: shift = 14; hit_addr += 3; break;
2946 case 2: shift = 23; hit_addr += 6; break;
2947 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
2948 }
2949 dword = bfd_get_64 (abfd, hit_addr);
2950 insn = (dword >> shift) & 0x1ffffffffffLL;
2951
2952 op = elf64_ia64_operands + opnd;
2953 err = (*op->insert) (op, val, &insn);
2954 if (err)
2955 return bfd_reloc_overflow;
2956
2957 dword &= ~(0x1ffffffffffLL << shift);
2958 dword |= (insn << shift);
2959 bfd_put_64 (abfd, dword, hit_addr);
2960 break;
2961
2962 case IA64_OPND_NIL:
2963 /* A data relocation. */
2964 if (bigendian)
2965 if (size == 4)
2966 bfd_putb32 (val, hit_addr);
2967 else
2968 bfd_putb64 (val, hit_addr);
2969 else
2970 if (size == 4)
2971 bfd_putl32 (val, hit_addr);
2972 else
2973 bfd_putl64 (val, hit_addr);
2974 break;
2975 }
2976
2977 return bfd_reloc_ok;
2978 }
2979
2980 static void
2981 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
2982 dynindx, addend)
2983 bfd *abfd;
2984 struct bfd_link_info *info;
2985 asection *sec;
2986 asection *srel;
2987 bfd_vma offset;
2988 unsigned int type;
2989 long dynindx;
2990 bfd_vma addend;
2991 {
2992 Elf_Internal_Rela outrel;
2993
2994 outrel.r_offset = (sec->output_section->vma
2995 + sec->output_offset
2996 + offset);
2997
2998 BFD_ASSERT (dynindx != -1);
2999 outrel.r_info = ELFNN_R_INFO (dynindx, type);
3000 outrel.r_addend = addend;
3001
3002 if (elf_section_data (sec)->stab_info != NULL)
3003 {
3004 /* This may be NULL for linker-generated relocations, as it is
3005 inconvenient to pass all the bits around. And this shouldn't
3006 happen. */
3007 BFD_ASSERT (info != NULL);
3008
3009 offset = (_bfd_stab_section_offset
3010 (abfd, &elf_hash_table (info)->stab_info, sec,
3011 &elf_section_data (sec)->stab_info, offset));
3012 if (offset == (bfd_vma) -1)
3013 {
3014 /* Run for the hills. We shouldn't be outputting a relocation
3015 for this. So do what everyone else does and output a no-op. */
3016 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3017 outrel.r_addend = 0;
3018 offset = 0;
3019 }
3020 outrel.r_offset = offset;
3021 }
3022
3023 bfd_elfNN_swap_reloca_out (abfd, &outrel,
3024 ((ElfNN_External_Rela *) srel->contents
3025 + srel->reloc_count++));
3026 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3027 <= srel->_cooked_size);
3028 }
3029
3030 /* Store an entry for target address TARGET_ADDR in the linkage table
3031 and return the gp-relative address of the linkage table entry. */
3032
3033 static bfd_vma
3034 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3035 bfd *abfd;
3036 struct bfd_link_info *info;
3037 struct elfNN_ia64_dyn_sym_info *dyn_i;
3038 long dynindx;
3039 bfd_vma addend;
3040 bfd_vma value;
3041 unsigned int dyn_r_type;
3042 {
3043 struct elfNN_ia64_link_hash_table *ia64_info;
3044 asection *got_sec;
3045
3046 ia64_info = elfNN_ia64_hash_table (info);
3047 got_sec = ia64_info->got_sec;
3048
3049 BFD_ASSERT ((dyn_i->got_offset & 7) == 0);
3050
3051 if (! dyn_i->got_done)
3052 {
3053 dyn_i->got_done = true;
3054
3055 /* Store the target address in the linkage table entry. */
3056 bfd_put_64 (abfd, value, got_sec->contents + dyn_i->got_offset);
3057
3058 /* Install a dynamic relocation if needed. */
3059 if (info->shared
3060 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
3061 || elfNN_ia64_aix_vec (abfd->xvec)
3062 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3063 {
3064 if (dynindx == -1)
3065 {
3066 dyn_r_type = R_IA64_REL64LSB;
3067 dynindx = 0;
3068 addend = value;
3069 }
3070
3071 if (bfd_big_endian (abfd))
3072 {
3073 switch (dyn_r_type)
3074 {
3075 case R_IA64_REL64LSB:
3076 dyn_r_type = R_IA64_REL64MSB;
3077 break;
3078 case R_IA64_DIR64LSB:
3079 dyn_r_type = R_IA64_DIR64MSB;
3080 break;
3081 case R_IA64_FPTR64LSB:
3082 dyn_r_type = R_IA64_FPTR64MSB;
3083 break;
3084 default:
3085 BFD_ASSERT (false);
3086 break;
3087 }
3088 }
3089
3090 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3091 ia64_info->rel_got_sec,
3092 dyn_i->got_offset, dyn_r_type,
3093 dynindx, addend);
3094 }
3095 }
3096
3097 /* Return the address of the linkage table entry. */
3098 value = (got_sec->output_section->vma
3099 + got_sec->output_offset
3100 + dyn_i->got_offset);
3101
3102 return value;
3103 }
3104
3105 /* Fill in a function descriptor consisting of the function's code
3106 address and its global pointer. Return the descriptor's address. */
3107
3108 static bfd_vma
3109 set_fptr_entry (abfd, info, dyn_i, value)
3110 bfd *abfd;
3111 struct bfd_link_info *info;
3112 struct elfNN_ia64_dyn_sym_info *dyn_i;
3113 bfd_vma value;
3114 {
3115 struct elfNN_ia64_link_hash_table *ia64_info;
3116 asection *fptr_sec;
3117
3118 ia64_info = elfNN_ia64_hash_table (info);
3119 fptr_sec = ia64_info->fptr_sec;
3120
3121 if (!dyn_i->fptr_done)
3122 {
3123 dyn_i->fptr_done = 1;
3124
3125 /* Fill in the function descriptor. */
3126 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3127 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3128 fptr_sec->contents + dyn_i->fptr_offset + 8);
3129 }
3130
3131 /* Return the descriptor's address. */
3132 value = (fptr_sec->output_section->vma
3133 + fptr_sec->output_offset
3134 + dyn_i->fptr_offset);
3135
3136 return value;
3137 }
3138
3139 /* Fill in a PLTOFF entry consisting of the function's code address
3140 and its global pointer. Return the descriptor's address. */
3141
3142 static bfd_vma
3143 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3144 bfd *abfd;
3145 struct bfd_link_info *info;
3146 struct elfNN_ia64_dyn_sym_info *dyn_i;
3147 bfd_vma value;
3148 boolean is_plt;
3149 {
3150 struct elfNN_ia64_link_hash_table *ia64_info;
3151 asection *pltoff_sec;
3152
3153 ia64_info = elfNN_ia64_hash_table (info);
3154 pltoff_sec = ia64_info->pltoff_sec;
3155
3156 /* Don't do anything if this symbol uses a real PLT entry. In
3157 that case, we'll fill this in during finish_dynamic_symbol. */
3158 if ((! dyn_i->want_plt || is_plt)
3159 && !dyn_i->pltoff_done)
3160 {
3161 bfd_vma gp = _bfd_get_gp_value (abfd);
3162
3163 /* Fill in the function descriptor. */
3164 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3165 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3166
3167 /* Install dynamic relocations if needed. */
3168 if (!is_plt && info->shared)
3169 {
3170 unsigned int dyn_r_type;
3171
3172 if (bfd_big_endian (abfd))
3173 dyn_r_type = R_IA64_REL64MSB;
3174 else
3175 dyn_r_type = R_IA64_REL64LSB;
3176
3177 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3178 ia64_info->rel_pltoff_sec,
3179 dyn_i->pltoff_offset,
3180 dyn_r_type, 0, value);
3181 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3182 ia64_info->rel_pltoff_sec,
3183 dyn_i->pltoff_offset + 8,
3184 dyn_r_type, 0, gp);
3185 }
3186
3187 dyn_i->pltoff_done = 1;
3188 }
3189
3190 /* Return the descriptor's address. */
3191 value = (pltoff_sec->output_section->vma
3192 + pltoff_sec->output_offset
3193 + dyn_i->pltoff_offset);
3194
3195 return value;
3196 }
3197
3198 /* Called through qsort to sort the .IA_64.unwind section during a
3199 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3200 to the output bfd so we can do proper endianness frobbing. */
3201
3202 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3203
3204 static int
3205 elfNN_ia64_unwind_entry_compare (a, b)
3206 const PTR a;
3207 const PTR b;
3208 {
3209 bfd_vma av, bv;
3210
3211 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3212 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3213
3214 return (av < bv ? -1 : av > bv ? 1 : 0);
3215 }
3216
3217 static boolean
3218 elfNN_ia64_final_link (abfd, info)
3219 bfd *abfd;
3220 struct bfd_link_info *info;
3221 {
3222 struct elfNN_ia64_link_hash_table *ia64_info;
3223 asection *unwind_output_sec;
3224
3225 ia64_info = elfNN_ia64_hash_table (info);
3226
3227 /* Make sure we've got ourselves a nice fat __gp value. */
3228 if (!info->relocateable)
3229 {
3230 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3231 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3232 struct elf_link_hash_entry *gp;
3233 bfd_vma gp_val;
3234 asection *os;
3235
3236 /* Find the min and max vma of all sections marked short. Also
3237 collect min and max vma of any type, for use in selecting a
3238 nice gp. */
3239 for (os = abfd->sections; os ; os = os->next)
3240 {
3241 bfd_vma lo, hi;
3242
3243 if ((os->flags & SEC_ALLOC) == 0)
3244 continue;
3245
3246 lo = os->vma;
3247 hi = os->vma + os->_raw_size;
3248 if (hi < lo)
3249 hi = (bfd_vma) -1;
3250
3251 if (min_vma > lo)
3252 min_vma = lo;
3253 if (max_vma < hi)
3254 max_vma = hi;
3255 if (os->flags & SEC_SMALL_DATA)
3256 {
3257 if (min_short_vma > lo)
3258 min_short_vma = lo;
3259 if (max_short_vma < hi)
3260 max_short_vma = hi;
3261 }
3262 }
3263
3264 /* See if the user wants to force a value. */
3265 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
3266 false, false);
3267
3268 if (gp
3269 && (gp->root.type == bfd_link_hash_defined
3270 || gp->root.type == bfd_link_hash_defweak))
3271 {
3272 asection *gp_sec = gp->root.u.def.section;
3273 gp_val = (gp->root.u.def.value
3274 + gp_sec->output_section->vma
3275 + gp_sec->output_offset);
3276 }
3277 else
3278 {
3279 /* Pick a sensible value. */
3280
3281 asection *got_sec = ia64_info->got_sec;
3282
3283 /* Start with just the address of the .got. */
3284 if (got_sec)
3285 gp_val = got_sec->output_section->vma;
3286 else if (max_short_vma != 0)
3287 gp_val = min_short_vma;
3288 else
3289 gp_val = min_vma;
3290
3291 /* If it is possible to address the entire image, but we
3292 don't with the choice above, adjust. */
3293 if (max_vma - min_vma < 0x400000
3294 && max_vma - gp_val <= 0x200000
3295 && gp_val - min_vma > 0x200000)
3296 gp_val = min_vma + 0x200000;
3297 else if (max_short_vma != 0)
3298 {
3299 /* If we don't cover all the short data, adjust. */
3300 if (max_short_vma - gp_val >= 0x200000)
3301 gp_val = min_short_vma + 0x200000;
3302
3303 /* If we're addressing stuff past the end, adjust back. */
3304 if (gp_val > max_vma)
3305 gp_val = max_vma - 0x200000 + 8;
3306 }
3307 }
3308
3309 /* Validate whether all SHF_IA_64_SHORT sections are within
3310 range of the chosen GP. */
3311
3312 if (max_short_vma != 0)
3313 {
3314 if (max_short_vma - min_short_vma >= 0x400000)
3315 {
3316 (*_bfd_error_handler)
3317 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3318 bfd_get_filename (abfd),
3319 (unsigned long) (max_short_vma - min_short_vma));
3320 return false;
3321 }
3322 else if ((gp_val > min_short_vma
3323 && gp_val - min_short_vma > 0x200000)
3324 || (gp_val < max_short_vma
3325 && max_short_vma - gp_val >= 0x200000))
3326 {
3327 (*_bfd_error_handler)
3328 (_("%s: __gp does not cover short data segment"),
3329 bfd_get_filename (abfd));
3330 return false;
3331 }
3332 }
3333
3334 _bfd_set_gp_value (abfd, gp_val);
3335
3336 if (gp)
3337 {
3338 gp->root.type = bfd_link_hash_defined;
3339 gp->root.u.def.value = gp_val;
3340 gp->root.u.def.section = bfd_abs_section_ptr;
3341 }
3342 }
3343
3344 /* If we're producing a final executable, we need to sort the contents
3345 of the .IA_64.unwind section. Force this section to be relocated
3346 into memory rather than written immediately to the output file. */
3347 unwind_output_sec = NULL;
3348 if (!info->relocateable)
3349 {
3350 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3351 if (s)
3352 {
3353 unwind_output_sec = s->output_section;
3354 unwind_output_sec->contents
3355 = bfd_malloc (unwind_output_sec->_raw_size);
3356 if (unwind_output_sec->contents == NULL)
3357 return false;
3358 }
3359 }
3360
3361 /* Invoke the regular ELF backend linker to do all the work. */
3362 if (!bfd_elfNN_bfd_final_link (abfd, info))
3363 return false;
3364
3365 if (unwind_output_sec)
3366 {
3367 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3368 qsort (unwind_output_sec->contents, unwind_output_sec->_raw_size / 24,
3369 24, elfNN_ia64_unwind_entry_compare);
3370
3371 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3372 unwind_output_sec->contents, 0,
3373 unwind_output_sec->_raw_size))
3374 return false;
3375 }
3376
3377 return true;
3378 }
3379
3380 static boolean
3381 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3382 contents, relocs, local_syms, local_sections)
3383 bfd *output_bfd;
3384 struct bfd_link_info *info;
3385 bfd *input_bfd;
3386 asection *input_section;
3387 bfd_byte *contents;
3388 Elf_Internal_Rela *relocs;
3389 Elf_Internal_Sym *local_syms;
3390 asection **local_sections;
3391 {
3392 struct elfNN_ia64_link_hash_table *ia64_info;
3393 Elf_Internal_Shdr *symtab_hdr;
3394 Elf_Internal_Rela *rel;
3395 Elf_Internal_Rela *relend;
3396 asection *srel;
3397 boolean ret_val = true; /* for non-fatal errors */
3398 bfd_vma gp_val;
3399
3400 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3401 ia64_info = elfNN_ia64_hash_table (info);
3402
3403 /* Infect various flags from the input section to the output section. */
3404 if (info->relocateable)
3405 {
3406 bfd_vma flags;
3407
3408 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3409 flags &= SHF_IA_64_NORECOV;
3410
3411 elf_section_data(input_section->output_section)
3412 ->this_hdr.sh_flags |= flags;
3413 }
3414
3415 gp_val = _bfd_get_gp_value (output_bfd);
3416 srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3417
3418 rel = relocs;
3419 relend = relocs + input_section->reloc_count;
3420 for (; rel < relend; ++rel)
3421 {
3422 struct elf_link_hash_entry *h;
3423 struct elfNN_ia64_dyn_sym_info *dyn_i;
3424 bfd_reloc_status_type r;
3425 reloc_howto_type *howto;
3426 unsigned long r_symndx;
3427 Elf_Internal_Sym *sym;
3428 unsigned int r_type;
3429 bfd_vma value;
3430 asection *sym_sec;
3431 bfd_byte *hit_addr;
3432 boolean dynamic_symbol_p;
3433 boolean undef_weak_ref;
3434
3435 r_type = ELFNN_R_TYPE (rel->r_info);
3436 if (r_type > R_IA64_MAX_RELOC_CODE)
3437 {
3438 (*_bfd_error_handler)
3439 (_("%s: unknown relocation type %d"),
3440 bfd_get_filename (input_bfd), (int)r_type);
3441 bfd_set_error (bfd_error_bad_value);
3442 ret_val = false;
3443 continue;
3444 }
3445 howto = lookup_howto (r_type);
3446 r_symndx = ELFNN_R_SYM (rel->r_info);
3447
3448 if (info->relocateable)
3449 {
3450 /* This is a relocateable link. We don't have to change
3451 anything, unless the reloc is against a section symbol,
3452 in which case we have to adjust according to where the
3453 section symbol winds up in the output section. */
3454 if (r_symndx < symtab_hdr->sh_info)
3455 {
3456 sym = local_syms + r_symndx;
3457 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3458 {
3459 sym_sec = local_sections[r_symndx];
3460 rel->r_addend += sym_sec->output_offset;
3461 }
3462 }
3463 continue;
3464 }
3465
3466 /* This is a final link. */
3467
3468 h = NULL;
3469 sym = NULL;
3470 sym_sec = NULL;
3471 undef_weak_ref = false;
3472
3473 if (r_symndx < symtab_hdr->sh_info)
3474 {
3475 /* Reloc against local symbol. */
3476 sym = local_syms + r_symndx;
3477 sym_sec = local_sections[r_symndx];
3478 value = (sym_sec->output_section->vma
3479 + sym_sec->output_offset
3480 + sym->st_value);
3481 }
3482 else
3483 {
3484 long indx;
3485
3486 /* Reloc against global symbol. */
3487 indx = r_symndx - symtab_hdr->sh_info;
3488 h = elf_sym_hashes (input_bfd)[indx];
3489 while (h->root.type == bfd_link_hash_indirect
3490 || h->root.type == bfd_link_hash_warning)
3491 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3492
3493 value = 0;
3494 if (h->root.type == bfd_link_hash_defined
3495 || h->root.type == bfd_link_hash_defweak)
3496 {
3497 sym_sec = h->root.u.def.section;
3498
3499 /* Detect the cases that sym_sec->output_section is
3500 expected to be NULL -- all cases in which the symbol
3501 is defined in another shared module. This includes
3502 PLT relocs for which we've created a PLT entry and
3503 other relocs for which we're prepared to create
3504 dynamic relocations. */
3505 /* ??? Just accept it NULL and continue. */
3506
3507 if (sym_sec->output_section != NULL)
3508 {
3509 value = (h->root.u.def.value
3510 + sym_sec->output_section->vma
3511 + sym_sec->output_offset);
3512 }
3513 }
3514 else if (h->root.type == bfd_link_hash_undefweak)
3515 undef_weak_ref = true;
3516 else if (info->shared && !info->symbolic
3517 && !info->no_undefined
3518 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3519 ;
3520 else
3521 {
3522 if (! ((*info->callbacks->undefined_symbol)
3523 (info, h->root.root.string, input_bfd,
3524 input_section, rel->r_offset,
3525 (!info->shared || info->no_undefined
3526 || ELF_ST_VISIBILITY (h->other)))))
3527 return false;
3528 ret_val = false;
3529 continue;
3530 }
3531 }
3532
3533 hit_addr = contents + rel->r_offset;
3534 value += rel->r_addend;
3535 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3536
3537 switch (r_type)
3538 {
3539 case R_IA64_NONE:
3540 case R_IA64_LDXMOV:
3541 continue;
3542
3543 case R_IA64_IMM14:
3544 case R_IA64_IMM22:
3545 case R_IA64_IMM64:
3546 case R_IA64_DIR32MSB:
3547 case R_IA64_DIR32LSB:
3548 case R_IA64_DIR64MSB:
3549 case R_IA64_DIR64LSB:
3550 /* Install a dynamic relocation for this reloc. */
3551 if ((dynamic_symbol_p || info->shared
3552 || (elfNN_ia64_aix_vec (info->hash->creator)
3553 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3554 && (!h || strcmp (h->root.root.string,
3555 "__GLOB_DATA_PTR") != 0)))
3556 && (input_section->flags & SEC_ALLOC) != 0)
3557 {
3558 unsigned int dyn_r_type;
3559 long dynindx;
3560 bfd_vma addend;
3561
3562 BFD_ASSERT (srel != NULL);
3563
3564 /* If we don't need dynamic symbol lookup, find a
3565 matching RELATIVE relocation. */
3566 dyn_r_type = r_type;
3567 if (dynamic_symbol_p)
3568 {
3569 dynindx = h->dynindx;
3570 addend = rel->r_addend;
3571 value = 0;
3572 }
3573 else
3574 {
3575 switch (r_type)
3576 {
3577 case R_IA64_DIR32MSB:
3578 dyn_r_type = R_IA64_REL32MSB;
3579 break;
3580 case R_IA64_DIR32LSB:
3581 dyn_r_type = R_IA64_REL32LSB;
3582 break;
3583 case R_IA64_DIR64MSB:
3584 dyn_r_type = R_IA64_REL64MSB;
3585 break;
3586 case R_IA64_DIR64LSB:
3587 dyn_r_type = R_IA64_REL64LSB;
3588 break;
3589
3590 default:
3591 /* We can't represent this without a dynamic symbol.
3592 Adjust the relocation to be against an output
3593 section symbol, which are always present in the
3594 dynamic symbol table. */
3595 /* ??? People shouldn't be doing non-pic code in
3596 shared libraries. Hork. */
3597 (*_bfd_error_handler)
3598 (_("%s: linking non-pic code in a shared library"),
3599 bfd_get_filename (input_bfd));
3600 ret_val = false;
3601 continue;
3602 }
3603 dynindx = 0;
3604 addend = value;
3605 }
3606
3607 if (elfNN_ia64_aix_vec (info->hash->creator))
3608 rel->r_addend = value;
3609 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3610 srel, rel->r_offset, dyn_r_type,
3611 dynindx, addend);
3612 }
3613 /* FALLTHRU */
3614
3615 case R_IA64_LTV32MSB:
3616 case R_IA64_LTV32LSB:
3617 case R_IA64_LTV64MSB:
3618 case R_IA64_LTV64LSB:
3619 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3620 break;
3621
3622 case R_IA64_GPREL22:
3623 case R_IA64_GPREL64I:
3624 case R_IA64_GPREL32MSB:
3625 case R_IA64_GPREL32LSB:
3626 case R_IA64_GPREL64MSB:
3627 case R_IA64_GPREL64LSB:
3628 if (dynamic_symbol_p)
3629 {
3630 (*_bfd_error_handler)
3631 (_("%s: @gprel relocation against dynamic symbol %s"),
3632 bfd_get_filename (input_bfd), h->root.root.string);
3633 ret_val = false;
3634 continue;
3635 }
3636 value -= gp_val;
3637 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3638 break;
3639
3640 case R_IA64_LTOFF22:
3641 case R_IA64_LTOFF22X:
3642 case R_IA64_LTOFF64I:
3643 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3644 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
3645 rel->r_addend, value, R_IA64_DIR64LSB);
3646 value -= gp_val;
3647 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3648 break;
3649
3650 case R_IA64_PLTOFF22:
3651 case R_IA64_PLTOFF64I:
3652 case R_IA64_PLTOFF64MSB:
3653 case R_IA64_PLTOFF64LSB:
3654 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3655 value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
3656 value -= gp_val;
3657 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3658 break;
3659
3660 case R_IA64_FPTR64I:
3661 case R_IA64_FPTR32MSB:
3662 case R_IA64_FPTR32LSB:
3663 case R_IA64_FPTR64MSB:
3664 case R_IA64_FPTR64LSB:
3665 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3666 if (dyn_i->want_fptr)
3667 {
3668 if (!undef_weak_ref)
3669 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3670 }
3671 else
3672 {
3673 long dynindx;
3674
3675 /* Otherwise, we expect the dynamic linker to create
3676 the entry. */
3677
3678 if (h)
3679 {
3680 if (h->dynindx != -1)
3681 dynindx = h->dynindx;
3682 else
3683 dynindx = (_bfd_elf_link_lookup_local_dynindx
3684 (info, h->root.u.def.section->owner,
3685 global_sym_index (h)));
3686 }
3687 else
3688 {
3689 dynindx = (_bfd_elf_link_lookup_local_dynindx
3690 (info, input_bfd, r_symndx));
3691 }
3692
3693 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3694 srel, rel->r_offset, r_type,
3695 dynindx, rel->r_addend);
3696 value = 0;
3697 }
3698
3699 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3700 break;
3701
3702 case R_IA64_LTOFF_FPTR22:
3703 case R_IA64_LTOFF_FPTR64I:
3704 case R_IA64_LTOFF_FPTR32MSB:
3705 case R_IA64_LTOFF_FPTR32LSB:
3706 case R_IA64_LTOFF_FPTR64MSB:
3707 case R_IA64_LTOFF_FPTR64LSB:
3708 {
3709 long dynindx;
3710
3711 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3712 if (dyn_i->want_fptr)
3713 {
3714 BFD_ASSERT (h == NULL || h->dynindx == -1)
3715 if (!undef_weak_ref)
3716 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3717 dynindx = -1;
3718 }
3719 else
3720 {
3721 /* Otherwise, we expect the dynamic linker to create
3722 the entry. */
3723 if (h)
3724 {
3725 if (h->dynindx != -1)
3726 dynindx = h->dynindx;
3727 else
3728 dynindx = (_bfd_elf_link_lookup_local_dynindx
3729 (info, h->root.u.def.section->owner,
3730 global_sym_index (h)));
3731 }
3732 else
3733 dynindx = (_bfd_elf_link_lookup_local_dynindx
3734 (info, input_bfd, r_symndx));
3735 value = 0;
3736 }
3737
3738 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
3739 rel->r_addend, value, R_IA64_FPTR64LSB);
3740 value -= gp_val;
3741 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3742 }
3743 break;
3744
3745 case R_IA64_PCREL32MSB:
3746 case R_IA64_PCREL32LSB:
3747 case R_IA64_PCREL64MSB:
3748 case R_IA64_PCREL64LSB:
3749 /* Install a dynamic relocation for this reloc. */
3750 if (dynamic_symbol_p
3751 || elfNN_ia64_aix_vec (info->hash->creator))
3752 {
3753 BFD_ASSERT (srel != NULL);
3754
3755 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3756 srel, rel->r_offset, r_type,
3757 h->dynindx, rel->r_addend);
3758 }
3759 goto finish_pcrel;
3760
3761 case R_IA64_PCREL21BI:
3762 case R_IA64_PCREL21F:
3763 case R_IA64_PCREL21M:
3764 /* ??? These two are only used for speculation fixup code.
3765 They should never be dynamic. */
3766 if (dynamic_symbol_p)
3767 {
3768 (*_bfd_error_handler)
3769 (_("%s: dynamic relocation against speculation fixup"),
3770 bfd_get_filename (input_bfd));
3771 ret_val = false;
3772 continue;
3773 }
3774 if (undef_weak_ref)
3775 {
3776 (*_bfd_error_handler)
3777 (_("%s: speculation fixup against undefined weak symbol"),
3778 bfd_get_filename (input_bfd));
3779 ret_val = false;
3780 continue;
3781 }
3782 goto finish_pcrel;
3783
3784 case R_IA64_PCREL21B:
3785 case R_IA64_PCREL60B:
3786 /* We should have created a PLT entry for any dynamic symbol. */
3787 dyn_i = NULL;
3788 if (h)
3789 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3790
3791 if (dyn_i && dyn_i->want_plt2)
3792 {
3793 /* Should have caught this earlier. */
3794 BFD_ASSERT (rel->r_addend == 0);
3795
3796 value = (ia64_info->plt_sec->output_section->vma
3797 + ia64_info->plt_sec->output_offset
3798 + dyn_i->plt2_offset);
3799 }
3800 else
3801 {
3802 /* Since there's no PLT entry, Validate that this is
3803 locally defined. */
3804 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
3805
3806 /* If the symbol is undef_weak, we shouldn't be trying
3807 to call it. There's every chance that we'd wind up
3808 with an out-of-range fixup here. Don't bother setting
3809 any value at all. */
3810 if (undef_weak_ref)
3811 continue;
3812 }
3813 goto finish_pcrel;
3814
3815 case R_IA64_PCREL22:
3816 case R_IA64_PCREL64I:
3817 finish_pcrel:
3818 /* Make pc-relative. */
3819 value -= (input_section->output_section->vma
3820 + input_section->output_offset
3821 + rel->r_offset) & ~ (bfd_vma) 0x3;
3822 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3823 break;
3824
3825 case R_IA64_SEGREL32MSB:
3826 case R_IA64_SEGREL32LSB:
3827 case R_IA64_SEGREL64MSB:
3828 case R_IA64_SEGREL64LSB:
3829 {
3830 struct elf_segment_map *m;
3831 Elf_Internal_Phdr *p;
3832
3833 /* Find the segment that contains the output_section. */
3834 for (m = elf_tdata (output_bfd)->segment_map,
3835 p = elf_tdata (output_bfd)->phdr;
3836 m != NULL;
3837 m = m->next, p++)
3838 {
3839 int i;
3840 for (i = m->count - 1; i >= 0; i--)
3841 if (m->sections[i] == sym_sec->output_section)
3842 break;
3843 if (i >= 0)
3844 break;
3845 }
3846
3847 if (m == NULL)
3848 {
3849 /* If the input section was discarded from the output, then
3850 do nothing. */
3851
3852 if (bfd_is_abs_section (sym_sec->output_section))
3853 r = bfd_reloc_ok;
3854 else
3855 r = bfd_reloc_notsupported;
3856 }
3857 else
3858 {
3859 /* The VMA of the segment is the vaddr of the associated
3860 program header. */
3861 if (value > p->p_vaddr)
3862 value -= p->p_vaddr;
3863 else
3864 value = 0;
3865 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
3866 r_type);
3867 }
3868 break;
3869 }
3870
3871 case R_IA64_SECREL32MSB:
3872 case R_IA64_SECREL32LSB:
3873 case R_IA64_SECREL64MSB:
3874 case R_IA64_SECREL64LSB:
3875 /* Make output-section relative. */
3876 if (value > input_section->output_section->vma)
3877 value -= input_section->output_section->vma;
3878 else
3879 value = 0;
3880 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3881 break;
3882
3883 case R_IA64_IPLTMSB:
3884 case R_IA64_IPLTLSB:
3885 /* Install a dynamic relocation for this reloc. */
3886 if ((dynamic_symbol_p || info->shared)
3887 && (input_section->flags & SEC_ALLOC) != 0)
3888 {
3889 BFD_ASSERT (srel != NULL);
3890
3891 /* If we don't need dynamic symbol lookup, install two
3892 RELATIVE relocations. */
3893 if (! dynamic_symbol_p)
3894 {
3895 unsigned int dyn_r_type;
3896
3897 if (r_type == R_IA64_IPLTMSB)
3898 dyn_r_type = R_IA64_REL64MSB;
3899 else
3900 dyn_r_type = R_IA64_REL64LSB;
3901
3902 elfNN_ia64_install_dyn_reloc (output_bfd, info,
3903 input_section,
3904 srel, rel->r_offset,
3905 dyn_r_type, 0, value);
3906 elfNN_ia64_install_dyn_reloc (output_bfd, info,
3907 input_section,
3908 srel, rel->r_offset + 8,
3909 dyn_r_type, 0, gp_val);
3910 }
3911 else
3912 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3913 srel, rel->r_offset, r_type,
3914 h->dynindx, rel->r_addend);
3915 }
3916
3917 if (r_type == R_IA64_IPLTMSB)
3918 r_type = R_IA64_DIR64MSB;
3919 else
3920 r_type = R_IA64_DIR64LSB;
3921 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3922 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
3923 r_type);
3924 break;
3925
3926 default:
3927 r = bfd_reloc_notsupported;
3928 break;
3929 }
3930
3931 switch (r)
3932 {
3933 case bfd_reloc_ok:
3934 break;
3935
3936 case bfd_reloc_undefined:
3937 /* This can happen for global table relative relocs if
3938 __gp is undefined. This is a panic situation so we
3939 don't try to continue. */
3940 (*info->callbacks->undefined_symbol)
3941 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
3942 return false;
3943
3944 case bfd_reloc_notsupported:
3945 {
3946 const char *name;
3947
3948 if (h)
3949 name = h->root.root.string;
3950 else
3951 {
3952 name = bfd_elf_string_from_elf_section (input_bfd,
3953 symtab_hdr->sh_link,
3954 sym->st_name);
3955 if (name == NULL)
3956 return false;
3957 if (*name == '\0')
3958 name = bfd_section_name (input_bfd, input_section);
3959 }
3960 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
3961 name, input_bfd,
3962 input_section, rel->r_offset))
3963 return false;
3964 ret_val = false;
3965 }
3966 break;
3967
3968 case bfd_reloc_dangerous:
3969 case bfd_reloc_outofrange:
3970 case bfd_reloc_overflow:
3971 default:
3972 {
3973 const char *name;
3974
3975 if (h)
3976 name = h->root.root.string;
3977 else
3978 {
3979 name = bfd_elf_string_from_elf_section (input_bfd,
3980 symtab_hdr->sh_link,
3981 sym->st_name);
3982 if (name == NULL)
3983 return false;
3984 if (*name == '\0')
3985 name = bfd_section_name (input_bfd, input_section);
3986 }
3987 if (!(*info->callbacks->reloc_overflow) (info, name,
3988 howto->name, 0,
3989 input_bfd,
3990 input_section,
3991 rel->r_offset))
3992 return false;
3993 ret_val = false;
3994 }
3995 break;
3996 }
3997 }
3998
3999 return ret_val;
4000 }
4001
4002 static boolean
4003 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4004 bfd *output_bfd;
4005 struct bfd_link_info *info;
4006 struct elf_link_hash_entry *h;
4007 Elf_Internal_Sym *sym;
4008 {
4009 struct elfNN_ia64_link_hash_table *ia64_info;
4010 struct elfNN_ia64_dyn_sym_info *dyn_i;
4011
4012 ia64_info = elfNN_ia64_hash_table (info);
4013 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
4014
4015 /* Fill in the PLT data, if required. */
4016 if (dyn_i && dyn_i->want_plt)
4017 {
4018 Elf_Internal_Rela outrel;
4019 bfd_byte *loc;
4020 asection *plt_sec;
4021 bfd_vma plt_addr, pltoff_addr, gp_val, index;
4022 ElfNN_External_Rela *rel;
4023
4024 gp_val = _bfd_get_gp_value (output_bfd);
4025
4026 /* Initialize the minimal PLT entry. */
4027
4028 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4029 plt_sec = ia64_info->plt_sec;
4030 loc = plt_sec->contents + dyn_i->plt_offset;
4031
4032 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4033 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4034 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4035 R_IA64_PCREL21B);
4036
4037 plt_addr = (plt_sec->output_section->vma
4038 + plt_sec->output_offset
4039 + dyn_i->plt_offset);
4040 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
4041
4042 /* Initialize the FULL PLT entry, if needed. */
4043 if (dyn_i->want_plt2)
4044 {
4045 loc = plt_sec->contents + dyn_i->plt2_offset;
4046
4047 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4048 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4049 R_IA64_IMM22);
4050
4051 /* Mark the symbol as undefined, rather than as defined in the
4052 plt section. Leave the value alone. */
4053 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4054 first place. But perhaps elflink.h did some for us. */
4055 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4056 sym->st_shndx = SHN_UNDEF;
4057 }
4058
4059 /* Create the dynamic relocation. */
4060 outrel.r_offset = pltoff_addr;
4061 if (bfd_little_endian (output_bfd))
4062 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4063 else
4064 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4065 outrel.r_addend = 0;
4066
4067 /* This is fun. In the .IA_64.pltoff section, we've got entries
4068 that correspond both to real PLT entries, and those that
4069 happened to resolve to local symbols but need to be created
4070 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4071 relocations for the real PLT should come at the end of the
4072 section, so that they can be indexed by plt entry at runtime.
4073
4074 We emitted all of the relocations for the non-PLT @pltoff
4075 entries during relocate_section. So we can consider the
4076 existing sec->reloc_count to be the base of the array of
4077 PLT relocations. */
4078
4079 rel = (ElfNN_External_Rela *)ia64_info->rel_pltoff_sec->contents;
4080 rel += ia64_info->rel_pltoff_sec->reloc_count;
4081
4082 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, rel + index);
4083 }
4084
4085 /* Mark some specially defined symbols as absolute. */
4086 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4087 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4088 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4089 sym->st_shndx = SHN_ABS;
4090
4091 return true;
4092 }
4093
4094 static boolean
4095 elfNN_ia64_finish_dynamic_sections (abfd, info)
4096 bfd *abfd;
4097 struct bfd_link_info *info;
4098 {
4099 struct elfNN_ia64_link_hash_table *ia64_info;
4100 bfd *dynobj;
4101
4102 ia64_info = elfNN_ia64_hash_table (info);
4103 dynobj = ia64_info->root.dynobj;
4104
4105 if (elf_hash_table (info)->dynamic_sections_created)
4106 {
4107 ElfNN_External_Dyn *dyncon, *dynconend;
4108 asection *sdyn, *sgotplt;
4109 bfd_vma gp_val;
4110
4111 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4112 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4113 BFD_ASSERT (sdyn != NULL);
4114 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4115 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4116
4117 gp_val = _bfd_get_gp_value (abfd);
4118
4119 for (; dyncon < dynconend; dyncon++)
4120 {
4121 Elf_Internal_Dyn dyn;
4122
4123 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4124
4125 switch (dyn.d_tag)
4126 {
4127 case DT_PLTGOT:
4128 dyn.d_un.d_ptr = gp_val;
4129 break;
4130
4131 case DT_PLTRELSZ:
4132 dyn.d_un.d_val = (ia64_info->minplt_entries
4133 * sizeof (ElfNN_External_Rela));
4134 break;
4135
4136 case DT_JMPREL:
4137 /* See the comment above in finish_dynamic_symbol. */
4138 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4139 + ia64_info->rel_pltoff_sec->output_offset
4140 + (ia64_info->rel_pltoff_sec->reloc_count
4141 * sizeof (ElfNN_External_Rela)));
4142 break;
4143
4144 case DT_IA_64_PLT_RESERVE:
4145 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4146 + sgotplt->output_offset);
4147 break;
4148
4149 case DT_RELASZ:
4150 /* Do not have RELASZ include JMPREL. This makes things
4151 easier on ld.so. This is not what the rest of BFD set up. */
4152 dyn.d_un.d_val -= (ia64_info->minplt_entries
4153 * sizeof (ElfNN_External_Rela));
4154 break;
4155 }
4156
4157 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4158 }
4159
4160 /* Initialize the PLT0 entry */
4161 if (ia64_info->plt_sec)
4162 {
4163 bfd_byte *loc = ia64_info->plt_sec->contents;
4164 bfd_vma pltres;
4165
4166 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4167
4168 pltres = (sgotplt->output_section->vma
4169 + sgotplt->output_offset
4170 - gp_val);
4171
4172 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4173 }
4174 }
4175
4176 return true;
4177 }
4178 \f
4179 /* ELF file flag handling: */
4180
4181 /* Function to keep IA-64 specific file flags. */
4182 static boolean
4183 elfNN_ia64_set_private_flags (abfd, flags)
4184 bfd *abfd;
4185 flagword flags;
4186 {
4187 BFD_ASSERT (!elf_flags_init (abfd)
4188 || elf_elfheader (abfd)->e_flags == flags);
4189
4190 elf_elfheader (abfd)->e_flags = flags;
4191 elf_flags_init (abfd) = true;
4192 return true;
4193 }
4194
4195 /* Copy backend specific data from one object module to another */
4196 static boolean
4197 elfNN_ia64_copy_private_bfd_data (ibfd, obfd)
4198 bfd *ibfd, *obfd;
4199 {
4200 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4201 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4202 return true;
4203
4204 BFD_ASSERT (!elf_flags_init (obfd)
4205 || (elf_elfheader (obfd)->e_flags
4206 == elf_elfheader (ibfd)->e_flags));
4207
4208 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
4209 elf_flags_init (obfd) = true;
4210 return true;
4211 }
4212
4213 /* Merge backend specific data from an object file to the output
4214 object file when linking. */
4215 static boolean
4216 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4217 bfd *ibfd, *obfd;
4218 {
4219 flagword out_flags;
4220 flagword in_flags;
4221 boolean ok = true;
4222
4223 /* Don't even pretend to support mixed-format linking. */
4224 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4225 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4226 return false;
4227
4228 in_flags = elf_elfheader (ibfd)->e_flags;
4229 out_flags = elf_elfheader (obfd)->e_flags;
4230
4231 if (! elf_flags_init (obfd))
4232 {
4233 elf_flags_init (obfd) = true;
4234 elf_elfheader (obfd)->e_flags = in_flags;
4235
4236 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4237 && bfd_get_arch_info (obfd)->the_default)
4238 {
4239 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4240 bfd_get_mach (ibfd));
4241 }
4242
4243 return true;
4244 }
4245
4246 /* Check flag compatibility. */
4247 if (in_flags == out_flags)
4248 return true;
4249
4250 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4251 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4252 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4253
4254 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4255 {
4256 (*_bfd_error_handler)
4257 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4258 bfd_get_filename (ibfd));
4259
4260 bfd_set_error (bfd_error_bad_value);
4261 ok = false;
4262 }
4263 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4264 {
4265 (*_bfd_error_handler)
4266 (_("%s: linking big-endian files with little-endian files"),
4267 bfd_get_filename (ibfd));
4268
4269 bfd_set_error (bfd_error_bad_value);
4270 ok = false;
4271 }
4272 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4273 {
4274 (*_bfd_error_handler)
4275 (_("%s: linking 64-bit files with 32-bit files"),
4276 bfd_get_filename (ibfd));
4277
4278 bfd_set_error (bfd_error_bad_value);
4279 ok = false;
4280 }
4281 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4282 {
4283 (*_bfd_error_handler)
4284 (_("%s: linking constant-gp files with non-constant-gp files"),
4285 bfd_get_filename (ibfd));
4286
4287 bfd_set_error (bfd_error_bad_value);
4288 ok = false;
4289 }
4290 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4291 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4292 {
4293 (*_bfd_error_handler)
4294 (_("%s: linking auto-pic files with non-auto-pic files"),
4295 bfd_get_filename (ibfd));
4296
4297 bfd_set_error (bfd_error_bad_value);
4298 ok = false;
4299 }
4300
4301 return ok;
4302 }
4303
4304 static boolean
4305 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4306 bfd *abfd;
4307 PTR ptr;
4308 {
4309 FILE *file = (FILE *) ptr;
4310 flagword flags = elf_elfheader (abfd)->e_flags;
4311
4312 BFD_ASSERT (abfd != NULL && ptr != NULL);
4313
4314 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4315 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4316 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4317 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4318 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4319 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4320 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4321 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4322 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4323
4324 _bfd_elf_print_private_bfd_data (abfd, ptr);
4325 return true;
4326 }
4327 \f
4328 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4329 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4330 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4331 #define TARGET_BIG_NAME "elfNN-ia64-big"
4332 #define ELF_ARCH bfd_arch_ia64
4333 #define ELF_MACHINE_CODE EM_IA_64
4334 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4335 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4336 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4337
4338 #define elf_backend_section_from_shdr \
4339 elfNN_ia64_section_from_shdr
4340 #define elf_backend_section_flags \
4341 elfNN_ia64_section_flags
4342 #define elf_backend_fake_sections \
4343 elfNN_ia64_fake_sections
4344 #define elf_backend_final_write_processing \
4345 elfNN_ia64_final_write_processing
4346 #define elf_backend_add_symbol_hook \
4347 elfNN_ia64_add_symbol_hook
4348 #define elf_backend_additional_program_headers \
4349 elfNN_ia64_additional_program_headers
4350 #define elf_backend_modify_segment_map \
4351 elfNN_ia64_modify_segment_map
4352 #define elf_info_to_howto \
4353 elfNN_ia64_info_to_howto
4354
4355 #define bfd_elfNN_bfd_reloc_type_lookup \
4356 elfNN_ia64_reloc_type_lookup
4357 #define bfd_elfNN_bfd_is_local_label_name \
4358 elfNN_ia64_is_local_label_name
4359 #define bfd_elfNN_bfd_relax_section \
4360 elfNN_ia64_relax_section
4361
4362 /* Stuff for the BFD linker: */
4363 #define bfd_elfNN_bfd_link_hash_table_create \
4364 elfNN_ia64_hash_table_create
4365 #define elf_backend_create_dynamic_sections \
4366 elfNN_ia64_create_dynamic_sections
4367 #define elf_backend_check_relocs \
4368 elfNN_ia64_check_relocs
4369 #define elf_backend_adjust_dynamic_symbol \
4370 elfNN_ia64_adjust_dynamic_symbol
4371 #define elf_backend_size_dynamic_sections \
4372 elfNN_ia64_size_dynamic_sections
4373 #define elf_backend_relocate_section \
4374 elfNN_ia64_relocate_section
4375 #define elf_backend_finish_dynamic_symbol \
4376 elfNN_ia64_finish_dynamic_symbol
4377 #define elf_backend_finish_dynamic_sections \
4378 elfNN_ia64_finish_dynamic_sections
4379 #define bfd_elfNN_bfd_final_link \
4380 elfNN_ia64_final_link
4381
4382 #define bfd_elfNN_bfd_copy_private_bfd_data \
4383 elfNN_ia64_copy_private_bfd_data
4384 #define bfd_elfNN_bfd_merge_private_bfd_data \
4385 elfNN_ia64_merge_private_bfd_data
4386 #define bfd_elfNN_bfd_set_private_flags \
4387 elfNN_ia64_set_private_flags
4388 #define bfd_elfNN_bfd_print_private_bfd_data \
4389 elfNN_ia64_print_private_bfd_data
4390
4391 #define elf_backend_plt_readonly 1
4392 #define elf_backend_want_plt_sym 0
4393 #define elf_backend_plt_alignment 5
4394 #define elf_backend_got_header_size 0
4395 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4396 #define elf_backend_want_got_plt 1
4397 #define elf_backend_may_use_rel_p 1
4398 #define elf_backend_may_use_rela_p 1
4399 #define elf_backend_default_use_rela_p 1
4400 #define elf_backend_want_dynbss 0
4401 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4402 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4403
4404 #include "elfNN-target.h"
4405
4406 /* AIX-specific vectors. */
4407
4408 #undef TARGET_LITTLE_SYM
4409 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4410 #undef TARGET_LITTLE_NAME
4411 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4412 #undef TARGET_BIG_SYM
4413 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4414 #undef TARGET_BIG_NAME
4415 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4416
4417 #undef elf_backend_add_symbol_hook
4418 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4419
4420 #undef bfd_elfNN_bfd_link_add_symbols
4421 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4422
4423 #define elfNN_bed elfNN_ia64_aix_bed
4424
4425 #include "elfNN-target.h"
This page took 0.151235 seconds and 4 git commands to generate.