OSDN Git Service

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