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