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