OSDN Git Service

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