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