OSDN Git Service

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