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