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