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