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