Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / elfnn-ia64.c
CommitLineData
cbe79dfe 1/* IA-64 support for 64-bit ELF
b3adc24a 2 Copyright (C) 1998-2020 Free Software Foundation, Inc.
cbe79dfe
TG
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
22#include "sysdep.h"
23#include "bfd.h"
24#include "libbfd.h"
25#include "elf-bfd.h"
26#include "opcode/ia64.h"
27#include "elf/ia64.h"
28#include "objalloc.h"
29#include "hashtab.h"
cbe79dfe
TG
30#include "elfxx-ia64.h"
31
32#define ARCH_SIZE NN
33
34#if ARCH_SIZE == 64
35#define LOG_SECTION_ALIGN 3
36#endif
37
38#if ARCH_SIZE == 32
39#define LOG_SECTION_ALIGN 2
40#endif
41
b26a3d58
ST
42#define is_ia64_elf(bfd) \
43 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
44 && elf_object_id (bfd) == IA64_ELF_DATA)
45
cbe79dfe
TG
46typedef struct bfd_hash_entry *(*new_hash_entry_func)
47 (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
48
49/* In dynamically (linker-) created sections, we generally need to keep track
50 of the place a symbol or expression got allocated to. This is done via hash
51 tables that store entries of the following type. */
52
53struct elfNN_ia64_dyn_sym_info
54{
55 /* The addend for which this entry is relevant. */
56 bfd_vma addend;
57
58 bfd_vma got_offset;
59 bfd_vma fptr_offset;
60 bfd_vma pltoff_offset;
61 bfd_vma plt_offset;
62 bfd_vma plt2_offset;
63 bfd_vma tprel_offset;
64 bfd_vma dtpmod_offset;
65 bfd_vma dtprel_offset;
66
67 /* The symbol table entry, if any, that this was derived from. */
68 struct elf_link_hash_entry *h;
69
70 /* Used to count non-got, non-plt relocations for delayed sizing
71 of relocation sections. */
72 struct elfNN_ia64_dyn_reloc_entry
73 {
74 struct elfNN_ia64_dyn_reloc_entry *next;
75 asection *srel;
76 int type;
77 int count;
78
79 /* Is this reloc against readonly section? */
80 bfd_boolean reltext;
81 } *reloc_entries;
82
83 /* TRUE when the section contents have been updated. */
84 unsigned got_done : 1;
85 unsigned fptr_done : 1;
86 unsigned pltoff_done : 1;
87 unsigned tprel_done : 1;
88 unsigned dtpmod_done : 1;
89 unsigned dtprel_done : 1;
90
91 /* TRUE for the different kinds of linker data we want created. */
92 unsigned want_got : 1;
93 unsigned want_gotx : 1;
94 unsigned want_fptr : 1;
95 unsigned want_ltoff_fptr : 1;
96 unsigned want_plt : 1;
97 unsigned want_plt2 : 1;
98 unsigned want_pltoff : 1;
99 unsigned want_tprel : 1;
100 unsigned want_dtpmod : 1;
101 unsigned want_dtprel : 1;
102};
103
104struct elfNN_ia64_local_hash_entry
105{
106 int id;
107 unsigned int r_sym;
108 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
109 unsigned int count;
110 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
111 unsigned int sorted_count;
112 /* The size of elfNN_ia64_dyn_sym_info array. */
113 unsigned int size;
114 /* The array of elfNN_ia64_dyn_sym_info. */
115 struct elfNN_ia64_dyn_sym_info *info;
116
117 /* TRUE if this hash entry's addends was translated for
118 SHF_MERGE optimization. */
119 unsigned sec_merge_done : 1;
120};
121
122struct elfNN_ia64_link_hash_entry
123{
124 struct elf_link_hash_entry root;
125 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
126 unsigned int count;
127 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
128 unsigned int sorted_count;
129 /* The size of elfNN_ia64_dyn_sym_info array. */
130 unsigned int size;
131 /* The array of elfNN_ia64_dyn_sym_info. */
132 struct elfNN_ia64_dyn_sym_info *info;
133};
134
135struct elfNN_ia64_link_hash_table
136{
137 /* The main hash table. */
138 struct elf_link_hash_table root;
139
140 asection *fptr_sec; /* Function descriptor table (or NULL). */
141 asection *rel_fptr_sec; /* Dynamic relocation section for same. */
142 asection *pltoff_sec; /* Private descriptors for plt (or NULL). */
143 asection *rel_pltoff_sec; /* Dynamic relocation section for same. */
144
145 bfd_size_type minplt_entries; /* Number of minplt entries. */
cbe79dfe
TG
146 unsigned self_dtpmod_done : 1;/* Has self DTPMOD entry been finished? */
147 bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry. */
148 /* There are maybe R_IA64_GPREL22 relocations, including those
149 optimized from R_IA64_LTOFF22X, against non-SHF_IA_64_SHORT
150 sections. We need to record those sections so that we can choose
151 a proper GP to cover all R_IA64_GPREL22 relocations. */
152 asection *max_short_sec; /* Maximum short output section. */
153 bfd_vma max_short_offset; /* Maximum short offset. */
154 asection *min_short_sec; /* Minimum short output section. */
155 bfd_vma min_short_offset; /* Minimum short offset. */
156
157 htab_t loc_hash_table;
158 void *loc_hash_memory;
159};
160
161struct elfNN_ia64_allocate_data
162{
163 struct bfd_link_info *info;
164 bfd_size_type ofs;
165 bfd_boolean only_got;
166};
167
168#define elfNN_ia64_hash_table(p) \
0f55320b
AM
169 ((is_elf_hash_table ((p)->hash) \
170 && elf_hash_table_id (elf_hash_table (p)) == IA64_ELF_DATA) \
171 ? (struct elfNN_ia64_link_hash_table *) (p)->hash : NULL)
cbe79dfe
TG
172
173static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
174 (struct elfNN_ia64_link_hash_table *ia64_info,
175 struct elf_link_hash_entry *h,
176 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create);
177static bfd_boolean elfNN_ia64_dynamic_symbol_p
178 (struct elf_link_hash_entry *h, struct bfd_link_info *info, int);
179static bfd_boolean elfNN_ia64_choose_gp
180 (bfd *abfd, struct bfd_link_info *info, bfd_boolean final);
181static void elfNN_ia64_dyn_sym_traverse
182 (struct elfNN_ia64_link_hash_table *ia64_info,
2c3fc389
NC
183 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *),
184 void * info);
cbe79dfe 185static bfd_boolean allocate_global_data_got
2c3fc389 186 (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
cbe79dfe 187static bfd_boolean allocate_global_fptr_got
2c3fc389 188 (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
cbe79dfe 189static bfd_boolean allocate_local_got
2c3fc389 190 (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
cbe79dfe
TG
191static bfd_boolean elfNN_ia64_hpux_vec
192 (const bfd_target *vec);
193static bfd_boolean allocate_dynrel_entries
2c3fc389 194 (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
cbe79dfe
TG
195static asection *get_pltoff
196 (bfd *abfd, struct bfd_link_info *info,
197 struct elfNN_ia64_link_hash_table *ia64_info);
198\f
199/* ia64-specific relocation. */
200
201/* Given a ELF reloc, return the matching HOWTO structure. */
202
f3185997 203static bfd_boolean
cbe79dfe
TG
204elfNN_ia64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
205 arelent *bfd_reloc,
206 Elf_Internal_Rela *elf_reloc)
207{
f3185997
NC
208 unsigned int r_type = ELF32_R_TYPE (elf_reloc->r_info);
209
210 bfd_reloc->howto = ia64_elf_lookup_howto (r_type);
211 if (bfd_reloc->howto == NULL)
212 {
213 /* xgettext:c-format */
214 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
215 abfd, r_type);
216 bfd_set_error (bfd_error_bad_value);
217 return FALSE;
218 }
219
220 return TRUE;
cbe79dfe
TG
221}
222\f
223#define PLT_HEADER_SIZE (3 * 16)
224#define PLT_MIN_ENTRY_SIZE (1 * 16)
225#define PLT_FULL_ENTRY_SIZE (2 * 16)
226#define PLT_RESERVED_WORDS 3
227
228static const bfd_byte plt_header[PLT_HEADER_SIZE] =
229{
07d6d2b8
AM
230 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
231 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
232 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
233 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
234 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
235 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
236 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
237 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
238 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
cbe79dfe
TG
239};
240
241static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
242{
07d6d2b8
AM
243 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
244 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
245 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
cbe79dfe
TG
246};
247
248static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
249{
07d6d2b8
AM
250 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
251 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
252 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
253 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
254 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
255 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
cbe79dfe
TG
256};
257
258#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
259
260static const bfd_byte oor_brl[16] =
261{
07d6d2b8
AM
262 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
cbe79dfe
TG
264 0x00, 0x00, 0x00, 0xc0
265};
266
267static const bfd_byte oor_ip[48] =
268{
07d6d2b8
AM
269 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
270 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
cbe79dfe 271 0x01, 0x00, 0x00, 0x60,
07d6d2b8
AM
272 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
273 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
274 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
275 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
276 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
277 0x60, 0x00, 0x80, 0x00 /* br b6;; */
cbe79dfe
TG
278};
279
280static size_t oor_branch_size = sizeof (oor_brl);
281
282void
283bfd_elfNN_ia64_after_parse (int itanium)
284{
285 oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
286}
287\f
288
289/* Rename some of the generic section flags to better document how they
290 are used here. */
291#define skip_relax_pass_0 sec_flg0
292#define skip_relax_pass_1 sec_flg1
293
294/* These functions do relaxation for IA-64 ELF. */
295
296static void
297elfNN_ia64_update_short_info (asection *sec, bfd_vma offset,
298 struct elfNN_ia64_link_hash_table *ia64_info)
299{
300 /* Skip ABS and SHF_IA_64_SHORT sections. */
301 if (sec == bfd_abs_section_ptr
302 || (sec->flags & SEC_SMALL_DATA) != 0)
303 return;
304
305 if (!ia64_info->min_short_sec)
306 {
307 ia64_info->max_short_sec = sec;
308 ia64_info->max_short_offset = offset;
309 ia64_info->min_short_sec = sec;
310 ia64_info->min_short_offset = offset;
311 }
312 else if (sec == ia64_info->max_short_sec
313 && offset > ia64_info->max_short_offset)
314 ia64_info->max_short_offset = offset;
315 else if (sec == ia64_info->min_short_sec
316 && offset < ia64_info->min_short_offset)
317 ia64_info->min_short_offset = offset;
318 else if (sec->output_section->vma
319 > ia64_info->max_short_sec->vma)
320 {
321 ia64_info->max_short_sec = sec;
322 ia64_info->max_short_offset = offset;
323 }
324 else if (sec->output_section->vma
325 < ia64_info->min_short_sec->vma)
326 {
327 ia64_info->min_short_sec = sec;
328 ia64_info->min_short_offset = offset;
329 }
330}
331
332static bfd_boolean
333elfNN_ia64_relax_section (bfd *abfd, asection *sec,
334 struct bfd_link_info *link_info,
335 bfd_boolean *again)
336{
337 struct one_fixup
338 {
339 struct one_fixup *next;
340 asection *tsec;
341 bfd_vma toff;
342 bfd_vma trampoff;
343 };
344
345 Elf_Internal_Shdr *symtab_hdr;
346 Elf_Internal_Rela *internal_relocs;
347 Elf_Internal_Rela *irel, *irelend;
348 bfd_byte *contents;
349 Elf_Internal_Sym *isymbuf = NULL;
350 struct elfNN_ia64_link_hash_table *ia64_info;
351 struct one_fixup *fixups = NULL;
352 bfd_boolean changed_contents = FALSE;
353 bfd_boolean changed_relocs = FALSE;
354 bfd_boolean changed_got = FALSE;
355 bfd_boolean skip_relax_pass_0 = TRUE;
356 bfd_boolean skip_relax_pass_1 = TRUE;
357 bfd_vma gp = 0;
358
359 /* Assume we're not going to change any sizes, and we'll only need
360 one pass. */
361 *again = FALSE;
362
0e1862bb 363 if (bfd_link_relocatable (link_info))
cbe79dfe
TG
364 (*link_info->callbacks->einfo)
365 (_("%P%F: --relax and -r may not be used together\n"));
366
367 /* Don't even try to relax for non-ELF outputs. */
368 if (!is_elf_hash_table (link_info->hash))
369 return FALSE;
370
371 /* Nothing to do if there are no relocations or there is no need for
372 the current pass. */
373 if ((sec->flags & SEC_RELOC) == 0
374 || sec->reloc_count == 0
375 || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
376 || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
377 return TRUE;
378
379 ia64_info = elfNN_ia64_hash_table (link_info);
380 if (ia64_info == NULL)
381 return FALSE;
382
383 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
384
385 /* Load the relocations for this section. */
386 internal_relocs = (_bfd_elf_link_read_relocs
387 (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
388 link_info->keep_memory));
389 if (internal_relocs == NULL)
390 return FALSE;
391
392 irelend = internal_relocs + sec->reloc_count;
393
394 /* Get the section contents. */
395 if (elf_section_data (sec)->this_hdr.contents != NULL)
396 contents = elf_section_data (sec)->this_hdr.contents;
397 else
398 {
399 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
400 goto error_return;
401 }
402
403 for (irel = internal_relocs; irel < irelend; irel++)
404 {
405 unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
406 bfd_vma symaddr, reladdr, trampoff, toff, roff;
407 asection *tsec;
408 struct one_fixup *f;
409 bfd_size_type amt;
410 bfd_boolean is_branch;
411 struct elfNN_ia64_dyn_sym_info *dyn_i;
412 char symtype;
413
414 switch (r_type)
415 {
416 case R_IA64_PCREL21B:
417 case R_IA64_PCREL21BI:
418 case R_IA64_PCREL21M:
419 case R_IA64_PCREL21F:
420 /* In pass 1, all br relaxations are done. We can skip it. */
421 if (link_info->relax_pass == 1)
422 continue;
423 skip_relax_pass_0 = FALSE;
424 is_branch = TRUE;
425 break;
426
427 case R_IA64_PCREL60B:
428 /* We can't optimize brl to br in pass 0 since br relaxations
429 will increase the code size. Defer it to pass 1. */
430 if (link_info->relax_pass == 0)
431 {
432 skip_relax_pass_1 = FALSE;
433 continue;
434 }
435 is_branch = TRUE;
436 break;
437
438 case R_IA64_GPREL22:
439 /* Update max_short_sec/min_short_sec. */
440
441 case R_IA64_LTOFF22X:
442 case R_IA64_LDXMOV:
443 /* We can't relax ldx/mov in pass 0 since br relaxations will
444 increase the code size. Defer it to pass 1. */
445 if (link_info->relax_pass == 0)
446 {
447 skip_relax_pass_1 = FALSE;
448 continue;
449 }
450 is_branch = FALSE;
451 break;
452
453 default:
454 continue;
455 }
456
457 /* Get the value of the symbol referred to by the reloc. */
458 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
459 {
460 /* A local symbol. */
461 Elf_Internal_Sym *isym;
462
463 /* Read this BFD's local symbols. */
464 if (isymbuf == NULL)
465 {
466 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
467 if (isymbuf == NULL)
468 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
469 symtab_hdr->sh_info, 0,
470 NULL, NULL, NULL);
471 if (isymbuf == 0)
472 goto error_return;
473 }
474
475 isym = isymbuf + ELFNN_R_SYM (irel->r_info);
476 if (isym->st_shndx == SHN_UNDEF)
477 continue; /* We can't do anything with undefined symbols. */
478 else if (isym->st_shndx == SHN_ABS)
479 tsec = bfd_abs_section_ptr;
480 else if (isym->st_shndx == SHN_COMMON)
481 tsec = bfd_com_section_ptr;
482 else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
483 tsec = bfd_com_section_ptr;
484 else
485 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
486
487 toff = isym->st_value;
488 dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
489 symtype = ELF_ST_TYPE (isym->st_info);
490 }
491 else
492 {
493 unsigned long indx;
494 struct elf_link_hash_entry *h;
495
496 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
497 h = elf_sym_hashes (abfd)[indx];
498 BFD_ASSERT (h != NULL);
499
500 while (h->root.type == bfd_link_hash_indirect
501 || h->root.type == bfd_link_hash_warning)
502 h = (struct elf_link_hash_entry *) h->root.u.i.link;
503
504 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
505
506 /* For branches to dynamic symbols, we're interested instead
507 in a branch to the PLT entry. */
508 if (is_branch && dyn_i && dyn_i->want_plt2)
509 {
510 /* Internal branches shouldn't be sent to the PLT.
511 Leave this for now and we'll give an error later. */
512 if (r_type != R_IA64_PCREL21B)
513 continue;
514
515 tsec = ia64_info->root.splt;
516 toff = dyn_i->plt2_offset;
517 BFD_ASSERT (irel->r_addend == 0);
518 }
519
520 /* Can't do anything else with dynamic symbols. */
521 else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
522 continue;
523
524 else
525 {
526 /* We can't do anything with undefined symbols. */
527 if (h->root.type == bfd_link_hash_undefined
528 || h->root.type == bfd_link_hash_undefweak)
529 continue;
530
531 tsec = h->root.u.def.section;
532 toff = h->root.u.def.value;
533 }
534
535 symtype = h->type;
536 }
537
dbaa2011 538 if (tsec->sec_info_type == SEC_INFO_TYPE_MERGE)
cbe79dfe
TG
539 {
540 /* At this stage in linking, no SEC_MERGE symbol has been
541 adjusted, so all references to such symbols need to be
542 passed through _bfd_merged_section_offset. (Later, in
543 relocate_section, all SEC_MERGE symbols *except* for
544 section symbols have been adjusted.)
545
546 gas may reduce relocations against symbols in SEC_MERGE
547 sections to a relocation against the section symbol when
548 the original addend was zero. When the reloc is against
549 a section symbol we should include the addend in the
550 offset passed to _bfd_merged_section_offset, since the
551 location of interest is the original symbol. On the
552 other hand, an access to "sym+addend" where "sym" is not
553 a section symbol should not include the addend; Such an
554 access is presumed to be an offset from "sym"; The
555 location of interest is just "sym". */
556 if (symtype == STT_SECTION)
557 toff += irel->r_addend;
558
559 toff = _bfd_merged_section_offset (abfd, &tsec,
560 elf_section_data (tsec)->sec_info,
561 toff);
562
563 if (symtype != STT_SECTION)
564 toff += irel->r_addend;
565 }
566 else
567 toff += irel->r_addend;
568
569 symaddr = tsec->output_section->vma + tsec->output_offset + toff;
570
571 roff = irel->r_offset;
572
573 if (is_branch)
574 {
575 bfd_signed_vma offset;
576
577 reladdr = (sec->output_section->vma
578 + sec->output_offset
579 + roff) & (bfd_vma) -4;
580
581 /* The .plt section is aligned at 32byte and the .text section
582 is aligned at 64byte. The .text section is right after the
583 .plt section. After the first relaxation pass, linker may
584 increase the gap between the .plt and .text sections up
585 to 32byte. We assume linker will always insert 32byte
a8685210 586 between the .plt and .text sections after the first
cbe79dfe
TG
587 relaxation pass. */
588 if (tsec == ia64_info->root.splt)
589 offset = -0x1000000 + 32;
590 else
591 offset = -0x1000000;
592
593 /* If the branch is in range, no need to do anything. */
d17fe7b7 594 if ((bfd_signed_vma) (symaddr - reladdr) >= offset
cbe79dfe
TG
595 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
596 {
597 /* If the 60-bit branch is in 21-bit range, optimize it. */
598 if (r_type == R_IA64_PCREL60B)
599 {
600 ia64_elf_relax_brl (contents, roff);
601
602 irel->r_info
603 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
604 R_IA64_PCREL21B);
605
606 /* If the original relocation offset points to slot
607 1, change it to slot 2. */
608 if ((irel->r_offset & 3) == 1)
609 irel->r_offset += 1;
6f6372fa
JW
610
611 changed_contents = TRUE;
612 changed_relocs = TRUE;
cbe79dfe
TG
613 }
614
615 continue;
616 }
617 else if (r_type == R_IA64_PCREL60B)
618 continue;
619 else if (ia64_elf_relax_br (contents, roff))
620 {
621 irel->r_info
622 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
623 R_IA64_PCREL60B);
624
625 /* Make the relocation offset point to slot 1. */
626 irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
6f6372fa
JW
627
628 changed_contents = TRUE;
629 changed_relocs = TRUE;
cbe79dfe
TG
630 continue;
631 }
632
633 /* We can't put a trampoline in a .init/.fini section. Issue
634 an error. */
635 if (strcmp (sec->output_section->name, ".init") == 0
636 || strcmp (sec->output_section->name, ".fini") == 0)
637 {
4eca0228 638 _bfd_error_handler
695344c0 639 /* xgettext:c-format */
38f14ab8
AM
640 (_("%pB: can't relax br at %#" PRIx64 " in section `%pA';"
641 " please use brl or indirect branch"),
2dcf00ce 642 sec->owner, (uint64_t) roff, sec);
cbe79dfe
TG
643 bfd_set_error (bfd_error_bad_value);
644 goto error_return;
645 }
646
647 /* If the branch and target are in the same section, you've
648 got one honking big section and we can't help you unless
649 you are branching backwards. You'll get an error message
650 later. */
651 if (tsec == sec && toff > roff)
652 continue;
653
654 /* Look for an existing fixup to this address. */
655 for (f = fixups; f ; f = f->next)
656 if (f->tsec == tsec && f->toff == toff)
657 break;
658
659 if (f == NULL)
660 {
661 /* Two alternatives: If it's a branch to a PLT entry, we can
662 make a copy of the FULL_PLT entry. Otherwise, we'll have
663 to use a `brl' insn to get where we're going. */
664
665 size_t size;
666
667 if (tsec == ia64_info->root.splt)
668 size = sizeof (plt_full_entry);
669 else
670 size = oor_branch_size;
671
672 /* Resize the current section to make room for the new branch. */
673 trampoff = (sec->size + 15) & (bfd_vma) -16;
674
675 /* If trampoline is out of range, there is nothing we
676 can do. */
677 offset = trampoff - (roff & (bfd_vma) -4);
678 if (offset < -0x1000000 || offset > 0x0FFFFF0)
679 continue;
680
681 amt = trampoff + size;
682 contents = (bfd_byte *) bfd_realloc (contents, amt);
683 if (contents == NULL)
684 goto error_return;
685 sec->size = amt;
686
687 if (tsec == ia64_info->root.splt)
688 {
689 memcpy (contents + trampoff, plt_full_entry, size);
690
691 /* Hijack the old relocation for use as the PLTOFF reloc. */
692 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
693 R_IA64_PLTOFF22);
694 irel->r_offset = trampoff;
695 }
696 else
697 {
698 if (size == sizeof (oor_ip))
699 {
700 memcpy (contents + trampoff, oor_ip, size);
701 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
702 R_IA64_PCREL64I);
703 irel->r_addend -= 16;
704 irel->r_offset = trampoff + 2;
705 }
706 else
707 {
708 memcpy (contents + trampoff, oor_brl, size);
709 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
710 R_IA64_PCREL60B);
711 irel->r_offset = trampoff + 2;
712 }
713
714 }
715
716 /* Record the fixup so we don't do it again this section. */
717 f = (struct one_fixup *)
718 bfd_malloc ((bfd_size_type) sizeof (*f));
719 f->next = fixups;
720 f->tsec = tsec;
721 f->toff = toff;
722 f->trampoff = trampoff;
723 fixups = f;
724 }
725 else
726 {
727 /* If trampoline is out of range, there is nothing we
728 can do. */
729 offset = f->trampoff - (roff & (bfd_vma) -4);
730 if (offset < -0x1000000 || offset > 0x0FFFFF0)
731 continue;
732
733 /* Nop out the reloc, since we're finalizing things here. */
734 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
735 }
736
737 /* Fix up the existing branch to hit the trampoline. */
738 if (ia64_elf_install_value (contents + roff, offset, r_type)
739 != bfd_reloc_ok)
740 goto error_return;
741
742 changed_contents = TRUE;
743 changed_relocs = TRUE;
744 }
745 else
746 {
747 /* Fetch the gp. */
748 if (gp == 0)
749 {
750 bfd *obfd = sec->output_section->owner;
751 gp = _bfd_get_gp_value (obfd);
752 if (gp == 0)
753 {
754 if (!elfNN_ia64_choose_gp (obfd, link_info, FALSE))
755 goto error_return;
756 gp = _bfd_get_gp_value (obfd);
757 }
758 }
759
760 /* If the data is out of range, do nothing. */
761 if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
762 ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
763 continue;
764
765 if (r_type == R_IA64_GPREL22)
766 elfNN_ia64_update_short_info (tsec->output_section,
767 tsec->output_offset + toff,
768 ia64_info);
769 else if (r_type == R_IA64_LTOFF22X)
770 {
771 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
772 R_IA64_GPREL22);
773 changed_relocs = TRUE;
774 if (dyn_i->want_gotx)
775 {
776 dyn_i->want_gotx = 0;
777 changed_got |= !dyn_i->want_got;
778 }
779
780 elfNN_ia64_update_short_info (tsec->output_section,
781 tsec->output_offset + toff,
782 ia64_info);
783 }
784 else
785 {
786 ia64_elf_relax_ldxmov (contents, roff);
787 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
788 changed_contents = TRUE;
789 changed_relocs = TRUE;
790 }
791 }
792 }
793
794 /* ??? If we created fixups, this may push the code segment large
795 enough that the data segment moves, which will change the GP.
796 Reset the GP so that we re-calculate next round. We need to
797 do this at the _beginning_ of the next round; now will not do. */
798
799 /* Clean up and go home. */
800 while (fixups)
801 {
802 struct one_fixup *f = fixups;
803 fixups = fixups->next;
804 free (f);
805 }
806
807 if (isymbuf != NULL
808 && symtab_hdr->contents != (unsigned char *) isymbuf)
809 {
810 if (! link_info->keep_memory)
811 free (isymbuf);
812 else
813 {
814 /* Cache the symbols for elf_link_input_bfd. */
815 symtab_hdr->contents = (unsigned char *) isymbuf;
816 }
817 }
818
819 if (contents != NULL
820 && elf_section_data (sec)->this_hdr.contents != contents)
821 {
822 if (!changed_contents && !link_info->keep_memory)
823 free (contents);
824 else
825 {
826 /* Cache the section contents for elf_link_input_bfd. */
827 elf_section_data (sec)->this_hdr.contents = contents;
828 }
829 }
830
831 if (elf_section_data (sec)->relocs != internal_relocs)
832 {
833 if (!changed_relocs)
834 free (internal_relocs);
835 else
836 elf_section_data (sec)->relocs = internal_relocs;
837 }
838
839 if (changed_got)
840 {
841 struct elfNN_ia64_allocate_data data;
842 data.info = link_info;
843 data.ofs = 0;
844 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
845
846 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
847 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
848 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
849 ia64_info->root.sgot->size = data.ofs;
850
851 if (ia64_info->root.dynamic_sections_created
852 && ia64_info->root.srelgot != NULL)
853 {
854 /* Resize .rela.got. */
855 ia64_info->root.srelgot->size = 0;
0e1862bb 856 if (bfd_link_pic (link_info)
cbe79dfe
TG
857 && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
858 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
859 data.only_got = TRUE;
860 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
861 &data);
862 }
863 }
864
865 if (link_info->relax_pass == 0)
866 {
867 /* Pass 0 is only needed to relax br. */
868 sec->skip_relax_pass_0 = skip_relax_pass_0;
869 sec->skip_relax_pass_1 = skip_relax_pass_1;
870 }
871
872 *again = changed_contents || changed_relocs;
873 return TRUE;
874
875 error_return:
c9594989 876 if ((unsigned char *) isymbuf != symtab_hdr->contents)
cbe79dfe 877 free (isymbuf);
c9594989 878 if (elf_section_data (sec)->this_hdr.contents != contents)
cbe79dfe 879 free (contents);
c9594989 880 if (elf_section_data (sec)->relocs != internal_relocs)
cbe79dfe
TG
881 free (internal_relocs);
882 return FALSE;
883}
884#undef skip_relax_pass_0
885#undef skip_relax_pass_1
886\f
887/* Return TRUE if NAME is an unwind table section name. */
888
889static inline bfd_boolean
890is_unwind_section_name (bfd *abfd, const char *name)
891{
892 if (elfNN_ia64_hpux_vec (abfd->xvec)
893 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
894 return FALSE;
895
896 return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
897 && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
898 || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
899}
900
901/* Handle an IA-64 specific section when reading an object file. This
902 is called when bfd_section_from_shdr finds a section with an unknown
903 type. */
904
905static bfd_boolean
906elfNN_ia64_section_from_shdr (bfd *abfd,
907 Elf_Internal_Shdr *hdr,
908 const char *name,
909 int shindex)
910{
911 /* There ought to be a place to keep ELF backend specific flags, but
912 at the moment there isn't one. We just keep track of the
913 sections by their name, instead. Fortunately, the ABI gives
914 suggested names for all the MIPS specific sections, so we will
915 probably get away with this. */
916 switch (hdr->sh_type)
917 {
918 case SHT_IA_64_UNWIND:
919 case SHT_IA_64_HP_OPT_ANOT:
920 break;
921
922 case SHT_IA_64_EXT:
923 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
924 return FALSE;
925 break;
926
927 default:
928 return FALSE;
929 }
930
931 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
932 return FALSE;
933
934 return TRUE;
935}
936
937/* Convert IA-64 specific section flags to bfd internal section flags. */
938
939/* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
940 flag. */
941
942static bfd_boolean
8c803a2d 943elfNN_ia64_section_flags (const Elf_Internal_Shdr *hdr)
cbe79dfe
TG
944{
945 if (hdr->sh_flags & SHF_IA_64_SHORT)
8c803a2d 946 hdr->bfd_section->flags |= SEC_SMALL_DATA;
cbe79dfe
TG
947
948 return TRUE;
949}
950
951/* Set the correct type for an IA-64 ELF section. We do this by the
952 section name, which is a hack, but ought to work. */
953
954static bfd_boolean
955elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
956 asection *sec)
957{
958 const char *name;
959
fd361982 960 name = bfd_section_name (sec);
cbe79dfe
TG
961
962 if (is_unwind_section_name (abfd, name))
963 {
964 /* We don't have the sections numbered at this point, so sh_info
965 is set later, in elfNN_ia64_final_write_processing. */
966 hdr->sh_type = SHT_IA_64_UNWIND;
967 hdr->sh_flags |= SHF_LINK_ORDER;
968 }
969 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
970 hdr->sh_type = SHT_IA_64_EXT;
971 else if (strcmp (name, ".HP.opt_annot") == 0)
972 hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
973 else if (strcmp (name, ".reloc") == 0)
974 /* This is an ugly, but unfortunately necessary hack that is
975 needed when producing EFI binaries on IA-64. It tells
976 elf.c:elf_fake_sections() not to consider ".reloc" as a section
977 containing ELF relocation info. We need this hack in order to
978 be able to generate ELF binaries that can be translated into
979 EFI applications (which are essentially COFF objects). Those
980 files contain a COFF ".reloc" section inside an ELFNN object,
981 which would normally cause BFD to segfault because it would
982 attempt to interpret this section as containing relocation
983 entries for section "oc". With this hack enabled, ".reloc"
984 will be treated as a normal data section, which will avoid the
985 segfault. However, you won't be able to create an ELFNN binary
986 with a section named "oc" that needs relocations, but that's
987 the kind of ugly side-effects you get when detecting section
988 types based on their names... In practice, this limitation is
989 unlikely to bite. */
990 hdr->sh_type = SHT_PROGBITS;
991
992 if (sec->flags & SEC_SMALL_DATA)
993 hdr->sh_flags |= SHF_IA_64_SHORT;
994
995 /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
996
997 if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
998 hdr->sh_flags |= SHF_IA_64_HP_TLS;
999
1000 return TRUE;
1001}
1002
1003/* The final processing done just before writing out an IA-64 ELF
1004 object file. */
1005
cc364be6
AM
1006static bfd_boolean
1007elfNN_ia64_final_write_processing (bfd *abfd)
cbe79dfe
TG
1008{
1009 Elf_Internal_Shdr *hdr;
1010 asection *s;
1011
1012 for (s = abfd->sections; s; s = s->next)
1013 {
1014 hdr = &elf_section_data (s)->this_hdr;
1015 switch (hdr->sh_type)
1016 {
1017 case SHT_IA_64_UNWIND:
1018 /* The IA-64 processor-specific ABI requires setting sh_link
1019 to the unwind section, whereas HP-UX requires sh_info to
1020 do so. For maximum compatibility, we'll set both for
1021 now... */
1022 hdr->sh_info = hdr->sh_link;
1023 break;
1024 }
1025 }
1026
1027 if (! elf_flags_init (abfd))
1028 {
1029 unsigned long flags = 0;
1030
1031 if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
1032 flags |= EF_IA_64_BE;
1033 if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
1034 flags |= EF_IA_64_ABI64;
1035
1036 elf_elfheader(abfd)->e_flags = flags;
1037 elf_flags_init (abfd) = TRUE;
1038 }
cc364be6 1039 return _bfd_elf_final_write_processing (abfd);
cbe79dfe
TG
1040}
1041
1042/* Hook called by the linker routine which adds symbols from an object
1043 file. We use it to put .comm items in .sbss, and not .bss. */
1044
1045static bfd_boolean
1046elfNN_ia64_add_symbol_hook (bfd *abfd,
1047 struct bfd_link_info *info,
1048 Elf_Internal_Sym *sym,
1049 const char **namep ATTRIBUTE_UNUSED,
1050 flagword *flagsp ATTRIBUTE_UNUSED,
1051 asection **secp,
1052 bfd_vma *valp)
1053{
1054 if (sym->st_shndx == SHN_COMMON
0e1862bb 1055 && !bfd_link_relocatable (info)
cbe79dfe
TG
1056 && sym->st_size <= elf_gp_size (abfd))
1057 {
1058 /* Common symbols less than or equal to -G nn bytes are
1059 automatically put into .sbss. */
1060
1061 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1062
1063 if (scomm == NULL)
1064 {
1065 scomm = bfd_make_section_with_flags (abfd, ".scommon",
1066 (SEC_ALLOC
1067 | SEC_IS_COMMON
10885e24 1068 | SEC_SMALL_DATA
cbe79dfe
TG
1069 | SEC_LINKER_CREATED));
1070 if (scomm == NULL)
1071 return FALSE;
1072 }
1073
1074 *secp = scomm;
1075 *valp = sym->st_size;
1076 }
1077
1078 return TRUE;
1079}
1080
1081/* Return the number of additional phdrs we will need. */
1082
1083static int
1084elfNN_ia64_additional_program_headers (bfd *abfd,
1085 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1086{
1087 asection *s;
1088 int ret = 0;
1089
1090 /* See if we need a PT_IA_64_ARCHEXT segment. */
1091 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1092 if (s && (s->flags & SEC_LOAD))
1093 ++ret;
1094
1095 /* Count how many PT_IA_64_UNWIND segments we need. */
1096 for (s = abfd->sections; s; s = s->next)
1097 if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1098 ++ret;
1099
1100 return ret;
1101}
1102
1103static bfd_boolean
1104elfNN_ia64_modify_segment_map (bfd *abfd,
1105 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1106{
1107 struct elf_segment_map *m, **pm;
1108 Elf_Internal_Shdr *hdr;
1109 asection *s;
1110
1111 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1112 all PT_LOAD segments. */
1113 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1114 if (s && (s->flags & SEC_LOAD))
1115 {
12bd6957 1116 for (m = elf_seg_map (abfd); m != NULL; m = m->next)
cbe79dfe
TG
1117 if (m->p_type == PT_IA_64_ARCHEXT)
1118 break;
1119 if (m == NULL)
1120 {
1121 m = ((struct elf_segment_map *)
1122 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1123 if (m == NULL)
1124 return FALSE;
1125
1126 m->p_type = PT_IA_64_ARCHEXT;
1127 m->count = 1;
1128 m->sections[0] = s;
1129
1130 /* We want to put it after the PHDR and INTERP segments. */
12bd6957 1131 pm = &elf_seg_map (abfd);
cbe79dfe
TG
1132 while (*pm != NULL
1133 && ((*pm)->p_type == PT_PHDR
1134 || (*pm)->p_type == PT_INTERP))
1135 pm = &(*pm)->next;
1136
1137 m->next = *pm;
1138 *pm = m;
1139 }
1140 }
1141
1142 /* Install PT_IA_64_UNWIND segments, if needed. */
1143 for (s = abfd->sections; s; s = s->next)
1144 {
1145 hdr = &elf_section_data (s)->this_hdr;
1146 if (hdr->sh_type != SHT_IA_64_UNWIND)
1147 continue;
1148
1149 if (s && (s->flags & SEC_LOAD))
1150 {
12bd6957 1151 for (m = elf_seg_map (abfd); m != NULL; m = m->next)
cbe79dfe
TG
1152 if (m->p_type == PT_IA_64_UNWIND)
1153 {
1154 int i;
1155
1156 /* Look through all sections in the unwind segment
1157 for a match since there may be multiple sections
1158 to a segment. */
1159 for (i = m->count - 1; i >= 0; --i)
1160 if (m->sections[i] == s)
1161 break;
1162
1163 if (i >= 0)
1164 break;
1165 }
1166
1167 if (m == NULL)
1168 {
1169 m = ((struct elf_segment_map *)
1170 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1171 if (m == NULL)
1172 return FALSE;
1173
1174 m->p_type = PT_IA_64_UNWIND;
1175 m->count = 1;
1176 m->sections[0] = s;
1177 m->next = NULL;
1178
1179 /* We want to put it last. */
12bd6957 1180 pm = &elf_seg_map (abfd);
cbe79dfe
TG
1181 while (*pm != NULL)
1182 pm = &(*pm)->next;
1183 *pm = m;
1184 }
1185 }
1186 }
1187
1188 return TRUE;
1189}
1190
1191/* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1192 the input sections for each output section in the segment and testing
1193 for SHF_IA_64_NORECOV on each. */
1194
1195static bfd_boolean
6d6c25c8 1196elfNN_ia64_modify_headers (bfd *abfd, struct bfd_link_info *info)
cbe79dfe
TG
1197{
1198 struct elf_obj_tdata *tdata = elf_tdata (abfd);
1199 struct elf_segment_map *m;
1200 Elf_Internal_Phdr *p;
1201
12bd6957 1202 for (p = tdata->phdr, m = elf_seg_map (abfd); m != NULL; m = m->next, p++)
cbe79dfe
TG
1203 if (m->p_type == PT_LOAD)
1204 {
1205 int i;
1206 for (i = m->count - 1; i >= 0; --i)
1207 {
1208 struct bfd_link_order *order = m->sections[i]->map_head.link_order;
1209
1210 while (order != NULL)
1211 {
1212 if (order->type == bfd_indirect_link_order)
1213 {
1214 asection *is = order->u.indirect.section;
1215 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1216 if (flags & SHF_IA_64_NORECOV)
1217 {
1218 p->p_flags |= PF_IA_64_NORECOV;
1219 goto found;
1220 }
1221 }
1222 order = order->next;
1223 }
1224 }
1225 found:;
1226 }
1227
6d6c25c8 1228 return _bfd_elf_modify_headers (abfd, info);
cbe79dfe
TG
1229}
1230
1231/* According to the Tahoe assembler spec, all labels starting with a
1232 '.' are local. */
1233
1234static bfd_boolean
1235elfNN_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
1236 const char *name)
1237{
1238 return name[0] == '.';
1239}
1240
1241/* Should we do dynamic things to this symbol? */
1242
1243static bfd_boolean
1244elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry *h,
1245 struct bfd_link_info *info, int r_type)
1246{
1247 bfd_boolean ignore_protected
1248 = ((r_type & 0xf8) == 0x40 /* FPTR relocs */
1249 || (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */
1250
1251 return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
1252}
1253\f
1254static struct bfd_hash_entry*
1255elfNN_ia64_new_elf_hash_entry (struct bfd_hash_entry *entry,
1256 struct bfd_hash_table *table,
1257 const char *string)
1258{
1259 struct elfNN_ia64_link_hash_entry *ret;
1260 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1261
1262 /* Allocate the structure if it has not already been allocated by a
1263 subclass. */
1264 if (!ret)
1265 ret = bfd_hash_allocate (table, sizeof (*ret));
1266
1267 if (!ret)
1268 return 0;
1269
1270 /* Call the allocation method of the superclass. */
1271 ret = ((struct elfNN_ia64_link_hash_entry *)
1272 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1273 table, string));
1274
1275 ret->info = NULL;
1276 ret->count = 0;
1277 ret->sorted_count = 0;
1278 ret->size = 0;
1279 return (struct bfd_hash_entry *) ret;
1280}
1281
1282static void
1283elfNN_ia64_hash_copy_indirect (struct bfd_link_info *info,
1284 struct elf_link_hash_entry *xdir,
1285 struct elf_link_hash_entry *xind)
1286{
1287 struct elfNN_ia64_link_hash_entry *dir, *ind;
1288
1289 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1290 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1291
1292 /* Copy down any references that we may have already seen to the
1293 symbol which just became indirect. */
1294
e81830c5
AM
1295 if (dir->root.versioned != versioned_hidden)
1296 dir->root.ref_dynamic |= ind->root.ref_dynamic;
cbe79dfe
TG
1297 dir->root.ref_regular |= ind->root.ref_regular;
1298 dir->root.ref_regular_nonweak |= ind->root.ref_regular_nonweak;
1299 dir->root.needs_plt |= ind->root.needs_plt;
1300
1301 if (ind->root.root.type != bfd_link_hash_indirect)
1302 return;
1303
1304 /* Copy over the got and plt data. This would have been done
1305 by check_relocs. */
1306
1307 if (ind->info != NULL)
1308 {
1309 struct elfNN_ia64_dyn_sym_info *dyn_i;
1310 unsigned int count;
1311
c9594989 1312 free (dir->info);
cbe79dfe
TG
1313
1314 dir->info = ind->info;
1315 dir->count = ind->count;
1316 dir->sorted_count = ind->sorted_count;
1317 dir->size = ind->size;
1318
1319 ind->info = NULL;
1320 ind->count = 0;
1321 ind->sorted_count = 0;
1322 ind->size = 0;
1323
1324 /* Fix up the dyn_sym_info pointers to the global symbol. */
1325 for (count = dir->count, dyn_i = dir->info;
1326 count != 0;
1327 count--, dyn_i++)
1328 dyn_i->h = &dir->root;
1329 }
1330
1331 /* Copy over the dynindx. */
1332
1333 if (ind->root.dynindx != -1)
1334 {
1335 if (dir->root.dynindx != -1)
1336 _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
1337 dir->root.dynstr_index);
1338 dir->root.dynindx = ind->root.dynindx;
1339 dir->root.dynstr_index = ind->root.dynstr_index;
1340 ind->root.dynindx = -1;
1341 ind->root.dynstr_index = 0;
1342 }
1343}
1344
1345static void
1346elfNN_ia64_hash_hide_symbol (struct bfd_link_info *info,
1347 struct elf_link_hash_entry *xh,
1348 bfd_boolean force_local)
1349{
1350 struct elfNN_ia64_link_hash_entry *h;
1351 struct elfNN_ia64_dyn_sym_info *dyn_i;
1352 unsigned int count;
1353
1354 h = (struct elfNN_ia64_link_hash_entry *)xh;
1355
1356 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1357
1358 for (count = h->count, dyn_i = h->info;
1359 count != 0;
1360 count--, dyn_i++)
1361 {
1362 dyn_i->want_plt2 = 0;
1363 dyn_i->want_plt = 0;
1364 }
1365}
1366
1367/* Compute a hash of a local hash entry. */
1368
1369static hashval_t
1370elfNN_ia64_local_htab_hash (const void *ptr)
1371{
1372 struct elfNN_ia64_local_hash_entry *entry
1373 = (struct elfNN_ia64_local_hash_entry *) ptr;
1374
1375 return ELF_LOCAL_SYMBOL_HASH (entry->id, entry->r_sym);
1376}
1377
1378/* Compare local hash entries. */
1379
1380static int
1381elfNN_ia64_local_htab_eq (const void *ptr1, const void *ptr2)
1382{
1383 struct elfNN_ia64_local_hash_entry *entry1
1384 = (struct elfNN_ia64_local_hash_entry *) ptr1;
1385 struct elfNN_ia64_local_hash_entry *entry2
1386 = (struct elfNN_ia64_local_hash_entry *) ptr2;
1387
1388 return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
1389}
1390
cbe79dfe
TG
1391/* Free the global elfNN_ia64_dyn_sym_info array. */
1392
1393static bfd_boolean
1394elfNN_ia64_global_dyn_info_free (void **xentry,
2c3fc389 1395 void * unused ATTRIBUTE_UNUSED)
cbe79dfe
TG
1396{
1397 struct elfNN_ia64_link_hash_entry *entry
1398 = (struct elfNN_ia64_link_hash_entry *) xentry;
1399
c9594989
AM
1400 free (entry->info);
1401 entry->info = NULL;
1402 entry->count = 0;
1403 entry->sorted_count = 0;
1404 entry->size = 0;
cbe79dfe
TG
1405
1406 return TRUE;
1407}
1408
1409/* Free the local elfNN_ia64_dyn_sym_info array. */
1410
1411static bfd_boolean
1412elfNN_ia64_local_dyn_info_free (void **slot,
2c3fc389 1413 void * unused ATTRIBUTE_UNUSED)
cbe79dfe
TG
1414{
1415 struct elfNN_ia64_local_hash_entry *entry
1416 = (struct elfNN_ia64_local_hash_entry *) *slot;
1417
c9594989
AM
1418 free (entry->info);
1419 entry->info = NULL;
1420 entry->count = 0;
1421 entry->sorted_count = 0;
1422 entry->size = 0;
cbe79dfe
TG
1423
1424 return TRUE;
1425}
1426
1427/* Destroy IA-64 linker hash table. */
1428
1429static void
d495ab0d 1430elfNN_ia64_link_hash_table_free (bfd *obfd)
cbe79dfe
TG
1431{
1432 struct elfNN_ia64_link_hash_table *ia64_info
d495ab0d 1433 = (struct elfNN_ia64_link_hash_table *) obfd->link.hash;
cbe79dfe
TG
1434 if (ia64_info->loc_hash_table)
1435 {
1436 htab_traverse (ia64_info->loc_hash_table,
1437 elfNN_ia64_local_dyn_info_free, NULL);
1438 htab_delete (ia64_info->loc_hash_table);
1439 }
1440 if (ia64_info->loc_hash_memory)
1441 objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
1442 elf_link_hash_traverse (&ia64_info->root,
1443 elfNN_ia64_global_dyn_info_free, NULL);
d495ab0d 1444 _bfd_elf_link_hash_table_free (obfd);
cbe79dfe
TG
1445}
1446
68faa637
AM
1447/* Create the derived linker hash table. The IA-64 ELF port uses this
1448 derived hash table to keep information specific to the IA-64 ElF
1449 linker (without using static variables). */
1450
1451static struct bfd_link_hash_table *
1452elfNN_ia64_hash_table_create (bfd *abfd)
1453{
1454 struct elfNN_ia64_link_hash_table *ret;
1455
1456 ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
1457 if (!ret)
1458 return NULL;
1459
1460 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1461 elfNN_ia64_new_elf_hash_entry,
1462 sizeof (struct elfNN_ia64_link_hash_entry),
1463 IA64_ELF_DATA))
1464 {
1465 free (ret);
1466 return NULL;
1467 }
1468
1469 ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
1470 elfNN_ia64_local_htab_eq, NULL);
1471 ret->loc_hash_memory = objalloc_create ();
1472 if (!ret->loc_hash_table || !ret->loc_hash_memory)
1473 {
d495ab0d 1474 elfNN_ia64_link_hash_table_free (abfd);
68faa637
AM
1475 return NULL;
1476 }
d495ab0d 1477 ret->root.root.hash_table_free = elfNN_ia64_link_hash_table_free;
3084d7a2 1478 ret->root.dt_pltgot_required = TRUE;
68faa637
AM
1479
1480 return &ret->root.root;
1481}
1482
cbe79dfe
TG
1483/* Traverse both local and global hash tables. */
1484
1485struct elfNN_ia64_dyn_sym_traverse_data
1486{
2c3fc389
NC
1487 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *);
1488 void * data;
cbe79dfe
TG
1489};
1490
1491static bfd_boolean
1492elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
2c3fc389 1493 void * xdata)
cbe79dfe
TG
1494{
1495 struct elfNN_ia64_link_hash_entry *entry
1496 = (struct elfNN_ia64_link_hash_entry *) xentry;
1497 struct elfNN_ia64_dyn_sym_traverse_data *data
1498 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1499 struct elfNN_ia64_dyn_sym_info *dyn_i;
1500 unsigned int count;
1501
cbe79dfe
TG
1502 for (count = entry->count, dyn_i = entry->info;
1503 count != 0;
1504 count--, dyn_i++)
1505 if (! (*data->func) (dyn_i, data->data))
1506 return FALSE;
1507 return TRUE;
1508}
1509
1510static bfd_boolean
2c3fc389 1511elfNN_ia64_local_dyn_sym_thunk (void **slot, void * xdata)
cbe79dfe
TG
1512{
1513 struct elfNN_ia64_local_hash_entry *entry
1514 = (struct elfNN_ia64_local_hash_entry *) *slot;
1515 struct elfNN_ia64_dyn_sym_traverse_data *data
1516 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1517 struct elfNN_ia64_dyn_sym_info *dyn_i;
1518 unsigned int count;
1519
1520 for (count = entry->count, dyn_i = entry->info;
1521 count != 0;
1522 count--, dyn_i++)
1523 if (! (*data->func) (dyn_i, data->data))
1524 return FALSE;
1525 return TRUE;
1526}
1527
1528static void
1529elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table *ia64_info,
2c3fc389
NC
1530 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *),
1531 void * data)
cbe79dfe
TG
1532{
1533 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1534
1535 xdata.func = func;
1536 xdata.data = data;
1537
1538 elf_link_hash_traverse (&ia64_info->root,
1539 elfNN_ia64_global_dyn_sym_thunk, &xdata);
1540 htab_traverse (ia64_info->loc_hash_table,
1541 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1542}
1543\f
1544static bfd_boolean
1545elfNN_ia64_create_dynamic_sections (bfd *abfd,
1546 struct bfd_link_info *info)
1547{
1548 struct elfNN_ia64_link_hash_table *ia64_info;
1549 asection *s;
1550
1551 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1552 return FALSE;
1553
1554 ia64_info = elfNN_ia64_hash_table (info);
1555 if (ia64_info == NULL)
1556 return FALSE;
1557
1558 {
fd361982
AM
1559 flagword flags = bfd_section_flags (ia64_info->root.sgot);
1560 bfd_set_section_flags (ia64_info->root.sgot, SEC_SMALL_DATA | flags);
cbe79dfe 1561 /* The .got section is always aligned at 8 bytes. */
fd361982 1562 if (!bfd_set_section_alignment (ia64_info->root.sgot, 3))
a253d456 1563 return FALSE;
cbe79dfe
TG
1564 }
1565
1566 if (!get_pltoff (abfd, info, ia64_info))
1567 return FALSE;
1568
3d4d4302
AM
1569 s = bfd_make_section_anyway_with_flags (abfd, ".rela.IA_64.pltoff",
1570 (SEC_ALLOC | SEC_LOAD
1571 | SEC_HAS_CONTENTS
1572 | SEC_IN_MEMORY
1573 | SEC_LINKER_CREATED
1574 | SEC_READONLY));
cbe79dfe 1575 if (s == NULL
fd361982 1576 || !bfd_set_section_alignment (s, LOG_SECTION_ALIGN))
cbe79dfe
TG
1577 return FALSE;
1578 ia64_info->rel_pltoff_sec = s;
1579
1580 return TRUE;
1581}
1582
1583/* Find and/or create a hash entry for local symbol. */
1584static struct elfNN_ia64_local_hash_entry *
1585get_local_sym_hash (struct elfNN_ia64_link_hash_table *ia64_info,
1586 bfd *abfd, const Elf_Internal_Rela *rel,
1587 bfd_boolean create)
1588{
1589 struct elfNN_ia64_local_hash_entry e, *ret;
1590 asection *sec = abfd->sections;
1591 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
1592 ELFNN_R_SYM (rel->r_info));
1593 void **slot;
1594
1595 e.id = sec->id;
1596 e.r_sym = ELFNN_R_SYM (rel->r_info);
1597 slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
1598 create ? INSERT : NO_INSERT);
1599
1600 if (!slot)
1601 return NULL;
1602
1603 if (*slot)
1604 return (struct elfNN_ia64_local_hash_entry *) *slot;
1605
1606 ret = (struct elfNN_ia64_local_hash_entry *)
1607 objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
1608 sizeof (struct elfNN_ia64_local_hash_entry));
1609 if (ret)
1610 {
1611 memset (ret, 0, sizeof (*ret));
1612 ret->id = sec->id;
1613 ret->r_sym = ELFNN_R_SYM (rel->r_info);
1614 *slot = ret;
1615 }
1616 return ret;
1617}
1618
1619/* Used to sort elfNN_ia64_dyn_sym_info array. */
1620
1621static int
1622addend_compare (const void *xp, const void *yp)
1623{
1624 const struct elfNN_ia64_dyn_sym_info *x
1625 = (const struct elfNN_ia64_dyn_sym_info *) xp;
1626 const struct elfNN_ia64_dyn_sym_info *y
1627 = (const struct elfNN_ia64_dyn_sym_info *) yp;
1628
1629 return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
1630}
1631
1632/* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
1633
1634static unsigned int
1635sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
1636 unsigned int count)
1637{
1638 bfd_vma curr, prev, got_offset;
1639 unsigned int i, kept, dupes, diff, dest, src, len;
1640
1641 qsort (info, count, sizeof (*info), addend_compare);
1642
1643 /* Find the first duplicate. */
1644 prev = info [0].addend;
1645 got_offset = info [0].got_offset;
1646 for (i = 1; i < count; i++)
1647 {
1648 curr = info [i].addend;
1649 if (curr == prev)
1650 {
1651 /* For duplicates, make sure that GOT_OFFSET is valid. */
1652 if (got_offset == (bfd_vma) -1)
1653 got_offset = info [i].got_offset;
1654 break;
1655 }
1656 got_offset = info [i].got_offset;
1657 prev = curr;
1658 }
1659
1660 /* We may move a block of elements to here. */
1661 dest = i++;
1662
1663 /* Remove duplicates. */
1664 if (i < count)
1665 {
1666 while (i < count)
1667 {
1668 /* For duplicates, make sure that the kept one has a valid
1669 got_offset. */
1670 kept = dest - 1;
1671 if (got_offset != (bfd_vma) -1)
1672 info [kept].got_offset = got_offset;
1673
1674 curr = info [i].addend;
1675 got_offset = info [i].got_offset;
1676
1677 /* Move a block of elements whose first one is different from
1678 the previous. */
1679 if (curr == prev)
1680 {
1681 for (src = i + 1; src < count; src++)
1682 {
1683 if (info [src].addend != curr)
1684 break;
1685 /* For duplicates, make sure that GOT_OFFSET is
1686 valid. */
1687 if (got_offset == (bfd_vma) -1)
1688 got_offset = info [src].got_offset;
1689 }
1690
1691 /* Make sure that the kept one has a valid got_offset. */
1692 if (got_offset != (bfd_vma) -1)
1693 info [kept].got_offset = got_offset;
1694 }
1695 else
1696 src = i;
1697
1698 if (src >= count)
1699 break;
1700
1701 /* Find the next duplicate. SRC will be kept. */
1702 prev = info [src].addend;
1703 got_offset = info [src].got_offset;
1704 for (dupes = src + 1; dupes < count; dupes ++)
1705 {
1706 curr = info [dupes].addend;
1707 if (curr == prev)
1708 {
1709 /* Make sure that got_offset is valid. */
1710 if (got_offset == (bfd_vma) -1)
1711 got_offset = info [dupes].got_offset;
1712
1713 /* For duplicates, make sure that the kept one has
1714 a valid got_offset. */
1715 if (got_offset != (bfd_vma) -1)
1716 info [dupes - 1].got_offset = got_offset;
1717 break;
1718 }
1719 got_offset = info [dupes].got_offset;
1720 prev = curr;
1721 }
1722
1723 /* How much to move. */
1724 len = dupes - src;
1725 i = dupes + 1;
1726
1727 if (len == 1 && dupes < count)
1728 {
1729 /* If we only move 1 element, we combine it with the next
1730 one. There must be at least a duplicate. Find the
1731 next different one. */
1732 for (diff = dupes + 1, src++; diff < count; diff++, src++)
1733 {
1734 if (info [diff].addend != curr)
1735 break;
1736 /* Make sure that got_offset is valid. */
1737 if (got_offset == (bfd_vma) -1)
1738 got_offset = info [diff].got_offset;
1739 }
1740
1741 /* Makre sure that the last duplicated one has an valid
1742 offset. */
1743 BFD_ASSERT (curr == prev);
1744 if (got_offset != (bfd_vma) -1)
1745 info [diff - 1].got_offset = got_offset;
1746
1747 if (diff < count)
1748 {
1749 /* Find the next duplicate. Track the current valid
1750 offset. */
1751 prev = info [diff].addend;
1752 got_offset = info [diff].got_offset;
1753 for (dupes = diff + 1; dupes < count; dupes ++)
1754 {
1755 curr = info [dupes].addend;
1756 if (curr == prev)
1757 {
1758 /* For duplicates, make sure that GOT_OFFSET
1759 is valid. */
1760 if (got_offset == (bfd_vma) -1)
1761 got_offset = info [dupes].got_offset;
1762 break;
1763 }
1764 got_offset = info [dupes].got_offset;
1765 prev = curr;
1766 diff++;
1767 }
1768
1769 len = diff - src + 1;
1770 i = diff + 1;
1771 }
1772 }
1773
1774 memmove (&info [dest], &info [src], len * sizeof (*info));
1775
1776 dest += len;
1777 }
1778
1779 count = dest;
1780 }
1781 else
1782 {
1783 /* When we get here, either there is no duplicate at all or
1784 the only duplicate is the last element. */
1785 if (dest < count)
1786 {
1787 /* If the last element is a duplicate, make sure that the
1788 kept one has a valid got_offset. We also update count. */
1789 if (got_offset != (bfd_vma) -1)
1790 info [dest - 1].got_offset = got_offset;
1791 count = dest;
1792 }
1793 }
1794
1795 return count;
1796}
1797
1798/* Find and/or create a descriptor for dynamic symbol info. This will
1799 vary based on global or local symbol, and the addend to the reloc.
1800
1801 We don't sort when inserting. Also, we sort and eliminate
1802 duplicates if there is an unsorted section. Typically, this will
1803 only happen once, because we do all insertions before lookups. We
1804 then use bsearch to do a lookup. This also allows lookups to be
1805 fast. So we have fast insertion (O(log N) due to duplicate check),
1806 fast lookup (O(log N)) and one sort (O(N log N) expected time).
1807 Previously, all lookups were O(N) because of the use of the linked
1808 list and also all insertions were O(N) because of the check for
1809 duplicates. There are some complications here because the array
1810 size grows occasionally, which may add an O(N) factor, but this
1811 should be rare. Also, we free the excess array allocation, which
1812 requires a copy which is O(N), but this only happens once. */
1813
1814static struct elfNN_ia64_dyn_sym_info *
1815get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
1816 struct elf_link_hash_entry *h, bfd *abfd,
1817 const Elf_Internal_Rela *rel, bfd_boolean create)
1818{
1819 struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
1820 unsigned int *count_p, *sorted_count_p, *size_p;
1821 unsigned int count, sorted_count, size;
1822 bfd_vma addend = rel ? rel->r_addend : 0;
1823 bfd_size_type amt;
1824
1825 if (h)
1826 {
1827 struct elfNN_ia64_link_hash_entry *global_h;
1828
1829 global_h = (struct elfNN_ia64_link_hash_entry *) h;
1830 info_p = &global_h->info;
1831 count_p = &global_h->count;
1832 sorted_count_p = &global_h->sorted_count;
1833 size_p = &global_h->size;
1834 }
1835 else
1836 {
1837 struct elfNN_ia64_local_hash_entry *loc_h;
1838
1839 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1840 if (!loc_h)
1841 {
1842 BFD_ASSERT (!create);
1843 return NULL;
1844 }
1845
1846 info_p = &loc_h->info;
1847 count_p = &loc_h->count;
1848 sorted_count_p = &loc_h->sorted_count;
1849 size_p = &loc_h->size;
1850 }
1851
1852 count = *count_p;
1853 sorted_count = *sorted_count_p;
1854 size = *size_p;
1855 info = *info_p;
1856 if (create)
1857 {
1858 /* When we create the array, we don't check for duplicates,
07d6d2b8 1859 except in the previously sorted section if one exists, and
cbe79dfe
TG
1860 against the last inserted entry. This allows insertions to
1861 be fast. */
1862 if (info)
1863 {
1864 if (sorted_count)
1865 {
1866 /* Try bsearch first on the sorted section. */
1867 key.addend = addend;
1868 dyn_i = bsearch (&key, info, sorted_count,
1869 sizeof (*info), addend_compare);
1870
1871 if (dyn_i)
1872 {
1873 return dyn_i;
1874 }
1875 }
1876
1877 /* Do a quick check for the last inserted entry. */
1878 dyn_i = info + count - 1;
1879 if (dyn_i->addend == addend)
1880 {
1881 return dyn_i;
1882 }
1883 }
1884
1885 if (size == 0)
1886 {
1887 /* It is the very first element. We create the array of size
1888 1. */
1889 size = 1;
1890 amt = size * sizeof (*info);
1891 info = bfd_malloc (amt);
1892 }
1893 else if (size <= count)
1894 {
1895 /* We double the array size every time when we reach the
1896 size limit. */
1897 size += size;
1898 amt = size * sizeof (*info);
1899 info = bfd_realloc (info, amt);
1900 }
1901 else
1902 goto has_space;
1903
1904 if (info == NULL)
1905 return NULL;
1906 *size_p = size;
1907 *info_p = info;
1908
dc1e8a47 1909 has_space:
cbe79dfe
TG
1910 /* Append the new one to the array. */
1911 dyn_i = info + count;
1912 memset (dyn_i, 0, sizeof (*dyn_i));
1913 dyn_i->got_offset = (bfd_vma) -1;
1914 dyn_i->addend = addend;
1915
1916 /* We increment count only since the new ones are unsorted and
1917 may have duplicate. */
1918 (*count_p)++;
1919 }
1920 else
1921 {
1922 /* It is a lookup without insertion. Sort array if part of the
1923 array isn't sorted. */
1924 if (count != sorted_count)
1925 {
1926 count = sort_dyn_sym_info (info, count);
1927 *count_p = count;
1928 *sorted_count_p = count;
1929 }
1930
1931 /* Free unused memory. */
1932 if (size != count)
1933 {
1934 amt = count * sizeof (*info);
1935 info = bfd_malloc (amt);
1936 if (info != NULL)
1937 {
1938 memcpy (info, *info_p, amt);
1939 free (*info_p);
1940 *size_p = count;
1941 *info_p = info;
1942 }
1943 }
1944
1945 key.addend = addend;
1946 dyn_i = bsearch (&key, info, count,
1947 sizeof (*info), addend_compare);
1948 }
1949
1950 return dyn_i;
1951}
1952
1953static asection *
1954get_got (bfd *abfd, struct bfd_link_info *info,
1955 struct elfNN_ia64_link_hash_table *ia64_info)
1956{
1957 asection *got;
1958 bfd *dynobj;
1959
1960 got = ia64_info->root.sgot;
1961 if (!got)
1962 {
1963 flagword flags;
1964
1965 dynobj = ia64_info->root.dynobj;
1966 if (!dynobj)
1967 ia64_info->root.dynobj = dynobj = abfd;
1968 if (!_bfd_elf_create_got_section (dynobj, info))
a253d456 1969 return NULL;
cbe79dfe
TG
1970
1971 got = ia64_info->root.sgot;
1972
1973 /* The .got section is always aligned at 8 bytes. */
fd361982 1974 if (!bfd_set_section_alignment (got, 3))
a253d456 1975 return NULL;
cbe79dfe 1976
fd361982
AM
1977 flags = bfd_section_flags (got);
1978 if (!bfd_set_section_flags (got, SEC_SMALL_DATA | flags))
a253d456 1979 return NULL;
cbe79dfe
TG
1980 }
1981
1982 return got;
1983}
1984
1985/* Create function descriptor section (.opd). This section is called .opd
1986 because it contains "official procedure descriptors". The "official"
1987 refers to the fact that these descriptors are used when taking the address
1988 of a procedure, thus ensuring a unique address for each procedure. */
1989
1990static asection *
1991get_fptr (bfd *abfd, struct bfd_link_info *info,
1992 struct elfNN_ia64_link_hash_table *ia64_info)
1993{
1994 asection *fptr;
1995 bfd *dynobj;
1996
1997 fptr = ia64_info->fptr_sec;
1998 if (!fptr)
1999 {
2000 dynobj = ia64_info->root.dynobj;
2001 if (!dynobj)
2002 ia64_info->root.dynobj = dynobj = abfd;
2003
3d4d4302
AM
2004 fptr = bfd_make_section_anyway_with_flags (dynobj, ".opd",
2005 (SEC_ALLOC
2006 | SEC_LOAD
2007 | SEC_HAS_CONTENTS
2008 | SEC_IN_MEMORY
0e1862bb
L
2009 | (bfd_link_pie (info)
2010 ? 0 : SEC_READONLY)
3d4d4302 2011 | SEC_LINKER_CREATED));
cbe79dfe 2012 if (!fptr
fd361982 2013 || !bfd_set_section_alignment (fptr, 4))
cbe79dfe
TG
2014 {
2015 BFD_ASSERT (0);
2016 return NULL;
2017 }
2018
2019 ia64_info->fptr_sec = fptr;
2020
0e1862bb 2021 if (bfd_link_pie (info))
cbe79dfe
TG
2022 {
2023 asection *fptr_rel;
3d4d4302
AM
2024 fptr_rel = bfd_make_section_anyway_with_flags (dynobj, ".rela.opd",
2025 (SEC_ALLOC | SEC_LOAD
2026 | SEC_HAS_CONTENTS
2027 | SEC_IN_MEMORY
2028 | SEC_LINKER_CREATED
2029 | SEC_READONLY));
cbe79dfe 2030 if (fptr_rel == NULL
fd361982 2031 || !bfd_set_section_alignment (fptr_rel, LOG_SECTION_ALIGN))
cbe79dfe
TG
2032 {
2033 BFD_ASSERT (0);
2034 return NULL;
2035 }
2036
2037 ia64_info->rel_fptr_sec = fptr_rel;
2038 }
2039 }
2040
2041 return fptr;
2042}
2043
2044static asection *
2045get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
2046 struct elfNN_ia64_link_hash_table *ia64_info)
2047{
2048 asection *pltoff;
2049 bfd *dynobj;
2050
2051 pltoff = ia64_info->pltoff_sec;
2052 if (!pltoff)
2053 {
2054 dynobj = ia64_info->root.dynobj;
2055 if (!dynobj)
2056 ia64_info->root.dynobj = dynobj = abfd;
2057
3d4d4302
AM
2058 pltoff = bfd_make_section_anyway_with_flags (dynobj,
2059 ELF_STRING_ia64_pltoff,
2060 (SEC_ALLOC
2061 | SEC_LOAD
2062 | SEC_HAS_CONTENTS
2063 | SEC_IN_MEMORY
2064 | SEC_SMALL_DATA
2065 | SEC_LINKER_CREATED));
cbe79dfe 2066 if (!pltoff
fd361982 2067 || !bfd_set_section_alignment (pltoff, 4))
cbe79dfe
TG
2068 {
2069 BFD_ASSERT (0);
2070 return NULL;
2071 }
2072
2073 ia64_info->pltoff_sec = pltoff;
2074 }
2075
2076 return pltoff;
2077}
2078
2079static asection *
2080get_reloc_section (bfd *abfd,
2081 struct elfNN_ia64_link_hash_table *ia64_info,
2082 asection *sec, bfd_boolean create)
2083{
2084 const char *srel_name;
2085 asection *srel;
2086 bfd *dynobj;
2087
2088 srel_name = (bfd_elf_string_from_elf_section
2089 (abfd, elf_elfheader(abfd)->e_shstrndx,
2090 _bfd_elf_single_rel_hdr (sec)->sh_name));
2091 if (srel_name == NULL)
2092 return NULL;
2093
2094 dynobj = ia64_info->root.dynobj;
2095 if (!dynobj)
2096 ia64_info->root.dynobj = dynobj = abfd;
2097
3d4d4302 2098 srel = bfd_get_linker_section (dynobj, srel_name);
cbe79dfe
TG
2099 if (srel == NULL && create)
2100 {
3d4d4302
AM
2101 srel = bfd_make_section_anyway_with_flags (dynobj, srel_name,
2102 (SEC_ALLOC | SEC_LOAD
2103 | SEC_HAS_CONTENTS
2104 | SEC_IN_MEMORY
2105 | SEC_LINKER_CREATED
2106 | SEC_READONLY));
cbe79dfe 2107 if (srel == NULL
fd361982 2108 || !bfd_set_section_alignment (srel, LOG_SECTION_ALIGN))
cbe79dfe
TG
2109 return NULL;
2110 }
2111
2112 return srel;
2113}
2114
2115static bfd_boolean
2116count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
2117 asection *srel, int type, bfd_boolean reltext)
2118{
2119 struct elfNN_ia64_dyn_reloc_entry *rent;
2120
2121 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2122 if (rent->srel == srel && rent->type == type)
2123 break;
2124
2125 if (!rent)
2126 {
2127 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2128 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2129 if (!rent)
2130 return FALSE;
2131
2132 rent->next = dyn_i->reloc_entries;
2133 rent->srel = srel;
2134 rent->type = type;
2135 rent->count = 0;
2136 dyn_i->reloc_entries = rent;
2137 }
23ebcd30 2138 rent->reltext = reltext;
cbe79dfe
TG
2139 rent->count++;
2140
2141 return TRUE;
2142}
2143
2144static bfd_boolean
2145elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
2146 asection *sec,
2147 const Elf_Internal_Rela *relocs)
2148{
2149 struct elfNN_ia64_link_hash_table *ia64_info;
2150 const Elf_Internal_Rela *relend;
2151 Elf_Internal_Shdr *symtab_hdr;
2152 const Elf_Internal_Rela *rel;
2153 asection *got, *fptr, *srel, *pltoff;
2154 enum {
2155 NEED_GOT = 1,
2156 NEED_GOTX = 2,
2157 NEED_FPTR = 4,
2158 NEED_PLTOFF = 8,
2159 NEED_MIN_PLT = 16,
2160 NEED_FULL_PLT = 32,
2161 NEED_DYNREL = 64,
2162 NEED_LTOFF_FPTR = 128,
2163 NEED_TPREL = 256,
2164 NEED_DTPMOD = 512,
2165 NEED_DTPREL = 1024
2166 };
2167 int need_entry;
2168 struct elf_link_hash_entry *h;
2169 unsigned long r_symndx;
2170 bfd_boolean maybe_dynamic;
2171
0e1862bb 2172 if (bfd_link_relocatable (info))
cbe79dfe
TG
2173 return TRUE;
2174
2175 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2176 ia64_info = elfNN_ia64_hash_table (info);
2177 if (ia64_info == NULL)
2178 return FALSE;
2179
2180 got = fptr = srel = pltoff = NULL;
2181
2182 relend = relocs + sec->reloc_count;
2183
2184 /* We scan relocations first to create dynamic relocation arrays. We
2185 modified get_dyn_sym_info to allow fast insertion and support fast
2186 lookup in the next loop. */
2187 for (rel = relocs; rel < relend; ++rel)
2188 {
2189 r_symndx = ELFNN_R_SYM (rel->r_info);
2190 if (r_symndx >= symtab_hdr->sh_info)
2191 {
2192 long indx = r_symndx - symtab_hdr->sh_info;
2193 h = elf_sym_hashes (abfd)[indx];
2194 while (h->root.type == bfd_link_hash_indirect
2195 || h->root.type == bfd_link_hash_warning)
2196 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2197 }
2198 else
2199 h = NULL;
2200
db41f6eb
L
2201 if (h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
2202 continue;
2203
cbe79dfe
TG
2204 /* We can only get preliminary data on whether a symbol is
2205 locally or externally defined, as not all of the input files
2206 have yet been processed. Do something with what we know, as
2207 this may help reduce memory usage and processing time later. */
0e1862bb 2208 maybe_dynamic = (h && ((!bfd_link_executable (info)
cbe79dfe
TG
2209 && (!SYMBOLIC_BIND (info, h)
2210 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2211 || !h->def_regular
2212 || h->root.type == bfd_link_hash_defweak));
2213
2214 need_entry = 0;
2215 switch (ELFNN_R_TYPE (rel->r_info))
2216 {
2217 case R_IA64_TPREL64MSB:
2218 case R_IA64_TPREL64LSB:
0e1862bb 2219 if (bfd_link_pic (info) || maybe_dynamic)
cbe79dfe
TG
2220 need_entry = NEED_DYNREL;
2221 break;
2222
2223 case R_IA64_LTOFF_TPREL22:
2224 need_entry = NEED_TPREL;
0e1862bb 2225 if (bfd_link_pic (info))
cbe79dfe
TG
2226 info->flags |= DF_STATIC_TLS;
2227 break;
2228
2229 case R_IA64_DTPREL32MSB:
2230 case R_IA64_DTPREL32LSB:
2231 case R_IA64_DTPREL64MSB:
2232 case R_IA64_DTPREL64LSB:
0e1862bb 2233 if (bfd_link_pic (info) || maybe_dynamic)
cbe79dfe
TG
2234 need_entry = NEED_DYNREL;
2235 break;
2236
2237 case R_IA64_LTOFF_DTPREL22:
2238 need_entry = NEED_DTPREL;
2239 break;
2240
2241 case R_IA64_DTPMOD64MSB:
2242 case R_IA64_DTPMOD64LSB:
0e1862bb 2243 if (bfd_link_pic (info) || maybe_dynamic)
cbe79dfe
TG
2244 need_entry = NEED_DYNREL;
2245 break;
2246
2247 case R_IA64_LTOFF_DTPMOD22:
2248 need_entry = NEED_DTPMOD;
2249 break;
2250
2251 case R_IA64_LTOFF_FPTR22:
2252 case R_IA64_LTOFF_FPTR64I:
2253 case R_IA64_LTOFF_FPTR32MSB:
2254 case R_IA64_LTOFF_FPTR32LSB:
2255 case R_IA64_LTOFF_FPTR64MSB:
2256 case R_IA64_LTOFF_FPTR64LSB:
2257 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2258 break;
2259
2260 case R_IA64_FPTR64I:
2261 case R_IA64_FPTR32MSB:
2262 case R_IA64_FPTR32LSB:
2263 case R_IA64_FPTR64MSB:
2264 case R_IA64_FPTR64LSB:
0e1862bb 2265 if (bfd_link_pic (info) || h)
cbe79dfe
TG
2266 need_entry = NEED_FPTR | NEED_DYNREL;
2267 else
2268 need_entry = NEED_FPTR;
2269 break;
2270
2271 case R_IA64_LTOFF22:
2272 case R_IA64_LTOFF64I:
2273 need_entry = NEED_GOT;
2274 break;
2275
2276 case R_IA64_LTOFF22X:
2277 need_entry = NEED_GOTX;
2278 break;
2279
2280 case R_IA64_PLTOFF22:
2281 case R_IA64_PLTOFF64I:
2282 case R_IA64_PLTOFF64MSB:
2283 case R_IA64_PLTOFF64LSB:
2284 need_entry = NEED_PLTOFF;
2285 if (h)
2286 {
2287 if (maybe_dynamic)
2288 need_entry |= NEED_MIN_PLT;
2289 }
2290 else
2291 {
2292 (*info->callbacks->warning)
2293 (info, _("@pltoff reloc against local symbol"), 0,
2294 abfd, 0, (bfd_vma) 0);
2295 }
2296 break;
2297
2298 case R_IA64_PCREL21B:
07d6d2b8 2299 case R_IA64_PCREL60B:
cbe79dfe
TG
2300 /* Depending on where this symbol is defined, we may or may not
2301 need a full plt entry. Only skip if we know we'll not need
2302 the entry -- static or symbolic, and the symbol definition
2303 has already been seen. */
2304 if (maybe_dynamic && rel->r_addend == 0)
2305 need_entry = NEED_FULL_PLT;
2306 break;
2307
2308 case R_IA64_IMM14:
2309 case R_IA64_IMM22:
2310 case R_IA64_IMM64:
2311 case R_IA64_DIR32MSB:
2312 case R_IA64_DIR32LSB:
2313 case R_IA64_DIR64MSB:
2314 case R_IA64_DIR64LSB:
2315 /* Shared objects will always need at least a REL relocation. */
0e1862bb 2316 if (bfd_link_pic (info) || maybe_dynamic)
cbe79dfe
TG
2317 need_entry = NEED_DYNREL;
2318 break;
2319
2320 case R_IA64_IPLTMSB:
2321 case R_IA64_IPLTLSB:
2322 /* Shared objects will always need at least a REL relocation. */
0e1862bb 2323 if (bfd_link_pic (info) || maybe_dynamic)
cbe79dfe
TG
2324 need_entry = NEED_DYNREL;
2325 break;
2326
2327 case R_IA64_PCREL22:
2328 case R_IA64_PCREL64I:
2329 case R_IA64_PCREL32MSB:
2330 case R_IA64_PCREL32LSB:
2331 case R_IA64_PCREL64MSB:
2332 case R_IA64_PCREL64LSB:
2333 if (maybe_dynamic)
2334 need_entry = NEED_DYNREL;
2335 break;
2336 }
2337
2338 if (!need_entry)
2339 continue;
2340
2341 if ((need_entry & NEED_FPTR) != 0
2342 && rel->r_addend)
2343 {
2344 (*info->callbacks->warning)
2345 (info, _("non-zero addend in @fptr reloc"), 0,
2346 abfd, 0, (bfd_vma) 0);
2347 }
2348
2349 if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
2350 return FALSE;
2351 }
2352
2353 /* Now, we only do lookup without insertion, which is very fast
2354 with the modified get_dyn_sym_info. */
2355 for (rel = relocs; rel < relend; ++rel)
2356 {
2357 struct elfNN_ia64_dyn_sym_info *dyn_i;
2358 int dynrel_type = R_IA64_NONE;
2359
2360 r_symndx = ELFNN_R_SYM (rel->r_info);
2361 if (r_symndx >= symtab_hdr->sh_info)
2362 {
2363 /* We're dealing with a global symbol -- find its hash entry
2364 and mark it as being referenced. */
2365 long indx = r_symndx - symtab_hdr->sh_info;
2366 h = elf_sym_hashes (abfd)[indx];
2367 while (h->root.type == bfd_link_hash_indirect
2368 || h->root.type == bfd_link_hash_warning)
2369 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2370
81fbe831
AM
2371 /* PR15323, ref flags aren't set for references in the same
2372 object. */
cbe79dfe
TG
2373 h->ref_regular = 1;
2374 }
2375 else
2376 h = NULL;
2377
db41f6eb
L
2378 if (h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
2379 continue;
2380
cbe79dfe
TG
2381 /* We can only get preliminary data on whether a symbol is
2382 locally or externally defined, as not all of the input files
2383 have yet been processed. Do something with what we know, as
2384 this may help reduce memory usage and processing time later. */
0e1862bb 2385 maybe_dynamic = (h && ((!bfd_link_executable (info)
cbe79dfe
TG
2386 && (!SYMBOLIC_BIND (info, h)
2387 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2388 || !h->def_regular
2389 || h->root.type == bfd_link_hash_defweak));
2390
2391 need_entry = 0;
2392 switch (ELFNN_R_TYPE (rel->r_info))
2393 {
2394 case R_IA64_TPREL64MSB:
2395 case R_IA64_TPREL64LSB:
0e1862bb 2396 if (bfd_link_pic (info) || maybe_dynamic)
cbe79dfe
TG
2397 need_entry = NEED_DYNREL;
2398 dynrel_type = R_IA64_TPREL64LSB;
0e1862bb 2399 if (bfd_link_pic (info))
cbe79dfe
TG
2400 info->flags |= DF_STATIC_TLS;
2401 break;
2402
2403 case R_IA64_LTOFF_TPREL22:
2404 need_entry = NEED_TPREL;
0e1862bb 2405 if (bfd_link_pic (info))
cbe79dfe
TG
2406 info->flags |= DF_STATIC_TLS;
2407 break;
2408
2409 case R_IA64_DTPREL32MSB:
2410 case R_IA64_DTPREL32LSB:
2411 case R_IA64_DTPREL64MSB:
2412 case R_IA64_DTPREL64LSB:
0e1862bb 2413 if (bfd_link_pic (info) || maybe_dynamic)
cbe79dfe
TG
2414 need_entry = NEED_DYNREL;
2415 dynrel_type = R_IA64_DTPRELNNLSB;
2416 break;
2417
2418 case R_IA64_LTOFF_DTPREL22:
2419 need_entry = NEED_DTPREL;
2420 break;
2421
2422 case R_IA64_DTPMOD64MSB:
2423 case R_IA64_DTPMOD64LSB:
0e1862bb 2424 if (bfd_link_pic (info) || maybe_dynamic)
cbe79dfe
TG
2425 need_entry = NEED_DYNREL;
2426 dynrel_type = R_IA64_DTPMOD64LSB;
2427 break;
2428
2429 case R_IA64_LTOFF_DTPMOD22:
2430 need_entry = NEED_DTPMOD;
2431 break;
2432
2433 case R_IA64_LTOFF_FPTR22:
2434 case R_IA64_LTOFF_FPTR64I:
2435 case R_IA64_LTOFF_FPTR32MSB:
2436 case R_IA64_LTOFF_FPTR32LSB:
2437 case R_IA64_LTOFF_FPTR64MSB:
2438 case R_IA64_LTOFF_FPTR64LSB:
2439 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2440 break;
2441
2442 case R_IA64_FPTR64I:
2443 case R_IA64_FPTR32MSB:
2444 case R_IA64_FPTR32LSB:
2445 case R_IA64_FPTR64MSB:
2446 case R_IA64_FPTR64LSB:
0e1862bb 2447 if (bfd_link_pic (info) || h)
cbe79dfe
TG
2448 need_entry = NEED_FPTR | NEED_DYNREL;
2449 else
2450 need_entry = NEED_FPTR;
2451 dynrel_type = R_IA64_FPTRNNLSB;
2452 break;
2453
2454 case R_IA64_LTOFF22:
2455 case R_IA64_LTOFF64I:
2456 need_entry = NEED_GOT;
2457 break;
2458
2459 case R_IA64_LTOFF22X:
2460 need_entry = NEED_GOTX;
2461 break;
2462
2463 case R_IA64_PLTOFF22:
2464 case R_IA64_PLTOFF64I:
2465 case R_IA64_PLTOFF64MSB:
2466 case R_IA64_PLTOFF64LSB:
2467 need_entry = NEED_PLTOFF;
2468 if (h)
2469 {
2470 if (maybe_dynamic)
2471 need_entry |= NEED_MIN_PLT;
2472 }
2473 break;
2474
2475 case R_IA64_PCREL21B:
07d6d2b8 2476 case R_IA64_PCREL60B:
cbe79dfe
TG
2477 /* Depending on where this symbol is defined, we may or may not
2478 need a full plt entry. Only skip if we know we'll not need
2479 the entry -- static or symbolic, and the symbol definition
2480 has already been seen. */
2481 if (maybe_dynamic && rel->r_addend == 0)
2482 need_entry = NEED_FULL_PLT;
2483 break;
2484
2485 case R_IA64_IMM14:
2486 case R_IA64_IMM22:
2487 case R_IA64_IMM64:
2488 case R_IA64_DIR32MSB:
2489 case R_IA64_DIR32LSB:
2490 case R_IA64_DIR64MSB:
2491 case R_IA64_DIR64LSB:
2492 /* Shared objects will always need at least a REL relocation. */
0e1862bb 2493 if (bfd_link_pic (info) || maybe_dynamic)
cbe79dfe
TG
2494 need_entry = NEED_DYNREL;
2495 dynrel_type = R_IA64_DIRNNLSB;
2496 break;
2497
2498 case R_IA64_IPLTMSB:
2499 case R_IA64_IPLTLSB:
2500 /* Shared objects will always need at least a REL relocation. */
0e1862bb 2501 if (bfd_link_pic (info) || maybe_dynamic)
cbe79dfe
TG
2502 need_entry = NEED_DYNREL;
2503 dynrel_type = R_IA64_IPLTLSB;
2504 break;
2505
2506 case R_IA64_PCREL22:
2507 case R_IA64_PCREL64I:
2508 case R_IA64_PCREL32MSB:
2509 case R_IA64_PCREL32LSB:
2510 case R_IA64_PCREL64MSB:
2511 case R_IA64_PCREL64LSB:
2512 if (maybe_dynamic)
2513 need_entry = NEED_DYNREL;
2514 dynrel_type = R_IA64_PCRELNNLSB;
2515 break;
2516 }
2517
2518 if (!need_entry)
2519 continue;
2520
2521 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
2522
2523 /* Record whether or not this is a local symbol. */
2524 dyn_i->h = h;
2525
2526 /* Create what's needed. */
2527 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2528 | NEED_DTPMOD | NEED_DTPREL))
2529 {
2530 if (!got)
2531 {
2532 got = get_got (abfd, info, ia64_info);
2533 if (!got)
2534 return FALSE;
2535 }
2536 if (need_entry & NEED_GOT)
2537 dyn_i->want_got = 1;
2538 if (need_entry & NEED_GOTX)
2539 dyn_i->want_gotx = 1;
2540 if (need_entry & NEED_TPREL)
2541 dyn_i->want_tprel = 1;
2542 if (need_entry & NEED_DTPMOD)
2543 dyn_i->want_dtpmod = 1;
2544 if (need_entry & NEED_DTPREL)
2545 dyn_i->want_dtprel = 1;
2546 }
2547 if (need_entry & NEED_FPTR)
2548 {
2549 if (!fptr)
2550 {
2551 fptr = get_fptr (abfd, info, ia64_info);
2552 if (!fptr)
2553 return FALSE;
2554 }
2555
2556 /* FPTRs for shared libraries are allocated by the dynamic
2557 linker. Make sure this local symbol will appear in the
2558 dynamic symbol table. */
0e1862bb 2559 if (!h && bfd_link_pic (info))
cbe79dfe
TG
2560 {
2561 if (! (bfd_elf_link_record_local_dynamic_symbol
2562 (info, abfd, (long) r_symndx)))
2563 return FALSE;
2564 }
2565
2566 dyn_i->want_fptr = 1;
2567 }
2568 if (need_entry & NEED_LTOFF_FPTR)
2569 dyn_i->want_ltoff_fptr = 1;
2570 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2571 {
07d6d2b8 2572 if (!ia64_info->root.dynobj)
cbe79dfe
TG
2573 ia64_info->root.dynobj = abfd;
2574 h->needs_plt = 1;
2575 dyn_i->want_plt = 1;
2576 }
2577 if (need_entry & NEED_FULL_PLT)
2578 dyn_i->want_plt2 = 1;
2579 if (need_entry & NEED_PLTOFF)
2580 {
2581 /* This is needed here, in case @pltoff is used in a non-shared
2582 link. */
2583 if (!pltoff)
2584 {
2585 pltoff = get_pltoff (abfd, info, ia64_info);
2586 if (!pltoff)
2587 return FALSE;
2588 }
2589
2590 dyn_i->want_pltoff = 1;
2591 }
2592 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2593 {
2594 if (!srel)
2595 {
2596 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
2597 if (!srel)
2598 return FALSE;
2599 }
2600 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
2601 (sec->flags & SEC_READONLY) != 0))
2602 return FALSE;
2603 }
2604 }
2605
2606 return TRUE;
2607}
2608
2609/* For cleanliness, and potentially faster dynamic loading, allocate
2610 external GOT entries first. */
2611
2612static bfd_boolean
2613allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
2614 void * data)
2615{
2616 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2617
2618 if ((dyn_i->want_got || dyn_i->want_gotx)
2619 && ! dyn_i->want_fptr
2620 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2621 {
2622 dyn_i->got_offset = x->ofs;
2623 x->ofs += 8;
2624 }
2625 if (dyn_i->want_tprel)
2626 {
2627 dyn_i->tprel_offset = x->ofs;
2628 x->ofs += 8;
2629 }
2630 if (dyn_i->want_dtpmod)
2631 {
2632 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2633 {
2634 dyn_i->dtpmod_offset = x->ofs;
2635 x->ofs += 8;
2636 }
2637 else
2638 {
2639 struct elfNN_ia64_link_hash_table *ia64_info;
2640
2641 ia64_info = elfNN_ia64_hash_table (x->info);
2642 if (ia64_info == NULL)
2643 return FALSE;
2644
2645 if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
2646 {
2647 ia64_info->self_dtpmod_offset = x->ofs;
2648 x->ofs += 8;
2649 }
2650 dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
2651 }
2652 }
2653 if (dyn_i->want_dtprel)
2654 {
2655 dyn_i->dtprel_offset = x->ofs;
2656 x->ofs += 8;
2657 }
2658 return TRUE;
2659}
2660
2661/* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2662
2663static bfd_boolean
2664allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
2665 void * data)
2666{
2667 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2668
2669 if (dyn_i->want_got
2670 && dyn_i->want_fptr
2671 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
2672 {
2673 dyn_i->got_offset = x->ofs;
2674 x->ofs += 8;
2675 }
2676 return TRUE;
2677}
2678
2679/* Lastly, allocate all the GOT entries for local data. */
2680
2681static bfd_boolean
2682allocate_local_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
2c3fc389 2683 void * data)
cbe79dfe
TG
2684{
2685 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2686
2687 if ((dyn_i->want_got || dyn_i->want_gotx)
2688 && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2689 {
2690 dyn_i->got_offset = x->ofs;
2691 x->ofs += 8;
2692 }
2693 return TRUE;
2694}
2695
2696/* Search for the index of a global symbol in it's defining object file. */
2697
2698static long
2699global_sym_index (struct elf_link_hash_entry *h)
2700{
2701 struct elf_link_hash_entry **p;
2702 bfd *obj;
2703
2704 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2705 || h->root.type == bfd_link_hash_defweak);
2706
2707 obj = h->root.u.def.section->owner;
2708 for (p = elf_sym_hashes (obj); *p != h; ++p)
2709 continue;
2710
2711 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2712}
2713
2714/* Allocate function descriptors. We can do these for every function
2715 in a main executable that is not exported. */
2716
2717static bfd_boolean
2c3fc389 2718allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data)
cbe79dfe
TG
2719{
2720 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2721
2722 if (dyn_i->want_fptr)
2723 {
2724 struct elf_link_hash_entry *h = dyn_i->h;
2725
2726 if (h)
2727 while (h->root.type == bfd_link_hash_indirect
2728 || h->root.type == bfd_link_hash_warning)
2729 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2730
0e1862bb 2731 if (!bfd_link_executable (x->info)
cbe79dfe 2732 && (!h
db41f6eb
L
2733 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2734 && !UNDEFWEAK_NO_DYNAMIC_RELOC (x->info, h))
cbe79dfe
TG
2735 || (h->root.type != bfd_link_hash_undefweak
2736 && h->root.type != bfd_link_hash_undefined)))
2737 {
2738 if (h && h->dynindx == -1)
2739 {
2740 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2741 || (h->root.type == bfd_link_hash_defweak));
2742
2743 if (!bfd_elf_link_record_local_dynamic_symbol
2744 (x->info, h->root.u.def.section->owner,
2745 global_sym_index (h)))
2746 return FALSE;
2747 }
2748
2749 dyn_i->want_fptr = 0;
2750 }
2751 else if (h == NULL || h->dynindx == -1)
2752 {
2753 dyn_i->fptr_offset = x->ofs;
2754 x->ofs += 16;
2755 }
2756 else
2757 dyn_i->want_fptr = 0;
2758 }
2759 return TRUE;
2760}
2761
2762/* Allocate all the minimal PLT entries. */
2763
2764static bfd_boolean
2765allocate_plt_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2c3fc389 2766 void * data)
cbe79dfe
TG
2767{
2768 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2769
2770 if (dyn_i->want_plt)
2771 {
2772 struct elf_link_hash_entry *h = dyn_i->h;
2773
2774 if (h)
2775 while (h->root.type == bfd_link_hash_indirect
2776 || h->root.type == bfd_link_hash_warning)
2777 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2778
2779 /* ??? Versioned symbols seem to lose NEEDS_PLT. */
2780 if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
2781 {
2782 bfd_size_type offset = x->ofs;
2783 if (offset == 0)
2784 offset = PLT_HEADER_SIZE;
2785 dyn_i->plt_offset = offset;
2786 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2787
2788 dyn_i->want_pltoff = 1;
2789 }
2790 else
2791 {
2792 dyn_i->want_plt = 0;
2793 dyn_i->want_plt2 = 0;
2794 }
2795 }
2796 return TRUE;
2797}
2798
2799/* Allocate all the full PLT entries. */
2800
2801static bfd_boolean
2802allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2c3fc389 2803 void * data)
cbe79dfe
TG
2804{
2805 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2806
2807 if (dyn_i->want_plt2)
2808 {
2809 struct elf_link_hash_entry *h = dyn_i->h;
2810 bfd_size_type ofs = x->ofs;
2811
2812 dyn_i->plt2_offset = ofs;
2813 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2814
2815 while (h->root.type == bfd_link_hash_indirect
2816 || h->root.type == bfd_link_hash_warning)
2817 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2818 dyn_i->h->plt.offset = ofs;
2819 }
2820 return TRUE;
2821}
2822
2823/* Allocate all the PLTOFF entries requested by relocations and
2824 plt entries. We can't share space with allocated FPTR entries,
2825 because the latter are not necessarily addressable by the GP.
2826 ??? Relaxation might be able to determine that they are. */
2827
2828static bfd_boolean
2829allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2c3fc389 2830 void * data)
cbe79dfe
TG
2831{
2832 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2833
2834 if (dyn_i->want_pltoff)
2835 {
2836 dyn_i->pltoff_offset = x->ofs;
2837 x->ofs += 16;
2838 }
2839 return TRUE;
2840}
2841
2842/* Allocate dynamic relocations for those symbols that turned out
2843 to be dynamic. */
2844
2845static bfd_boolean
2846allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2c3fc389 2847 void * data)
cbe79dfe
TG
2848{
2849 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2850 struct elfNN_ia64_link_hash_table *ia64_info;
2851 struct elfNN_ia64_dyn_reloc_entry *rent;
2852 bfd_boolean dynamic_symbol, shared, resolved_zero;
2853
2854 ia64_info = elfNN_ia64_hash_table (x->info);
2855 if (ia64_info == NULL)
2856 return FALSE;
2857
2858 /* Note that this can't be used in relation to FPTR relocs below. */
2859 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
2860
0e1862bb 2861 shared = bfd_link_pic (x->info);
cbe79dfe 2862 resolved_zero = (dyn_i->h
db41f6eb
L
2863 && UNDEFWEAK_NO_DYNAMIC_RELOC (x->info,
2864 dyn_i->h));
cbe79dfe
TG
2865
2866 /* Take care of the GOT and PLT relocations. */
2867
2868 if ((!resolved_zero
2869 && (dynamic_symbol || shared)
2870 && (dyn_i->want_got || dyn_i->want_gotx))
2871 || (dyn_i->want_ltoff_fptr
2872 && dyn_i->h
2873 && dyn_i->h->dynindx != -1))
2874 {
2875 if (!dyn_i->want_ltoff_fptr
0e1862bb 2876 || !bfd_link_pie (x->info)
cbe79dfe
TG
2877 || dyn_i->h == NULL
2878 || dyn_i->h->root.type != bfd_link_hash_undefweak)
2879 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2880 }
2881 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2882 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2883 if (dynamic_symbol && dyn_i->want_dtpmod)
2884 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2885 if (dynamic_symbol && dyn_i->want_dtprel)
2886 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2887
2888 if (x->only_got)
2889 return TRUE;
2890
2891 if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
2892 {
2893 if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
2894 ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
2895 }
2896
2897 if (!resolved_zero && dyn_i->want_pltoff)
2898 {
2899 bfd_size_type t = 0;
2900
2901 /* Dynamic symbols get one IPLT relocation. Local symbols in
2902 shared libraries get two REL relocations. Local symbols in
2903 main applications get nothing. */
2904 if (dynamic_symbol)
2905 t = sizeof (ElfNN_External_Rela);
2906 else if (shared)
2907 t = 2 * sizeof (ElfNN_External_Rela);
2908
2909 ia64_info->rel_pltoff_sec->size += t;
2910 }
2911
2912 /* Take care of the normal data relocations. */
2913
2914 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2915 {
2916 int count = rent->count;
2917
2918 switch (rent->type)
2919 {
2920 case R_IA64_FPTR32LSB:
2921 case R_IA64_FPTR64LSB:
2922 /* Allocate one iff !want_fptr and not PIE, which by this point
2923 will be true only if we're actually allocating one statically
2924 in the main executable. Position independent executables
2925 need a relative reloc. */
0e1862bb 2926 if (dyn_i->want_fptr && !bfd_link_pie (x->info))
cbe79dfe
TG
2927 continue;
2928 break;
2929 case R_IA64_PCREL32LSB:
2930 case R_IA64_PCREL64LSB:
2931 if (!dynamic_symbol)
2932 continue;
2933 break;
2934 case R_IA64_DIR32LSB:
2935 case R_IA64_DIR64LSB:
2936 if (!dynamic_symbol && !shared)
2937 continue;
2938 break;
2939 case R_IA64_IPLTLSB:
2940 if (!dynamic_symbol && !shared)
2941 continue;
2942 /* Use two REL relocations for IPLT relocations
2943 against local symbols. */
2944 if (!dynamic_symbol)
2945 count *= 2;
2946 break;
2947 case R_IA64_DTPREL32LSB:
2948 case R_IA64_TPREL64LSB:
2949 case R_IA64_DTPREL64LSB:
2950 case R_IA64_DTPMOD64LSB:
2951 break;
2952 default:
2953 abort ();
2954 }
2955 if (rent->reltext)
447f6d86 2956 x->info->flags |= DF_TEXTREL;
cbe79dfe
TG
2957 rent->srel->size += sizeof (ElfNN_External_Rela) * count;
2958 }
2959
2960 return TRUE;
2961}
2962
2963static bfd_boolean
2964elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2965 struct elf_link_hash_entry *h)
2966{
2967 /* ??? Undefined symbols with PLT entries should be re-defined
2968 to be the PLT entry. */
2969
2970 /* If this is a weak symbol, and there is a real definition, the
2971 processor independent code will have arranged for us to see the
2972 real definition first, and we can just use the same value. */
60d67dc8 2973 if (h->is_weakalias)
cbe79dfe 2974 {
60d67dc8
AM
2975 struct elf_link_hash_entry *def = weakdef (h);
2976 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
2977 h->root.u.def.section = def->root.u.def.section;
2978 h->root.u.def.value = def->root.u.def.value;
cbe79dfe
TG
2979 return TRUE;
2980 }
2981
2982 /* If this is a reference to a symbol defined by a dynamic object which
2983 is not a function, we might allocate the symbol in our .dynbss section
2984 and allocate a COPY dynamic relocation.
2985
2986 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2987 of hackery. */
2988
2989 return TRUE;
2990}
2991
2992static bfd_boolean
2993elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2994 struct bfd_link_info *info)
2995{
2996 struct elfNN_ia64_allocate_data data;
2997 struct elfNN_ia64_link_hash_table *ia64_info;
2998 asection *sec;
2999 bfd *dynobj;
cbe79dfe 3000
cbe79dfe
TG
3001 ia64_info = elfNN_ia64_hash_table (info);
3002 if (ia64_info == NULL)
3003 return FALSE;
ce558b89 3004 dynobj = ia64_info->root.dynobj;
cbe79dfe
TG
3005 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
3006 BFD_ASSERT(dynobj != NULL);
3007 data.info = info;
3008
3009 /* Set the contents of the .interp section to the interpreter. */
3010 if (ia64_info->root.dynamic_sections_created
9b8b325a 3011 && bfd_link_executable (info) && !info->nointerp)
cbe79dfe 3012 {
3d4d4302 3013 sec = bfd_get_linker_section (dynobj, ".interp");
cbe79dfe
TG
3014 BFD_ASSERT (sec != NULL);
3015 sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3016 sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3017 }
3018
3019 /* Allocate the GOT entries. */
3020
3021 if (ia64_info->root.sgot)
3022 {
3023 data.ofs = 0;
3024 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
3025 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
3026 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
3027 ia64_info->root.sgot->size = data.ofs;
3028 }
3029
3030 /* Allocate the FPTR entries. */
3031
3032 if (ia64_info->fptr_sec)
3033 {
3034 data.ofs = 0;
3035 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
3036 ia64_info->fptr_sec->size = data.ofs;
3037 }
3038
3039 /* Now that we've seen all of the input files, we can decide which
3040 symbols need plt entries. Allocate the minimal PLT entries first.
3041 We do this even though dynamic_sections_created may be FALSE, because
3042 this has the side-effect of clearing want_plt and want_plt2. */
3043
3044 data.ofs = 0;
3045 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
3046
3047 ia64_info->minplt_entries = 0;
3048 if (data.ofs)
3049 {
3050 ia64_info->minplt_entries
3051 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3052 }
3053
3054 /* Align the pointer for the plt2 entries. */
3055 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
3056
3057 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
3058 if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
3059 {
3060 /* FIXME: we always reserve the memory for dynamic linker even if
3061 there are no PLT entries since dynamic linker may assume the
3062 reserved memory always exists. */
3063
3064 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
3065
3066 ia64_info->root.splt->size = data.ofs;
3067
3068 /* If we've got a .plt, we need some extra memory for the dynamic
3069 linker. We stuff these in .got.plt. */
ce558b89 3070 ia64_info->root.sgotplt->size = 8 * PLT_RESERVED_WORDS;
cbe79dfe
TG
3071 }
3072
3073 /* Allocate the PLTOFF entries. */
3074
3075 if (ia64_info->pltoff_sec)
3076 {
3077 data.ofs = 0;
3078 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
3079 ia64_info->pltoff_sec->size = data.ofs;
3080 }
3081
3082 if (ia64_info->root.dynamic_sections_created)
3083 {
3084 /* Allocate space for the dynamic relocations that turned out to be
3085 required. */
3086
0e1862bb 3087 if (bfd_link_pic (info) && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
cbe79dfe
TG
3088 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
3089 data.only_got = FALSE;
3090 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
3091 }
3092
3093 /* We have now determined the sizes of the various dynamic sections.
3094 Allocate memory for them. */
3095 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
3096 {
3097 bfd_boolean strip;
3098
3099 if (!(sec->flags & SEC_LINKER_CREATED))
3100 continue;
3101
3102 /* If we don't need this section, strip it from the output file.
3103 There were several sections primarily related to dynamic
3104 linking that must be create before the linker maps input
3105 sections to output sections. The linker does that before
3106 bfd_elf_size_dynamic_sections is called, and it is that
3107 function which decides whether anything needs to go into
3108 these sections. */
3109
3110 strip = (sec->size == 0);
3111
3112 if (sec == ia64_info->root.sgot)
3113 strip = FALSE;
3114 else if (sec == ia64_info->root.srelgot)
3115 {
3116 if (strip)
3117 ia64_info->root.srelgot = NULL;
3118 else
3119 /* We use the reloc_count field as a counter if we need to
3120 copy relocs into the output file. */
3121 sec->reloc_count = 0;
3122 }
3123 else if (sec == ia64_info->fptr_sec)
3124 {
3125 if (strip)
3126 ia64_info->fptr_sec = NULL;
3127 }
3128 else if (sec == ia64_info->rel_fptr_sec)
3129 {
3130 if (strip)
3131 ia64_info->rel_fptr_sec = NULL;
3132 else
3133 /* We use the reloc_count field as a counter if we need to
3134 copy relocs into the output file. */
3135 sec->reloc_count = 0;
3136 }
3137 else if (sec == ia64_info->root.splt)
3138 {
3139 if (strip)
3140 ia64_info->root.splt = NULL;
3141 }
3142 else if (sec == ia64_info->pltoff_sec)
3143 {
3144 if (strip)
3145 ia64_info->pltoff_sec = NULL;
3146 }
3147 else if (sec == ia64_info->rel_pltoff_sec)
3148 {
3149 if (strip)
3150 ia64_info->rel_pltoff_sec = NULL;
3151 else
3152 {
3084d7a2 3153 ia64_info->root.dt_jmprel_required = TRUE;
cbe79dfe
TG
3154 /* We use the reloc_count field as a counter if we need to
3155 copy relocs into the output file. */
3156 sec->reloc_count = 0;
3157 }
3158 }
3159 else
3160 {
3161 const char *name;
3162
3163 /* It's OK to base decisions on the section name, because none
3164 of the dynobj section names depend upon the input files. */
fd361982 3165 name = bfd_section_name (sec);
cbe79dfe
TG
3166
3167 if (strcmp (name, ".got.plt") == 0)
3168 strip = FALSE;
3169 else if (CONST_STRNEQ (name, ".rel"))
3170 {
3171 if (!strip)
3172 {
3173 /* We use the reloc_count field as a counter if we need to
3174 copy relocs into the output file. */
3175 sec->reloc_count = 0;
3176 }
3177 }
3178 else
3179 continue;
3180 }
3181
3182 if (strip)
3183 sec->flags |= SEC_EXCLUDE;
3184 else
3185 {
3186 /* Allocate memory for the section contents. */
3187 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
3188 if (sec->contents == NULL && sec->size != 0)
3189 return FALSE;
3190 }
3191 }
3192
ce558b89 3193 if (ia64_info->root.dynamic_sections_created)
cbe79dfe
TG
3194 {
3195 /* Add some entries to the .dynamic section. We fill in the values
3196 later (in finish_dynamic_sections) but we must add the entries now
3197 so that we get the correct size for the .dynamic section. */
3198
cbe79dfe
TG
3199#define add_dynamic_entry(TAG, VAL) \
3200 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3201
3084d7a2 3202 if (!_bfd_elf_add_dynamic_tags (output_bfd, info, TRUE))
cbe79dfe
TG
3203 return FALSE;
3204
3084d7a2 3205 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
cbe79dfe 3206 return FALSE;
cbe79dfe
TG
3207 }
3208
3209 /* ??? Perhaps force __gp local. */
3210
3211 return TRUE;
3212}
3213
3214static void
3215elfNN_ia64_install_dyn_reloc (bfd *abfd, struct bfd_link_info *info,
3216 asection *sec, asection *srel,
3217 bfd_vma offset, unsigned int type,
3218 long dynindx, bfd_vma addend)
3219{
3220 Elf_Internal_Rela outrel;
3221 bfd_byte *loc;
3222
3223 BFD_ASSERT (dynindx != -1);
3224 outrel.r_info = ELFNN_R_INFO (dynindx, type);
3225 outrel.r_addend = addend;
3226 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3227 if (outrel.r_offset >= (bfd_vma) -2)
3228 {
3229 /* Run for the hills. We shouldn't be outputting a relocation
3230 for this. So do what everyone else does and output a no-op. */
3231 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3232 outrel.r_addend = 0;
3233 outrel.r_offset = 0;
3234 }
3235 else
3236 outrel.r_offset += sec->output_section->vma + sec->output_offset;
3237
3238 loc = srel->contents;
3239 loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3240 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3241 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
3242}
3243
3244/* Store an entry for target address TARGET_ADDR in the linkage table
3245 and return the gp-relative address of the linkage table entry. */
3246
3247static bfd_vma
3248set_got_entry (bfd *abfd, struct bfd_link_info *info,
3249 struct elfNN_ia64_dyn_sym_info *dyn_i,
3250 long dynindx, bfd_vma addend, bfd_vma value,
3251 unsigned int dyn_r_type)
3252{
3253 struct elfNN_ia64_link_hash_table *ia64_info;
3254 asection *got_sec;
3255 bfd_boolean done;
3256 bfd_vma got_offset;
3257
3258 ia64_info = elfNN_ia64_hash_table (info);
3259 if (ia64_info == NULL)
3260 return 0;
3261
3262 got_sec = ia64_info->root.sgot;
3263
3264 switch (dyn_r_type)
3265 {
3266 case R_IA64_TPREL64LSB:
3267 done = dyn_i->tprel_done;
3268 dyn_i->tprel_done = TRUE;
3269 got_offset = dyn_i->tprel_offset;
3270 break;
3271 case R_IA64_DTPMOD64LSB:
3272 if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3273 {
3274 done = dyn_i->dtpmod_done;
3275 dyn_i->dtpmod_done = TRUE;
3276 }
3277 else
3278 {
3279 done = ia64_info->self_dtpmod_done;
3280 ia64_info->self_dtpmod_done = TRUE;
3281 dynindx = 0;
3282 }
3283 got_offset = dyn_i->dtpmod_offset;
3284 break;
3285 case R_IA64_DTPREL32LSB:
3286 case R_IA64_DTPREL64LSB:
3287 done = dyn_i->dtprel_done;
3288 dyn_i->dtprel_done = TRUE;
3289 got_offset = dyn_i->dtprel_offset;
3290 break;
3291 default:
3292 done = dyn_i->got_done;
3293 dyn_i->got_done = TRUE;
3294 got_offset = dyn_i->got_offset;
3295 break;
3296 }
3297
3298 BFD_ASSERT ((got_offset & 7) == 0);
3299
3300 if (! done)
3301 {
3302 /* Store the target address in the linkage table entry. */
3303 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3304
3305 /* Install a dynamic relocation if needed. */
0e1862bb 3306 if (((bfd_link_pic (info)
cbe79dfe 3307 && (!dyn_i->h
db41f6eb
L
3308 || (ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3309 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, dyn_i->h))
cbe79dfe
TG
3310 || dyn_i->h->root.type != bfd_link_hash_undefweak)
3311 && dyn_r_type != R_IA64_DTPREL32LSB
3312 && dyn_r_type != R_IA64_DTPREL64LSB)
07d6d2b8 3313 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
cbe79dfe
TG
3314 || (dynindx != -1
3315 && (dyn_r_type == R_IA64_FPTR32LSB
3316 || dyn_r_type == R_IA64_FPTR64LSB)))
3317 && (!dyn_i->want_ltoff_fptr
0e1862bb 3318 || !bfd_link_pie (info)
cbe79dfe
TG
3319 || !dyn_i->h
3320 || dyn_i->h->root.type != bfd_link_hash_undefweak))
3321 {
3322 if (dynindx == -1
3323 && dyn_r_type != R_IA64_TPREL64LSB
3324 && dyn_r_type != R_IA64_DTPMOD64LSB
3325 && dyn_r_type != R_IA64_DTPREL32LSB
3326 && dyn_r_type != R_IA64_DTPREL64LSB)
3327 {
3328 dyn_r_type = R_IA64_RELNNLSB;
3329 dynindx = 0;
3330 addend = value;
3331 }
3332
3333 if (bfd_big_endian (abfd))
3334 {
3335 switch (dyn_r_type)
3336 {
3337 case R_IA64_REL32LSB:
3338 dyn_r_type = R_IA64_REL32MSB;
3339 break;
3340 case R_IA64_DIR32LSB:
3341 dyn_r_type = R_IA64_DIR32MSB;
3342 break;
3343 case R_IA64_FPTR32LSB:
3344 dyn_r_type = R_IA64_FPTR32MSB;
3345 break;
3346 case R_IA64_DTPREL32LSB:
3347 dyn_r_type = R_IA64_DTPREL32MSB;
3348 break;
3349 case R_IA64_REL64LSB:
3350 dyn_r_type = R_IA64_REL64MSB;
3351 break;
3352 case R_IA64_DIR64LSB:
3353 dyn_r_type = R_IA64_DIR64MSB;
3354 break;
3355 case R_IA64_FPTR64LSB:
3356 dyn_r_type = R_IA64_FPTR64MSB;
3357 break;
3358 case R_IA64_TPREL64LSB:
3359 dyn_r_type = R_IA64_TPREL64MSB;
3360 break;
3361 case R_IA64_DTPMOD64LSB:
3362 dyn_r_type = R_IA64_DTPMOD64MSB;
3363 break;
3364 case R_IA64_DTPREL64LSB:
3365 dyn_r_type = R_IA64_DTPREL64MSB;
3366 break;
3367 default:
3368 BFD_ASSERT (FALSE);
3369 break;
3370 }
3371 }
3372
3373 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3374 ia64_info->root.srelgot,
3375 got_offset, dyn_r_type,
3376 dynindx, addend);
3377 }
3378 }
3379
3380 /* Return the address of the linkage table entry. */
3381 value = (got_sec->output_section->vma
3382 + got_sec->output_offset
3383 + got_offset);
3384
3385 return value;
3386}
3387
3388/* Fill in a function descriptor consisting of the function's code
3389 address and its global pointer. Return the descriptor's address. */
3390
3391static bfd_vma
3392set_fptr_entry (bfd *abfd, struct bfd_link_info *info,
3393 struct elfNN_ia64_dyn_sym_info *dyn_i,
3394 bfd_vma value)
3395{
3396 struct elfNN_ia64_link_hash_table *ia64_info;
3397 asection *fptr_sec;
3398
3399 ia64_info = elfNN_ia64_hash_table (info);
3400 if (ia64_info == NULL)
3401 return 0;
3402
3403 fptr_sec = ia64_info->fptr_sec;
3404
3405 if (!dyn_i->fptr_done)
3406 {
3407 dyn_i->fptr_done = 1;
3408
3409 /* Fill in the function descriptor. */
3410 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3411 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3412 fptr_sec->contents + dyn_i->fptr_offset + 8);
3413 if (ia64_info->rel_fptr_sec)
3414 {
3415 Elf_Internal_Rela outrel;
3416 bfd_byte *loc;
3417
3418 if (bfd_little_endian (abfd))
3419 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
3420 else
3421 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
3422 outrel.r_addend = value;
3423 outrel.r_offset = (fptr_sec->output_section->vma
3424 + fptr_sec->output_offset
3425 + dyn_i->fptr_offset);
3426 loc = ia64_info->rel_fptr_sec->contents;
3427 loc += ia64_info->rel_fptr_sec->reloc_count++
3428 * sizeof (ElfNN_External_Rela);
3429 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3430 }
3431 }
3432
3433 /* Return the descriptor's address. */
3434 value = (fptr_sec->output_section->vma
3435 + fptr_sec->output_offset
3436 + dyn_i->fptr_offset);
3437
3438 return value;
3439}
3440
3441/* Fill in a PLTOFF entry consisting of the function's code address
3442 and its global pointer. Return the descriptor's address. */
3443
3444static bfd_vma
3445set_pltoff_entry (bfd *abfd, struct bfd_link_info *info,
3446 struct elfNN_ia64_dyn_sym_info *dyn_i,
3447 bfd_vma value, bfd_boolean is_plt)
3448{
3449 struct elfNN_ia64_link_hash_table *ia64_info;
3450 asection *pltoff_sec;
3451
3452 ia64_info = elfNN_ia64_hash_table (info);
3453 if (ia64_info == NULL)
3454 return 0;
3455
3456 pltoff_sec = ia64_info->pltoff_sec;
3457
3458 /* Don't do anything if this symbol uses a real PLT entry. In
3459 that case, we'll fill this in during finish_dynamic_symbol. */
3460 if ((! dyn_i->want_plt || is_plt)
3461 && !dyn_i->pltoff_done)
3462 {
3463 bfd_vma gp = _bfd_get_gp_value (abfd);
3464
3465 /* Fill in the function descriptor. */
3466 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3467 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3468
3469 /* Install dynamic relocations if needed. */
3470 if (!is_plt
0e1862bb 3471 && bfd_link_pic (info)
cbe79dfe 3472 && (!dyn_i->h
db41f6eb
L
3473 || (ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3474 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, dyn_i->h))
cbe79dfe
TG
3475 || dyn_i->h->root.type != bfd_link_hash_undefweak))
3476 {
3477 unsigned int dyn_r_type;
3478
3479 if (bfd_big_endian (abfd))
3480 dyn_r_type = R_IA64_RELNNMSB;
3481 else
3482 dyn_r_type = R_IA64_RELNNLSB;
3483
3484 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3485 ia64_info->rel_pltoff_sec,
3486 dyn_i->pltoff_offset,
3487 dyn_r_type, 0, value);
3488 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3489 ia64_info->rel_pltoff_sec,
3490 dyn_i->pltoff_offset + ARCH_SIZE / 8,
3491 dyn_r_type, 0, gp);
3492 }
3493
3494 dyn_i->pltoff_done = 1;
3495 }
3496
3497 /* Return the descriptor's address. */
3498 value = (pltoff_sec->output_section->vma
3499 + pltoff_sec->output_offset
3500 + dyn_i->pltoff_offset);
3501
3502 return value;
3503}
3504
3505/* Return the base VMA address which should be subtracted from real addresses
3506 when resolving @tprel() relocation.
3507 Main program TLS (whose template starts at PT_TLS p_vaddr)
3508 is assigned offset round(2 * size of pointer, PT_TLS p_align). */
3509
3510static bfd_vma
3511elfNN_ia64_tprel_base (struct bfd_link_info *info)
3512{
3513 asection *tls_sec = elf_hash_table (info)->tls_sec;
3514 return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
3515 tls_sec->alignment_power);
3516}
3517
3518/* Return the base VMA address which should be subtracted from real addresses
3519 when resolving @dtprel() relocation.
3520 This is PT_TLS segment p_vaddr. */
3521
3522static bfd_vma
3523elfNN_ia64_dtprel_base (struct bfd_link_info *info)
3524{
3525 return elf_hash_table (info)->tls_sec->vma;
3526}
3527
3528/* Called through qsort to sort the .IA_64.unwind section during a
3529 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3530 to the output bfd so we can do proper endianness frobbing. */
3531
3532static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3533
3534static int
2c3fc389 3535elfNN_ia64_unwind_entry_compare (const void * a, const void * b)
cbe79dfe
TG
3536{
3537 bfd_vma av, bv;
3538
3539 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3540 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3541
3542 return (av < bv ? -1 : av > bv ? 1 : 0);
3543}
3544
3545/* Make sure we've got ourselves a nice fat __gp value. */
3546static bfd_boolean
3547elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
3548{
3549 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3550 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3551 struct elf_link_hash_entry *gp;
3552 bfd_vma gp_val;
3553 asection *os;
3554 struct elfNN_ia64_link_hash_table *ia64_info;
3555
3556 ia64_info = elfNN_ia64_hash_table (info);
3557 if (ia64_info == NULL)
3558 return FALSE;
3559
3560 /* Find the min and max vma of all sections marked short. Also collect
3561 min and max vma of any type, for use in selecting a nice gp. */
3562 for (os = abfd->sections; os ; os = os->next)
3563 {
3564 bfd_vma lo, hi;
3565
3566 if ((os->flags & SEC_ALLOC) == 0)
3567 continue;
3568
3569 lo = os->vma;
3570 /* When this function is called from elfNN_ia64_final_link
3571 the correct value to use is os->size. When called from
3572 elfNN_ia64_relax_section we are in the middle of section
3573 sizing; some sections will already have os->size set, others
3574 will have os->size zero and os->rawsize the previous size. */
3575 hi = os->vma + (!final && os->rawsize ? os->rawsize : os->size);
3576 if (hi < lo)
3577 hi = (bfd_vma) -1;
3578
3579 if (min_vma > lo)
3580 min_vma = lo;
3581 if (max_vma < hi)
3582 max_vma = hi;
3583 if (os->flags & SEC_SMALL_DATA)
3584 {
3585 if (min_short_vma > lo)
3586 min_short_vma = lo;
3587 if (max_short_vma < hi)
3588 max_short_vma = hi;
3589 }
3590 }
3591
3592 if (ia64_info->min_short_sec)
3593 {
d17fe7b7 3594 if (min_short_vma
cbe79dfe
TG
3595 > (ia64_info->min_short_sec->vma
3596 + ia64_info->min_short_offset))
3597 min_short_vma = (ia64_info->min_short_sec->vma
3598 + ia64_info->min_short_offset);
3599 if (max_short_vma
3600 < (ia64_info->max_short_sec->vma
3601 + ia64_info->max_short_offset))
3602 max_short_vma = (ia64_info->max_short_sec->vma
3603 + ia64_info->max_short_offset);
3604 }
3605
3606 /* See if the user wants to force a value. */
3607 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3608 FALSE, FALSE);
3609
3610 if (gp
3611 && (gp->root.type == bfd_link_hash_defined
3612 || gp->root.type == bfd_link_hash_defweak))
3613 {
3614 asection *gp_sec = gp->root.u.def.section;
3615 gp_val = (gp->root.u.def.value
3616 + gp_sec->output_section->vma
3617 + gp_sec->output_offset);
3618 }
3619 else
3620 {
3621 /* Pick a sensible value. */
3622
3623 if (ia64_info->min_short_sec)
3624 {
3625 bfd_vma short_range = max_short_vma - min_short_vma;
3626
3627 /* If min_short_sec is set, pick one in the middle bewteen
3628 min_short_vma and max_short_vma. */
3629 if (short_range >= 0x400000)
3630 goto overflow;
3631 gp_val = min_short_vma + short_range / 2;
3632 }
3633 else
3634 {
3635 asection *got_sec = ia64_info->root.sgot;
3636
3637 /* Start with just the address of the .got. */
3638 if (got_sec)
3639 gp_val = got_sec->output_section->vma;
3640 else if (max_short_vma != 0)
3641 gp_val = min_short_vma;
3642 else if (max_vma - min_vma < 0x200000)
3643 gp_val = min_vma;
3644 else
3645 gp_val = max_vma - 0x200000 + 8;
3646 }
3647
3648 /* If it is possible to address the entire image, but we
3649 don't with the choice above, adjust. */
3650 if (max_vma - min_vma < 0x400000
3651 && (max_vma - gp_val >= 0x200000
3652 || gp_val - min_vma > 0x200000))
3653 gp_val = min_vma + 0x200000;
3654 else if (max_short_vma != 0)
3655 {
3656 /* If we don't cover all the short data, adjust. */
3657 if (max_short_vma - gp_val >= 0x200000)
3658 gp_val = min_short_vma + 0x200000;
3659
3660 /* If we're addressing stuff past the end, adjust back. */
3661 if (gp_val > max_vma)
3662 gp_val = max_vma - 0x200000 + 8;
3663 }
3664 }
3665
3666 /* Validate whether all SHF_IA_64_SHORT sections are within
3667 range of the chosen GP. */
3668
3669 if (max_short_vma != 0)
3670 {
3671 if (max_short_vma - min_short_vma >= 0x400000)
3672 {
dc1e8a47 3673 overflow:
4eca0228 3674 _bfd_error_handler
695344c0 3675 /* xgettext:c-format */
2dcf00ce
AM
3676 (_("%pB: short data segment overflowed (%#" PRIx64 " >= 0x400000)"),
3677 abfd, (uint64_t) (max_short_vma - min_short_vma));
cbe79dfe
TG
3678 return FALSE;
3679 }
3680 else if ((gp_val > min_short_vma
3681 && gp_val - min_short_vma > 0x200000)
3682 || (gp_val < max_short_vma
3683 && max_short_vma - gp_val >= 0x200000))
3684 {
4eca0228 3685 _bfd_error_handler
871b3ab2 3686 (_("%pB: __gp does not cover short data segment"), abfd);
cbe79dfe
TG
3687 return FALSE;
3688 }
3689 }
3690
3691 _bfd_set_gp_value (abfd, gp_val);
3692
3693 return TRUE;
3694}
3695
3696static bfd_boolean
3697elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
3698{
3699 struct elfNN_ia64_link_hash_table *ia64_info;
3700 asection *unwind_output_sec;
3701
3702 ia64_info = elfNN_ia64_hash_table (info);
3703 if (ia64_info == NULL)
3704 return FALSE;
3705
3706 /* Make sure we've got ourselves a nice fat __gp value. */
0e1862bb 3707 if (!bfd_link_relocatable (info))
cbe79dfe
TG
3708 {
3709 bfd_vma gp_val;
3710 struct elf_link_hash_entry *gp;
3711
3712 /* We assume after gp is set, section size will only decrease. We
3713 need to adjust gp for it. */
3714 _bfd_set_gp_value (abfd, 0);
3715 if (! elfNN_ia64_choose_gp (abfd, info, TRUE))
3716 return FALSE;
3717 gp_val = _bfd_get_gp_value (abfd);
3718
3719 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
07d6d2b8 3720 FALSE, FALSE);
cbe79dfe
TG
3721 if (gp)
3722 {
3723 gp->root.type = bfd_link_hash_defined;
3724 gp->root.u.def.value = gp_val;
3725 gp->root.u.def.section = bfd_abs_section_ptr;
3726 }
3727 }
3728
3729 /* If we're producing a final executable, we need to sort the contents
3730 of the .IA_64.unwind section. Force this section to be relocated
3731 into memory rather than written immediately to the output file. */
3732 unwind_output_sec = NULL;
0e1862bb 3733 if (!bfd_link_relocatable (info))
cbe79dfe
TG
3734 {
3735 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3736 if (s)
3737 {
3738 unwind_output_sec = s->output_section;
3739 unwind_output_sec->contents
3740 = bfd_malloc (unwind_output_sec->size);
3741 if (unwind_output_sec->contents == NULL)
3742 return FALSE;
3743 }
3744 }
3745
3746 /* Invoke the regular ELF backend linker to do all the work. */
3747 if (!bfd_elf_final_link (abfd, info))
3748 return FALSE;
3749
3750 if (unwind_output_sec)
3751 {
3752 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3753 qsort (unwind_output_sec->contents,
3754 (size_t) (unwind_output_sec->size / 24),
3755 24,
3756 elfNN_ia64_unwind_entry_compare);
3757
3758 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3759 unwind_output_sec->contents, (bfd_vma) 0,
3760 unwind_output_sec->size))
3761 return FALSE;
3762 }
3763
3764 return TRUE;
3765}
3766
3767static bfd_boolean
3768elfNN_ia64_relocate_section (bfd *output_bfd,
3769 struct bfd_link_info *info,
3770 bfd *input_bfd,
3771 asection *input_section,
3772 bfd_byte *contents,
3773 Elf_Internal_Rela *relocs,
3774 Elf_Internal_Sym *local_syms,
3775 asection **local_sections)
3776{
3777 struct elfNN_ia64_link_hash_table *ia64_info;
3778 Elf_Internal_Shdr *symtab_hdr;
3779 Elf_Internal_Rela *rel;
3780 Elf_Internal_Rela *relend;
3781 asection *srel;
3782 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
3783 bfd_vma gp_val;
3784
3785 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3786 ia64_info = elfNN_ia64_hash_table (info);
3787 if (ia64_info == NULL)
3788 return FALSE;
3789
3790 /* Infect various flags from the input section to the output section. */
0e1862bb 3791 if (bfd_link_relocatable (info))
cbe79dfe
TG
3792 {
3793 bfd_vma flags;
3794
3795 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3796 flags &= SHF_IA_64_NORECOV;
3797
3798 elf_section_data(input_section->output_section)
3799 ->this_hdr.sh_flags |= flags;
3800 }
3801
3802 gp_val = _bfd_get_gp_value (output_bfd);
3803 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
3804
3805 rel = relocs;
3806 relend = relocs + input_section->reloc_count;
3807 for (; rel < relend; ++rel)
3808 {
3809 struct elf_link_hash_entry *h;
3810 struct elfNN_ia64_dyn_sym_info *dyn_i;
3811 bfd_reloc_status_type r;
3812 reloc_howto_type *howto;
3813 unsigned long r_symndx;
3814 Elf_Internal_Sym *sym;
3815 unsigned int r_type;
3816 bfd_vma value;
3817 asection *sym_sec;
3818 bfd_byte *hit_addr;
3819 bfd_boolean dynamic_symbol_p;
3820 bfd_boolean undef_weak_ref;
3821
3822 r_type = ELFNN_R_TYPE (rel->r_info);
3823 if (r_type > R_IA64_MAX_RELOC_CODE)
3824 {
0aa13fee
AM
3825 /* xgettext:c-format */
3826 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
3827 input_bfd, (int) r_type);
cbe79dfe
TG
3828 bfd_set_error (bfd_error_bad_value);
3829 ret_val = FALSE;
3830 continue;
3831 }
3832
3833 howto = ia64_elf_lookup_howto (r_type);
f3185997
NC
3834 if (howto == NULL)
3835 {
3836 ret_val = FALSE;
3837 continue;
3838 }
4b24dd1a 3839
cbe79dfe
TG
3840 r_symndx = ELFNN_R_SYM (rel->r_info);
3841 h = NULL;
3842 sym = NULL;
3843 sym_sec = NULL;
3844 undef_weak_ref = FALSE;
3845
3846 if (r_symndx < symtab_hdr->sh_info)
3847 {
3848 /* Reloc against local symbol. */
3849 asection *msec;
3850 sym = local_syms + r_symndx;
3851 sym_sec = local_sections[r_symndx];
3852 msec = sym_sec;
3853 value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
0e1862bb 3854 if (!bfd_link_relocatable (info)
cbe79dfe
TG
3855 && (sym_sec->flags & SEC_MERGE) != 0
3856 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
dbaa2011 3857 && sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE)
d17fe7b7 3858 {
cbe79dfe
TG
3859 struct elfNN_ia64_local_hash_entry *loc_h;
3860
3861 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
3862 if (loc_h && ! loc_h->sec_merge_done)
3863 {
3864 struct elfNN_ia64_dyn_sym_info *dynent;
3865 unsigned int count;
3866
3867 for (count = loc_h->count, dynent = loc_h->info;
3868 count != 0;
3869 count--, dynent++)
3870 {
3871 msec = sym_sec;
3872 dynent->addend =
3873 _bfd_merged_section_offset (output_bfd, &msec,
3874 elf_section_data (msec)->
3875 sec_info,
3876 sym->st_value
3877 + dynent->addend);
3878 dynent->addend -= sym->st_value;
3879 dynent->addend += msec->output_section->vma
3880 + msec->output_offset
3881 - sym_sec->output_section->vma
3882 - sym_sec->output_offset;
3883 }
3884
3885 /* We may have introduced duplicated entries. We need
3886 to remove them properly. */
3887 count = sort_dyn_sym_info (loc_h->info, loc_h->count);
3888 if (count != loc_h->count)
3889 {
3890 loc_h->count = count;
3891 loc_h->sorted_count = count;
3892 }
3893
3894 loc_h->sec_merge_done = 1;
3895 }
3896 }
3897 }
3898 else
3899 {
3900 bfd_boolean unresolved_reloc;
62d887d4 3901 bfd_boolean warned, ignored;
cbe79dfe
TG
3902 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
3903
3904 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
3905 r_symndx, symtab_hdr, sym_hashes,
3906 h, sym_sec, value,
62d887d4 3907 unresolved_reloc, warned, ignored);
cbe79dfe
TG
3908
3909 if (h->root.type == bfd_link_hash_undefweak)
3910 undef_weak_ref = TRUE;
0e1862bb 3911 else if (warned || (ignored && bfd_link_executable (info)))
cbe79dfe
TG
3912 continue;
3913 }
3914
dbaa2011 3915 if (sym_sec != NULL && discarded_section (sym_sec))
cbe79dfe 3916 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 3917 rel, 1, relend, howto, 0, contents);
cbe79dfe 3918
0e1862bb 3919 if (bfd_link_relocatable (info))
cbe79dfe
TG
3920 continue;
3921
3922 hit_addr = contents + rel->r_offset;
3923 value += rel->r_addend;
3924 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
3925
3926 switch (r_type)
3927 {
3928 case R_IA64_NONE:
3929 case R_IA64_LDXMOV:
3930 continue;
3931
3932 case R_IA64_IMM14:
3933 case R_IA64_IMM22:
3934 case R_IA64_IMM64:
3935 case R_IA64_DIR32MSB:
3936 case R_IA64_DIR32LSB:
3937 case R_IA64_DIR64MSB:
3938 case R_IA64_DIR64LSB:
3939 /* Install a dynamic relocation for this reloc. */
0e1862bb 3940 if ((dynamic_symbol_p || bfd_link_pic (info))
db41f6eb 3941 && !(h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
cbe79dfe
TG
3942 && r_symndx != STN_UNDEF
3943 && (input_section->flags & SEC_ALLOC) != 0)
3944 {
3945 unsigned int dyn_r_type;
3946 long dynindx;
3947 bfd_vma addend;
3948
3949 BFD_ASSERT (srel != NULL);
3950
3951 switch (r_type)
3952 {
3953 case R_IA64_IMM14:
3954 case R_IA64_IMM22:
3955 case R_IA64_IMM64:
3956 /* ??? People shouldn't be doing non-pic code in
3957 shared libraries nor dynamic executables. */
4eca0228 3958 _bfd_error_handler
695344c0 3959 /* xgettext:c-format */
871b3ab2 3960 (_("%pB: non-pic code with imm relocation against dynamic symbol `%s'"),
cbe79dfe
TG
3961 input_bfd,
3962 h ? h->root.root.string
3963 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
3964 sym_sec));
3965 ret_val = FALSE;
3966 continue;
3967
3968 default:
3969 break;
3970 }
3971
3972 /* If we don't need dynamic symbol lookup, find a
3973 matching RELATIVE relocation. */
3974 dyn_r_type = r_type;
3975 if (dynamic_symbol_p)
3976 {
3977 dynindx = h->dynindx;
3978 addend = rel->r_addend;
3979 value = 0;
3980 }
3981 else
3982 {
3983 switch (r_type)
3984 {
3985 case R_IA64_DIR32MSB:
3986 dyn_r_type = R_IA64_REL32MSB;
3987 break;
3988 case R_IA64_DIR32LSB:
3989 dyn_r_type = R_IA64_REL32LSB;
3990 break;
3991 case R_IA64_DIR64MSB:
3992 dyn_r_type = R_IA64_REL64MSB;
3993 break;
3994 case R_IA64_DIR64LSB:
3995 dyn_r_type = R_IA64_REL64LSB;
3996 break;
3997
3998 default:
3999 break;
4000 }
4001 dynindx = 0;
4002 addend = value;
4003 }
4004
4005 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4006 srel, rel->r_offset, dyn_r_type,
4007 dynindx, addend);
4008 }
4009 /* Fall through. */
4010
4011 case R_IA64_LTV32MSB:
4012 case R_IA64_LTV32LSB:
4013 case R_IA64_LTV64MSB:
4014 case R_IA64_LTV64LSB:
4015 r = ia64_elf_install_value (hit_addr, value, r_type);
4016 break;
4017
4018 case R_IA64_GPREL22:
4019 case R_IA64_GPREL64I:
4020 case R_IA64_GPREL32MSB:
4021 case R_IA64_GPREL32LSB:
4022 case R_IA64_GPREL64MSB:
4023 case R_IA64_GPREL64LSB:
4024 if (dynamic_symbol_p)
4025 {
4eca0228 4026 _bfd_error_handler
695344c0 4027 /* xgettext:c-format */
871b3ab2 4028 (_("%pB: @gprel relocation against dynamic symbol %s"),
cbe79dfe
TG
4029 input_bfd,
4030 h ? h->root.root.string
4031 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4032 sym_sec));
4033 ret_val = FALSE;
4034 continue;
4035 }
4036 value -= gp_val;
4037 r = ia64_elf_install_value (hit_addr, value, r_type);
4038 break;
4039
4040 case R_IA64_LTOFF22:
4041 case R_IA64_LTOFF22X:
4042 case R_IA64_LTOFF64I:
07d6d2b8 4043 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
cbe79dfe
TG
4044 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4045 rel->r_addend, value, R_IA64_DIRNNLSB);
4046 value -= gp_val;
4047 r = ia64_elf_install_value (hit_addr, value, r_type);
4048 break;
4049
4050 case R_IA64_PLTOFF22:
4051 case R_IA64_PLTOFF64I:
4052 case R_IA64_PLTOFF64MSB:
4053 case R_IA64_PLTOFF64LSB:
07d6d2b8 4054 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
cbe79dfe
TG
4055 value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4056 value -= gp_val;
4057 r = ia64_elf_install_value (hit_addr, value, r_type);
4058 break;
4059
4060 case R_IA64_FPTR64I:
4061 case R_IA64_FPTR32MSB:
4062 case R_IA64_FPTR32LSB:
4063 case R_IA64_FPTR64MSB:
4064 case R_IA64_FPTR64LSB:
07d6d2b8 4065 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
cbe79dfe
TG
4066 if (dyn_i->want_fptr)
4067 {
4068 if (!undef_weak_ref)
4069 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4070 }
0e1862bb 4071 if (!dyn_i->want_fptr || bfd_link_pie (info))
cbe79dfe
TG
4072 {
4073 long dynindx;
4074 unsigned int dyn_r_type = r_type;
4075 bfd_vma addend = rel->r_addend;
4076
4077 /* Otherwise, we expect the dynamic linker to create
4078 the entry. */
4079
4080 if (dyn_i->want_fptr)
4081 {
4082 if (r_type == R_IA64_FPTR64I)
4083 {
4084 /* We can't represent this without a dynamic symbol.
4085 Adjust the relocation to be against an output
4086 section symbol, which are always present in the
4087 dynamic symbol table. */
4088 /* ??? People shouldn't be doing non-pic code in
4089 shared libraries. Hork. */
4eca0228 4090 _bfd_error_handler
871b3ab2 4091 (_("%pB: linking non-pic code in a position independent executable"),
cbe79dfe
TG
4092 input_bfd);
4093 ret_val = FALSE;
4094 continue;
4095 }
4096 dynindx = 0;
4097 addend = value;
4098 dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
4099 }
4100 else if (h)
4101 {
4102 if (h->dynindx != -1)
4103 dynindx = h->dynindx;
4104 else
4105 dynindx = (_bfd_elf_link_lookup_local_dynindx
4106 (info, h->root.u.def.section->owner,
4107 global_sym_index (h)));
4108 value = 0;
4109 }
4110 else
4111 {
4112 dynindx = (_bfd_elf_link_lookup_local_dynindx
4113 (info, input_bfd, (long) r_symndx));
4114 value = 0;
4115 }
4116
4117 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4118 srel, rel->r_offset, dyn_r_type,
4119 dynindx, addend);
4120 }
4121
4122 r = ia64_elf_install_value (hit_addr, value, r_type);
4123 break;
4124
4125 case R_IA64_LTOFF_FPTR22:
4126 case R_IA64_LTOFF_FPTR64I:
4127 case R_IA64_LTOFF_FPTR32MSB:
4128 case R_IA64_LTOFF_FPTR32LSB:
4129 case R_IA64_LTOFF_FPTR64MSB:
4130 case R_IA64_LTOFF_FPTR64LSB:
4131 {
4132 long dynindx;
4133
4134 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4135 if (dyn_i->want_fptr)
4136 {
4137 BFD_ASSERT (h == NULL || h->dynindx == -1);
07d6d2b8
AM
4138 if (!undef_weak_ref)
4139 value = set_fptr_entry (output_bfd, info, dyn_i, value);
cbe79dfe
TG
4140 dynindx = -1;
4141 }
4142 else
4143 {
07d6d2b8 4144 /* Otherwise, we expect the dynamic linker to create
cbe79dfe 4145 the entry. */
07d6d2b8 4146 if (h)
cbe79dfe
TG
4147 {
4148 if (h->dynindx != -1)
4149 dynindx = h->dynindx;
4150 else
4151 dynindx = (_bfd_elf_link_lookup_local_dynindx
4152 (info, h->root.u.def.section->owner,
4153 global_sym_index (h)));
4154 }
4155 else
4156 dynindx = (_bfd_elf_link_lookup_local_dynindx
4157 (info, input_bfd, (long) r_symndx));
4158 value = 0;
4159 }
4160
4161 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4162 rel->r_addend, value, R_IA64_FPTRNNLSB);
4163 value -= gp_val;
4164 r = ia64_elf_install_value (hit_addr, value, r_type);
4165 }
4166 break;
4167
4168 case R_IA64_PCREL32MSB:
4169 case R_IA64_PCREL32LSB:
4170 case R_IA64_PCREL64MSB:
4171 case R_IA64_PCREL64LSB:
4172 /* Install a dynamic relocation for this reloc. */
4173 if (dynamic_symbol_p && r_symndx != STN_UNDEF)
4174 {
4175 BFD_ASSERT (srel != NULL);
4176
4177 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4178 srel, rel->r_offset, r_type,
4179 h->dynindx, rel->r_addend);
4180 }
4181 goto finish_pcrel;
4182
4183 case R_IA64_PCREL21B:
4184 case R_IA64_PCREL60B:
4185 /* We should have created a PLT entry for any dynamic symbol. */
4186 dyn_i = NULL;
4187 if (h)
4188 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4189
4190 if (dyn_i && dyn_i->want_plt2)
4191 {
4192 /* Should have caught this earlier. */
4193 BFD_ASSERT (rel->r_addend == 0);
4194
4195 value = (ia64_info->root.splt->output_section->vma
4196 + ia64_info->root.splt->output_offset
4197 + dyn_i->plt2_offset);
4198 }
4199 else
4200 {
4201 /* Since there's no PLT entry, Validate that this is
4202 locally defined. */
4203 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4204
4205 /* If the symbol is undef_weak, we shouldn't be trying
4206 to call it. There's every chance that we'd wind up
4207 with an out-of-range fixup here. Don't bother setting
4208 any value at all. */
4209 if (undef_weak_ref)
4210 continue;
4211 }
4212 goto finish_pcrel;
4213
4214 case R_IA64_PCREL21BI:
4215 case R_IA64_PCREL21F:
4216 case R_IA64_PCREL21M:
4217 case R_IA64_PCREL22:
4218 case R_IA64_PCREL64I:
4219 /* The PCREL21BI reloc is specifically not intended for use with
4220 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4221 fixup code, and thus probably ought not be dynamic. The
4222 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4223 if (dynamic_symbol_p)
4224 {
4225 const char *msg;
4226
4227 if (r_type == R_IA64_PCREL21BI)
695344c0 4228 /* xgettext:c-format */
871b3ab2 4229 msg = _("%pB: @internal branch to dynamic symbol %s");
cbe79dfe 4230 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
695344c0 4231 /* xgettext:c-format */
871b3ab2 4232 msg = _("%pB: speculation fixup to dynamic symbol %s");
cbe79dfe 4233 else
695344c0 4234 /* xgettext:c-format */
871b3ab2 4235 msg = _("%pB: @pcrel relocation against dynamic symbol %s");
4eca0228
AM
4236 _bfd_error_handler (msg, input_bfd,
4237 h ? h->root.root.string
4238 : bfd_elf_sym_name (input_bfd,
4239 symtab_hdr,
4240 sym,
4241 sym_sec));
cbe79dfe
TG
4242 ret_val = FALSE;
4243 continue;
4244 }
4245 goto finish_pcrel;
4246
4247 finish_pcrel:
4248 /* Make pc-relative. */
4249 value -= (input_section->output_section->vma
4250 + input_section->output_offset
4251 + rel->r_offset) & ~ (bfd_vma) 0x3;
4252 r = ia64_elf_install_value (hit_addr, value, r_type);
4253 break;
4254
4255 case R_IA64_SEGREL32MSB:
4256 case R_IA64_SEGREL32LSB:
4257 case R_IA64_SEGREL64MSB:
4258 case R_IA64_SEGREL64LSB:
4259 {
4260 /* Find the segment that contains the output_section. */
4261 Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section
4262 (output_bfd, input_section->output_section);
4263
4264 if (p == NULL)
4265 {
4266 r = bfd_reloc_notsupported;
4267 }
4268 else
4269 {
4270 /* The VMA of the segment is the vaddr of the associated
4271 program header. */
4272 if (value > p->p_vaddr)
4273 value -= p->p_vaddr;
4274 else
4275 value = 0;
4276 r = ia64_elf_install_value (hit_addr, value, r_type);
4277 }
4278 break;
4279 }
4280
4281 case R_IA64_SECREL32MSB:
4282 case R_IA64_SECREL32LSB:
4283 case R_IA64_SECREL64MSB:
4284 case R_IA64_SECREL64LSB:
4285 /* Make output-section relative to section where the symbol
4286 is defined. PR 475 */
4287 if (sym_sec)
4288 value -= sym_sec->output_section->vma;
4289 r = ia64_elf_install_value (hit_addr, value, r_type);
4290 break;
4291
4292 case R_IA64_IPLTMSB:
4293 case R_IA64_IPLTLSB:
4294 /* Install a dynamic relocation for this reloc. */
0e1862bb 4295 if ((dynamic_symbol_p || bfd_link_pic (info))
cbe79dfe
TG
4296 && (input_section->flags & SEC_ALLOC) != 0)
4297 {
4298 BFD_ASSERT (srel != NULL);
4299
4300 /* If we don't need dynamic symbol lookup, install two
4301 RELATIVE relocations. */
4302 if (!dynamic_symbol_p)
4303 {
4304 unsigned int dyn_r_type;
4305
4306 if (r_type == R_IA64_IPLTMSB)
4307 dyn_r_type = R_IA64_REL64MSB;
4308 else
4309 dyn_r_type = R_IA64_REL64LSB;
4310
4311 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4312 input_section,
4313 srel, rel->r_offset,
4314 dyn_r_type, 0, value);
4315 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4316 input_section,
4317 srel, rel->r_offset + 8,
4318 dyn_r_type, 0, gp_val);
4319 }
4320 else
4321 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4322 srel, rel->r_offset, r_type,
4323 h->dynindx, rel->r_addend);
4324 }
4325
4326 if (r_type == R_IA64_IPLTMSB)
4327 r_type = R_IA64_DIR64MSB;
4328 else
4329 r_type = R_IA64_DIR64LSB;
4330 ia64_elf_install_value (hit_addr, value, r_type);
4331 r = ia64_elf_install_value (hit_addr + 8, gp_val, r_type);
4332 break;
4333
4334 case R_IA64_TPREL14:
4335 case R_IA64_TPREL22:
4336 case R_IA64_TPREL64I:
4337 if (elf_hash_table (info)->tls_sec == NULL)
4338 goto missing_tls_sec;
4339 value -= elfNN_ia64_tprel_base (info);
4340 r = ia64_elf_install_value (hit_addr, value, r_type);
4341 break;
4342
4343 case R_IA64_DTPREL14:
4344 case R_IA64_DTPREL22:
4345 case R_IA64_DTPREL64I:
4346 case R_IA64_DTPREL32LSB:
4347 case R_IA64_DTPREL32MSB:
4348 case R_IA64_DTPREL64LSB:
4349 case R_IA64_DTPREL64MSB:
4350 if (elf_hash_table (info)->tls_sec == NULL)
4351 goto missing_tls_sec;
4352 value -= elfNN_ia64_dtprel_base (info);
4353 r = ia64_elf_install_value (hit_addr, value, r_type);
4354 break;
4355
4356 case R_IA64_LTOFF_TPREL22:
4357 case R_IA64_LTOFF_DTPMOD22:
4358 case R_IA64_LTOFF_DTPREL22:
4359 {
4360 int got_r_type;
4361 long dynindx = h ? h->dynindx : -1;
4362 bfd_vma r_addend = rel->r_addend;
4363
4364 switch (r_type)
4365 {
4366 default:
4367 case R_IA64_LTOFF_TPREL22:
4368 if (!dynamic_symbol_p)
4369 {
4370 if (elf_hash_table (info)->tls_sec == NULL)
4371 goto missing_tls_sec;
0e1862bb 4372 if (!bfd_link_pic (info))
cbe79dfe
TG
4373 value -= elfNN_ia64_tprel_base (info);
4374 else
4375 {
4376 r_addend += value - elfNN_ia64_dtprel_base (info);
4377 dynindx = 0;
4378 }
4379 }
4380 got_r_type = R_IA64_TPREL64LSB;
4381 break;
4382 case R_IA64_LTOFF_DTPMOD22:
0e1862bb 4383 if (!dynamic_symbol_p && !bfd_link_pic (info))
cbe79dfe
TG
4384 value = 1;
4385 got_r_type = R_IA64_DTPMOD64LSB;
4386 break;
4387 case R_IA64_LTOFF_DTPREL22:
4388 if (!dynamic_symbol_p)
4389 {
4390 if (elf_hash_table (info)->tls_sec == NULL)
4391 goto missing_tls_sec;
4392 value -= elfNN_ia64_dtprel_base (info);
4393 }
4394 got_r_type = R_IA64_DTPRELNNLSB;
4395 break;
4396 }
4397 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4398 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
4399 value, got_r_type);
4400 value -= gp_val;
4401 r = ia64_elf_install_value (hit_addr, value, r_type);
4402 }
4403 break;
4404
4405 default:
4406 r = bfd_reloc_notsupported;
4407 break;
4408 }
4409
4410 switch (r)
4411 {
4412 case bfd_reloc_ok:
4413 break;
4414
4415 case bfd_reloc_undefined:
4416 /* This can happen for global table relative relocs if
4417 __gp is undefined. This is a panic situation so we
4418 don't try to continue. */
4419 (*info->callbacks->undefined_symbol)
4420 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4421 return FALSE;
4422
4423 case bfd_reloc_notsupported:
4424 {
4425 const char *name;
4426
4427 if (h)
4428 name = h->root.root.string;
4429 else
4430 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4431 sym_sec);
1a72702b
AM
4432 (*info->callbacks->warning) (info, _("unsupported reloc"),
4433 name, input_bfd,
4434 input_section, rel->r_offset);
cbe79dfe
TG
4435 ret_val = FALSE;
4436 }
4437 break;
4438
4439 case bfd_reloc_dangerous:
4440 case bfd_reloc_outofrange:
4441 case bfd_reloc_overflow:
4442 default:
dc1e8a47 4443 missing_tls_sec:
cbe79dfe
TG
4444 {
4445 const char *name;
4446
4447 if (h)
4448 name = h->root.root.string;
4449 else
4450 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4451 sym_sec);
4452
4453 switch (r_type)
4454 {
4455 case R_IA64_TPREL14:
4456 case R_IA64_TPREL22:
4457 case R_IA64_TPREL64I:
4458 case R_IA64_DTPREL14:
4459 case R_IA64_DTPREL22:
4460 case R_IA64_DTPREL64I:
4461 case R_IA64_DTPREL32LSB:
4462 case R_IA64_DTPREL32MSB:
4463 case R_IA64_DTPREL64LSB:
4464 case R_IA64_DTPREL64MSB:
4465 case R_IA64_LTOFF_TPREL22:
4466 case R_IA64_LTOFF_DTPMOD22:
4467 case R_IA64_LTOFF_DTPREL22:
4eca0228 4468 _bfd_error_handler
695344c0 4469 /* xgettext:c-format */
871b3ab2 4470 (_("%pB: missing TLS section for relocation %s against `%s'"
2dcf00ce 4471 " at %#" PRIx64 " in section `%pA'."),
c08bb8dd 4472 input_bfd, howto->name, name,
2dcf00ce 4473 (uint64_t) rel->r_offset, input_section);
cbe79dfe
TG
4474 break;
4475
4476 case R_IA64_PCREL21B:
4477 case R_IA64_PCREL21BI:
4478 case R_IA64_PCREL21M:
4479 case R_IA64_PCREL21F:
4480 if (is_elf_hash_table (info->hash))
4481 {
4482 /* Relaxtion is always performed for ELF output.
4483 Overflow failures for those relocations mean
4484 that the section is too big to relax. */
4eca0228 4485 _bfd_error_handler
695344c0 4486 /* xgettext:c-format */
2dcf00ce
AM
4487 (_("%pB: Can't relax br (%s) to `%s' at %#" PRIx64
4488 " in section `%pA' with size %#" PRIx64
4489 " (> 0x1000000)."),
4490 input_bfd, howto->name, name, (uint64_t) rel->r_offset,
4491 input_section, (uint64_t) input_section->size);
cbe79dfe
TG
4492 break;
4493 }
1a0670f3 4494 /* Fall through. */
cbe79dfe 4495 default:
1a72702b
AM
4496 (*info->callbacks->reloc_overflow) (info,
4497 &h->root,
4498 name,
4499 howto->name,
4500 (bfd_vma) 0,
4501 input_bfd,
4502 input_section,
4503 rel->r_offset);
cbe79dfe
TG
4504 break;
4505 }
4506
4507 ret_val = FALSE;
4508 }
4509 break;
4510 }
4511 }
4512
4513 return ret_val;
4514}
4515
4516static bfd_boolean
4517elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
4518 struct bfd_link_info *info,
4519 struct elf_link_hash_entry *h,
4520 Elf_Internal_Sym *sym)
4521{
4522 struct elfNN_ia64_link_hash_table *ia64_info;
4523 struct elfNN_ia64_dyn_sym_info *dyn_i;
4524
4525 ia64_info = elfNN_ia64_hash_table (info);
4526 if (ia64_info == NULL)
4527 return FALSE;
4528
4529 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4530
4531 /* Fill in the PLT data, if required. */
4532 if (dyn_i && dyn_i->want_plt)
4533 {
4534 Elf_Internal_Rela outrel;
4535 bfd_byte *loc;
4536 asection *plt_sec;
4537 bfd_vma plt_addr, pltoff_addr, gp_val, plt_index;
4538
4539 gp_val = _bfd_get_gp_value (output_bfd);
4540
4541 /* Initialize the minimal PLT entry. */
4542
4543 plt_index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4544 plt_sec = ia64_info->root.splt;
4545 loc = plt_sec->contents + dyn_i->plt_offset;
4546
4547 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4548 ia64_elf_install_value (loc, plt_index, R_IA64_IMM22);
4549 ia64_elf_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
4550
4551 plt_addr = (plt_sec->output_section->vma
4552 + plt_sec->output_offset
4553 + dyn_i->plt_offset);
4554 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
4555
4556 /* Initialize the FULL PLT entry, if needed. */
4557 if (dyn_i->want_plt2)
4558 {
4559 loc = plt_sec->contents + dyn_i->plt2_offset;
4560
4561 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4562 ia64_elf_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
4563
4564 /* Mark the symbol as undefined, rather than as defined in the
4565 plt section. Leave the value alone. */
4566 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4567 first place. But perhaps elflink.c did some for us. */
4568 if (!h->def_regular)
4569 sym->st_shndx = SHN_UNDEF;
4570 }
4571
4572 /* Create the dynamic relocation. */
4573 outrel.r_offset = pltoff_addr;
4574 if (bfd_little_endian (output_bfd))
4575 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4576 else
4577 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4578 outrel.r_addend = 0;
4579
4580 /* This is fun. In the .IA_64.pltoff section, we've got entries
4581 that correspond both to real PLT entries, and those that
4582 happened to resolve to local symbols but need to be created
4583 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4584 relocations for the real PLT should come at the end of the
4585 section, so that they can be indexed by plt entry at runtime.
4586
4587 We emitted all of the relocations for the non-PLT @pltoff
4588 entries during relocate_section. So we can consider the
4589 existing sec->reloc_count to be the base of the array of
4590 PLT relocations. */
4591
4592 loc = ia64_info->rel_pltoff_sec->contents;
4593 loc += ((ia64_info->rel_pltoff_sec->reloc_count + plt_index)
4594 * sizeof (ElfNN_External_Rela));
4595 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4596 }
4597
4598 /* Mark some specially defined symbols as absolute. */
9637f6ef 4599 if (h == ia64_info->root.hdynamic
cbe79dfe
TG
4600 || h == ia64_info->root.hgot
4601 || h == ia64_info->root.hplt)
4602 sym->st_shndx = SHN_ABS;
4603
4604 return TRUE;
4605}
4606
4607static bfd_boolean
4608elfNN_ia64_finish_dynamic_sections (bfd *abfd,
4609 struct bfd_link_info *info)
4610{
4611 struct elfNN_ia64_link_hash_table *ia64_info;
4612 bfd *dynobj;
4613
4614 ia64_info = elfNN_ia64_hash_table (info);
4615 if (ia64_info == NULL)
4616 return FALSE;
4617
4618 dynobj = ia64_info->root.dynobj;
4619
ce558b89 4620 if (ia64_info->root.dynamic_sections_created)
cbe79dfe
TG
4621 {
4622 ElfNN_External_Dyn *dyncon, *dynconend;
4623 asection *sdyn, *sgotplt;
4624 bfd_vma gp_val;
4625
3d4d4302 4626 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
ce558b89 4627 sgotplt = ia64_info->root.sgotplt;
cbe79dfe
TG
4628 BFD_ASSERT (sdyn != NULL);
4629 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4630 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
4631
4632 gp_val = _bfd_get_gp_value (abfd);
4633
4634 for (; dyncon < dynconend; dyncon++)
4635 {
4636 Elf_Internal_Dyn dyn;
4637
4638 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4639
4640 switch (dyn.d_tag)
4641 {
4642 case DT_PLTGOT:
4643 dyn.d_un.d_ptr = gp_val;
4644 break;
4645
4646 case DT_PLTRELSZ:
4647 dyn.d_un.d_val = (ia64_info->minplt_entries
4648 * sizeof (ElfNN_External_Rela));
4649 break;
4650
4651 case DT_JMPREL:
4652 /* See the comment above in finish_dynamic_symbol. */
4653 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4654 + ia64_info->rel_pltoff_sec->output_offset
4655 + (ia64_info->rel_pltoff_sec->reloc_count
4656 * sizeof (ElfNN_External_Rela)));
4657 break;
4658
4659 case DT_IA_64_PLT_RESERVE:
4660 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4661 + sgotplt->output_offset);
4662 break;
cbe79dfe
TG
4663 }
4664
4665 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4666 }
4667
4668 /* Initialize the PLT0 entry. */
4669 if (ia64_info->root.splt)
4670 {
4671 bfd_byte *loc = ia64_info->root.splt->contents;
4672 bfd_vma pltres;
4673
4674 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4675
4676 pltres = (sgotplt->output_section->vma
4677 + sgotplt->output_offset
4678 - gp_val);
4679
4680 ia64_elf_install_value (loc+1, pltres, R_IA64_GPREL22);
4681 }
4682 }
4683
4684 return TRUE;
4685}
4686\f
4687/* ELF file flag handling: */
4688
4689/* Function to keep IA-64 specific file flags. */
4690static bfd_boolean
4691elfNN_ia64_set_private_flags (bfd *abfd, flagword flags)
4692{
4693 BFD_ASSERT (!elf_flags_init (abfd)
4694 || elf_elfheader (abfd)->e_flags == flags);
4695
4696 elf_elfheader (abfd)->e_flags = flags;
4697 elf_flags_init (abfd) = TRUE;
4698 return TRUE;
4699}
4700
4701/* Merge backend specific data from an object file to the output
4702 object file when linking. */
b26a3d58 4703
cbe79dfe 4704static bfd_boolean
50e03d47 4705elfNN_ia64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
cbe79dfe 4706{
50e03d47 4707 bfd *obfd = info->output_bfd;
cbe79dfe
TG
4708 flagword out_flags;
4709 flagword in_flags;
4710 bfd_boolean ok = TRUE;
4711
6b728d32
AM
4712 /* FIXME: What should be checked when linking shared libraries? */
4713 if ((ibfd->flags & DYNAMIC) != 0)
4714 return TRUE;
4715
b26a3d58
ST
4716 if (!is_ia64_elf (ibfd) || !is_ia64_elf (obfd))
4717 return TRUE;
cbe79dfe
TG
4718
4719 in_flags = elf_elfheader (ibfd)->e_flags;
4720 out_flags = elf_elfheader (obfd)->e_flags;
4721
4722 if (! elf_flags_init (obfd))
4723 {
4724 elf_flags_init (obfd) = TRUE;
4725 elf_elfheader (obfd)->e_flags = in_flags;
4726
4727 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4728 && bfd_get_arch_info (obfd)->the_default)
4729 {
4730 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4731 bfd_get_mach (ibfd));
4732 }
4733
4734 return TRUE;
4735 }
4736
4737 /* Check flag compatibility. */
4738 if (in_flags == out_flags)
4739 return TRUE;
4740
4741 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4742 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4743 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4744
4745 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4746 {
4eca0228 4747 _bfd_error_handler
871b3ab2 4748 (_("%pB: linking trap-on-NULL-dereference with non-trapping files"),
cbe79dfe
TG
4749 ibfd);
4750
4751 bfd_set_error (bfd_error_bad_value);
4752 ok = FALSE;
4753 }
4754 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4755 {
4eca0228 4756 _bfd_error_handler
871b3ab2 4757 (_("%pB: linking big-endian files with little-endian files"),
cbe79dfe
TG
4758 ibfd);
4759
4760 bfd_set_error (bfd_error_bad_value);
4761 ok = FALSE;
4762 }
4763 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4764 {
4eca0228 4765 _bfd_error_handler
871b3ab2 4766 (_("%pB: linking 64-bit files with 32-bit files"),
cbe79dfe
TG
4767 ibfd);
4768
4769 bfd_set_error (bfd_error_bad_value);
4770 ok = FALSE;
4771 }
4772 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4773 {
4eca0228 4774 _bfd_error_handler
871b3ab2 4775 (_("%pB: linking constant-gp files with non-constant-gp files"),
cbe79dfe
TG
4776 ibfd);
4777
4778 bfd_set_error (bfd_error_bad_value);
4779 ok = FALSE;
4780 }
4781 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4782 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4783 {
4eca0228 4784 _bfd_error_handler
871b3ab2 4785 (_("%pB: linking auto-pic files with non-auto-pic files"),
cbe79dfe
TG
4786 ibfd);
4787
4788 bfd_set_error (bfd_error_bad_value);
4789 ok = FALSE;
4790 }
4791
4792 return ok;
4793}
4794
4795static bfd_boolean
2c3fc389 4796elfNN_ia64_print_private_bfd_data (bfd *abfd, void * ptr)
cbe79dfe
TG
4797{
4798 FILE *file = (FILE *) ptr;
4799 flagword flags = elf_elfheader (abfd)->e_flags;
4800
4801 BFD_ASSERT (abfd != NULL && ptr != NULL);
4802
4803 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4804 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4805 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4806 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4807 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4808 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4809 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4810 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4811 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4812
4813 _bfd_elf_print_private_bfd_data (abfd, ptr);
4814 return TRUE;
4815}
4816
4817static enum elf_reloc_type_class
7e612e98
AM
4818elfNN_ia64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
4819 const asection *rel_sec ATTRIBUTE_UNUSED,
4820 const Elf_Internal_Rela *rela)
cbe79dfe
TG
4821{
4822 switch ((int) ELFNN_R_TYPE (rela->r_info))
4823 {
4824 case R_IA64_REL32MSB:
4825 case R_IA64_REL32LSB:
4826 case R_IA64_REL64MSB:
4827 case R_IA64_REL64LSB:
4828 return reloc_class_relative;
4829 case R_IA64_IPLTMSB:
4830 case R_IA64_IPLTLSB:
4831 return reloc_class_plt;
4832 case R_IA64_COPY:
4833 return reloc_class_copy;
4834 default:
4835 return reloc_class_normal;
4836 }
4837}
4838
4839static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
4840{
07d6d2b8 4841 { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
cbe79dfe 4842 { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
07d6d2b8 4843 { NULL, 0, 0, 0, 0 }
cbe79dfe
TG
4844};
4845
4846static bfd_boolean
4847elfNN_ia64_object_p (bfd *abfd)
4848{
4849 asection *sec;
4850 asection *group, *unwi, *unw;
4851 flagword flags;
4852 const char *name;
4853 char *unwi_name, *unw_name;
986f0783 4854 size_t amt;
cbe79dfe
TG
4855
4856 if (abfd->flags & DYNAMIC)
4857 return TRUE;
4858
4859 /* Flags for fake group section. */
4860 flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
4861 | SEC_EXCLUDE);
4862
4863 /* We add a fake section group for each .gnu.linkonce.t.* section,
4864 which isn't in a section group, and its unwind sections. */
4865 for (sec = abfd->sections; sec != NULL; sec = sec->next)
4866 {
4867 if (elf_sec_group (sec) == NULL
4868 && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
4869 == (SEC_LINK_ONCE | SEC_CODE))
4870 && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
4871 {
4872 name = sec->name + 16;
4873
4874 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
4875 unwi_name = bfd_alloc (abfd, amt);
4876 if (!unwi_name)
4877 return FALSE;
4878
4879 strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
4880 unwi = bfd_get_section_by_name (abfd, unwi_name);
4881
4882 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
4883 unw_name = bfd_alloc (abfd, amt);
4884 if (!unw_name)
4885 return FALSE;
4886
4887 strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
4888 unw = bfd_get_section_by_name (abfd, unw_name);
4889
4890 /* We need to create a fake group section for it and its
4891 unwind sections. */
4892 group = bfd_make_section_anyway_with_flags (abfd, name,
4893 flags);
4894 if (group == NULL)
4895 return FALSE;
4896
4897 /* Move the fake group section to the beginning. */
4898 bfd_section_list_remove (abfd, group);
4899 bfd_section_list_prepend (abfd, group);
4900
4901 elf_next_in_group (group) = sec;
4902
4903 elf_group_name (sec) = name;
4904 elf_next_in_group (sec) = sec;
4905 elf_sec_group (sec) = group;
4906
4907 if (unwi)
4908 {
4909 elf_group_name (unwi) = name;
4910 elf_next_in_group (unwi) = sec;
4911 elf_next_in_group (sec) = unwi;
4912 elf_sec_group (unwi) = group;
4913 }
4914
4915 if (unw)
4916 {
4917 elf_group_name (unw) = name;
4918 if (unwi)
4919 {
4920 elf_next_in_group (unw) = elf_next_in_group (unwi);
4921 elf_next_in_group (unwi) = unw;
4922 }
4923 else
4924 {
4925 elf_next_in_group (unw) = sec;
4926 elf_next_in_group (sec) = unw;
4927 }
4928 elf_sec_group (unw) = group;
4929 }
4930
4931 /* Fake SHT_GROUP section header. */
4932 elf_section_data (group)->this_hdr.bfd_section = group;
4933 elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
4934 }
4935 }
4936 return TRUE;
4937}
4938
4939static bfd_boolean
4940elfNN_ia64_hpux_vec (const bfd_target *vec)
4941{
6d00b590
AM
4942 extern const bfd_target ia64_elfNN_hpux_be_vec;
4943 return (vec == &ia64_elfNN_hpux_be_vec);
cbe79dfe
TG
4944}
4945
ed7e9d0b
AM
4946static bfd_boolean
4947elfNN_hpux_init_file_header (bfd *abfd, struct bfd_link_info *info)
cbe79dfe 4948{
ed7e9d0b 4949 Elf_Internal_Ehdr *i_ehdrp;
cbe79dfe 4950
ed7e9d0b
AM
4951 if (!_bfd_elf_init_file_header (abfd, info))
4952 return FALSE;
4953
4954 i_ehdrp = elf_elfheader (abfd);
cbe79dfe
TG
4955 i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
4956 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
ed7e9d0b 4957 return TRUE;
cbe79dfe
TG
4958}
4959
4960static bfd_boolean
4961elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
4962 asection *sec, int *retval)
4963{
4964 if (bfd_is_com_section (sec))
4965 {
4966 *retval = SHN_IA_64_ANSI_COMMON;
4967 return TRUE;
4968 }
4969 return FALSE;
4970}
4971
4972static void
4973elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
4974 asymbol *asym)
4975{
4976 elf_symbol_type *elfsym = (elf_symbol_type *) asym;
4977
4978 switch (elfsym->internal_elf_sym.st_shndx)
4979 {
4980 case SHN_IA_64_ANSI_COMMON:
4981 asym->section = bfd_com_section_ptr;
4982 asym->value = elfsym->internal_elf_sym.st_size;
4983 asym->flags &= ~BSF_GLOBAL;
4984 break;
4985 }
4986}
a859124d
AM
4987
4988static void
4989ignore_errors (const char *fmt ATTRIBUTE_UNUSED, ...)
4990{
4991}
cbe79dfe 4992\f
6d00b590 4993#define TARGET_LITTLE_SYM ia64_elfNN_le_vec
cbe79dfe 4994#define TARGET_LITTLE_NAME "elfNN-ia64-little"
6d00b590 4995#define TARGET_BIG_SYM ia64_elfNN_be_vec
cbe79dfe
TG
4996#define TARGET_BIG_NAME "elfNN-ia64-big"
4997#define ELF_ARCH bfd_arch_ia64
4998#define ELF_TARGET_ID IA64_ELF_DATA
4999#define ELF_MACHINE_CODE EM_IA_64
5000#define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
5001#define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
5002#define ELF_MAXPAGESIZE 0x10000 /* 64KB */
5003#define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
5004
5005#define elf_backend_section_from_shdr \
5006 elfNN_ia64_section_from_shdr
5007#define elf_backend_section_flags \
5008 elfNN_ia64_section_flags
5009#define elf_backend_fake_sections \
5010 elfNN_ia64_fake_sections
5011#define elf_backend_final_write_processing \
5012 elfNN_ia64_final_write_processing
5013#define elf_backend_add_symbol_hook \
5014 elfNN_ia64_add_symbol_hook
5015#define elf_backend_additional_program_headers \
5016 elfNN_ia64_additional_program_headers
5017#define elf_backend_modify_segment_map \
5018 elfNN_ia64_modify_segment_map
6d6c25c8
AM
5019#define elf_backend_modify_headers \
5020 elfNN_ia64_modify_headers
cbe79dfe
TG
5021#define elf_info_to_howto \
5022 elfNN_ia64_info_to_howto
5023
5024#define bfd_elfNN_bfd_reloc_type_lookup \
5025 ia64_elf_reloc_type_lookup
5026#define bfd_elfNN_bfd_reloc_name_lookup \
5027 ia64_elf_reloc_name_lookup
5028#define bfd_elfNN_bfd_is_local_label_name \
5029 elfNN_ia64_is_local_label_name
5030#define bfd_elfNN_bfd_relax_section \
5031 elfNN_ia64_relax_section
5032
5033#define elf_backend_object_p \
5034 elfNN_ia64_object_p
5035
5036/* Stuff for the BFD linker: */
5037#define bfd_elfNN_bfd_link_hash_table_create \
5038 elfNN_ia64_hash_table_create
cbe79dfe
TG
5039#define elf_backend_create_dynamic_sections \
5040 elfNN_ia64_create_dynamic_sections
5041#define elf_backend_check_relocs \
5042 elfNN_ia64_check_relocs
5043#define elf_backend_adjust_dynamic_symbol \
5044 elfNN_ia64_adjust_dynamic_symbol
5045#define elf_backend_size_dynamic_sections \
5046 elfNN_ia64_size_dynamic_sections
5047#define elf_backend_omit_section_dynsym \
d00dd7dc 5048 _bfd_elf_omit_section_dynsym_all
cbe79dfe
TG
5049#define elf_backend_relocate_section \
5050 elfNN_ia64_relocate_section
5051#define elf_backend_finish_dynamic_symbol \
5052 elfNN_ia64_finish_dynamic_symbol
5053#define elf_backend_finish_dynamic_sections \
5054 elfNN_ia64_finish_dynamic_sections
5055#define bfd_elfNN_bfd_final_link \
5056 elfNN_ia64_final_link
5057
5058#define bfd_elfNN_bfd_merge_private_bfd_data \
5059 elfNN_ia64_merge_private_bfd_data
5060#define bfd_elfNN_bfd_set_private_flags \
5061 elfNN_ia64_set_private_flags
5062#define bfd_elfNN_bfd_print_private_bfd_data \
5063 elfNN_ia64_print_private_bfd_data
5064
5065#define elf_backend_plt_readonly 1
6e8d06db 5066#define elf_backend_can_gc_sections 1
cbe79dfe
TG
5067#define elf_backend_want_plt_sym 0
5068#define elf_backend_plt_alignment 5
5069#define elf_backend_got_header_size 0
5070#define elf_backend_want_got_plt 1
5071#define elf_backend_may_use_rel_p 1
5072#define elf_backend_may_use_rela_p 1
5073#define elf_backend_default_use_rela_p 1
5074#define elf_backend_want_dynbss 0
5075#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5076#define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
5077#define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
5078#define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
5079#define elf_backend_rela_normal 1
64f52338 5080#define elf_backend_dtrel_excludes_plt 1
cbe79dfe
TG
5081#define elf_backend_special_sections elfNN_ia64_special_sections
5082#define elf_backend_default_execstack 0
5083
5084/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5085 SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
5086 We don't want to flood users with so many error messages. We turn
5087 off the warning for now. It will be turned on later when the Intel
5088 compiler is fixed. */
a859124d 5089#define elf_backend_link_order_error_handler ignore_errors
cbe79dfe
TG
5090
5091#include "elfNN-target.h"
5092
5093/* HPUX-specific vectors. */
5094
5095#undef TARGET_LITTLE_SYM
5096#undef TARGET_LITTLE_NAME
5097#undef TARGET_BIG_SYM
07d6d2b8
AM
5098#define TARGET_BIG_SYM ia64_elfNN_hpux_be_vec
5099#undef TARGET_BIG_NAME
5100#define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
cbe79dfe
TG
5101
5102/* These are HP-UX specific functions. */
5103
ed7e9d0b
AM
5104#undef elf_backend_init_file_header
5105#define elf_backend_init_file_header elfNN_hpux_init_file_header
cbe79dfe
TG
5106
5107#undef elf_backend_section_from_bfd_section
5108#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5109
5110#undef elf_backend_symbol_processing
5111#define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5112
5113#undef elf_backend_want_p_paddr_set_to_zero
5114#define elf_backend_want_p_paddr_set_to_zero 1
5115
5116#undef ELF_COMMONPAGESIZE
5117#undef ELF_OSABI
5118#define ELF_OSABI ELFOSABI_HPUX
5119
5120#undef elfNN_bed
5121#define elfNN_bed elfNN_ia64_hpux_bed
5122
5123#include "elfNN-target.h"
This page took 0.7446 seconds and 4 git commands to generate.