OSDN Git Service

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