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