OSDN Git Service

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