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