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