Eliminate ia64 compiler warnings. Fix ia64 gas testsuite again.
[external/binutils.git] / bfd / elfxx-ia64.c
1 /* IA-64 support for 64-bit ELF
2    Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
3    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "opcode/ia64.h"
26 #include "elf/ia64.h"
27
28
29 /*
30  * THE RULES for all the stuff the linker creates --
31  *
32  * GOT          Entries created in response to LTOFF or LTOFF_FPTR
33  *              relocations.  Dynamic relocs created for dynamic
34  *              symbols in an application; REL relocs for locals
35  *              in a shared library.
36  *
37  * FPTR         The canonical function descriptor.  Created for local
38  *              symbols in applications.  Descriptors for dynamic symbols
39  *              and local symbols in shared libraries are created by
40  *              ld.so.  Thus there are no dynamic relocs against these
41  *              objects.  The FPTR relocs for such _are_ passed through
42  *              to the dynamic relocation tables.
43  *
44  * FULL_PLT     Created for a PCREL21B relocation against a dynamic symbol.
45  *              Requires the creation of a PLTOFF entry.  This does not
46  *              require any dynamic relocations.
47  *
48  * PLTOFF       Created by PLTOFF relocations.  For local symbols, this
49  *              is an alternate function descriptor, and in shared libraries
50  *              requires two REL relocations.  Note that this cannot be
51  *              transformed into an FPTR relocation, since it must be in
52  *              range of the GP.  For dynamic symbols, this is a function
53  *              descriptor for a MIN_PLT entry, and requires one IPLT reloc.
54  *
55  * MIN_PLT      Created by PLTOFF entries against dynamic symbols.  This
56  *              does not reqire dynamic relocations.
57  */
58
59 #define USE_RELA                /* we want RELA relocs, not REL */
60
61 #define NELEMS(a)       ((int) (sizeof (a) / sizeof ((a)[0])))
62
63 typedef struct bfd_hash_entry *(*new_hash_entry_func)
64   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
65
66 /* In dynamically (linker-) created sections, we generally need to keep track
67    of the place a symbol or expression got allocated to. This is done via hash
68    tables that store entries of the following type.  */
69
70 struct elfNN_ia64_dyn_sym_info
71 {
72   /* The addend for which this entry is relevant.  */
73   bfd_vma addend;
74
75   /* Next addend in the list.  */
76   struct elfNN_ia64_dyn_sym_info *next;
77
78   bfd_vma got_offset;
79   bfd_vma fptr_offset;
80   bfd_vma pltoff_offset;
81   bfd_vma plt_offset;
82   bfd_vma plt2_offset;
83
84   /* The symbol table entry, if any, that this was derrived from.  */
85   struct elf_link_hash_entry *h;
86   
87   /* Used to count non-got, non-plt relocations for delayed sizing
88      of relocation sections.  */
89   struct elfNN_ia64_dyn_reloc_entry
90   {
91     struct elfNN_ia64_dyn_reloc_entry *next;
92     asection *srel;
93     int type;
94     int count;
95   } *reloc_entries;
96
97   /* True when the section contents have been updated.  */
98   unsigned got_done : 1;
99   unsigned fptr_done : 1;
100   unsigned pltoff_done : 1;
101
102   /* True for the different kinds of linker data we want created.  */
103   unsigned want_got : 1;
104   unsigned want_fptr : 1;
105   unsigned want_ltoff_fptr : 1;
106   unsigned want_plt : 1;
107   unsigned want_plt2 : 1;
108   unsigned want_pltoff : 1;
109 };
110
111 struct elfNN_ia64_local_hash_entry
112 {
113   struct bfd_hash_entry root;
114   struct elfNN_ia64_dyn_sym_info *info;
115 };
116
117 struct elfNN_ia64_local_hash_table
118 {
119   struct bfd_hash_table root;
120   /* No additional fields for now.  */
121 };
122
123 struct elfNN_ia64_link_hash_entry
124 {
125   struct elf_link_hash_entry root;
126   struct elfNN_ia64_dyn_sym_info *info;
127 };
128
129 struct elfNN_ia64_link_hash_table
130 {
131   /* The main hash table */
132   struct elf_link_hash_table root;
133
134   asection *got_sec;            /* the linkage table section (or NULL) */
135   asection *rel_got_sec;        /* dynamic relocation section for same */
136   asection *fptr_sec;           /* function descriptor table (or NULL) */
137   asection *plt_sec;            /* the primary plt section (or NULL) */
138   asection *pltoff_sec;         /* private descriptors for plt (or NULL) */
139   asection *rel_pltoff_sec;     /* dynamic relocation section for same */
140
141   bfd_size_type minplt_entries; /* number of minplt entries */
142
143   struct elfNN_ia64_local_hash_table loc_hash_table;
144 };
145
146 #define elfNN_ia64_hash_table(p) \
147   ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
148
149 static bfd_reloc_status_type elfNN_ia64_reloc
150   PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
151            asection *input_section, bfd *output_bfd, char **error_message));
152 static reloc_howto_type * lookup_howto
153   PARAMS ((unsigned int rtype));
154 static reloc_howto_type *elfNN_ia64_reloc_type_lookup
155   PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
156 static void elfNN_ia64_info_to_howto
157   PARAMS ((bfd *abfd, arelent *bfd_reloc, ElfNN_Internal_Rela *elf_reloc));
158 static boolean elfNN_ia64_relax_section
159   PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
160           boolean *again));
161 static boolean elfNN_ia64_section_from_shdr
162   PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *));
163 static boolean elfNN_ia64_fake_sections
164   PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec));
165 static boolean elfNN_ia64_add_symbol_hook
166   PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
167            const char **namep, flagword *flagsp, asection **secp,
168            bfd_vma *valp));
169 static int elfNN_ia64_additional_program_headers
170   PARAMS ((bfd *abfd));
171 static boolean elfNN_ia64_is_local_label_name
172   PARAMS ((bfd *abfd, const char *name));
173 static boolean elfNN_ia64_dynamic_symbol_p
174   PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
175 static boolean elfNN_ia64_local_hash_table_init
176   PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
177            new_hash_entry_func new));
178 static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
179   PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
180            const char *string));
181 static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
182   PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
183            const char *string));
184 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
185   PARAMS ((bfd *abfd));
186 static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
187   PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
188            boolean create, boolean copy));
189 static void elfNN_ia64_dyn_sym_traverse
190   PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
191            boolean (*func)(struct elfNN_ia64_dyn_sym_info *, PTR),
192            PTR info));
193 static boolean elfNN_ia64_create_dynamic_sections
194   PARAMS ((bfd *abfd, struct bfd_link_info *info));
195 static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
196   PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
197            struct elf_link_hash_entry *h,
198            bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
199 static asection *get_got
200   PARAMS ((bfd *abfd, struct bfd_link_info *info,
201            struct elfNN_ia64_link_hash_table *ia64_info));
202 static asection *get_fptr
203   PARAMS ((bfd *abfd, struct bfd_link_info *info,
204            struct elfNN_ia64_link_hash_table *ia64_info));
205 static asection *get_pltoff
206   PARAMS ((bfd *abfd, struct bfd_link_info *info,
207            struct elfNN_ia64_link_hash_table *ia64_info));
208 static asection *get_reloc_section
209   PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
210            asection *sec, boolean create));
211 static boolean count_dyn_reloc
212   PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
213            asection *srel, int type));
214 static boolean elfNN_ia64_check_relocs
215   PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
216            const Elf_Internal_Rela *relocs));
217 static boolean elfNN_ia64_adjust_dynamic_symbol
218   PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
219 static unsigned long global_sym_index
220   PARAMS ((struct elf_link_hash_entry *h));
221 static boolean allocate_fptr
222   PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
223 static boolean allocate_global_data_got
224   PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
225 static boolean allocate_global_fptr_got
226   PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
227 static boolean allocate_local_got
228   PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
229 static boolean allocate_pltoff_entries
230   PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
231 static boolean allocate_plt_entries
232   PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
233 static boolean allocate_plt2_entries
234   PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
235 static boolean allocate_dynrel_entries
236   PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
237 static boolean elfNN_ia64_size_dynamic_sections
238   PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
239 static bfd_reloc_status_type elfNN_ia64_install_value
240   PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
241 static void elfNN_ia64_install_dyn_reloc
242   PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
243            asection *srel, bfd_vma offset, unsigned int type,
244            long dynindx, bfd_vma addend));
245 static bfd_vma set_got_entry
246   PARAMS ((bfd *abfd, struct bfd_link_info *info,
247            struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
248            bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
249 static bfd_vma set_fptr_entry
250   PARAMS ((bfd *abfd, struct bfd_link_info *info,
251            struct elfNN_ia64_dyn_sym_info *dyn_i,
252            bfd_vma value));
253 static bfd_vma set_pltoff_entry
254   PARAMS ((bfd *abfd, struct bfd_link_info *info,
255            struct elfNN_ia64_dyn_sym_info *dyn_i,
256            bfd_vma value, boolean));
257 static boolean elfNN_ia64_final_link
258   PARAMS ((bfd *abfd, struct bfd_link_info *info));
259 static boolean elfNN_ia64_relocate_section
260   PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
261            asection *input_section, bfd_byte *contents,
262            Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
263            asection **local_sections));
264 static boolean elfNN_ia64_finish_dynamic_symbol
265   PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
266            struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
267 static boolean elfNN_ia64_finish_dynamic_sections
268   PARAMS ((bfd *abfd, struct bfd_link_info *info));
269 static boolean elfNN_ia64_set_private_flags
270   PARAMS ((bfd *abfd, flagword flags));
271 static boolean elfNN_ia64_copy_private_bfd_data
272   PARAMS ((bfd *ibfd, bfd *obfd));
273 static boolean elfNN_ia64_merge_private_bfd_data
274   PARAMS ((bfd *ibfd, bfd *obfd));
275 static boolean elfNN_ia64_print_private_bfd_data
276   PARAMS ((bfd *abfd, PTR ptr));
277
278 \f
279 /* ia64-specific relocation */
280
281 /* Perform a relocation.  Not much to do here as all the hard work is
282    done in elfNN_ia64_final_link_relocate.  */
283 static bfd_reloc_status_type
284 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
285                   output_bfd, error_message)
286      bfd *abfd ATTRIBUTE_UNUSED;
287      arelent *reloc;
288      asymbol *sym ATTRIBUTE_UNUSED;
289      PTR data ATTRIBUTE_UNUSED;
290      asection *input_section;
291      bfd *output_bfd;
292      char **error_message;
293 {
294   if (output_bfd)
295     {
296       reloc->address += input_section->output_offset;
297       return bfd_reloc_ok;
298     }
299   *error_message = "Unsupported call to elfNN_ia64_reloc";
300   return bfd_reloc_notsupported;
301 }
302
303 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN)                 \
304   HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed,  \
305          elfNN_ia64_reloc, NAME, false, 0, 0, IN)
306
307 /* This table has to be sorted according to increasing number of the
308    TYPE field.  */
309 static reloc_howto_type ia64_howto_table[] =
310   {
311     IA64_HOWTO (R_IA64_NONE,        "NONE",        0, false, true),
312
313     IA64_HOWTO (R_IA64_IMM14,       "IMM14",       0, false, true),
314     IA64_HOWTO (R_IA64_IMM22,       "IMM22",       0, false, true),
315     IA64_HOWTO (R_IA64_IMM64,       "IMM64",       0, false, true),
316     IA64_HOWTO (R_IA64_DIR32MSB,    "DIR32MSB",    2, false, true),
317     IA64_HOWTO (R_IA64_DIR32LSB,    "DIR32LSB",    2, false, true),
318     IA64_HOWTO (R_IA64_DIR64MSB,    "DIR64MSB",    4, false, true),
319     IA64_HOWTO (R_IA64_DIR64LSB,    "DIR64LSB",    4, false, true),
320
321     IA64_HOWTO (R_IA64_GPREL22,     "GPREL22",     0, false, true),
322     IA64_HOWTO (R_IA64_GPREL64I,    "GPREL64I",    0, false, true),
323     IA64_HOWTO (R_IA64_GPREL32MSB,  "GPREL32MSB",  2, false, true),
324     IA64_HOWTO (R_IA64_GPREL32LSB,  "GPREL32LSB",  2, false, true),
325     IA64_HOWTO (R_IA64_GPREL64MSB,  "GPREL64MSB",  4, false, true),
326     IA64_HOWTO (R_IA64_GPREL64LSB,  "GPREL64LSB",  4, false, true),
327
328     IA64_HOWTO (R_IA64_LTOFF22,     "LTOFF22",     0, false, true),
329     IA64_HOWTO (R_IA64_LTOFF64I,    "LTOFF64I",    0, false, true),
330
331     IA64_HOWTO (R_IA64_PLTOFF22,    "PLTOFF22",    0, false, true),
332     IA64_HOWTO (R_IA64_PLTOFF64I,   "PLTOFF64I",   0, false, true),
333     IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, false, true),
334     IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, false, true),
335
336     IA64_HOWTO (R_IA64_FPTR64I,     "FPTR64I",     0, false, true),
337     IA64_HOWTO (R_IA64_FPTR32MSB,   "FPTR32MSB",   2, false, true),
338     IA64_HOWTO (R_IA64_FPTR32LSB,   "FPTR32LSB",   2, false, true),
339     IA64_HOWTO (R_IA64_FPTR64MSB,   "FPTR64MSB",   4, false, true),
340     IA64_HOWTO (R_IA64_FPTR64LSB,   "FPTR64LSB",   4, false, true),
341
342     IA64_HOWTO (R_IA64_PCREL60B,    "PCREL60B",    0, true, true),
343     IA64_HOWTO (R_IA64_PCREL21B,    "PCREL21B",    0, true, true),
344     IA64_HOWTO (R_IA64_PCREL21M,    "PCREL21M",    0, true, true),
345     IA64_HOWTO (R_IA64_PCREL21F,    "PCREL21F",    0, true, true),
346     IA64_HOWTO (R_IA64_PCREL32MSB,  "PCREL32MSB",  2, true, true),
347     IA64_HOWTO (R_IA64_PCREL32LSB,  "PCREL32LSB",  2, true, true),
348     IA64_HOWTO (R_IA64_PCREL64MSB,  "PCREL64MSB",  4, true, true),
349     IA64_HOWTO (R_IA64_PCREL64LSB,  "PCREL64LSB",  4, true, true),
350
351     IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true),
352     IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true),
353     IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
354     IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
355
356     IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
357     IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
358     IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
359     IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, false, true),
360
361     IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, false, true),
362     IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, false, true),
363     IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, false, true),
364     IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, false, true),
365
366     IA64_HOWTO (R_IA64_REL32MSB,    "REL32MSB",    2, false, true),
367     IA64_HOWTO (R_IA64_REL32LSB,    "REL32LSB",    2, false, true),
368     IA64_HOWTO (R_IA64_REL64MSB,    "REL64MSB",    4, false, true),
369     IA64_HOWTO (R_IA64_REL64LSB,    "REL64LSB",    4, false, true),
370
371     IA64_HOWTO (R_IA64_LTV32MSB,    "LTV32MSB",    2, false, true),
372     IA64_HOWTO (R_IA64_LTV32LSB,    "LTV32LSB",    2, false, true),
373     IA64_HOWTO (R_IA64_LTV64MSB,    "LTV64MSB",    4, false, true),
374     IA64_HOWTO (R_IA64_LTV64LSB,    "LTV64LSB",    4, false, true),
375
376     IA64_HOWTO (R_IA64_PCREL21BI,   "PCREL21BI",   0, true, true),
377     IA64_HOWTO (R_IA64_PCREL22,     "PCREL22",     0, true, true),
378     IA64_HOWTO (R_IA64_PCREL64I,    "PCREL64I",    0, true, true),
379
380     IA64_HOWTO (R_IA64_IPLTMSB,     "IPLTMSB",     4, false, true),
381     IA64_HOWTO (R_IA64_IPLTLSB,     "IPLTLSB",     4, false, true),
382     IA64_HOWTO (R_IA64_COPY,        "COPY",        4, false, true),
383     IA64_HOWTO (R_IA64_LTOFF22X,    "LTOFF22X",    0, false, true),
384     IA64_HOWTO (R_IA64_LDXMOV,      "LDXMOV",      0, false, true),
385
386     IA64_HOWTO (R_IA64_TPREL22,     "TPREL22",     0, false, false),
387     IA64_HOWTO (R_IA64_TPREL64MSB,  "TPREL64MSB",  8, false, false),
388     IA64_HOWTO (R_IA64_TPREL64LSB,  "TPREL64LSB",  8, false, false),
389     IA64_HOWTO (R_IA64_LTOFF_TP22,  "LTOFF_TP22",  0, false, false),
390   };
391
392 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
393
394 /* Given a BFD reloc type, return the matching HOWTO structure.  */
395
396 static reloc_howto_type*
397 lookup_howto (rtype)
398      unsigned int rtype;
399 {
400   static int inited = 0;
401   int i;
402
403   if (!inited)
404     {
405       inited = 1;
406
407       memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
408       for (i = 0; i < NELEMS (ia64_howto_table); ++i)
409         elf_code_to_howto_index[ia64_howto_table[i].type] = i;
410     }
411
412   BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
413   i = elf_code_to_howto_index[rtype];
414   if (i >= NELEMS (ia64_howto_table))
415     return 0;
416   return ia64_howto_table + i;
417 }
418
419 static reloc_howto_type*
420 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
421      bfd *abfd ATTRIBUTE_UNUSED;
422      bfd_reloc_code_real_type bfd_code;
423 {
424   unsigned int rtype;
425
426   switch (bfd_code)
427     {
428     case BFD_RELOC_NONE:                rtype = R_IA64_NONE; break;
429
430     case BFD_RELOC_IA64_IMM14:          rtype = R_IA64_IMM14; break;
431     case BFD_RELOC_IA64_IMM22:          rtype = R_IA64_IMM22; break;
432     case BFD_RELOC_IA64_IMM64:          rtype = R_IA64_IMM64; break;
433
434     case BFD_RELOC_IA64_DIR32MSB:       rtype = R_IA64_DIR32MSB; break;
435     case BFD_RELOC_IA64_DIR32LSB:       rtype = R_IA64_DIR32LSB; break;
436     case BFD_RELOC_IA64_DIR64MSB:       rtype = R_IA64_DIR64MSB; break;
437     case BFD_RELOC_IA64_DIR64LSB:       rtype = R_IA64_DIR64LSB; break;
438
439     case BFD_RELOC_IA64_GPREL22:        rtype = R_IA64_GPREL22; break;
440     case BFD_RELOC_IA64_GPREL64I:       rtype = R_IA64_GPREL64I; break;
441     case BFD_RELOC_IA64_GPREL32MSB:     rtype = R_IA64_GPREL32MSB; break;
442     case BFD_RELOC_IA64_GPREL32LSB:     rtype = R_IA64_GPREL32LSB; break;
443     case BFD_RELOC_IA64_GPREL64MSB:     rtype = R_IA64_GPREL64MSB; break;
444     case BFD_RELOC_IA64_GPREL64LSB:     rtype = R_IA64_GPREL64LSB; break;
445
446     case BFD_RELOC_IA64_LTOFF22:        rtype = R_IA64_LTOFF22; break;
447     case BFD_RELOC_IA64_LTOFF64I:       rtype = R_IA64_LTOFF64I; break;
448
449     case BFD_RELOC_IA64_PLTOFF22:       rtype = R_IA64_PLTOFF22; break;
450     case BFD_RELOC_IA64_PLTOFF64I:      rtype = R_IA64_PLTOFF64I; break;
451     case BFD_RELOC_IA64_PLTOFF64MSB:    rtype = R_IA64_PLTOFF64MSB; break;
452     case BFD_RELOC_IA64_PLTOFF64LSB:    rtype = R_IA64_PLTOFF64LSB; break;
453     case BFD_RELOC_IA64_FPTR64I:        rtype = R_IA64_FPTR64I; break;
454     case BFD_RELOC_IA64_FPTR32MSB:      rtype = R_IA64_FPTR32MSB; break;
455     case BFD_RELOC_IA64_FPTR32LSB:      rtype = R_IA64_FPTR32LSB; break;
456     case BFD_RELOC_IA64_FPTR64MSB:      rtype = R_IA64_FPTR64MSB; break;
457     case BFD_RELOC_IA64_FPTR64LSB:      rtype = R_IA64_FPTR64LSB; break;
458
459     case BFD_RELOC_IA64_PCREL21B:       rtype = R_IA64_PCREL21B; break;
460     case BFD_RELOC_IA64_PCREL21BI:      rtype = R_IA64_PCREL21BI; break;
461     case BFD_RELOC_IA64_PCREL21M:       rtype = R_IA64_PCREL21M; break;
462     case BFD_RELOC_IA64_PCREL21F:       rtype = R_IA64_PCREL21F; break;
463     case BFD_RELOC_IA64_PCREL22:        rtype = R_IA64_PCREL22; break;
464     case BFD_RELOC_IA64_PCREL60B:       rtype = R_IA64_PCREL60B; break;
465     case BFD_RELOC_IA64_PCREL64I:       rtype = R_IA64_PCREL64I; break;
466     case BFD_RELOC_IA64_PCREL32MSB:     rtype = R_IA64_PCREL32MSB; break;
467     case BFD_RELOC_IA64_PCREL32LSB:     rtype = R_IA64_PCREL32LSB; break;
468     case BFD_RELOC_IA64_PCREL64MSB:     rtype = R_IA64_PCREL64MSB; break;
469     case BFD_RELOC_IA64_PCREL64LSB:     rtype = R_IA64_PCREL64LSB; break;
470
471     case BFD_RELOC_IA64_LTOFF_FPTR22:   rtype = R_IA64_LTOFF_FPTR22; break;
472     case BFD_RELOC_IA64_LTOFF_FPTR64I:  rtype = R_IA64_LTOFF_FPTR64I; break;
473     case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
474     case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
475
476     case BFD_RELOC_IA64_SEGREL32MSB:    rtype = R_IA64_SEGREL32MSB; break;
477     case BFD_RELOC_IA64_SEGREL32LSB:    rtype = R_IA64_SEGREL32LSB; break;
478     case BFD_RELOC_IA64_SEGREL64MSB:    rtype = R_IA64_SEGREL64MSB; break;
479     case BFD_RELOC_IA64_SEGREL64LSB:    rtype = R_IA64_SEGREL64LSB; break;
480
481     case BFD_RELOC_IA64_SECREL32MSB:    rtype = R_IA64_SECREL32MSB; break;
482     case BFD_RELOC_IA64_SECREL32LSB:    rtype = R_IA64_SECREL32LSB; break;
483     case BFD_RELOC_IA64_SECREL64MSB:    rtype = R_IA64_SECREL64MSB; break;
484     case BFD_RELOC_IA64_SECREL64LSB:    rtype = R_IA64_SECREL64LSB; break;
485
486     case BFD_RELOC_IA64_REL32MSB:       rtype = R_IA64_REL32MSB; break;
487     case BFD_RELOC_IA64_REL32LSB:       rtype = R_IA64_REL32LSB; break;
488     case BFD_RELOC_IA64_REL64MSB:       rtype = R_IA64_REL64MSB; break;
489     case BFD_RELOC_IA64_REL64LSB:       rtype = R_IA64_REL64LSB; break;
490
491     case BFD_RELOC_IA64_LTV32MSB:       rtype = R_IA64_LTV32MSB; break;
492     case BFD_RELOC_IA64_LTV32LSB:       rtype = R_IA64_LTV32LSB; break;
493     case BFD_RELOC_IA64_LTV64MSB:       rtype = R_IA64_LTV64MSB; break;
494     case BFD_RELOC_IA64_LTV64LSB:       rtype = R_IA64_LTV64LSB; break;
495
496     case BFD_RELOC_IA64_IPLTMSB:        rtype = R_IA64_IPLTMSB; break;
497     case BFD_RELOC_IA64_IPLTLSB:        rtype = R_IA64_IPLTLSB; break;
498     case BFD_RELOC_IA64_COPY:           rtype = R_IA64_COPY; break;
499     case BFD_RELOC_IA64_LTOFF22X:       rtype = R_IA64_LTOFF22X; break;
500     case BFD_RELOC_IA64_LDXMOV:         rtype = R_IA64_LDXMOV; break;
501
502     case BFD_RELOC_IA64_TPREL22:        rtype = R_IA64_TPREL22; break;
503     case BFD_RELOC_IA64_TPREL64MSB:     rtype = R_IA64_TPREL64MSB; break;
504     case BFD_RELOC_IA64_TPREL64LSB:     rtype = R_IA64_TPREL64LSB; break;
505     case BFD_RELOC_IA64_LTOFF_TP22:     rtype = R_IA64_LTOFF_TP22; break;
506
507     default: return 0;
508     }
509   return lookup_howto (rtype);
510 }
511
512 /* Given a ELF reloc, return the matching HOWTO structure.  */
513
514 static void
515 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
516      bfd *abfd ATTRIBUTE_UNUSED;
517      arelent *bfd_reloc;
518      ElfNN_Internal_Rela *elf_reloc;
519 {
520   bfd_reloc->howto = lookup_howto (ELFNN_R_TYPE (elf_reloc->r_info));
521 }
522 \f
523 #define PLT_HEADER_SIZE         (3 * 16)
524 #define PLT_MIN_ENTRY_SIZE      (1 * 16)
525 #define PLT_FULL_ENTRY_SIZE     (2 * 16)
526 #define PLT_RESERVED_WORDS      3
527
528 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
529 {
530   0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21,  /*   [MMI]       mov r2=r14;;       */
531   0xe0, 0x00, 0x08, 0x00, 0x48, 0x00,  /*               addl r14=0,r2      */
532   0x00, 0x00, 0x04, 0x00,              /*               nop.i 0x0;;        */
533   0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14,  /*   [MMI]       ld8 r16=[r14],8;;  */
534   0x10, 0x41, 0x38, 0x30, 0x28, 0x00,  /*               ld8 r17=[r14],8    */
535   0x00, 0x00, 0x04, 0x00,              /*               nop.i 0x0;;        */
536   0x11, 0x08, 0x00, 0x1c, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r14]       */
537   0x60, 0x88, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r17         */
538   0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
539 };
540
541 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
542 {
543   0x11, 0x78, 0x00, 0x00, 0x00, 0x24,  /*   [MIB]       mov r15=0          */
544   0x00, 0x00, 0x00, 0x02, 0x00, 0x00,  /*               nop.i 0x0          */
545   0x00, 0x00, 0x00, 0x40               /*               br.few 0 <PLT0>;;  */
546 };
547
548 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
549 {
550   0x0b, 0x78, 0x00, 0x02, 0x00, 0x24,  /*   [MMI]       addl r15=0,r1;;    */
551   0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0,  /*               ld8 r16=[r15],8    */
552   0x01, 0x08, 0x00, 0x84,              /*               mov r14=r1;;       */
553   0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r15]       */
554   0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
555   0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
556 };
557
558 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
559
560 /* Select out of range branch fixup type.  Note that Itanium does
561    not support brl, and so it gets emulated by the kernel.  */
562 #undef USE_BRL
563
564 static const bfd_byte oor_brl[16] =
565 {
566   0x05, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
567   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /*               brl.sptk.few tgt;; */
568   0x00, 0x00, 0x00, 0xc0
569 };
570
571 static const bfd_byte oor_ip[48] =
572 {
573   0x04, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
574   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,  /*               movl r15=0         */
575   0x01, 0x00, 0x00, 0x60,
576   0x03, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MII]        nop.m 0            */
577   0x00, 0x01, 0x00, 0x60, 0x00, 0x00,  /*               mov r16=ip;;       */
578   0xf2, 0x80, 0x00, 0x80,              /*               add r16=r15,r16;;  */
579   0x11, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MIB]        nop.m 0            */
580   0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
581   0x60, 0x00, 0x80, 0x00               /*               br b6;;            */
582 };
583 \f
584 /* These functions do relaxation for IA-64 ELF.
585
586    This is primarily to support branches to targets out of range;
587    relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported.  */
588
589 static boolean
590 elfNN_ia64_relax_section (abfd, sec, link_info, again)
591      bfd *abfd;
592      asection *sec;
593      struct bfd_link_info *link_info;
594      boolean *again;
595 {
596   struct one_fixup
597     {
598       struct one_fixup *next;
599       asection *tsec;
600       bfd_vma toff;
601       bfd_vma trampoff;
602     };
603
604   Elf_Internal_Shdr *symtab_hdr;
605   Elf_Internal_Rela *internal_relocs;
606   Elf_Internal_Rela *free_relocs = NULL;
607   Elf_Internal_Rela *irel, *irelend;
608   bfd_byte *contents;
609   bfd_byte *free_contents = NULL;
610   ElfNN_External_Sym *extsyms;
611   ElfNN_External_Sym *free_extsyms = NULL;
612   struct elfNN_ia64_link_hash_table *ia64_info;
613   struct one_fixup *fixups = NULL;
614   boolean changed_contents = false;
615   boolean changed_relocs = false;
616
617   /* Assume we're not going to change any sizes, and we'll only need
618      one pass.  */
619   *again = false;
620
621   /* Nothing to do if there are no relocations.  */
622   if ((sec->flags & SEC_RELOC) == 0
623       || sec->reloc_count == 0)
624     return true;
625
626   /* If this is the first time we have been called for this section,
627      initialize the cooked size.  */
628   if (sec->_cooked_size == 0)
629     sec->_cooked_size = sec->_raw_size;
630
631   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
632
633   /* Load the relocations for this section.  */
634   internal_relocs = (_bfd_elfNN_link_read_relocs
635                      (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
636                       link_info->keep_memory));
637   if (internal_relocs == NULL)
638     goto error_return;
639
640   if (! link_info->keep_memory)
641     free_relocs = internal_relocs;
642
643   ia64_info = elfNN_ia64_hash_table (link_info);
644   irelend = internal_relocs + sec->reloc_count;
645
646   for (irel = internal_relocs; irel < irelend; irel++)
647     if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
648       break;
649
650   /* No branch-type relocations.  */
651   if (irel == irelend)
652     {
653       if (free_relocs != NULL)
654         free (free_relocs);
655       return true;
656     }
657
658   /* Get the section contents.  */
659   if (elf_section_data (sec)->this_hdr.contents != NULL)
660     contents = elf_section_data (sec)->this_hdr.contents;
661   else
662     {
663       contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
664       if (contents == NULL)
665         goto error_return;
666       free_contents = contents;
667
668       if (! bfd_get_section_contents (abfd, sec, contents,
669                                       (file_ptr) 0, sec->_raw_size))
670         goto error_return;
671     }
672
673   /* Read this BFD's symbols.  */
674   if (symtab_hdr->contents != NULL)
675     extsyms = (ElfNN_External_Sym *) symtab_hdr->contents;
676   else
677     {
678       extsyms = (ElfNN_External_Sym *) bfd_malloc (symtab_hdr->sh_size);
679       if (extsyms == NULL)
680         goto error_return;
681       free_extsyms = extsyms;
682       if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
683           || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
684               != symtab_hdr->sh_size))
685         goto error_return;
686     }
687
688   for (; irel < irelend; irel++)
689     {
690       bfd_vma symaddr, reladdr, trampoff, toff, roff;
691       Elf_Internal_Sym isym;
692       asection *tsec;
693       struct one_fixup *f;
694
695       if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
696         continue;
697
698       /* Get the value of the symbol referred to by the reloc.  */
699       if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
700         {
701           /* A local symbol.  */
702           bfd_elfNN_swap_symbol_in (abfd,
703                                     extsyms + ELFNN_R_SYM (irel->r_info),
704                                     &isym);
705           if (isym.st_shndx == SHN_UNDEF)
706             continue;   /* We can't do anthing with undefined symbols.  */
707           else if (isym.st_shndx == SHN_ABS)
708             tsec = bfd_abs_section_ptr;
709           else if (isym.st_shndx == SHN_COMMON)
710             tsec = bfd_com_section_ptr;
711           else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
712             tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
713           else 
714             continue;   /* who knows. */
715
716           toff = isym.st_value;
717         }
718       else
719         {
720           unsigned long indx;
721           struct elf_link_hash_entry *h;
722           struct elfNN_ia64_dyn_sym_info *dyn_i;
723
724           indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
725           h = elf_sym_hashes (abfd)[indx];
726           BFD_ASSERT (h != NULL);
727
728           while (h->root.type == bfd_link_hash_indirect
729                  || h->root.type == bfd_link_hash_warning)
730             h = (struct elf_link_hash_entry *) h->root.u.i.link;
731
732           dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
733
734           /* For branches to dynamic symbols, we're interested instead
735              in a branch to the PLT entry.  */
736           if (dyn_i && dyn_i->want_plt2)
737             {
738               tsec = ia64_info->plt_sec;
739               toff = dyn_i->plt2_offset;
740             }
741           else
742             {
743               /* We can't do anthing with undefined symbols.  */
744               if (h->root.type == bfd_link_hash_undefined
745                   || h->root.type == bfd_link_hash_undefweak)
746                 continue;
747
748               tsec = h->root.u.def.section;
749               toff = h->root.u.def.value;
750             }
751         }
752
753       symaddr = (tsec->output_section->vma
754                  + tsec->output_offset
755                  + toff
756                  + irel->r_addend);
757
758       roff = irel->r_offset;
759       reladdr = (sec->output_section->vma
760                  + sec->output_offset
761                  + roff) & -4;
762
763       /* If the branch is in range, no need to do anything.  */
764       if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
765           && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
766         continue;
767
768       /* If the branch and target are in the same section, you've
769          got one honking big section and we can't help you.  You'll
770          get an error message later.  */
771       if (tsec == sec)
772         continue;
773
774       /* Look for an existing fixup to this address.  */
775       for (f = fixups; f ; f = f->next)
776         if (f->tsec == tsec && f->toff == toff)
777           break;
778
779       if (f == NULL)
780         {
781           /* Two alternatives: If it's a branch to a PLT entry, we can
782              make a copy of the FULL_PLT entry.  Otherwise, we'll have
783              to use a `brl' insn to get where we're going.  */
784
785           int size;
786
787           if (tsec == ia64_info->plt_sec)
788             size = sizeof (plt_full_entry);
789           else
790             {
791 #ifdef USE_BRL
792               size = sizeof (oor_brl);
793 #else
794               size = sizeof (oor_ip);
795 #endif
796             }
797
798           /* Resize the current section to make room for the new branch.  */
799           trampoff = (sec->_cooked_size + 15) & -16;
800           contents = (bfd_byte *) bfd_realloc (contents, trampoff + size);
801           if (contents == NULL)
802             goto error_return;
803           sec->_cooked_size = trampoff + size;
804
805           if (tsec == ia64_info->plt_sec)
806             {
807               memcpy (contents + trampoff, plt_full_entry, size);
808
809               /* Hijack the old relocation for use as the PLTOFF reloc.  */
810               irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
811                                            R_IA64_PLTOFF22);
812               irel->r_offset = trampoff;
813             }
814           else
815             {
816 #ifdef USE_BRL
817               memcpy (contents + trampoff, oor_brl, size);
818               irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
819                                            R_IA64_PCREL60B);
820               irel->r_offset = trampoff + 2;
821 #else
822               memcpy (contents + trampoff, oor_ip, size);
823               irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
824                                            R_IA64_PCREL64I);
825               irel->r_addend -= 16;
826               irel->r_offset = trampoff + 2;
827 #endif
828             }
829
830           /* Record the fixup so we don't do it again this section.  */
831           f = (struct one_fixup *) bfd_malloc (sizeof (*f));
832           f->next = fixups;
833           f->tsec = tsec;
834           f->toff = toff;
835           f->trampoff = trampoff;
836           fixups = f;
837         }
838       else
839         {
840           /* Nop out the reloc, since we're finalizing things here.  */
841           irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
842         }
843
844       /* Fix up the existing branch to hit the trampoline.  Hope like
845          hell this doesn't overflow too.  */
846       if (elfNN_ia64_install_value (abfd, contents + roff,
847                                     f->trampoff - (roff & -4),
848                                     R_IA64_PCREL21B) != bfd_reloc_ok)
849         goto error_return;
850
851       changed_contents = true;
852       changed_relocs = true;
853     }
854
855   /* Clean up and go home.  */
856   while (fixups)
857     {
858       struct one_fixup *f = fixups;
859       fixups = fixups->next;
860       free (f);
861     }
862
863   if (changed_relocs)
864     elf_section_data (sec)->relocs = internal_relocs;
865   else if (free_relocs != NULL)
866     free (free_relocs);
867
868   if (changed_contents)
869     elf_section_data (sec)->this_hdr.contents = contents;
870   else if (free_contents != NULL)
871     {
872       if (! link_info->keep_memory)
873         free (free_contents);
874       else
875         {
876           /* Cache the section contents for elf_link_input_bfd.  */
877           elf_section_data (sec)->this_hdr.contents = contents;
878         }
879     }
880
881   if (free_extsyms != NULL)
882     {
883       if (! link_info->keep_memory)
884         free (free_extsyms);
885       else
886         {
887           /* Cache the symbols for elf_link_input_bfd.  */
888           symtab_hdr->contents = extsyms;
889         }
890     }
891
892   *again = changed_contents || changed_relocs;
893   return true;
894
895  error_return:
896   if (free_relocs != NULL)
897     free (free_relocs);
898   if (free_contents != NULL)
899     free (free_contents);
900   if (free_extsyms != NULL)
901     free (free_extsyms);
902   return false;
903 }
904 \f
905 /* Handle an IA-64 specific section when reading an object file.  This
906    is called when elfcode.h finds a section with an unknown type.  */
907
908 static boolean
909 elfNN_ia64_section_from_shdr (abfd, hdr, name)
910      bfd *abfd;
911      ElfNN_Internal_Shdr *hdr;
912      char *name;
913 {
914   asection *newsect;
915
916   /* There ought to be a place to keep ELF backend specific flags, but
917      at the moment there isn't one.  We just keep track of the
918      sections by their name, instead.  Fortunately, the ABI gives
919      suggested names for all the MIPS specific sections, so we will
920      probably get away with this.  */
921   switch (hdr->sh_type)
922     {
923     case SHT_IA_64_UNWIND:
924       if (strcmp (name, ELF_STRING_ia64_unwind) != 0)
925         return false;
926       break;
927
928     case SHT_IA_64_EXT:
929       if (strcmp (name, ELF_STRING_ia64_archext) != 0)
930         return false;
931       break;
932
933     default:
934       return false;
935     }
936
937   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
938     return false;
939   newsect = hdr->bfd_section;
940
941   return true;
942 }
943
944 /* Convert IA-64 specific section flags to bfd internal section flags.  */
945
946 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
947    flag.  */
948
949 static boolean
950 elfNN_ia64_section_flags (flags, hdr)
951      flagword *flags;
952      ElfNN_Internal_Shdr *hdr;
953 {
954   if (hdr->sh_flags & SHF_IA_64_SHORT)
955     *flags |= SEC_SMALL_DATA;
956
957   return true;
958 }
959
960 /* Set the correct type for an IA-64 ELF section.  We do this by the
961    section name, which is a hack, but ought to work.  */
962
963 static boolean
964 elfNN_ia64_fake_sections (abfd, hdr, sec)
965      bfd *abfd ATTRIBUTE_UNUSED;
966      ElfNN_Internal_Shdr *hdr;
967      asection *sec;
968 {
969   register const char *name;
970
971   name = bfd_get_section_name (abfd, sec);
972
973   if (strcmp (name, ELF_STRING_ia64_unwind) == 0)
974     hdr->sh_type = SHT_IA_64_UNWIND;
975   else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
976     hdr->sh_type = SHT_IA_64_EXT;
977   else if (strcmp (name, ".reloc") == 0)
978     /*
979      * This is an ugly, but unfortunately necessary hack that is
980      * needed when producing EFI binaries on IA-64. It tells
981      * elf.c:elf_fake_sections() not to consider ".reloc" as a section
982      * containing ELF relocation info.  We need this hack in order to
983      * be able to generate ELF binaries that can be translated into
984      * EFI applications (which are essentially COFF objects).  Those
985      * files contain a COFF ".reloc" section inside an ELFNN object,
986      * which would normally cause BFD to segfault because it would
987      * attempt to interpret this section as containing relocation
988      * entries for section "oc".  With this hack enabled, ".reloc"
989      * will be treated as a normal data section, which will avoid the
990      * segfault.  However, you won't be able to create an ELFNN binary
991      * with a section named "oc" that needs relocations, but that's
992      * the kind of ugly side-effects you get when detecting section
993      * types based on their names...  In practice, this limitation is
994      * unlikely to bite.
995      */
996     hdr->sh_type = SHT_PROGBITS;
997
998   if (sec->flags & SEC_SMALL_DATA)
999     hdr->sh_flags |= SHF_IA_64_SHORT;
1000
1001   return true;
1002 }
1003
1004 /* Hook called by the linker routine which adds symbols from an object
1005    file.  We use it to put .comm items in .sbss, and not .bss.  */
1006
1007 static boolean
1008 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1009      bfd *abfd;
1010      struct bfd_link_info *info;
1011      const Elf_Internal_Sym *sym;
1012      const char **namep ATTRIBUTE_UNUSED;
1013      flagword *flagsp ATTRIBUTE_UNUSED;
1014      asection **secp;
1015      bfd_vma *valp;
1016 {
1017   if (sym->st_shndx == SHN_COMMON
1018       && !info->relocateable
1019       && sym->st_size <= (unsigned) bfd_get_gp_size (abfd))
1020     {
1021       /* Common symbols less than or equal to -G nn bytes are
1022          automatically put into .sbss.  */
1023
1024       asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1025
1026       if (scomm == NULL)
1027         {
1028           scomm = bfd_make_section (abfd, ".scommon");
1029           if (scomm == NULL
1030               || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1031                                                        | SEC_IS_COMMON
1032                                                        | SEC_LINKER_CREATED)))
1033             return false;
1034         }
1035
1036       *secp = scomm;
1037       *valp = sym->st_size;
1038     }
1039
1040   return true;
1041 }
1042
1043 /* Return the number of additional phdrs we will need.  */
1044
1045 static int
1046 elfNN_ia64_additional_program_headers (abfd)
1047      bfd *abfd;
1048 {
1049   asection *s;
1050   int ret = 0;
1051
1052   /* See if we need a PT_IA_64_ARCHEXT segment.  */
1053   s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1054   if (s && (s->flags & SEC_LOAD))
1055     ++ret;
1056
1057   /* See if we need a PT_IA_64_UNWIND segment.  */
1058   s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
1059   if (s && (s->flags & SEC_LOAD))
1060     ++ret;
1061
1062   return ret;
1063 }
1064
1065 static boolean
1066 elfNN_ia64_modify_segment_map (abfd)
1067      bfd *abfd;
1068 {
1069   struct elf_segment_map *m, **pm;
1070   asection *s;
1071
1072   /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1073      all PT_LOAD segments.  */
1074   s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1075   if (s && (s->flags & SEC_LOAD))
1076     {
1077       for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1078         if (m->p_type == PT_IA_64_ARCHEXT)
1079           break;
1080       if (m == NULL)
1081         {
1082           m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1083           if (m == NULL)
1084             return false;
1085
1086           m->p_type = PT_IA_64_ARCHEXT;
1087           m->count = 1;
1088           m->sections[0] = s;
1089
1090           /* We want to put it after the PHDR and INTERP segments.  */
1091           pm = &elf_tdata (abfd)->segment_map;
1092           while (*pm != NULL
1093                  && ((*pm)->p_type == PT_PHDR
1094                      || (*pm)->p_type == PT_INTERP))
1095             pm = &(*pm)->next;
1096
1097           m->next = *pm;
1098           *pm = m;
1099         }
1100     }
1101
1102   /* Install the PT_IA_64_UNWIND segment, if needed.  */
1103   s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
1104   if (s && (s->flags & SEC_LOAD))
1105     {
1106       for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1107         if (m->p_type == PT_IA_64_UNWIND)
1108           break;
1109       if (m == NULL)
1110         {
1111           m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1112           if (m == NULL)
1113             return false;
1114
1115           m->p_type = PT_IA_64_UNWIND;
1116           m->count = 1;
1117           m->sections[0] = s;
1118           m->next = NULL;
1119
1120           /* We want to put it last.  */
1121           pm = &elf_tdata (abfd)->segment_map;
1122           while (*pm != NULL)
1123             pm = &(*pm)->next;
1124           *pm = m;
1125         }
1126     }
1127
1128   /* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
1129      the input sections for each output section in the segment and testing
1130      for SHF_IA_64_NORECOV on each.  */
1131   for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1132     if (m->p_type == PT_LOAD)
1133       {
1134         int i;
1135         for (i = m->count - 1; i >= 0; --i)
1136           {
1137             struct bfd_link_order *order = m->sections[i]->link_order_head;
1138             while (order)
1139               {
1140                 if (order->type == bfd_indirect_link_order)
1141                   {
1142                     asection *is = order->u.indirect.section;
1143                     bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1144                     if (flags & SHF_IA_64_NORECOV)
1145                       {
1146                         m->p_flags |= PF_IA_64_NORECOV;
1147                         goto found;
1148                       }
1149                   }
1150                 order = order->next;
1151               }
1152           }
1153       found:;
1154       }
1155
1156   return true;
1157 }
1158
1159
1160 /* According to the Tahoe assembler spec, all labels starting with a
1161    '.' are local.  */
1162
1163 static boolean
1164 elfNN_ia64_is_local_label_name (abfd, name)
1165      bfd *abfd ATTRIBUTE_UNUSED;
1166      const char *name;
1167 {
1168   return name[0] == '.';
1169 }
1170
1171 /* Should we do dynamic things to this symbol?  */
1172
1173 static boolean
1174 elfNN_ia64_dynamic_symbol_p (h, info)
1175      struct elf_link_hash_entry *h;
1176      struct bfd_link_info *info;
1177 {
1178   if (h == NULL)
1179     return false;
1180
1181   while (h->root.type == bfd_link_hash_indirect
1182          || h->root.type == bfd_link_hash_warning)
1183     h = (struct elf_link_hash_entry *) h->root.u.i.link;
1184
1185   if (h->dynindx == -1)
1186     return false;
1187
1188   if (h->root.type == bfd_link_hash_undefweak
1189       || h->root.type == bfd_link_hash_defweak)
1190     return true;
1191
1192   if ((info->shared && !info->symbolic)
1193       || ((h->elf_link_hash_flags
1194            & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1195           == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1196     return true;
1197
1198   return false;
1199 }
1200 \f
1201 static boolean
1202 elfNN_ia64_local_hash_table_init (ht, abfd, new)
1203      struct elfNN_ia64_local_hash_table *ht;
1204      bfd *abfd ATTRIBUTE_UNUSED;
1205      new_hash_entry_func new;
1206 {
1207   memset (ht, 0, sizeof(*ht));
1208   return bfd_hash_table_init (&ht->root, new);
1209 }
1210
1211 static struct bfd_hash_entry*
1212 elfNN_ia64_new_loc_hash_entry (entry, table, string)
1213      struct bfd_hash_entry *entry;
1214      struct bfd_hash_table *table;
1215      const char *string;
1216 {
1217   struct elfNN_ia64_local_hash_entry *ret;
1218   ret = (struct elfNN_ia64_local_hash_entry *) entry;
1219
1220   /* Allocate the structure if it has not already been allocated by a
1221      subclass.  */
1222   if (!ret)
1223     ret = bfd_hash_allocate (table, sizeof (*ret));
1224
1225   if (!ret)
1226     return 0;
1227
1228   /* Initialize our local data.  All zeros, and definitely easier
1229      than setting a handful of bit fields.  */
1230   memset (ret, 0, sizeof(*ret));
1231
1232   /* Call the allocation method of the superclass.  */
1233   ret = ((struct elfNN_ia64_local_hash_entry *)
1234          bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1235
1236   return (struct bfd_hash_entry *) ret;
1237 }
1238
1239 static struct bfd_hash_entry*
1240 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1241      struct bfd_hash_entry *entry;
1242      struct bfd_hash_table *table;
1243      const char *string;
1244 {
1245   struct elfNN_ia64_link_hash_entry *ret;
1246   ret = (struct elfNN_ia64_link_hash_entry *) entry;
1247
1248   /* Allocate the structure if it has not already been allocated by a
1249      subclass.  */
1250   if (!ret)
1251     ret = bfd_hash_allocate (table, sizeof (*ret));
1252
1253   if (!ret)
1254     return 0;
1255
1256   /* Initialize our local data.  All zeros, and definitely easier
1257      than setting a handful of bit fields.  */
1258   memset (ret, 0, sizeof(*ret));
1259
1260   /* Call the allocation method of the superclass.  */
1261   ret = ((struct elfNN_ia64_link_hash_entry *)
1262          _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1263                                      table, string));
1264
1265   return (struct bfd_hash_entry *) ret;
1266 }
1267
1268 static void
1269 elfNN_ia64_hash_copy_indirect (xdir, xind)
1270      struct elf_link_hash_entry *xdir, *xind;
1271 {
1272   struct elfNN_ia64_link_hash_entry *dir, *ind;
1273
1274   dir = (struct elfNN_ia64_link_hash_entry *)xdir;
1275   ind = (struct elfNN_ia64_link_hash_entry *)xind;
1276
1277   /* Copy down any references that we may have already seen to the 
1278      symbol which just became indirect.  */
1279
1280   dir->root.elf_link_hash_flags |=
1281     (ind->root.elf_link_hash_flags
1282      & (ELF_LINK_HASH_REF_DYNAMIC
1283         | ELF_LINK_HASH_REF_REGULAR
1284         | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1285
1286   /* Copy over the got and plt data.  This would have been done
1287      by check_relocs.  */
1288
1289   if (dir->info == NULL)
1290     {
1291       struct elfNN_ia64_dyn_sym_info *dyn_i;
1292
1293       dir->info = dyn_i = ind->info;
1294       ind->info = NULL;
1295
1296       /* Fix up the dyn_sym_info pointers to the global symbol.  */
1297       for (; dyn_i; dyn_i = dyn_i->next)
1298         dyn_i->h = &dir->root;
1299     }
1300   BFD_ASSERT (ind->info == NULL);
1301
1302   /* Copy over the dynindx.  */
1303
1304   if (dir->root.dynindx == -1)
1305     {
1306       dir->root.dynindx = ind->root.dynindx;
1307       dir->root.dynstr_index = ind->root.dynstr_index;
1308       ind->root.dynindx = -1;
1309       ind->root.dynstr_index = 0;
1310     }
1311   BFD_ASSERT (ind->root.dynindx == -1);
1312 }
1313
1314 static void
1315 elfNN_ia64_hash_hide_symbol (info, xh)
1316      struct bfd_link_info *info ATTRIBUTE_UNUSED;
1317      struct elf_link_hash_entry *xh;
1318 {
1319   struct elfNN_ia64_link_hash_entry *h;
1320   struct elfNN_ia64_dyn_sym_info *dyn_i;
1321
1322   h = (struct elfNN_ia64_link_hash_entry *)xh;
1323
1324   h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
1325   h->root.dynindx = -1;
1326
1327   for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1328     dyn_i->want_plt2 = 0;
1329 }
1330
1331 /* Create the derived linker hash table.  The IA-64 ELF port uses this
1332    derived hash table to keep information specific to the IA-64 ElF
1333    linker (without using static variables).  */
1334
1335 static struct bfd_link_hash_table*
1336 elfNN_ia64_hash_table_create (abfd)
1337      bfd *abfd;
1338 {
1339   struct elfNN_ia64_link_hash_table *ret;
1340
1341   ret = bfd_alloc (abfd, sizeof (*ret));
1342   if (!ret)
1343     return 0;
1344   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1345                                       elfNN_ia64_new_elf_hash_entry))
1346     {
1347       bfd_release (abfd, ret);
1348       return 0;
1349     }
1350
1351   if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1352                                          elfNN_ia64_new_loc_hash_entry))
1353     return 0;
1354   return &ret->root.root;
1355 }
1356
1357 /* Look up an entry in a Alpha ELF linker hash table.  */
1358
1359 static INLINE struct elfNN_ia64_local_hash_entry *
1360 elfNN_ia64_local_hash_lookup(table, string, create, copy)
1361      struct elfNN_ia64_local_hash_table *table;
1362      const char *string;
1363      boolean create, copy;
1364 {
1365   return ((struct elfNN_ia64_local_hash_entry *)
1366           bfd_hash_lookup (&table->root, string, create, copy));
1367 }
1368
1369 /* Traverse both local and global hash tables.  */
1370
1371 struct elfNN_ia64_dyn_sym_traverse_data
1372 {
1373   boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1374   PTR data;
1375 };
1376
1377 static boolean
1378 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1379      struct bfd_hash_entry *xentry;
1380      PTR xdata;
1381 {
1382   struct elfNN_ia64_link_hash_entry *entry
1383     = (struct elfNN_ia64_link_hash_entry *) xentry;
1384   struct elfNN_ia64_dyn_sym_traverse_data *data
1385     = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1386   struct elfNN_ia64_dyn_sym_info *dyn_i;
1387
1388   for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1389     if (! (*data->func) (dyn_i, data->data))
1390       return false;
1391   return true;
1392 }
1393
1394 static boolean
1395 elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1396      struct bfd_hash_entry *xentry;
1397      PTR xdata;
1398 {
1399   struct elfNN_ia64_local_hash_entry *entry
1400     = (struct elfNN_ia64_local_hash_entry *) xentry;
1401   struct elfNN_ia64_dyn_sym_traverse_data *data
1402     = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1403   struct elfNN_ia64_dyn_sym_info *dyn_i;
1404
1405   for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1406     if (! (*data->func) (dyn_i, data->data))
1407       return false;
1408   return true;
1409 }
1410
1411 static void
1412 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1413      struct elfNN_ia64_link_hash_table *ia64_info;
1414      boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1415      PTR data;
1416 {
1417   struct elfNN_ia64_dyn_sym_traverse_data xdata;
1418
1419   xdata.func = func;
1420   xdata.data = data;
1421
1422   elf_link_hash_traverse (&ia64_info->root,
1423                           elfNN_ia64_global_dyn_sym_thunk, &xdata);
1424   bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1425                      elfNN_ia64_local_dyn_sym_thunk, &xdata);
1426 }
1427 \f
1428 static boolean
1429 elfNN_ia64_create_dynamic_sections (abfd, info)
1430      bfd *abfd;
1431      struct bfd_link_info *info;
1432 {
1433   struct elfNN_ia64_link_hash_table *ia64_info;
1434   asection *s;
1435
1436   if (! _bfd_elf_create_dynamic_sections (abfd, info))
1437     return false;
1438
1439   ia64_info = elfNN_ia64_hash_table (info);
1440
1441   ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1442   ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1443
1444   {
1445     flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1446     bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1447   }
1448
1449   if (!get_pltoff (abfd, info, ia64_info))
1450     return false;
1451
1452   s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1453   if (s == NULL
1454       || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1455                                            | SEC_HAS_CONTENTS
1456                                            | SEC_IN_MEMORY
1457                                            | SEC_LINKER_CREATED
1458                                            | SEC_READONLY))
1459       || !bfd_set_section_alignment (abfd, s, 3))
1460     return false;
1461   ia64_info->rel_pltoff_sec = s;
1462
1463   s = bfd_make_section(abfd, ".rela.got");
1464   if (s == NULL
1465       || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1466                                            | SEC_HAS_CONTENTS
1467                                            | SEC_IN_MEMORY
1468                                            | SEC_LINKER_CREATED
1469                                            | SEC_READONLY))
1470       || !bfd_set_section_alignment (abfd, s, 3))
1471     return false;
1472   ia64_info->rel_got_sec = s;
1473
1474   return true;
1475 }
1476
1477 /* Find and/or create a descriptor for dynamic symbol info.  This will
1478    vary based on global or local symbol, and the addend to the reloc.  */
1479
1480 static struct elfNN_ia64_dyn_sym_info *
1481 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1482      struct elfNN_ia64_link_hash_table *ia64_info;
1483      struct elf_link_hash_entry *h;
1484      bfd *abfd;
1485      const Elf_Internal_Rela *rel;
1486      boolean create;
1487 {
1488   struct elfNN_ia64_dyn_sym_info **pp;
1489   struct elfNN_ia64_dyn_sym_info *dyn_i;
1490   bfd_vma addend = rel ? rel->r_addend : 0;
1491   
1492   if (h)
1493     pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1494   else
1495     {
1496       struct elfNN_ia64_local_hash_entry *loc_h;
1497       char *addr_name;
1498       size_t len;
1499
1500       /* Construct a string for use in the elfNN_ia64_local_hash_table.
1501          The name describes what was once anonymous memory.  */
1502
1503       len = sizeof(void*)*2 + 1 + sizeof(bfd_vma)*4 + 1 + 1;
1504       len += 10;        /* %p slop */
1505
1506       addr_name = alloca (len);
1507       sprintf (addr_name, "%p:%lx", (void *) abfd, ELFNN_R_SYM (rel->r_info));
1508
1509       /* Collect the canonical entry data for this address.  */
1510       loc_h = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1511                                             addr_name, create, create);
1512       BFD_ASSERT (loc_h);
1513
1514       pp = &loc_h->info;
1515     }    
1516
1517   for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1518     pp = &dyn_i->next;
1519
1520   if (dyn_i == NULL && create)
1521     {
1522       dyn_i = (struct elfNN_ia64_dyn_sym_info *)
1523         bfd_zalloc (abfd, sizeof *dyn_i);
1524       *pp = dyn_i;
1525       dyn_i->addend = addend;
1526     }
1527
1528   return dyn_i;
1529 }
1530
1531 static asection *
1532 get_got (abfd, info, ia64_info)
1533      bfd *abfd;
1534      struct bfd_link_info *info;
1535      struct elfNN_ia64_link_hash_table *ia64_info;
1536 {
1537   asection *got;
1538   bfd *dynobj;
1539
1540   got = ia64_info->got_sec;
1541   if (!got)
1542     {
1543       flagword flags;
1544
1545       dynobj = ia64_info->root.dynobj;
1546       if (!dynobj)
1547         ia64_info->root.dynobj = dynobj = abfd;
1548       if (!_bfd_elf_create_got_section (dynobj, info))
1549         return 0;
1550
1551       got = bfd_get_section_by_name (dynobj, ".got");
1552       BFD_ASSERT (got);
1553       ia64_info->got_sec = got;
1554
1555       flags = bfd_get_section_flags (abfd, got);
1556       bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1557     }
1558
1559   return got;
1560 }
1561
1562 /* Create function descriptor section (.opd).  This section is called .opd
1563    because it contains "official prodecure descriptors".  The "official"
1564    refers to the fact that these descriptors are used when taking the address
1565    of a procedure, thus ensuring a unique address for each procedure.  */
1566
1567 static asection *
1568 get_fptr (abfd, info, ia64_info)
1569      bfd *abfd;
1570      struct bfd_link_info *info ATTRIBUTE_UNUSED;
1571      struct elfNN_ia64_link_hash_table *ia64_info;
1572 {
1573   asection *fptr;
1574   bfd *dynobj;
1575
1576   fptr = ia64_info->fptr_sec;
1577   if (!fptr)
1578     {
1579       dynobj = ia64_info->root.dynobj;
1580       if (!dynobj)
1581         ia64_info->root.dynobj = dynobj = abfd;
1582
1583       fptr = bfd_make_section (dynobj, ".opd");
1584       if (!fptr
1585           || !bfd_set_section_flags (dynobj, fptr,
1586                                      (SEC_ALLOC
1587                                       | SEC_LOAD
1588                                       | SEC_HAS_CONTENTS
1589                                       | SEC_IN_MEMORY
1590                                       | SEC_READONLY
1591                                       | SEC_LINKER_CREATED))
1592           || !bfd_set_section_alignment (abfd, fptr, 4))
1593         {
1594           BFD_ASSERT (0);
1595           return NULL;
1596         }
1597
1598       ia64_info->fptr_sec = fptr;
1599     }
1600
1601   return fptr;
1602 }
1603
1604 static asection *
1605 get_pltoff (abfd, info, ia64_info)
1606      bfd *abfd;
1607      struct bfd_link_info *info ATTRIBUTE_UNUSED;
1608      struct elfNN_ia64_link_hash_table *ia64_info;
1609 {
1610   asection *pltoff;
1611   bfd *dynobj;
1612
1613   pltoff = ia64_info->pltoff_sec;
1614   if (!pltoff)
1615     {
1616       dynobj = ia64_info->root.dynobj;
1617       if (!dynobj)
1618         ia64_info->root.dynobj = dynobj = abfd;
1619
1620       pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
1621       if (!pltoff
1622           || !bfd_set_section_flags (dynobj, pltoff,
1623                                      (SEC_ALLOC
1624                                       | SEC_LOAD
1625                                       | SEC_HAS_CONTENTS
1626                                       | SEC_IN_MEMORY
1627                                       | SEC_SMALL_DATA
1628                                       | SEC_LINKER_CREATED))
1629           || !bfd_set_section_alignment (abfd, pltoff, 4))
1630         {
1631           BFD_ASSERT (0);
1632           return NULL;
1633         }
1634
1635       ia64_info->pltoff_sec = pltoff;
1636     }
1637
1638   return pltoff;
1639 }
1640
1641 static asection *
1642 get_reloc_section (abfd, ia64_info, sec, create)
1643      bfd *abfd;
1644      struct elfNN_ia64_link_hash_table *ia64_info;
1645      asection *sec;
1646      boolean create;
1647 {
1648   const char *srel_name;
1649   asection *srel;
1650   bfd *dynobj;
1651
1652   srel_name = (bfd_elf_string_from_elf_section
1653                (abfd, elf_elfheader(abfd)->e_shstrndx,
1654                 elf_section_data(sec)->rel_hdr.sh_name));
1655   if (srel_name == NULL)
1656     return NULL;
1657
1658   BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
1659                && strcmp (bfd_get_section_name (abfd, sec),
1660                           srel_name+5) == 0)
1661               || (strncmp (srel_name, ".rel", 4) == 0
1662                   && strcmp (bfd_get_section_name (abfd, sec),
1663                              srel_name+4) == 0));
1664
1665   dynobj = ia64_info->root.dynobj;
1666   if (!dynobj)
1667     ia64_info->root.dynobj = dynobj = abfd;
1668
1669   srel = bfd_get_section_by_name (dynobj, srel_name);
1670   if (srel == NULL && create)
1671     {
1672       srel = bfd_make_section (dynobj, srel_name);
1673       if (srel == NULL
1674           || !bfd_set_section_flags (dynobj, srel,
1675                                      (SEC_ALLOC
1676                                       | SEC_LOAD
1677                                       | SEC_HAS_CONTENTS
1678                                       | SEC_IN_MEMORY
1679                                       | SEC_LINKER_CREATED
1680                                       | SEC_READONLY))
1681           || !bfd_set_section_alignment (dynobj, srel, 3))
1682         return NULL;
1683     }
1684
1685   return srel;
1686 }
1687
1688 static boolean
1689 count_dyn_reloc (abfd, dyn_i, srel, type)
1690      bfd *abfd;
1691      struct elfNN_ia64_dyn_sym_info *dyn_i;
1692      asection *srel;
1693      int type;
1694 {
1695   struct elfNN_ia64_dyn_reloc_entry *rent;
1696
1697   for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
1698     if (rent->srel == srel && rent->type == type)
1699       break;
1700
1701   if (!rent)
1702     {
1703       rent = (struct elfNN_ia64_dyn_reloc_entry *)
1704         bfd_alloc (abfd, sizeof (*rent));
1705       if (!rent)
1706         return false;
1707
1708       rent->next = dyn_i->reloc_entries;
1709       rent->srel = srel;
1710       rent->type = type;
1711       rent->count = 0;
1712       dyn_i->reloc_entries = rent;
1713     }
1714   rent->count++;
1715
1716   return true;
1717 }
1718
1719 static boolean
1720 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
1721      bfd *abfd;
1722      struct bfd_link_info *info;
1723      asection *sec;
1724      const Elf_Internal_Rela *relocs;
1725 {
1726   struct elfNN_ia64_link_hash_table *ia64_info;
1727   const Elf_Internal_Rela *relend;
1728   Elf_Internal_Shdr *symtab_hdr;
1729   const Elf_Internal_Rela *rel;
1730   asection *got, *fptr, *srel;
1731
1732   if (info->relocateable)
1733     return true;
1734
1735   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1736   ia64_info = elfNN_ia64_hash_table (info);
1737
1738   got = fptr = srel = NULL;
1739
1740   relend = relocs + sec->reloc_count;
1741   for (rel = relocs; rel < relend; ++rel)
1742     {
1743       enum {
1744         NEED_GOT = 1,
1745         NEED_FPTR = 2,
1746         NEED_PLTOFF = 4,
1747         NEED_MIN_PLT = 8,
1748         NEED_FULL_PLT = 16,
1749         NEED_DYNREL = 32,
1750         NEED_LTOFF_FPTR = 64,
1751       };
1752
1753       struct elf_link_hash_entry *h = NULL;
1754       unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
1755       struct elfNN_ia64_dyn_sym_info *dyn_i;
1756       int need_entry;
1757       boolean maybe_dynamic;
1758       int dynrel_type = R_IA64_NONE;
1759
1760       if (r_symndx >= symtab_hdr->sh_info)
1761         {
1762           /* We're dealing with a global symbol -- find its hash entry
1763              and mark it as being referenced.  */
1764           long indx = r_symndx - symtab_hdr->sh_info;
1765           h = elf_sym_hashes (abfd)[indx];
1766           while (h->root.type == bfd_link_hash_indirect
1767                  || h->root.type == bfd_link_hash_warning)
1768             h = (struct elf_link_hash_entry *) h->root.u.i.link;
1769
1770           h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
1771         }
1772
1773       /* We can only get preliminary data on whether a symbol is
1774          locally or externally defined, as not all of the input files
1775          have yet been processed.  Do something with what we know, as
1776          this may help reduce memory usage and processing time later.  */
1777       maybe_dynamic = false;
1778       if (h && ((info->shared && ! info->symbolic)
1779                 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
1780                 || h->root.type == bfd_link_hash_defweak))
1781         maybe_dynamic = true;
1782
1783       need_entry = 0;
1784       switch (ELFNN_R_TYPE (rel->r_info))
1785         {
1786         case R_IA64_TPREL22:
1787         case R_IA64_TPREL64MSB:
1788         case R_IA64_TPREL64LSB:
1789         case R_IA64_LTOFF_TP22:
1790           return false;
1791
1792         case R_IA64_LTOFF_FPTR22:
1793         case R_IA64_LTOFF_FPTR64I:
1794         case R_IA64_LTOFF_FPTR64MSB:
1795         case R_IA64_LTOFF_FPTR64LSB:
1796           need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
1797           break;
1798
1799         case R_IA64_FPTR64I:
1800         case R_IA64_FPTR32MSB:
1801         case R_IA64_FPTR32LSB:
1802         case R_IA64_FPTR64MSB:
1803         case R_IA64_FPTR64LSB:
1804           if (info->shared || h)
1805             need_entry = NEED_FPTR | NEED_DYNREL;
1806           else
1807             need_entry = NEED_FPTR;
1808           dynrel_type = R_IA64_FPTR64LSB;
1809           break;
1810
1811         case R_IA64_LTOFF22:
1812         case R_IA64_LTOFF22X:
1813         case R_IA64_LTOFF64I:
1814           need_entry = NEED_GOT;
1815           break;
1816
1817         case R_IA64_PLTOFF22:
1818         case R_IA64_PLTOFF64I:
1819         case R_IA64_PLTOFF64MSB:
1820         case R_IA64_PLTOFF64LSB:
1821           need_entry = NEED_PLTOFF;
1822           if (h)
1823             {
1824               if (maybe_dynamic)
1825                 need_entry |= NEED_MIN_PLT;
1826             }
1827           else
1828             {
1829               (*info->callbacks->warning)
1830                 (info, _("@pltoff reloc against local symbol"), 0,
1831                  abfd, 0, 0);
1832             }
1833           break;
1834
1835         case R_IA64_PCREL21B:
1836         case R_IA64_PCREL60B:
1837           /* Depending on where this symbol is defined, we may or may not
1838              need a full plt entry.  Only skip if we know we'll not need
1839              the entry -- static or symbolic, and the symbol definition
1840              has already been seen.  */
1841           if (maybe_dynamic && rel->r_addend == 0)
1842             need_entry = NEED_FULL_PLT;
1843           break;
1844
1845         case R_IA64_IMM14:
1846         case R_IA64_IMM22:
1847         case R_IA64_IMM64:
1848         case R_IA64_DIR32MSB:
1849         case R_IA64_DIR32LSB:
1850         case R_IA64_DIR64MSB:
1851         case R_IA64_DIR64LSB:
1852           /* Shared objects will always need at least a REL relocation.  */
1853           if (info->shared || maybe_dynamic)
1854             need_entry = NEED_DYNREL;
1855           dynrel_type = R_IA64_DIR64LSB;
1856           break;
1857
1858         case R_IA64_IPLTMSB:
1859         case R_IA64_IPLTLSB:
1860           /* Shared objects will always need at least a REL relocation.  */
1861           if (info->shared || maybe_dynamic)
1862             need_entry = NEED_DYNREL;
1863           dynrel_type = R_IA64_IPLTLSB;
1864           break;
1865
1866         case R_IA64_PCREL22:
1867         case R_IA64_PCREL64I:
1868         case R_IA64_PCREL32MSB:
1869         case R_IA64_PCREL32LSB:
1870         case R_IA64_PCREL64MSB:
1871         case R_IA64_PCREL64LSB:
1872           if (maybe_dynamic)
1873             need_entry = NEED_DYNREL;
1874           dynrel_type = R_IA64_PCREL64LSB;
1875           break;
1876         }
1877
1878       if (!need_entry)
1879         continue;
1880
1881       if ((need_entry & NEED_FPTR) != 0
1882           && rel->r_addend)
1883         {
1884           (*info->callbacks->warning)
1885             (info, _("non-zero addend in @fptr reloc"), 0,
1886              abfd, 0, 0);
1887         }
1888
1889       dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
1890
1891       /* Record whether or not this is a local symbol.  */
1892       dyn_i->h = h;
1893
1894       /* Create what's needed.  */
1895       if (need_entry & NEED_GOT)
1896         {
1897           if (!got)
1898             {
1899               got = get_got (abfd, info, ia64_info);
1900               if (!got)
1901                 return false;
1902             }
1903           dyn_i->want_got = 1;
1904         }
1905       if (need_entry & NEED_FPTR)
1906         {
1907           if (!fptr)
1908             {
1909               fptr = get_fptr (abfd, info, ia64_info);
1910               if (!fptr)
1911                 return false;
1912             }
1913
1914           /* FPTRs for shared libraries are allocated by the dynamic
1915              linker.  Make sure this local symbol will appear in the
1916              dynamic symbol table.  */
1917           if (!h && info->shared)
1918             {
1919               if (! (_bfd_elfNN_link_record_local_dynamic_symbol
1920                      (info, abfd, r_symndx)))
1921                 return false;
1922             }
1923
1924           dyn_i->want_fptr = 1;
1925         }
1926       if (need_entry & NEED_LTOFF_FPTR)
1927         dyn_i->want_ltoff_fptr = 1;
1928       if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
1929         {
1930           if (!ia64_info->root.dynobj)
1931             ia64_info->root.dynobj = abfd;
1932           h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
1933           dyn_i->want_plt = 1;
1934         }
1935       if (need_entry & NEED_FULL_PLT)
1936         dyn_i->want_plt2 = 1;
1937       if (need_entry & NEED_PLTOFF)
1938         dyn_i->want_pltoff = 1;
1939       if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
1940         {
1941           if (!srel)
1942             {
1943               srel = get_reloc_section (abfd, ia64_info, sec, true);
1944               if (!srel)
1945                 return false;
1946             }
1947           if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
1948             return false;
1949         }
1950     }
1951
1952   return true;
1953 }
1954
1955 struct elfNN_ia64_allocate_data
1956 {
1957   struct bfd_link_info *info;
1958   bfd_size_type ofs;
1959 };
1960
1961 /* For cleanliness, and potentially faster dynamic loading, allocate
1962    external GOT entries first.  */
1963
1964 static boolean
1965 allocate_global_data_got (dyn_i, data)
1966      struct elfNN_ia64_dyn_sym_info *dyn_i;
1967      PTR data;
1968 {
1969   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
1970
1971   if (dyn_i->want_got
1972       && ! dyn_i->want_fptr
1973       && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
1974      {
1975        dyn_i->got_offset = x->ofs;
1976        x->ofs += 8;
1977      }
1978   return true;
1979 }
1980
1981 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs.  */
1982
1983 static boolean
1984 allocate_global_fptr_got (dyn_i, data)
1985      struct elfNN_ia64_dyn_sym_info *dyn_i;
1986      PTR data;
1987 {
1988   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
1989
1990   if (dyn_i->want_got
1991       && dyn_i->want_fptr
1992       && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
1993     {
1994       dyn_i->got_offset = x->ofs;
1995       x->ofs += 8;
1996     }
1997   return true;
1998 }
1999
2000 /* Lastly, allocate all the GOT entries for local data.  */
2001
2002 static boolean
2003 allocate_local_got (dyn_i, data)
2004      struct elfNN_ia64_dyn_sym_info *dyn_i;
2005      PTR data;
2006 {
2007   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2008
2009   if (dyn_i->want_got
2010       && ! elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
2011     {
2012       dyn_i->got_offset = x->ofs;
2013       x->ofs += 8;
2014     }
2015   return true;
2016 }
2017
2018 /* Search for the index of a global symbol in it's defining object file.  */
2019
2020 static unsigned long
2021 global_sym_index (h)
2022      struct elf_link_hash_entry *h;
2023 {
2024   struct elf_link_hash_entry **p;
2025   bfd *obj;
2026
2027   BFD_ASSERT (h->root.type == bfd_link_hash_defined
2028               || h->root.type == bfd_link_hash_defweak);
2029
2030   obj = h->root.u.def.section->owner;
2031   for (p = elf_sym_hashes (obj); *p != h; ++p)
2032     continue;
2033
2034   return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2035 }
2036
2037 /* Allocate function descriptors.  We can do these for every function
2038    in a main executable that is not exported.  */
2039
2040 static boolean
2041 allocate_fptr (dyn_i, data)
2042      struct elfNN_ia64_dyn_sym_info *dyn_i;
2043      PTR data;
2044 {
2045   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2046
2047   if (dyn_i->want_fptr)
2048     {
2049       struct elf_link_hash_entry *h = dyn_i->h;
2050       
2051       if (h)
2052         while (h->root.type == bfd_link_hash_indirect
2053                || h->root.type == bfd_link_hash_warning)
2054           h = (struct elf_link_hash_entry *) h->root.u.i.link;
2055
2056       if (x->info->shared)
2057         {
2058           if (h && h->dynindx == -1)
2059             {
2060               BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2061                           || (h->root.type == bfd_link_hash_defweak));
2062
2063               if (!_bfd_elfNN_link_record_local_dynamic_symbol
2064                     (x->info, h->root.u.def.section->owner,
2065                      global_sym_index (h)))
2066                 return false;
2067             }
2068
2069           dyn_i->want_fptr = 0;
2070         }
2071       else if (h == NULL || h->dynindx == -1)
2072         {
2073           dyn_i->fptr_offset = x->ofs;
2074           x->ofs += 16;
2075         }
2076       else
2077         dyn_i->want_fptr = 0;
2078     }
2079   return true;
2080 }
2081
2082 /* Allocate all the minimal PLT entries.  */
2083
2084 static boolean
2085 allocate_plt_entries (dyn_i, data)
2086      struct elfNN_ia64_dyn_sym_info *dyn_i;
2087      PTR data;
2088 {
2089   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2090
2091   if (dyn_i->want_plt)
2092     {
2093       struct elf_link_hash_entry *h = dyn_i->h;
2094
2095       if (h)
2096         while (h->root.type == bfd_link_hash_indirect
2097                || h->root.type == bfd_link_hash_warning)
2098           h = (struct elf_link_hash_entry *) h->root.u.i.link;
2099
2100       /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT.  */
2101       if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2102         {
2103           bfd_size_type offset = x->ofs;
2104           if (offset == 0)
2105             offset = PLT_HEADER_SIZE;
2106           dyn_i->plt_offset = offset;
2107           x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2108
2109           dyn_i->want_pltoff = 1;
2110         }
2111       else
2112         {
2113           dyn_i->want_plt = 0;
2114           dyn_i->want_plt2 = 0;
2115         }
2116     }
2117   return true;
2118 }
2119
2120 /* Allocate all the full PLT entries.  */
2121
2122 static boolean
2123 allocate_plt2_entries (dyn_i, data)
2124      struct elfNN_ia64_dyn_sym_info *dyn_i;
2125      PTR data;
2126 {
2127   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2128
2129   if (dyn_i->want_plt2)
2130     {
2131       struct elf_link_hash_entry *h = dyn_i->h;
2132       bfd_size_type ofs = x->ofs;
2133
2134       dyn_i->plt2_offset = ofs;
2135       x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2136
2137       while (h->root.type == bfd_link_hash_indirect
2138              || h->root.type == bfd_link_hash_warning)
2139         h = (struct elf_link_hash_entry *) h->root.u.i.link;
2140       dyn_i->h->plt.offset = ofs;
2141     }
2142   return true;
2143 }
2144
2145 /* Allocate all the PLTOFF entries requested by relocations and
2146    plt entries.  We can't share space with allocated FPTR entries,
2147    because the latter are not necessarily addressable by the GP.
2148    ??? Relaxation might be able to determine that they are.  */
2149
2150 static boolean
2151 allocate_pltoff_entries (dyn_i, data)
2152      struct elfNN_ia64_dyn_sym_info *dyn_i;
2153      PTR data;
2154 {
2155   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2156
2157   if (dyn_i->want_pltoff)
2158     {
2159       dyn_i->pltoff_offset = x->ofs;
2160       x->ofs += 16;
2161     }
2162   return true;
2163 }
2164
2165 /* Allocate dynamic relocations for those symbols that turned out
2166    to be dynamic.  */
2167
2168 static boolean
2169 allocate_dynrel_entries (dyn_i, data)
2170      struct elfNN_ia64_dyn_sym_info *dyn_i;
2171      PTR data;
2172 {
2173   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2174   struct elfNN_ia64_link_hash_table *ia64_info;
2175   struct elfNN_ia64_dyn_reloc_entry *rent;
2176   boolean dynamic_symbol, shared;
2177
2178   ia64_info = elfNN_ia64_hash_table (x->info);
2179   dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info);
2180   shared = x->info->shared;
2181
2182   /* Take care of the normal data relocations.  */
2183
2184   for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2185     {
2186       int count = rent->count;
2187
2188       switch (rent->type)
2189         {
2190         case R_IA64_FPTR64LSB:
2191           /* Allocate one iff !want_fptr, which by this point will
2192              be true only if we're actually allocating one statically
2193              in the main executable.  */
2194           if (dyn_i->want_fptr)
2195             continue;
2196           break;
2197         case R_IA64_PCREL64LSB:
2198           if (!dynamic_symbol)
2199             continue;
2200           break;
2201         case R_IA64_DIR64LSB:
2202           if (!dynamic_symbol && !shared)
2203             continue;
2204           break;
2205         case R_IA64_IPLTLSB:
2206           if (!dynamic_symbol && !shared)
2207             continue;
2208           /* Use two REL relocations for IPLT relocations
2209              against local symbols.  */
2210           if (!dynamic_symbol)
2211             count *= 2;
2212           break;
2213         default:
2214           abort ();
2215         }
2216       rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2217     }
2218
2219   /* Take care of the GOT and PLT relocations.  */
2220
2221   if (((dynamic_symbol || shared) && dyn_i->want_got)
2222       || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2223     ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2224
2225   if (dyn_i->want_pltoff)
2226     {
2227       bfd_size_type t = 0;
2228
2229       /* Dynamic symbols get one IPLT relocation.  Local symbols in
2230          shared libraries get two REL relocations.  Local symbols in
2231          main applications get nothing.  */
2232       if (dynamic_symbol)
2233         t = sizeof (ElfNN_External_Rela);
2234       else if (shared)
2235         t = 2 * sizeof (ElfNN_External_Rela);
2236
2237       ia64_info->rel_pltoff_sec->_raw_size += t;
2238     }
2239
2240   return true;
2241 }
2242
2243 static boolean
2244 elfNN_ia64_adjust_dynamic_symbol (info, h)
2245      struct bfd_link_info *info ATTRIBUTE_UNUSED;
2246      struct elf_link_hash_entry *h;
2247 {
2248   /* ??? Undefined symbols with PLT entries should be re-defined
2249      to be the PLT entry.  */
2250
2251   /* If this is a weak symbol, and there is a real definition, the
2252      processor independent code will have arranged for us to see the
2253      real definition first, and we can just use the same value.  */
2254   if (h->weakdef != NULL)
2255     {
2256       BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2257                   || h->weakdef->root.type == bfd_link_hash_defweak);
2258       h->root.u.def.section = h->weakdef->root.u.def.section;
2259       h->root.u.def.value = h->weakdef->root.u.def.value;
2260       return true;
2261     }
2262
2263   /* If this is a reference to a symbol defined by a dynamic object which
2264      is not a function, we might allocate the symbol in our .dynbss section
2265      and allocate a COPY dynamic relocation.
2266
2267      But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2268      of hackery.  */
2269
2270   return true;
2271 }
2272
2273 static boolean
2274 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2275      bfd *output_bfd;
2276      struct bfd_link_info *info;
2277 {
2278   struct elfNN_ia64_allocate_data data;
2279   struct elfNN_ia64_link_hash_table *ia64_info;
2280   asection *sec;
2281   bfd *dynobj;
2282   boolean reltext = false;
2283   boolean relplt = false;
2284
2285   dynobj = elf_hash_table(info)->dynobj;
2286   ia64_info = elfNN_ia64_hash_table (info);
2287   BFD_ASSERT(dynobj != NULL);
2288   data.info = info;
2289
2290   /* Set the contents of the .interp section to the interpreter.  */
2291   if (ia64_info->root.dynamic_sections_created
2292       && !info->shared)
2293     {
2294       sec = bfd_get_section_by_name (dynobj, ".interp");
2295       BFD_ASSERT (sec != NULL);
2296       sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
2297       sec->_raw_size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
2298     }
2299
2300   /* Allocate the GOT entries.  */
2301
2302   if (ia64_info->got_sec)
2303     {
2304       data.ofs = 0;
2305       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2306       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2307       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2308       ia64_info->got_sec->_raw_size = data.ofs;
2309     }
2310
2311   /* Allocate the FPTR entries.  */
2312
2313   if (ia64_info->fptr_sec)
2314     {
2315       data.ofs = 0;
2316       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2317       ia64_info->fptr_sec->_raw_size = data.ofs;
2318     }
2319
2320   /* Now that we've seen all of the input files, we can decide which
2321      symbols need plt entries.  Allocate the minimal PLT entries first.
2322      We do this even though dynamic_sections_created may be false, because
2323      this has the side-effect of clearing want_plt and want_plt2.  */
2324
2325   data.ofs = 0;
2326   elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2327
2328   ia64_info->minplt_entries = 0;
2329   if (data.ofs)
2330     {
2331       ia64_info->minplt_entries
2332         = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2333     }
2334
2335   /* Align the pointer for the plt2 entries.  */
2336   data.ofs = (data.ofs + 31) & -32;
2337
2338   elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2339   if (data.ofs != 0)
2340     {
2341       BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2342
2343       ia64_info->plt_sec->_raw_size = data.ofs;
2344
2345       /* If we've got a .plt, we need some extra memory for the dynamic
2346          linker.  We stuff these in .got.plt.  */
2347       sec = bfd_get_section_by_name (dynobj, ".got.plt");
2348       sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2349     }
2350
2351   /* Allocate the PLTOFF entries.  */
2352
2353   if (ia64_info->pltoff_sec)
2354     {
2355       data.ofs = 0;
2356       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2357       ia64_info->pltoff_sec->_raw_size = data.ofs;
2358     }
2359
2360   if (ia64_info->root.dynamic_sections_created)
2361     {
2362       /* Allocate space for the dynamic relocations that turned out to be
2363          required.  */
2364
2365       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2366     }
2367
2368   /* We have now determined the sizes of the various dynamic sections.
2369      Allocate memory for them.  */
2370   for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2371     {
2372       boolean strip;
2373
2374       if (!(sec->flags & SEC_LINKER_CREATED))
2375         continue;
2376
2377       /* If we don't need this section, strip it from the output file.
2378          There were several sections primarily related to dynamic
2379          linking that must be create before the linker maps input
2380          sections to output sections.  The linker does that before
2381          bfd_elf_size_dynamic_sections is called, and it is that
2382          function which decides whether anything needs to go into
2383          these sections.  */
2384
2385       strip = (sec->_raw_size == 0);
2386
2387       if (sec == ia64_info->got_sec)
2388         strip = false;
2389       else if (sec == ia64_info->rel_got_sec)
2390         {
2391           if (strip)
2392             ia64_info->rel_got_sec = NULL;
2393           else
2394             /* We use the reloc_count field as a counter if we need to
2395                copy relocs into the output file.  */
2396             sec->reloc_count = 0;
2397         }
2398       else if (sec == ia64_info->fptr_sec)
2399         {
2400           if (strip)
2401             ia64_info->fptr_sec = NULL;
2402         }
2403       else if (sec == ia64_info->plt_sec)
2404         {
2405           if (strip)
2406             ia64_info->plt_sec = NULL;
2407         }
2408       else if (sec == ia64_info->pltoff_sec)
2409         {
2410           if (strip)
2411             ia64_info->pltoff_sec = NULL;
2412         }
2413       else if (sec == ia64_info->rel_pltoff_sec)
2414         {
2415           if (strip)
2416             ia64_info->rel_pltoff_sec = NULL;
2417           else
2418             {
2419               relplt = true;
2420               /* We use the reloc_count field as a counter if we need to
2421                  copy relocs into the output file.  */
2422               sec->reloc_count = 0;
2423             }
2424         }
2425       else
2426         {
2427           const char *name;
2428
2429           /* It's OK to base decisions on the section name, because none
2430              of the dynobj section names depend upon the input files.  */
2431           name = bfd_get_section_name (dynobj, sec);
2432
2433           if (strcmp (name, ".got.plt") == 0)
2434             strip = false;
2435           else if (strncmp (name, ".rel", 4) == 0)
2436             {
2437               if (!strip)
2438                 {
2439                   const char *outname;
2440                   asection *target;
2441
2442                   /* If this relocation section applies to a read only
2443                      section, then we probably need a DT_TEXTREL entry.  */
2444                   outname = bfd_get_section_name (output_bfd,
2445                                                   sec->output_section);
2446                   if (outname[4] == 'a')
2447                     outname += 5;
2448                   else
2449                     outname += 4;
2450
2451                   target = bfd_get_section_by_name (output_bfd, outname);
2452                   if (target != NULL
2453                       && (target->flags & SEC_READONLY) != 0
2454                       && (target->flags & SEC_ALLOC) != 0)
2455                     reltext = true;
2456
2457                   /* We use the reloc_count field as a counter if we need to
2458                      copy relocs into the output file.  */
2459                   sec->reloc_count = 0;
2460                 }
2461             }
2462           else
2463             continue;
2464         }
2465
2466       if (strip)
2467         _bfd_strip_section_from_output (info, sec);
2468       else
2469         {
2470           /* Allocate memory for the section contents.  */
2471           sec->contents = (bfd_byte *) bfd_zalloc(dynobj, sec->_raw_size);
2472           if (sec->contents == NULL && sec->_raw_size != 0)
2473             return false;
2474         }
2475     }
2476
2477   if (elf_hash_table (info)->dynamic_sections_created)
2478     {
2479       /* Add some entries to the .dynamic section.  We fill in the values
2480          later (in finish_dynamic_sections) but we must add the entries now
2481          so that we get the correct size for the .dynamic section.  */
2482
2483       if (!info->shared)
2484         {
2485           /* The DT_DEBUG entry is filled in by the dynamic linker and used
2486              by the debugger.  */
2487           if (!bfd_elfNN_add_dynamic_entry (info, DT_DEBUG, 0))
2488             return false;
2489         }
2490
2491       if (! bfd_elfNN_add_dynamic_entry (info, DT_IA_64_PLT_RESERVE, 0))
2492         return false;
2493       if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTGOT, 0))
2494         return false;
2495
2496       if (relplt)
2497         {
2498           if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2499               || ! bfd_elfNN_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2500               || ! bfd_elfNN_add_dynamic_entry (info, DT_JMPREL, 0))
2501             return false;
2502         }
2503
2504       if (! bfd_elfNN_add_dynamic_entry (info, DT_RELA, 0)
2505           || ! bfd_elfNN_add_dynamic_entry (info, DT_RELASZ, 0)
2506           || ! bfd_elfNN_add_dynamic_entry (info, DT_RELAENT,
2507                                             sizeof(ElfNN_External_Rela)))
2508         return false;
2509
2510       if (reltext)
2511         {
2512           if (! bfd_elfNN_add_dynamic_entry (info, DT_TEXTREL, 0))
2513             return false;
2514           info->flags |= DF_TEXTREL;
2515         }
2516     }
2517
2518   /* ??? Perhaps force __gp local.  */
2519
2520   return true;
2521 }
2522
2523 static bfd_reloc_status_type
2524 elfNN_ia64_install_value (abfd, hit_addr, val, r_type)
2525      bfd *abfd;
2526      bfd_byte *hit_addr;
2527      bfd_vma val;
2528      unsigned int r_type;
2529 {
2530   const struct ia64_operand *op;
2531   int bigendian = 0, shift = 0;
2532   bfd_vma t0, t1, insn, dword;
2533   enum ia64_opnd opnd;
2534   const char *err;
2535   size_t size = 8;
2536
2537   opnd = IA64_OPND_NIL;
2538   switch (r_type)
2539     {
2540     case R_IA64_NONE:
2541     case R_IA64_LDXMOV:
2542       return bfd_reloc_ok;
2543
2544       /* Instruction relocations. */
2545
2546     case R_IA64_IMM14:          opnd = IA64_OPND_IMM14; break;
2547
2548     case R_IA64_PCREL21F:       opnd = IA64_OPND_TGT25; break;
2549     case R_IA64_PCREL21M:       opnd = IA64_OPND_TGT25b; break;
2550     case R_IA64_PCREL60B:       opnd = IA64_OPND_TGT64; break;
2551     case R_IA64_PCREL21B:
2552     case R_IA64_PCREL21BI:
2553       opnd = IA64_OPND_TGT25c;
2554       break;
2555
2556     case R_IA64_IMM22:
2557     case R_IA64_GPREL22:
2558     case R_IA64_LTOFF22:
2559     case R_IA64_LTOFF22X:
2560     case R_IA64_PLTOFF22:
2561     case R_IA64_PCREL22:
2562     case R_IA64_LTOFF_FPTR22:
2563       opnd = IA64_OPND_IMM22;
2564       break;
2565
2566     case R_IA64_IMM64:
2567     case R_IA64_GPREL64I:
2568     case R_IA64_LTOFF64I:
2569     case R_IA64_PLTOFF64I:
2570     case R_IA64_PCREL64I:
2571     case R_IA64_FPTR64I:
2572     case R_IA64_LTOFF_FPTR64I:
2573       opnd = IA64_OPND_IMMU64;
2574       break;
2575
2576       /* Data relocations.  */
2577
2578     case R_IA64_DIR32MSB:
2579     case R_IA64_GPREL32MSB:
2580     case R_IA64_FPTR32MSB:
2581     case R_IA64_PCREL32MSB:
2582     case R_IA64_SEGREL32MSB:
2583     case R_IA64_SECREL32MSB:
2584     case R_IA64_LTV32MSB:
2585       size = 4; bigendian = 1;
2586       break;
2587
2588     case R_IA64_DIR32LSB:
2589     case R_IA64_GPREL32LSB:
2590     case R_IA64_FPTR32LSB:
2591     case R_IA64_PCREL32LSB:
2592     case R_IA64_SEGREL32LSB:
2593     case R_IA64_SECREL32LSB:
2594     case R_IA64_LTV32LSB:
2595       size = 4; bigendian = 0;
2596       break;
2597
2598     case R_IA64_DIR64MSB:
2599     case R_IA64_GPREL64MSB:
2600     case R_IA64_PLTOFF64MSB:
2601     case R_IA64_FPTR64MSB:
2602     case R_IA64_PCREL64MSB:
2603     case R_IA64_LTOFF_FPTR64MSB:
2604     case R_IA64_SEGREL64MSB:
2605     case R_IA64_SECREL64MSB:
2606     case R_IA64_LTV64MSB:
2607       size = 8; bigendian = 1;
2608       break;
2609
2610     case R_IA64_DIR64LSB:
2611     case R_IA64_GPREL64LSB:
2612     case R_IA64_PLTOFF64LSB:
2613     case R_IA64_FPTR64LSB:
2614     case R_IA64_PCREL64LSB:
2615     case R_IA64_LTOFF_FPTR64LSB:
2616     case R_IA64_SEGREL64LSB:
2617     case R_IA64_SECREL64LSB:
2618     case R_IA64_LTV64LSB:
2619       size = 8; bigendian = 0;
2620       break;
2621
2622       /* Unsupported / Dynamic relocations.  */
2623     default:
2624       return bfd_reloc_notsupported;
2625     }
2626
2627   switch (opnd)
2628     {
2629     case IA64_OPND_IMMU64:
2630       hit_addr -= (long) hit_addr & 0x3;
2631       t0 = bfd_get_64 (abfd, hit_addr);
2632       t1 = bfd_get_64 (abfd, hit_addr + 8);
2633
2634       /* tmpl/s: bits  0.. 5 in t0
2635          slot 0: bits  5..45 in t0
2636          slot 1: bits 46..63 in t0, bits 0..22 in t1
2637          slot 2: bits 23..63 in t1 */
2638
2639       /* First, clear the bits that form the 64 bit constant.  */
2640       t0 &= ~(0x3ffffLL << 46);
2641       t1 &= ~(0x7fffffLL
2642               | ((  (0x07fLL << 13) | (0x1ffLL << 27)
2643                     | (0x01fLL << 22) | (0x001LL << 21)
2644                     | (0x001LL << 36)) << 23));
2645
2646       t0 |= ((val >> 22) & 0x03ffffLL) << 46;           /* 18 lsbs of imm41 */
2647       t1 |= ((val >> 40) & 0x7fffffLL) <<  0;           /* 23 msbs of imm41 */
2648       t1 |= (  (((val >>  0) & 0x07f) << 13)            /* imm7b */
2649                | (((val >>  7) & 0x1ff) << 27)          /* imm9d */
2650                | (((val >> 16) & 0x01f) << 22)          /* imm5c */
2651                | (((val >> 21) & 0x001) << 21)          /* ic */
2652                | (((val >> 63) & 0x001) << 36)) << 23;  /* i */
2653
2654       bfd_put_64 (abfd, t0, hit_addr);
2655       bfd_put_64 (abfd, t1, hit_addr + 8);
2656       break;
2657
2658     case IA64_OPND_TGT64:
2659       hit_addr -= (long) hit_addr & 0x3;
2660       t0 = bfd_get_64 (abfd, hit_addr);
2661       t1 = bfd_get_64 (abfd, hit_addr + 8);
2662
2663       /* tmpl/s: bits  0.. 5 in t0
2664          slot 0: bits  5..45 in t0
2665          slot 1: bits 46..63 in t0, bits 0..22 in t1
2666          slot 2: bits 23..63 in t1 */
2667
2668       /* First, clear the bits that form the 64 bit constant.  */
2669       t0 &= ~(0x3ffffLL << 46);
2670       t1 &= ~(0x7fffffLL
2671               | ((1LL << 36 | 0xfffffLL << 13) << 23));
2672
2673       val >>= 4;
2674       t0 |= ((val >> 20) & 0xffffLL) << 2 << 46;        /* 16 lsbs of imm39 */
2675       t1 |= ((val >> 36) & 0x7fffffLL) << 0;            /* 23 msbs of imm39 */
2676       t1 |= ((((val >> 0) & 0xfffffLL) << 13)           /* imm20b */
2677               | (((val >> 59) & 0x1LL) << 36)) << 23;   /* i */
2678
2679       bfd_put_64 (abfd, t0, hit_addr);
2680       bfd_put_64 (abfd, t1, hit_addr + 8);
2681       break;
2682
2683     default:
2684       switch ((long) hit_addr & 0x3)
2685         {
2686         case 0: shift =  5; break;
2687         case 1: shift = 14; hit_addr += 3; break;
2688         case 2: shift = 23; hit_addr += 6; break;
2689         case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
2690         }
2691       dword = bfd_get_64 (abfd, hit_addr);
2692       insn = (dword >> shift) & 0x1ffffffffffLL;
2693
2694       op = elf64_ia64_operands + opnd;
2695       err = (*op->insert) (op, val, &insn);
2696       if (err)
2697         return bfd_reloc_overflow;
2698
2699       dword &= ~(0x1ffffffffffLL << shift);
2700       dword |= (insn << shift);
2701       bfd_put_64 (abfd, dword, hit_addr);
2702       break;
2703
2704     case IA64_OPND_NIL:
2705       /* A data relocation.  */
2706       if (bigendian)
2707         if (size == 4)
2708           bfd_putb32 (val, hit_addr);
2709         else
2710           bfd_putb64 (val, hit_addr);
2711       else
2712         if (size == 4)
2713           bfd_putl32 (val, hit_addr);
2714         else
2715           bfd_putl64 (val, hit_addr);
2716       break;
2717     }
2718
2719   return bfd_reloc_ok;
2720 }
2721
2722 static void
2723 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
2724                               dynindx, addend)
2725      bfd *abfd;
2726      struct bfd_link_info *info;
2727      asection *sec;
2728      asection *srel;
2729      bfd_vma offset;
2730      unsigned int type;
2731      long dynindx;
2732      bfd_vma addend;
2733 {
2734   Elf_Internal_Rela outrel;
2735
2736   outrel.r_offset = (sec->output_section->vma
2737                      + sec->output_offset
2738                      + offset);
2739
2740   BFD_ASSERT (dynindx != -1);
2741   outrel.r_info = ELFNN_R_INFO (dynindx, type);
2742   outrel.r_addend = addend;
2743
2744   if (elf_section_data (sec)->stab_info != NULL)
2745     {
2746       /* This may be NULL for linker-generated relocations, as it is
2747          inconvenient to pass all the bits around.  And this shouldn't
2748          happen.  */
2749       BFD_ASSERT (info != NULL);
2750
2751       offset = (_bfd_stab_section_offset
2752                 (abfd, &elf_hash_table (info)->stab_info, sec,
2753                  &elf_section_data (sec)->stab_info, offset));
2754       if (offset == (bfd_vma) -1)
2755         {
2756           /* Run for the hills.  We shouldn't be outputting a relocation
2757              for this.  So do what everyone else does and output a no-op.  */
2758           outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
2759           outrel.r_addend = 0;
2760           offset = 0;
2761         }
2762       outrel.r_offset = offset;
2763     }
2764
2765   bfd_elfNN_swap_reloca_out (abfd, &outrel,
2766                              ((ElfNN_External_Rela *) srel->contents
2767                               + srel->reloc_count++));
2768   BFD_ASSERT (sizeof(ElfNN_External_Rela) * srel->reloc_count
2769               <= srel->_cooked_size);
2770 }
2771
2772 /* Store an entry for target address TARGET_ADDR in the linkage table
2773    and return the gp-relative address of the linkage table entry.  */
2774
2775 static bfd_vma
2776 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
2777      bfd *abfd;
2778      struct bfd_link_info *info;
2779      struct elfNN_ia64_dyn_sym_info *dyn_i;
2780      long dynindx;
2781      bfd_vma addend;
2782      bfd_vma value;
2783      unsigned int dyn_r_type;
2784 {
2785   struct elfNN_ia64_link_hash_table *ia64_info;
2786   asection *got_sec;
2787
2788   ia64_info = elfNN_ia64_hash_table (info);
2789   got_sec = ia64_info->got_sec;
2790
2791   BFD_ASSERT ((dyn_i->got_offset & 7) == 0);
2792
2793   if (! dyn_i->got_done)
2794     {
2795       dyn_i->got_done = true;
2796
2797       /* Store the target address in the linkage table entry.  */
2798       bfd_put_64 (abfd, value, got_sec->contents + dyn_i->got_offset);
2799
2800       /* Install a dynamic relocation if needed.  */
2801       if (info->shared
2802           || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
2803           || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
2804         {
2805           if (dynindx == -1)
2806             {
2807               dyn_r_type = R_IA64_REL64LSB;
2808               dynindx = 0;
2809               addend = value;
2810             }
2811
2812           if (bfd_big_endian (abfd))
2813             {
2814               switch (dyn_r_type)
2815                 {
2816                 case R_IA64_REL64LSB:
2817                   dyn_r_type = R_IA64_REL64MSB;
2818                   break;
2819                 case R_IA64_DIR64LSB:
2820                   dyn_r_type = R_IA64_DIR64MSB;
2821                   break;
2822                 case R_IA64_FPTR64LSB:
2823                   dyn_r_type = R_IA64_FPTR64MSB;
2824                   break;
2825                 default:
2826                   BFD_ASSERT (false);
2827                   break;
2828                 }
2829             }
2830
2831           elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
2832                                         ia64_info->rel_got_sec,
2833                                         dyn_i->got_offset, dyn_r_type,
2834                                         dynindx, addend);
2835         }
2836     }
2837
2838   /* Return the address of the linkage table entry.  */
2839   value = (got_sec->output_section->vma
2840            + got_sec->output_offset
2841            + dyn_i->got_offset);
2842
2843   return value;
2844 }
2845
2846 /* Fill in a function descriptor consisting of the function's code
2847    address and its global pointer.  Return the descriptor's address.  */
2848
2849 static bfd_vma
2850 set_fptr_entry (abfd, info, dyn_i, value)
2851      bfd *abfd;
2852      struct bfd_link_info *info;
2853      struct elfNN_ia64_dyn_sym_info *dyn_i;
2854      bfd_vma value;
2855 {
2856   struct elfNN_ia64_link_hash_table *ia64_info;
2857   asection *fptr_sec;
2858
2859   ia64_info = elfNN_ia64_hash_table (info);
2860   fptr_sec = ia64_info->fptr_sec;
2861
2862   if (!dyn_i->fptr_done)
2863     {
2864       dyn_i->fptr_done = 1;
2865
2866       /* Fill in the function descriptor.  */
2867       bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
2868       bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
2869                   fptr_sec->contents + dyn_i->fptr_offset + 8);
2870     }
2871
2872   /* Return the descriptor's address.  */
2873   value = (fptr_sec->output_section->vma
2874            + fptr_sec->output_offset
2875            + dyn_i->fptr_offset);
2876
2877   return value;
2878 }
2879
2880 /* Fill in a PLTOFF entry consisting of the function's code address
2881    and its global pointer.  Return the descriptor's address.  */
2882
2883 static bfd_vma
2884 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
2885      bfd *abfd;
2886      struct bfd_link_info *info;
2887      struct elfNN_ia64_dyn_sym_info *dyn_i;
2888      bfd_vma value;
2889      boolean is_plt;
2890 {
2891   struct elfNN_ia64_link_hash_table *ia64_info;
2892   asection *pltoff_sec;
2893
2894   ia64_info = elfNN_ia64_hash_table (info);
2895   pltoff_sec = ia64_info->pltoff_sec;
2896
2897   /* Don't do anything if this symbol uses a real PLT entry.  In
2898      that case, we'll fill this in during finish_dynamic_symbol.  */
2899   if ((! dyn_i->want_plt || is_plt)
2900       && !dyn_i->pltoff_done)
2901     {
2902       bfd_vma gp = _bfd_get_gp_value (abfd);
2903
2904       /* Fill in the function descriptor.  */
2905       bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
2906       bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
2907
2908       /* Install dynamic relocations if needed.  */
2909       if (!is_plt && info->shared)
2910         {
2911           unsigned int dyn_r_type;
2912
2913           if (bfd_big_endian (abfd))
2914             dyn_r_type = R_IA64_REL64MSB;
2915           else
2916             dyn_r_type = R_IA64_REL64LSB;
2917
2918           elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
2919                                         ia64_info->rel_pltoff_sec,
2920                                         dyn_i->pltoff_offset,
2921                                         dyn_r_type, 0, value);
2922           elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
2923                                         ia64_info->rel_pltoff_sec,
2924                                         dyn_i->pltoff_offset + 8,
2925                                         dyn_r_type, 0, gp);
2926         }
2927
2928       dyn_i->pltoff_done = 1;
2929     }
2930
2931   /* Return the descriptor's address.  */
2932   value = (pltoff_sec->output_section->vma
2933            + pltoff_sec->output_offset
2934            + dyn_i->pltoff_offset);
2935
2936   return value;
2937 }
2938
2939 /* Called through qsort to sort the .IA_64.unwind section during a
2940    non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
2941    to the output bfd so we can do proper endianness frobbing.  */
2942
2943 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
2944
2945 static int
2946 elfNN_ia64_unwind_entry_compare (a, b)
2947      PTR a;
2948      PTR b;
2949 {
2950   bfd_vma av, bv;
2951
2952   av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
2953   bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
2954
2955   return (av < bv ? -1 : av > bv ? 1 : 0);
2956 }
2957
2958 static boolean
2959 elfNN_ia64_final_link (abfd, info)
2960      bfd *abfd;
2961      struct bfd_link_info *info;
2962 {
2963   struct elfNN_ia64_link_hash_table *ia64_info;
2964   asection *unwind_output_sec;
2965
2966   ia64_info = elfNN_ia64_hash_table (info);
2967
2968   /* Make sure we've got ourselves a nice fat __gp value.  */
2969   if (!info->relocateable)
2970     {
2971       bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
2972       bfd_vma min_short_vma = min_vma, max_short_vma = 0;
2973       struct elf_link_hash_entry *gp;
2974       bfd_vma gp_val;
2975       asection *os;
2976
2977       /* Find the min and max vma of all sections marked short.  Also
2978          collect min and max vma of any type, for use in selecting a
2979          nice gp.  */
2980       for (os = abfd->sections; os ; os = os->next)
2981         {
2982           bfd_vma lo, hi;
2983
2984           if ((os->flags & SEC_ALLOC) == 0)
2985             continue;
2986
2987           lo = os->vma;
2988           hi = os->vma + os->_raw_size;
2989           if (hi < lo)
2990             hi = (bfd_vma) -1;
2991
2992           if (min_vma > lo)
2993             min_vma = lo;
2994           if (max_vma < hi)
2995             max_vma = hi;
2996           if (os->flags & SEC_SMALL_DATA)
2997             {
2998               if (min_short_vma > lo)
2999                 min_short_vma = lo;
3000               if (max_short_vma < hi)
3001                 max_short_vma = hi;
3002             }
3003         }
3004
3005       /* See if the user wants to force a value.  */
3006       gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
3007                                  false, false);
3008
3009       if (gp
3010           && (gp->root.type == bfd_link_hash_defined
3011               || gp->root.type == bfd_link_hash_defweak))
3012         {
3013           asection *gp_sec = gp->root.u.def.section;
3014           gp_val = (gp->root.u.def.value
3015                     + gp_sec->output_section->vma
3016                     + gp_sec->output_offset);
3017         }
3018       else
3019         {
3020           /* Pick a sensible value.  */
3021
3022           asection *got_sec = ia64_info->got_sec;
3023
3024           /* Start with just the address of the .got.  */
3025           if (got_sec)
3026             gp_val = got_sec->output_section->vma;
3027           else if (max_short_vma != 0)
3028             gp_val = min_short_vma;
3029           else
3030             gp_val = min_vma;
3031
3032           /* If it is possible to address the entire image, but we
3033              don't with the choice above, adjust.  */
3034           if (max_vma - min_vma < 0x400000
3035               && max_vma - gp_val <= 0x200000
3036               && gp_val - min_vma > 0x200000)
3037             gp_val = min_vma + 0x200000;
3038           else if (max_short_vma != 0)
3039             {
3040               /* If we don't cover all the short data, adjust.  */
3041               if (max_short_vma - gp_val >= 0x200000)
3042                 gp_val = min_short_vma + 0x200000;
3043
3044               /* If we're addressing stuff past the end, adjust back.  */
3045               if (gp_val > max_vma)
3046                 gp_val = max_vma - 0x200000 + 8;
3047             }
3048         }
3049
3050       /* Validate whether all SHF_IA_64_SHORT sections are within
3051          range of the chosen GP.  */
3052
3053       if (max_short_vma != 0)
3054         {
3055           if (max_short_vma - min_short_vma >= 0x400000)
3056             {
3057               (*_bfd_error_handler)
3058                 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3059                  bfd_get_filename (abfd),
3060                  (unsigned long)(max_short_vma - min_short_vma));
3061               return false;
3062             }
3063           else if ((gp_val > min_short_vma
3064                     && gp_val - min_short_vma > 0x200000)
3065                    || (gp_val < max_short_vma
3066                        && max_short_vma - gp_val >= 0x200000))
3067             {
3068               (*_bfd_error_handler)
3069                 (_("%s: __gp does not cover short data segment"),
3070                  bfd_get_filename (abfd));
3071               return false;
3072             }
3073         }
3074
3075       _bfd_set_gp_value (abfd, gp_val);
3076     }
3077
3078   /* If we're producing a final executable, we need to sort the contents
3079      of the .IA_64.unwind section.  Force this section to be relocated
3080      into memory rather than written immediately to the output file.  */
3081   unwind_output_sec = NULL;
3082   if (!info->relocateable)
3083     {
3084       asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3085       if (s)
3086         {
3087           unwind_output_sec = s->output_section;
3088           unwind_output_sec->contents
3089             = bfd_malloc (unwind_output_sec->_raw_size);
3090           if (unwind_output_sec->contents == NULL)
3091             return false;
3092         }
3093     }
3094
3095   /* Invoke the regular ELF backend linker to do all the work.  */
3096   if (!bfd_elfNN_bfd_final_link (abfd, info))
3097     return false;
3098
3099   if (unwind_output_sec)
3100     {
3101       elfNN_ia64_unwind_entry_compare_bfd = abfd;
3102       qsort (unwind_output_sec->contents, unwind_output_sec->_raw_size / 24,
3103              24, elfNN_ia64_unwind_entry_compare);
3104
3105       if (! bfd_set_section_contents (abfd, unwind_output_sec,
3106                                       unwind_output_sec->contents, 0,
3107                                       unwind_output_sec->_raw_size))
3108         return false;
3109     }
3110
3111   return true;
3112 }
3113
3114 static boolean
3115 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3116                              contents, relocs, local_syms, local_sections)
3117      bfd *output_bfd;
3118      struct bfd_link_info *info;
3119      bfd *input_bfd;
3120      asection *input_section;
3121      bfd_byte *contents;
3122      Elf_Internal_Rela *relocs;
3123      Elf_Internal_Sym *local_syms;
3124      asection **local_sections;
3125 {
3126   struct elfNN_ia64_link_hash_table *ia64_info;
3127   Elf_Internal_Shdr *symtab_hdr;
3128   Elf_Internal_Rela *rel;
3129   Elf_Internal_Rela *relend;
3130   asection *srel;
3131   boolean ret_val = true;       /* for non-fatal errors */
3132   bfd_vma gp_val;
3133
3134   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3135   ia64_info = elfNN_ia64_hash_table (info);
3136
3137   /* Infect various flags from the input section to the output section.  */
3138   if (info->relocateable)
3139     {
3140       bfd_vma flags;
3141
3142       flags = elf_section_data(input_section)->this_hdr.sh_flags;
3143       flags &= SHF_IA_64_NORECOV;
3144
3145       elf_section_data(input_section->output_section)
3146         ->this_hdr.sh_flags |= flags;
3147     }
3148
3149   gp_val = _bfd_get_gp_value (output_bfd);
3150   srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3151
3152   rel = relocs;
3153   relend = relocs + input_section->reloc_count;
3154   for (; rel < relend; ++rel)
3155     {
3156       struct elf_link_hash_entry *h;
3157       struct elfNN_ia64_dyn_sym_info *dyn_i;
3158       bfd_reloc_status_type r;
3159       reloc_howto_type *howto;
3160       unsigned long r_symndx;
3161       Elf_Internal_Sym *sym;
3162       unsigned int r_type;
3163       bfd_vma value;
3164       asection *sym_sec;
3165       bfd_byte *hit_addr;
3166       boolean dynamic_symbol_p;
3167       boolean undef_weak_ref;
3168
3169       r_type = ELFNN_R_TYPE (rel->r_info);
3170       if (r_type > R_IA64_MAX_RELOC_CODE)
3171         {
3172           (*_bfd_error_handler)
3173             (_("%s: unknown relocation type %d"),
3174              bfd_get_filename (input_bfd), (int)r_type);
3175           bfd_set_error (bfd_error_bad_value);
3176           ret_val = false;
3177           continue;
3178         }
3179       howto = lookup_howto (r_type);
3180       r_symndx = ELFNN_R_SYM (rel->r_info);
3181
3182       if (info->relocateable)
3183         {
3184           /* This is a relocateable link.  We don't have to change
3185              anything, unless the reloc is against a section symbol,
3186              in which case we have to adjust according to where the
3187              section symbol winds up in the output section.  */
3188           if (r_symndx < symtab_hdr->sh_info)
3189             {
3190               sym = local_syms + r_symndx;
3191               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3192                 {
3193                   sym_sec = local_sections[r_symndx];
3194                   rel->r_addend += sym_sec->output_offset;
3195                 }
3196             }
3197           continue;
3198         }
3199
3200       /* This is a final link.  */
3201
3202       h = NULL;
3203       sym = NULL;
3204       sym_sec = NULL;
3205       undef_weak_ref = false;
3206
3207       if (r_symndx < symtab_hdr->sh_info)
3208         {
3209           /* Reloc against local symbol.  */
3210           sym = local_syms + r_symndx;
3211           sym_sec = local_sections[r_symndx];
3212           value  = (sym_sec->output_section->vma
3213                     + sym_sec->output_offset
3214                     + sym->st_value);
3215         }
3216       else
3217         {
3218           long indx;
3219
3220           /* Reloc against global symbol.  */
3221           indx = r_symndx - symtab_hdr->sh_info;
3222           h = elf_sym_hashes (input_bfd)[indx];
3223           while (h->root.type == bfd_link_hash_indirect
3224                  || h->root.type == bfd_link_hash_warning)
3225             h = (struct elf_link_hash_entry *) h->root.u.i.link;
3226
3227           value = 0;
3228           if (h->root.type == bfd_link_hash_defined
3229               || h->root.type == bfd_link_hash_defweak)
3230             {
3231               sym_sec = h->root.u.def.section;
3232
3233               /* Detect the cases that sym_sec->output_section is
3234                  expected to be NULL -- all cases in which the symbol
3235                  is defined in another shared module.  This includes
3236                  PLT relocs for which we've created a PLT entry and
3237                  other relocs for which we're prepared to create
3238                  dynamic relocations.  */
3239               /* ??? Just accept it NULL and continue.  */
3240
3241               if (sym_sec->output_section != NULL)
3242                 {
3243                   value = (h->root.u.def.value
3244                            + sym_sec->output_section->vma
3245                            + sym_sec->output_offset);
3246                 }
3247             }
3248           else if (h->root.type == bfd_link_hash_undefweak)
3249             undef_weak_ref = true;
3250           else if (info->shared && !info->symbolic
3251                    && !info->no_undefined
3252                    && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3253             ;
3254           else
3255             {
3256               if (! ((*info->callbacks->undefined_symbol)
3257                      (info, h->root.root.string, input_bfd,
3258                       input_section, rel->r_offset,
3259                       (!info->shared || info->no_undefined
3260                        || ELF_ST_VISIBILITY (h->other)))))
3261                 return false;
3262               ret_val = false;
3263               continue;
3264             }
3265         }
3266
3267       hit_addr = contents + rel->r_offset;
3268       value += rel->r_addend;
3269       dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3270
3271       switch (r_type)
3272         {
3273         case R_IA64_NONE:
3274         case R_IA64_LDXMOV:
3275           continue;
3276
3277         case R_IA64_IMM14:
3278         case R_IA64_IMM22:
3279         case R_IA64_IMM64:
3280         case R_IA64_DIR32MSB:
3281         case R_IA64_DIR32LSB:
3282         case R_IA64_DIR64MSB:
3283         case R_IA64_DIR64LSB:
3284           /* Install a dynamic relocation for this reloc.  */
3285           if ((dynamic_symbol_p || info->shared)
3286               && (input_section->flags & SEC_ALLOC) != 0)
3287             {
3288               unsigned int dyn_r_type;
3289               long dynindx;
3290               bfd_vma addend;
3291
3292               BFD_ASSERT (srel != NULL);
3293
3294               /* If we don't need dynamic symbol lookup, find a
3295                  matching RELATIVE relocation.  */
3296               dyn_r_type = r_type;
3297               if (dynamic_symbol_p)
3298                 {
3299                   dynindx = h->dynindx;
3300                   addend = rel->r_addend;
3301                   value = 0;
3302                 }
3303               else
3304                 {
3305                   switch (r_type)
3306                     {
3307                     case R_IA64_DIR32MSB:
3308                       dyn_r_type = R_IA64_REL32MSB;
3309                       break;
3310                     case R_IA64_DIR32LSB:
3311                       dyn_r_type = R_IA64_REL32LSB;
3312                       break;
3313                     case R_IA64_DIR64MSB:
3314                       dyn_r_type = R_IA64_REL64MSB;
3315                       break;
3316                     case R_IA64_DIR64LSB:
3317                       dyn_r_type = R_IA64_REL64LSB;
3318                       break;
3319
3320                     default:
3321                       /* We can't represent this without a dynamic symbol.
3322                          Adjust the relocation to be against an output
3323                          section symbol, which are always present in the
3324                          dynamic symbol table.  */
3325                       /* ??? People shouldn't be doing non-pic code in
3326                          shared libraries.  Hork.  */
3327                       (*_bfd_error_handler)
3328                         (_("%s: linking non-pic code in a shared library"),
3329                          bfd_get_filename (input_bfd));
3330                       ret_val = false;
3331                       continue;
3332                     }
3333                   dynindx = 0;
3334                   addend = value;
3335                 }
3336
3337               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3338                                             srel, rel->r_offset, dyn_r_type,
3339                                             dynindx, addend);
3340             }
3341           /* FALLTHRU */
3342
3343         case R_IA64_LTV32MSB:
3344         case R_IA64_LTV32LSB:
3345         case R_IA64_LTV64MSB:
3346         case R_IA64_LTV64LSB:
3347           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3348           break;
3349
3350         case R_IA64_GPREL22:
3351         case R_IA64_GPREL64I:
3352         case R_IA64_GPREL32MSB:
3353         case R_IA64_GPREL32LSB:
3354         case R_IA64_GPREL64MSB:
3355         case R_IA64_GPREL64LSB:
3356           if (dynamic_symbol_p)
3357             {
3358               (*_bfd_error_handler)
3359                 (_("%s: @gprel relocation against dynamic symbol %s"),
3360                  bfd_get_filename (input_bfd), h->root.root.string);
3361               ret_val = false;
3362               continue;
3363             }
3364           value -= gp_val;
3365           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3366           break;
3367
3368         case R_IA64_LTOFF22:
3369         case R_IA64_LTOFF22X:
3370         case R_IA64_LTOFF64I:
3371           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3372           value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
3373                                  rel->r_addend, value, R_IA64_DIR64LSB);
3374           value -= gp_val;
3375           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3376           break;
3377
3378         case R_IA64_PLTOFF22:
3379         case R_IA64_PLTOFF64I:
3380         case R_IA64_PLTOFF64MSB:
3381         case R_IA64_PLTOFF64LSB:
3382           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3383           value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
3384           value -= gp_val;
3385           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3386           break;
3387
3388         case R_IA64_FPTR64I:
3389         case R_IA64_FPTR32MSB:
3390         case R_IA64_FPTR32LSB:
3391         case R_IA64_FPTR64MSB:
3392         case R_IA64_FPTR64LSB:
3393           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3394           if (dyn_i->want_fptr)
3395             {
3396               if (!undef_weak_ref)
3397                 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3398             }
3399           else
3400             {
3401               long dynindx;
3402
3403               /* Otherwise, we expect the dynamic linker to create
3404                  the entry.  */
3405
3406               if (h)
3407                 {
3408                   if (h->dynindx != -1)
3409                     dynindx = h->dynindx;
3410                   else
3411                     dynindx = (_bfd_elf_link_lookup_local_dynindx
3412                                (info, h->root.u.def.section->owner,
3413                                 global_sym_index (h)));
3414                 }
3415               else
3416                 {
3417                   dynindx = (_bfd_elf_link_lookup_local_dynindx
3418                              (info, input_bfd, r_symndx));
3419                 }
3420
3421               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3422                                             srel, rel->r_offset, r_type,
3423                                             dynindx, rel->r_addend);
3424               value = 0;
3425             }
3426
3427           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3428           break;
3429
3430         case R_IA64_LTOFF_FPTR22:
3431         case R_IA64_LTOFF_FPTR64I:
3432         case R_IA64_LTOFF_FPTR64MSB:
3433         case R_IA64_LTOFF_FPTR64LSB:
3434           {
3435             long dynindx;
3436
3437             dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3438             if (dyn_i->want_fptr)
3439               {
3440                 BFD_ASSERT (h == NULL || h->dynindx == -1)
3441                 if (!undef_weak_ref)
3442                   value = set_fptr_entry (output_bfd, info, dyn_i, value);
3443                 dynindx = -1;
3444               }
3445             else
3446               {
3447                 /* Otherwise, we expect the dynamic linker to create
3448                    the entry.  */
3449                 if (h)
3450                   {
3451                     if (h->dynindx != -1)
3452                       dynindx = h->dynindx;
3453                     else
3454                       dynindx = (_bfd_elf_link_lookup_local_dynindx
3455                                  (info, h->root.u.def.section->owner,
3456                                   global_sym_index (h)));
3457                   }
3458                 else
3459                   dynindx = (_bfd_elf_link_lookup_local_dynindx
3460                              (info, input_bfd, r_symndx));
3461                 value = 0;
3462               }
3463
3464             value = set_got_entry (output_bfd, info, dyn_i, dynindx,
3465                                    rel->r_addend, value, R_IA64_FPTR64LSB);
3466             value -= gp_val;
3467             r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3468           }
3469           break;
3470
3471         case R_IA64_PCREL32MSB:
3472         case R_IA64_PCREL32LSB:
3473         case R_IA64_PCREL64MSB:
3474         case R_IA64_PCREL64LSB:
3475           /* Install a dynamic relocation for this reloc.  */
3476           if (dynamic_symbol_p)
3477             {
3478               BFD_ASSERT (srel != NULL);
3479
3480               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3481                                             srel, rel->r_offset, r_type,
3482                                             h->dynindx, rel->r_addend);
3483             }
3484           goto finish_pcrel;
3485
3486         case R_IA64_PCREL21BI:
3487         case R_IA64_PCREL21F:
3488         case R_IA64_PCREL21M:
3489           /* ??? These two are only used for speculation fixup code.
3490              They should never be dynamic.  */
3491           if (dynamic_symbol_p)
3492             {
3493               (*_bfd_error_handler)
3494                 (_("%s: dynamic relocation against speculation fixup"),
3495                  bfd_get_filename (input_bfd));
3496               ret_val = false;
3497               continue;
3498             }
3499           if (undef_weak_ref)
3500             {
3501               (*_bfd_error_handler)
3502                 (_("%s: speculation fixup against undefined weak symbol"),
3503                  bfd_get_filename (input_bfd));
3504               ret_val = false;
3505               continue;
3506             }
3507           goto finish_pcrel;
3508
3509         case R_IA64_PCREL21B:
3510         case R_IA64_PCREL60B:
3511           /* We should have created a PLT entry for any dynamic symbol.  */
3512           dyn_i = NULL;
3513           if (h)
3514             dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3515
3516           if (dyn_i && dyn_i->want_plt2)
3517             {
3518               /* Should have caught this earlier.  */
3519               BFD_ASSERT (rel->r_addend == 0);
3520
3521               value = (ia64_info->plt_sec->output_section->vma
3522                        + ia64_info->plt_sec->output_offset
3523                        + dyn_i->plt2_offset);
3524             }
3525           else
3526             {
3527               /* Since there's no PLT entry, Validate that this is
3528                  locally defined.  */
3529               BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
3530
3531               /* If the symbol is undef_weak, we shouldn't be trying
3532                  to call it.  There's every chance that we'd wind up
3533                  with an out-of-range fixup here.  Don't bother setting
3534                  any value at all.  */
3535               if (undef_weak_ref)
3536                 continue;
3537             }
3538           goto finish_pcrel;
3539
3540         case R_IA64_PCREL22:
3541         case R_IA64_PCREL64I:
3542         finish_pcrel:
3543           /* Make pc-relative.  */
3544           value -= (input_section->output_section->vma
3545                     + input_section->output_offset
3546                     + rel->r_offset) & ~ (bfd_vma) 0x3;
3547           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3548           break;
3549
3550         case R_IA64_SEGREL32MSB:
3551         case R_IA64_SEGREL32LSB:
3552         case R_IA64_SEGREL64MSB:
3553         case R_IA64_SEGREL64LSB:
3554           {
3555             struct elf_segment_map *m;
3556             Elf_Internal_Phdr *p;
3557
3558             /* Find the segment that contains the output_section.  */
3559             for (m = elf_tdata (output_bfd)->segment_map,
3560                    p = elf_tdata (output_bfd)->phdr;
3561                  m != NULL;
3562                  m = m->next, p++)
3563               {
3564                 int i;
3565                 for (i = m->count - 1; i >= 0; i--)
3566                   if (m->sections[i] == sym_sec->output_section)
3567                     break;
3568                 if (i >= 0)
3569                   break;
3570               }
3571
3572             if (m == NULL)
3573               {
3574                 /* If the input section was discarded from the output, then
3575                    do nothing.  */
3576
3577                 if (bfd_is_abs_section (sym_sec->output_section))
3578                   r = bfd_reloc_ok;
3579                 else
3580                   r = bfd_reloc_notsupported;
3581               }
3582             else
3583               {
3584                 /* The VMA of the segment is the vaddr of the associated
3585                    program header.  */
3586                 if (value > p->p_vaddr)
3587                   value -= p->p_vaddr;
3588                 else
3589                   value = 0;
3590                 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
3591                                               r_type);
3592               }
3593             break;
3594           }
3595
3596         case R_IA64_SECREL32MSB:
3597         case R_IA64_SECREL32LSB:
3598         case R_IA64_SECREL64MSB:
3599         case R_IA64_SECREL64LSB:
3600           /* Make output-section relative.  */
3601           if (value > input_section->output_section->vma)
3602             value -= input_section->output_section->vma;
3603           else
3604             value = 0;
3605           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3606           break;
3607
3608         case R_IA64_IPLTMSB:
3609         case R_IA64_IPLTLSB:
3610           /* Install a dynamic relocation for this reloc.  */
3611           if ((dynamic_symbol_p || info->shared)
3612               && (input_section->flags & SEC_ALLOC) != 0)
3613             {
3614               BFD_ASSERT (srel != NULL);
3615
3616               /* If we don't need dynamic symbol lookup, install two
3617                  RELATIVE relocations.  */
3618               if (! dynamic_symbol_p)
3619                 {
3620                   unsigned int dyn_r_type;
3621                 
3622                   if (r_type == R_IA64_IPLTMSB)
3623                     dyn_r_type = R_IA64_REL64MSB;
3624                   else
3625                     dyn_r_type = R_IA64_REL64LSB;
3626
3627                   elfNN_ia64_install_dyn_reloc (output_bfd, info,
3628                                                 input_section,
3629                                                 srel, rel->r_offset,
3630                                                 dyn_r_type, 0, value);
3631                   elfNN_ia64_install_dyn_reloc (output_bfd, info,
3632                                                 input_section,
3633                                                 srel, rel->r_offset + 8,
3634                                                 dyn_r_type, 0, gp_val);
3635                 }
3636               else
3637                 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3638                                               srel, rel->r_offset, r_type,
3639                                               h->dynindx, rel->r_addend);
3640             }
3641
3642           if (r_type == R_IA64_IPLTMSB)
3643             r_type = R_IA64_DIR64MSB;
3644           else
3645             r_type = R_IA64_DIR64LSB;
3646           elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3647           r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
3648                                         r_type);
3649           break;
3650
3651         default:
3652           r = bfd_reloc_notsupported;
3653           break;
3654         }
3655
3656       switch (r)
3657         {
3658         case bfd_reloc_ok:
3659           break;
3660
3661         case bfd_reloc_undefined:
3662           /* This can happen for global table relative relocs if
3663              __gp is undefined.  This is a panic situation so we
3664              don't try to continue.  */
3665           (*info->callbacks->undefined_symbol)
3666             (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
3667           return false;
3668
3669         case bfd_reloc_notsupported:
3670           {
3671             const char *name;
3672
3673             if (h)
3674               name = h->root.root.string;
3675             else
3676               {
3677                 name = bfd_elf_string_from_elf_section (input_bfd,
3678                                                         symtab_hdr->sh_link,
3679                                                         sym->st_name);
3680                 if (name == NULL)
3681                   return false;
3682                 if (*name == '\0')
3683                   name = bfd_section_name (input_bfd, input_section);
3684               }
3685             if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
3686                                               name, input_bfd,
3687                                               input_section, rel->r_offset))
3688               return false;
3689             ret_val = false;
3690           }
3691           break;
3692
3693         case bfd_reloc_dangerous:
3694         case bfd_reloc_outofrange:
3695         case bfd_reloc_overflow:
3696         default:
3697           {
3698             const char *name;
3699
3700             if (h)
3701               name = h->root.root.string;
3702             else
3703               {
3704                 name = bfd_elf_string_from_elf_section (input_bfd,
3705                                                         symtab_hdr->sh_link,
3706                                                         sym->st_name);
3707                 if (name == NULL)
3708                   return false;
3709                 if (*name == '\0')
3710                   name = bfd_section_name (input_bfd, input_section);
3711               }
3712             if (!(*info->callbacks->reloc_overflow) (info, name,
3713                                                      howto->name, 0,
3714                                                      input_bfd,
3715                                                      input_section,
3716                                                      rel->r_offset))
3717               return false;
3718             ret_val = false;
3719           }
3720           break;
3721         }
3722     }
3723
3724   return ret_val;
3725 }
3726
3727 static boolean
3728 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
3729      bfd *output_bfd;
3730      struct bfd_link_info *info;
3731      struct elf_link_hash_entry *h;
3732      Elf_Internal_Sym *sym;
3733 {
3734   struct elfNN_ia64_link_hash_table *ia64_info;
3735   struct elfNN_ia64_dyn_sym_info *dyn_i;
3736
3737   ia64_info = elfNN_ia64_hash_table (info);
3738   dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3739
3740   /* Fill in the PLT data, if required.  */
3741   if (dyn_i && dyn_i->want_plt)
3742     {
3743       Elf_Internal_Rela outrel;
3744       bfd_byte *loc;
3745       asection *plt_sec;
3746       bfd_vma plt_addr, pltoff_addr, gp_val, index;
3747       ElfNN_External_Rela *rel;
3748
3749       gp_val = _bfd_get_gp_value (output_bfd);
3750
3751       /* Initialize the minimal PLT entry.  */
3752
3753       index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3754       plt_sec = ia64_info->plt_sec;
3755       loc = plt_sec->contents + dyn_i->plt_offset;
3756
3757       memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
3758       elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
3759       elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
3760                                 R_IA64_PCREL21B);
3761
3762       plt_addr = (plt_sec->output_section->vma
3763                   + plt_sec->output_offset
3764                   + dyn_i->plt_offset);
3765       pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
3766
3767       /* Initialize the FULL PLT entry, if needed.  */
3768       if (dyn_i->want_plt2)
3769         {
3770           loc = plt_sec->contents + dyn_i->plt2_offset;
3771
3772           memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
3773           elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
3774                                     R_IA64_IMM22);
3775
3776           /* Mark the symbol as undefined, rather than as defined in the
3777              plt section.  Leave the value alone.  */
3778           /* ??? We didn't redefine it in adjust_dynamic_symbol in the
3779              first place.  But perhaps elflink.h did some for us.  */
3780           if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
3781             sym->st_shndx = SHN_UNDEF;
3782         }
3783
3784       /* Create the dynamic relocation.  */
3785       outrel.r_offset = pltoff_addr;
3786       if (bfd_little_endian (output_bfd))
3787         outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
3788       else
3789         outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
3790       outrel.r_addend = 0;
3791
3792       /* This is fun.  In the .IA_64.pltoff section, we've got entries
3793          that correspond both to real PLT entries, and those that
3794          happened to resolve to local symbols but need to be created
3795          to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
3796          relocations for the real PLT should come at the end of the
3797          section, so that they can be indexed by plt entry at runtime.
3798
3799          We emitted all of the relocations for the non-PLT @pltoff
3800          entries during relocate_section.  So we can consider the
3801          existing sec->reloc_count to be the base of the array of
3802          PLT relocations.  */
3803
3804       rel = (ElfNN_External_Rela *)ia64_info->rel_pltoff_sec->contents;
3805       rel += ia64_info->rel_pltoff_sec->reloc_count;
3806
3807       bfd_elfNN_swap_reloca_out (output_bfd, &outrel, rel + index);
3808     }
3809
3810   /* Mark some specially defined symbols as absolute.  */
3811   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
3812       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
3813       || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
3814     sym->st_shndx = SHN_ABS;
3815
3816   return true;
3817 }
3818
3819 static boolean
3820 elfNN_ia64_finish_dynamic_sections (abfd, info)
3821      bfd *abfd;
3822      struct bfd_link_info *info;
3823 {
3824   struct elfNN_ia64_link_hash_table *ia64_info;
3825   bfd *dynobj;
3826
3827   ia64_info = elfNN_ia64_hash_table (info);
3828   dynobj = ia64_info->root.dynobj;
3829
3830   if (elf_hash_table (info)->dynamic_sections_created)
3831     {
3832       ElfNN_External_Dyn *dyncon, *dynconend;
3833       asection *sdyn, *sgotplt;
3834       bfd_vma gp_val;
3835
3836       sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3837       sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
3838       BFD_ASSERT (sdyn != NULL);
3839       dyncon = (ElfNN_External_Dyn *) sdyn->contents;
3840       dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
3841
3842       gp_val = _bfd_get_gp_value (abfd);
3843
3844       for (; dyncon < dynconend; dyncon++)
3845         {
3846           Elf_Internal_Dyn dyn;
3847
3848           bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
3849
3850           switch (dyn.d_tag)
3851             {
3852             case DT_PLTGOT:
3853               dyn.d_un.d_ptr = gp_val;
3854               break;
3855
3856             case DT_PLTRELSZ:
3857               dyn.d_un.d_val = (ia64_info->minplt_entries
3858                                 * sizeof (ElfNN_External_Rela));
3859               break;
3860
3861             case DT_JMPREL:
3862               /* See the comment above in finish_dynamic_symbol.  */
3863               dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
3864                                 + ia64_info->rel_pltoff_sec->output_offset
3865                                 + (ia64_info->rel_pltoff_sec->reloc_count
3866                                    * sizeof (ElfNN_External_Rela)));
3867               break;
3868
3869             case DT_IA_64_PLT_RESERVE:
3870               dyn.d_un.d_ptr = (sgotplt->output_section->vma
3871                                 + sgotplt->output_offset);
3872               break;
3873
3874             case DT_RELASZ:
3875               /* Do not have RELASZ include JMPREL.  This makes things
3876                  easier on ld.so.  This is not what the rest of BFD set up. */
3877               dyn.d_un.d_val -= (ia64_info->minplt_entries
3878                                  * sizeof (ElfNN_External_Rela));
3879               break;
3880             }
3881
3882           bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
3883         }
3884
3885       /* Initialize the PLT0 entry */
3886       if (ia64_info->plt_sec)
3887         {
3888           bfd_byte *loc = ia64_info->plt_sec->contents;
3889           bfd_vma pltres;
3890
3891           memcpy (loc, plt_header, PLT_HEADER_SIZE);
3892
3893           pltres = (sgotplt->output_section->vma
3894                     + sgotplt->output_offset
3895                     - gp_val);
3896
3897           elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
3898         }
3899     }
3900
3901   return true;
3902 }
3903 \f
3904 /* ELF file flag handling: */
3905
3906 /* Function to keep IA-64 specific file flags. */
3907 static boolean
3908 elfNN_ia64_set_private_flags (abfd, flags)
3909      bfd *abfd;
3910      flagword flags;
3911 {
3912   BFD_ASSERT (!elf_flags_init (abfd)
3913               || elf_elfheader (abfd)->e_flags == flags);
3914
3915   elf_elfheader (abfd)->e_flags = flags;
3916   elf_flags_init (abfd) = true;
3917   return true;
3918 }
3919
3920 /* Copy backend specific data from one object module to another */
3921 static boolean
3922 elfNN_ia64_copy_private_bfd_data (ibfd, obfd)
3923      bfd *ibfd, *obfd;
3924 {
3925   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3926       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3927     return true;
3928
3929   BFD_ASSERT (!elf_flags_init (obfd)
3930               || (elf_elfheader (obfd)->e_flags
3931                   == elf_elfheader (ibfd)->e_flags));
3932
3933   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
3934   elf_flags_init (obfd) = true;
3935   return true;
3936 }
3937
3938 /* Merge backend specific data from an object file to the output
3939    object file when linking.  */
3940 static boolean
3941 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
3942      bfd *ibfd, *obfd;
3943 {
3944   flagword out_flags;
3945   flagword in_flags;
3946   boolean ok = true;
3947
3948   /* Don't even pretend to support mixed-format linking.  */
3949   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3950       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3951     return false;
3952
3953   in_flags  = elf_elfheader (ibfd)->e_flags;
3954   out_flags = elf_elfheader (obfd)->e_flags;
3955
3956   if (! elf_flags_init (obfd))
3957     {
3958       elf_flags_init (obfd) = true;
3959       elf_elfheader (obfd)->e_flags = in_flags;
3960
3961       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3962           && bfd_get_arch_info (obfd)->the_default)
3963         {
3964           return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
3965                                     bfd_get_mach (ibfd));
3966         }
3967
3968       return true;
3969     }
3970
3971   /* Check flag compatibility.  */
3972   if (in_flags == out_flags)
3973     return true;
3974
3975   /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
3976   if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
3977     elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
3978
3979   if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
3980     {
3981       (*_bfd_error_handler)
3982         (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
3983          bfd_get_filename (ibfd));
3984
3985       bfd_set_error (bfd_error_bad_value);
3986       ok = false;
3987     }
3988   if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
3989     {
3990       (*_bfd_error_handler)
3991         (_("%s: linking big-endian files with little-endian files"),
3992          bfd_get_filename (ibfd));
3993
3994       bfd_set_error (bfd_error_bad_value);
3995       ok = false;
3996     }
3997   if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
3998     {
3999       (*_bfd_error_handler)
4000         (_("%s: linking 64-bit files with 32-bit files"),
4001          bfd_get_filename (ibfd));
4002
4003       bfd_set_error (bfd_error_bad_value);
4004       ok = false;
4005     }
4006   if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4007     {
4008       (*_bfd_error_handler)
4009         (_("%s: linking constant-gp files with non-constant-gp files"),
4010          bfd_get_filename (ibfd));
4011
4012       bfd_set_error (bfd_error_bad_value);
4013       ok = false;
4014     }
4015   if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4016       != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4017     {
4018       (*_bfd_error_handler)
4019         (_("%s: linking auto-pic files with non-auto-pic files"),
4020          bfd_get_filename (ibfd));
4021
4022       bfd_set_error (bfd_error_bad_value);
4023       ok = false;
4024     }
4025
4026   return ok;
4027 }
4028
4029 static boolean
4030 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4031      bfd *abfd;
4032      PTR ptr;
4033 {
4034   FILE *file = (FILE *) ptr;
4035   flagword flags = elf_elfheader (abfd)->e_flags;
4036
4037   BFD_ASSERT (abfd != NULL && ptr != NULL);
4038
4039   fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4040            (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4041            (flags & EF_IA_64_EXT) ? "EXT, " : "",
4042            (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4043            (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4044            (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4045            (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4046            (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4047            (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4048   
4049   _bfd_elf_print_private_bfd_data (abfd, ptr);
4050   return true;
4051 }
4052 \f
4053 #define TARGET_LITTLE_SYM               bfd_elfNN_ia64_little_vec
4054 #define TARGET_LITTLE_NAME              "elfNN-ia64-little"
4055 #define TARGET_BIG_SYM                  bfd_elfNN_ia64_big_vec
4056 #define TARGET_BIG_NAME                 "elfNN-ia64-big"
4057 #define ELF_ARCH                        bfd_arch_ia64
4058 #define ELF_MACHINE_CODE                EM_IA_64
4059 #define ELF_MACHINE_ALT1                1999    /* EAS2.3 */
4060 #define ELF_MACHINE_ALT2                1998    /* EAS2.2 */
4061 #define ELF_MAXPAGESIZE                 0x10000 /* 64KB */
4062
4063 #define elf_backend_section_from_shdr \
4064         elfNN_ia64_section_from_shdr
4065 #define elf_backend_section_flags \
4066         elfNN_ia64_section_flags
4067 #define elf_backend_fake_sections \
4068         elfNN_ia64_fake_sections
4069 #define elf_backend_add_symbol_hook \
4070         elfNN_ia64_add_symbol_hook
4071 #define elf_backend_additional_program_headers \
4072         elfNN_ia64_additional_program_headers
4073 #define elf_backend_modify_segment_map \
4074         elfNN_ia64_modify_segment_map
4075 #define elf_info_to_howto \
4076         elfNN_ia64_info_to_howto
4077
4078 #define bfd_elfNN_bfd_reloc_type_lookup \
4079         elfNN_ia64_reloc_type_lookup
4080 #define bfd_elfNN_bfd_is_local_label_name \
4081         elfNN_ia64_is_local_label_name
4082 #define bfd_elfNN_bfd_relax_section \
4083         elfNN_ia64_relax_section
4084
4085 /* Stuff for the BFD linker: */
4086 #define bfd_elfNN_bfd_link_hash_table_create \
4087         elfNN_ia64_hash_table_create
4088 #define elf_backend_create_dynamic_sections \
4089         elfNN_ia64_create_dynamic_sections
4090 #define elf_backend_check_relocs \
4091         elfNN_ia64_check_relocs
4092 #define elf_backend_adjust_dynamic_symbol \
4093         elfNN_ia64_adjust_dynamic_symbol
4094 #define elf_backend_size_dynamic_sections \
4095         elfNN_ia64_size_dynamic_sections
4096 #define elf_backend_relocate_section \
4097         elfNN_ia64_relocate_section
4098 #define elf_backend_finish_dynamic_symbol \
4099         elfNN_ia64_finish_dynamic_symbol
4100 #define elf_backend_finish_dynamic_sections \
4101         elfNN_ia64_finish_dynamic_sections
4102 #define bfd_elfNN_bfd_final_link \
4103         elfNN_ia64_final_link
4104
4105 #define bfd_elfNN_bfd_copy_private_bfd_data \
4106         elfNN_ia64_copy_private_bfd_data
4107 #define bfd_elfNN_bfd_merge_private_bfd_data \
4108         elfNN_ia64_merge_private_bfd_data
4109 #define bfd_elfNN_bfd_set_private_flags \
4110         elfNN_ia64_set_private_flags
4111 #define bfd_elfNN_bfd_print_private_bfd_data \
4112         elfNN_ia64_print_private_bfd_data
4113
4114 #define elf_backend_plt_readonly        1
4115 #define elf_backend_want_plt_sym        0
4116 #define elf_backend_plt_alignment       5
4117 #define elf_backend_got_header_size     0
4118 #define elf_backend_plt_header_size     PLT_HEADER_SIZE
4119 #define elf_backend_want_got_plt        1
4120 #define elf_backend_may_use_rel_p       1
4121 #define elf_backend_may_use_rela_p      1
4122 #define elf_backend_default_use_rela_p  1
4123 #define elf_backend_want_dynbss         0
4124 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4125 #define elf_backend_hide_symbol         elfNN_ia64_hash_hide_symbol
4126
4127 #include "elfNN-target.h"