OSDN Git Service

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