OSDN Git Service

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