OSDN Git Service

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