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