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