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