OSDN Git Service

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