OSDN Git Service

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