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