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