2005-05-04 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 (abfd, ".scommon");
1440           if (scomm == NULL
1441               || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1442                                                        | SEC_IS_COMMON
1443                                                        | SEC_LINKER_CREATED)))
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(abfd, ".rela.IA_64.pltoff");
1878   if (s == NULL
1879       || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1880                                            | SEC_HAS_CONTENTS
1881                                            | SEC_IN_MEMORY
1882                                            | SEC_LINKER_CREATED
1883                                            | SEC_READONLY))
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(abfd, ".rela.got");
1889   if (s == NULL
1890       || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1891                                            | SEC_HAS_CONTENTS
1892                                            | SEC_IN_MEMORY
1893                                            | SEC_LINKER_CREATED
1894                                            | SEC_READONLY))
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 (dynobj, ".opd");
2042       if (!fptr
2043           || !bfd_set_section_flags (dynobj, fptr,
2044                                      (SEC_ALLOC
2045                                       | SEC_LOAD
2046                                       | SEC_HAS_CONTENTS
2047                                       | SEC_IN_MEMORY
2048                                       | (info->pie ? 0 : SEC_READONLY)
2049                                       | SEC_LINKER_CREATED))
2050           || !bfd_set_section_alignment (abfd, fptr, 4))
2051         {
2052           BFD_ASSERT (0);
2053           return NULL;
2054         }
2055
2056       ia64_info->fptr_sec = fptr;
2057
2058       if (info->pie)
2059         {
2060           asection *fptr_rel;
2061           fptr_rel = bfd_make_section(dynobj, ".rela.opd");
2062           if (fptr_rel == NULL
2063               || !bfd_set_section_flags (dynobj, fptr_rel,
2064                                          (SEC_ALLOC | SEC_LOAD
2065                                           | SEC_HAS_CONTENTS
2066                                           | SEC_IN_MEMORY
2067                                           | SEC_LINKER_CREATED
2068                                           | SEC_READONLY))
2069               || !bfd_set_section_alignment (abfd, fptr_rel,
2070                                              LOG_SECTION_ALIGN))
2071             {
2072               BFD_ASSERT (0);
2073               return NULL;
2074             }
2075
2076           ia64_info->rel_fptr_sec = fptr_rel;
2077         }
2078     }
2079
2080   return fptr;
2081 }
2082
2083 static asection *
2084 get_pltoff (abfd, info, ia64_info)
2085      bfd *abfd;
2086      struct bfd_link_info *info ATTRIBUTE_UNUSED;
2087      struct elfNN_ia64_link_hash_table *ia64_info;
2088 {
2089   asection *pltoff;
2090   bfd *dynobj;
2091
2092   pltoff = ia64_info->pltoff_sec;
2093   if (!pltoff)
2094     {
2095       dynobj = ia64_info->root.dynobj;
2096       if (!dynobj)
2097         ia64_info->root.dynobj = dynobj = abfd;
2098
2099       pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
2100       if (!pltoff
2101           || !bfd_set_section_flags (dynobj, pltoff,
2102                                      (SEC_ALLOC
2103                                       | SEC_LOAD
2104                                       | SEC_HAS_CONTENTS
2105                                       | SEC_IN_MEMORY
2106                                       | SEC_SMALL_DATA
2107                                       | SEC_LINKER_CREATED))
2108           || !bfd_set_section_alignment (abfd, pltoff, 4))
2109         {
2110           BFD_ASSERT (0);
2111           return NULL;
2112         }
2113
2114       ia64_info->pltoff_sec = pltoff;
2115     }
2116
2117   return pltoff;
2118 }
2119
2120 static asection *
2121 get_reloc_section (abfd, ia64_info, sec, create)
2122      bfd *abfd;
2123      struct elfNN_ia64_link_hash_table *ia64_info;
2124      asection *sec;
2125      bfd_boolean create;
2126 {
2127   const char *srel_name;
2128   asection *srel;
2129   bfd *dynobj;
2130
2131   srel_name = (bfd_elf_string_from_elf_section
2132                (abfd, elf_elfheader(abfd)->e_shstrndx,
2133                 elf_section_data(sec)->rel_hdr.sh_name));
2134   if (srel_name == NULL)
2135     return NULL;
2136
2137   BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2138                && strcmp (bfd_get_section_name (abfd, sec),
2139                           srel_name+5) == 0)
2140               || (strncmp (srel_name, ".rel", 4) == 0
2141                   && strcmp (bfd_get_section_name (abfd, sec),
2142                              srel_name+4) == 0));
2143
2144   dynobj = ia64_info->root.dynobj;
2145   if (!dynobj)
2146     ia64_info->root.dynobj = dynobj = abfd;
2147
2148   srel = bfd_get_section_by_name (dynobj, srel_name);
2149   if (srel == NULL && create)
2150     {
2151       srel = bfd_make_section (dynobj, srel_name);
2152       if (srel == NULL
2153           || !bfd_set_section_flags (dynobj, srel,
2154                                      (SEC_ALLOC
2155                                       | SEC_LOAD
2156                                       | SEC_HAS_CONTENTS
2157                                       | SEC_IN_MEMORY
2158                                       | SEC_LINKER_CREATED
2159                                       | SEC_READONLY))
2160           || !bfd_set_section_alignment (dynobj, srel,
2161                                          LOG_SECTION_ALIGN))
2162         return NULL;
2163     }
2164
2165   return srel;
2166 }
2167
2168 static bfd_boolean
2169 count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
2170                  asection *srel, int type, bfd_boolean reltext)
2171 {
2172   struct elfNN_ia64_dyn_reloc_entry *rent;
2173
2174   for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2175     if (rent->srel == srel && rent->type == type)
2176       break;
2177
2178   if (!rent)
2179     {
2180       rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2181               bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2182       if (!rent)
2183         return FALSE;
2184
2185       rent->next = dyn_i->reloc_entries;
2186       rent->srel = srel;
2187       rent->type = type;
2188       rent->count = 0;
2189       dyn_i->reloc_entries = rent;
2190     }
2191   rent->reltext = reltext;
2192   rent->count++;
2193
2194   return TRUE;
2195 }
2196
2197 static bfd_boolean
2198 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2199      bfd *abfd;
2200      struct bfd_link_info *info;
2201      asection *sec;
2202      const Elf_Internal_Rela *relocs;
2203 {
2204   struct elfNN_ia64_link_hash_table *ia64_info;
2205   const Elf_Internal_Rela *relend;
2206   Elf_Internal_Shdr *symtab_hdr;
2207   const Elf_Internal_Rela *rel;
2208   asection *got, *fptr, *srel, *pltoff;
2209
2210   if (info->relocatable)
2211     return TRUE;
2212
2213   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2214   ia64_info = elfNN_ia64_hash_table (info);
2215
2216   got = fptr = srel = pltoff = NULL;
2217
2218   relend = relocs + sec->reloc_count;
2219   for (rel = relocs; rel < relend; ++rel)
2220     {
2221       enum {
2222         NEED_GOT = 1,
2223         NEED_GOTX = 2,
2224         NEED_FPTR = 4,
2225         NEED_PLTOFF = 8,
2226         NEED_MIN_PLT = 16,
2227         NEED_FULL_PLT = 32,
2228         NEED_DYNREL = 64,
2229         NEED_LTOFF_FPTR = 128,
2230         NEED_TPREL = 256,
2231         NEED_DTPMOD = 512,
2232         NEED_DTPREL = 1024
2233       };
2234
2235       struct elf_link_hash_entry *h = NULL;
2236       unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2237       struct elfNN_ia64_dyn_sym_info *dyn_i;
2238       int need_entry;
2239       bfd_boolean maybe_dynamic;
2240       int dynrel_type = R_IA64_NONE;
2241
2242       if (r_symndx >= symtab_hdr->sh_info)
2243         {
2244           /* We're dealing with a global symbol -- find its hash entry
2245              and mark it as being referenced.  */
2246           long indx = r_symndx - symtab_hdr->sh_info;
2247           h = elf_sym_hashes (abfd)[indx];
2248           while (h->root.type == bfd_link_hash_indirect
2249                  || h->root.type == bfd_link_hash_warning)
2250             h = (struct elf_link_hash_entry *) h->root.u.i.link;
2251
2252           h->ref_regular = 1;
2253         }
2254
2255       /* We can only get preliminary data on whether a symbol is
2256          locally or externally defined, as not all of the input files
2257          have yet been processed.  Do something with what we know, as
2258          this may help reduce memory usage and processing time later.  */
2259       maybe_dynamic = FALSE;
2260       if (h && ((!info->executable
2261                  && (!info->symbolic
2262                      || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2263                 || !h->def_regular
2264                 || h->root.type == bfd_link_hash_defweak))
2265         maybe_dynamic = TRUE;
2266
2267       need_entry = 0;
2268       switch (ELFNN_R_TYPE (rel->r_info))
2269         {
2270         case R_IA64_TPREL64MSB:
2271         case R_IA64_TPREL64LSB:
2272           if (info->shared || maybe_dynamic)
2273             need_entry = NEED_DYNREL;
2274           dynrel_type = R_IA64_TPREL64LSB;
2275           if (info->shared)
2276             info->flags |= DF_STATIC_TLS;
2277           break;
2278
2279         case R_IA64_LTOFF_TPREL22:
2280           need_entry = NEED_TPREL;
2281           if (info->shared)
2282             info->flags |= DF_STATIC_TLS;
2283           break;
2284
2285         case R_IA64_DTPREL32MSB:
2286         case R_IA64_DTPREL32LSB:
2287         case R_IA64_DTPREL64MSB:
2288         case R_IA64_DTPREL64LSB:
2289           if (info->shared || maybe_dynamic)
2290             need_entry = NEED_DYNREL;
2291           dynrel_type = R_IA64_DTPRELNNLSB;
2292           break;
2293
2294         case R_IA64_LTOFF_DTPREL22:
2295           need_entry = NEED_DTPREL;
2296           break;
2297
2298         case R_IA64_DTPMOD64MSB:
2299         case R_IA64_DTPMOD64LSB:
2300           if (info->shared || maybe_dynamic)
2301             need_entry = NEED_DYNREL;
2302           dynrel_type = R_IA64_DTPMOD64LSB;
2303           break;
2304
2305         case R_IA64_LTOFF_DTPMOD22:
2306           need_entry = NEED_DTPMOD;
2307           break;
2308
2309         case R_IA64_LTOFF_FPTR22:
2310         case R_IA64_LTOFF_FPTR64I:
2311         case R_IA64_LTOFF_FPTR32MSB:
2312         case R_IA64_LTOFF_FPTR32LSB:
2313         case R_IA64_LTOFF_FPTR64MSB:
2314         case R_IA64_LTOFF_FPTR64LSB:
2315           need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2316           break;
2317
2318         case R_IA64_FPTR64I:
2319         case R_IA64_FPTR32MSB:
2320         case R_IA64_FPTR32LSB:
2321         case R_IA64_FPTR64MSB:
2322         case R_IA64_FPTR64LSB:
2323           if (info->shared || h)
2324             need_entry = NEED_FPTR | NEED_DYNREL;
2325           else
2326             need_entry = NEED_FPTR;
2327           dynrel_type = R_IA64_FPTRNNLSB;
2328           break;
2329
2330         case R_IA64_LTOFF22:
2331         case R_IA64_LTOFF64I:
2332           need_entry = NEED_GOT;
2333           break;
2334
2335         case R_IA64_LTOFF22X:
2336           need_entry = NEED_GOTX;
2337           break;
2338
2339         case R_IA64_PLTOFF22:
2340         case R_IA64_PLTOFF64I:
2341         case R_IA64_PLTOFF64MSB:
2342         case R_IA64_PLTOFF64LSB:
2343           need_entry = NEED_PLTOFF;
2344           if (h)
2345             {
2346               if (maybe_dynamic)
2347                 need_entry |= NEED_MIN_PLT;
2348             }
2349           else
2350             {
2351               (*info->callbacks->warning)
2352                 (info, _("@pltoff reloc against local symbol"), 0,
2353                  abfd, 0, (bfd_vma) 0);
2354             }
2355           break;
2356
2357         case R_IA64_PCREL21B:
2358         case R_IA64_PCREL60B:
2359           /* Depending on where this symbol is defined, we may or may not
2360              need a full plt entry.  Only skip if we know we'll not need
2361              the entry -- static or symbolic, and the symbol definition
2362              has already been seen.  */
2363           if (maybe_dynamic && rel->r_addend == 0)
2364             need_entry = NEED_FULL_PLT;
2365           break;
2366
2367         case R_IA64_IMM14:
2368         case R_IA64_IMM22:
2369         case R_IA64_IMM64:
2370         case R_IA64_DIR32MSB:
2371         case R_IA64_DIR32LSB:
2372         case R_IA64_DIR64MSB:
2373         case R_IA64_DIR64LSB:
2374           /* Shared objects will always need at least a REL relocation.  */
2375           if (info->shared || maybe_dynamic)
2376             need_entry = NEED_DYNREL;
2377           dynrel_type = R_IA64_DIRNNLSB;
2378           break;
2379
2380         case R_IA64_IPLTMSB:
2381         case R_IA64_IPLTLSB:
2382           /* Shared objects will always need at least a REL relocation.  */
2383           if (info->shared || maybe_dynamic)
2384             need_entry = NEED_DYNREL;
2385           dynrel_type = R_IA64_IPLTLSB;
2386           break;
2387
2388         case R_IA64_PCREL22:
2389         case R_IA64_PCREL64I:
2390         case R_IA64_PCREL32MSB:
2391         case R_IA64_PCREL32LSB:
2392         case R_IA64_PCREL64MSB:
2393         case R_IA64_PCREL64LSB:
2394           if (maybe_dynamic)
2395             need_entry = NEED_DYNREL;
2396           dynrel_type = R_IA64_PCRELNNLSB;
2397           break;
2398         }
2399
2400       if (!need_entry)
2401         continue;
2402
2403       if ((need_entry & NEED_FPTR) != 0
2404           && rel->r_addend)
2405         {
2406           (*info->callbacks->warning)
2407             (info, _("non-zero addend in @fptr reloc"), 0,
2408              abfd, 0, (bfd_vma) 0);
2409         }
2410
2411       dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE);
2412
2413       /* Record whether or not this is a local symbol.  */
2414       dyn_i->h = h;
2415
2416       /* Create what's needed.  */
2417       if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2418                         | NEED_DTPMOD | NEED_DTPREL))
2419         {
2420           if (!got)
2421             {
2422               got = get_got (abfd, info, ia64_info);
2423               if (!got)
2424                 return FALSE;
2425             }
2426           if (need_entry & NEED_GOT)
2427             dyn_i->want_got = 1;
2428           if (need_entry & NEED_GOTX)
2429             dyn_i->want_gotx = 1;
2430           if (need_entry & NEED_TPREL)
2431             dyn_i->want_tprel = 1;
2432           if (need_entry & NEED_DTPMOD)
2433             dyn_i->want_dtpmod = 1;
2434           if (need_entry & NEED_DTPREL)
2435             dyn_i->want_dtprel = 1;
2436         }
2437       if (need_entry & NEED_FPTR)
2438         {
2439           if (!fptr)
2440             {
2441               fptr = get_fptr (abfd, info, ia64_info);
2442               if (!fptr)
2443                 return FALSE;
2444             }
2445
2446           /* FPTRs for shared libraries are allocated by the dynamic
2447              linker.  Make sure this local symbol will appear in the
2448              dynamic symbol table.  */
2449           if (!h && info->shared)
2450             {
2451               if (! (bfd_elf_link_record_local_dynamic_symbol
2452                      (info, abfd, (long) r_symndx)))
2453                 return FALSE;
2454             }
2455
2456           dyn_i->want_fptr = 1;
2457         }
2458       if (need_entry & NEED_LTOFF_FPTR)
2459         dyn_i->want_ltoff_fptr = 1;
2460       if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2461         {
2462           if (!ia64_info->root.dynobj)
2463             ia64_info->root.dynobj = abfd;
2464           h->needs_plt = 1;
2465           dyn_i->want_plt = 1;
2466         }
2467       if (need_entry & NEED_FULL_PLT)
2468         dyn_i->want_plt2 = 1;
2469       if (need_entry & NEED_PLTOFF)
2470         {
2471           /* This is needed here, in case @pltoff is used in a non-shared
2472              link.  */
2473           if (!pltoff)
2474             {
2475               pltoff = get_pltoff (abfd, info, ia64_info);
2476               if (!pltoff)
2477                 return FALSE;
2478             }
2479
2480           dyn_i->want_pltoff = 1;
2481         }
2482       if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2483         {
2484           if (!srel)
2485             {
2486               srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
2487               if (!srel)
2488                 return FALSE;
2489             }
2490           if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
2491                                 (sec->flags & SEC_READONLY) != 0))
2492             return FALSE;
2493         }
2494     }
2495
2496   return TRUE;
2497 }
2498
2499 /* For cleanliness, and potentially faster dynamic loading, allocate
2500    external GOT entries first.  */
2501
2502 static bfd_boolean
2503 allocate_global_data_got (dyn_i, data)
2504      struct elfNN_ia64_dyn_sym_info *dyn_i;
2505      PTR data;
2506 {
2507   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2508
2509   if ((dyn_i->want_got || dyn_i->want_gotx)
2510       && ! dyn_i->want_fptr
2511       && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2512      {
2513        dyn_i->got_offset = x->ofs;
2514        x->ofs += 8;
2515      }
2516   if (dyn_i->want_tprel)
2517     {
2518       dyn_i->tprel_offset = x->ofs;
2519       x->ofs += 8;
2520     }
2521   if (dyn_i->want_dtpmod)
2522     {
2523       if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2524         {
2525           dyn_i->dtpmod_offset = x->ofs;
2526           x->ofs += 8;
2527         }
2528       else
2529         {
2530           struct elfNN_ia64_link_hash_table *ia64_info;
2531
2532           ia64_info = elfNN_ia64_hash_table (x->info);
2533           if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
2534             {
2535               ia64_info->self_dtpmod_offset = x->ofs;
2536               x->ofs += 8;
2537             }
2538           dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
2539         }
2540     }
2541   if (dyn_i->want_dtprel)
2542     {
2543       dyn_i->dtprel_offset = x->ofs;
2544       x->ofs += 8;
2545     }
2546   return TRUE;
2547 }
2548
2549 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs.  */
2550
2551 static bfd_boolean
2552 allocate_global_fptr_got (dyn_i, data)
2553      struct elfNN_ia64_dyn_sym_info *dyn_i;
2554      PTR data;
2555 {
2556   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2557
2558   if (dyn_i->want_got
2559       && dyn_i->want_fptr
2560       && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
2561     {
2562       dyn_i->got_offset = x->ofs;
2563       x->ofs += 8;
2564     }
2565   return TRUE;
2566 }
2567
2568 /* Lastly, allocate all the GOT entries for local data.  */
2569
2570 static bfd_boolean
2571 allocate_local_got (dyn_i, data)
2572      struct elfNN_ia64_dyn_sym_info *dyn_i;
2573      PTR data;
2574 {
2575   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2576
2577   if ((dyn_i->want_got || dyn_i->want_gotx)
2578       && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2579     {
2580       dyn_i->got_offset = x->ofs;
2581       x->ofs += 8;
2582     }
2583   return TRUE;
2584 }
2585
2586 /* Search for the index of a global symbol in it's defining object file.  */
2587
2588 static long
2589 global_sym_index (h)
2590      struct elf_link_hash_entry *h;
2591 {
2592   struct elf_link_hash_entry **p;
2593   bfd *obj;
2594
2595   BFD_ASSERT (h->root.type == bfd_link_hash_defined
2596               || h->root.type == bfd_link_hash_defweak);
2597
2598   obj = h->root.u.def.section->owner;
2599   for (p = elf_sym_hashes (obj); *p != h; ++p)
2600     continue;
2601
2602   return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2603 }
2604
2605 /* Allocate function descriptors.  We can do these for every function
2606    in a main executable that is not exported.  */
2607
2608 static bfd_boolean
2609 allocate_fptr (dyn_i, data)
2610      struct elfNN_ia64_dyn_sym_info *dyn_i;
2611      PTR data;
2612 {
2613   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2614
2615   if (dyn_i->want_fptr)
2616     {
2617       struct elf_link_hash_entry *h = dyn_i->h;
2618
2619       if (h)
2620         while (h->root.type == bfd_link_hash_indirect
2621                || h->root.type == bfd_link_hash_warning)
2622           h = (struct elf_link_hash_entry *) h->root.u.i.link;
2623
2624       if (!x->info->executable
2625           && (!h
2626               || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2627               || h->root.type != bfd_link_hash_undefweak))
2628         {
2629           if (h && h->dynindx == -1)
2630             {
2631               BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2632                           || (h->root.type == bfd_link_hash_defweak));
2633
2634               if (!bfd_elf_link_record_local_dynamic_symbol
2635                     (x->info, h->root.u.def.section->owner,
2636                      global_sym_index (h)))
2637                 return FALSE;
2638             }
2639
2640           dyn_i->want_fptr = 0;
2641         }
2642       else if (h == NULL || h->dynindx == -1)
2643         {
2644           dyn_i->fptr_offset = x->ofs;
2645           x->ofs += 16;
2646         }
2647       else
2648         dyn_i->want_fptr = 0;
2649     }
2650   return TRUE;
2651 }
2652
2653 /* Allocate all the minimal PLT entries.  */
2654
2655 static bfd_boolean
2656 allocate_plt_entries (dyn_i, data)
2657      struct elfNN_ia64_dyn_sym_info *dyn_i;
2658      PTR data;
2659 {
2660   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2661
2662   if (dyn_i->want_plt)
2663     {
2664       struct elf_link_hash_entry *h = dyn_i->h;
2665
2666       if (h)
2667         while (h->root.type == bfd_link_hash_indirect
2668                || h->root.type == bfd_link_hash_warning)
2669           h = (struct elf_link_hash_entry *) h->root.u.i.link;
2670
2671       /* ??? Versioned symbols seem to lose NEEDS_PLT.  */
2672       if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
2673         {
2674           bfd_size_type offset = x->ofs;
2675           if (offset == 0)
2676             offset = PLT_HEADER_SIZE;
2677           dyn_i->plt_offset = offset;
2678           x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2679
2680           dyn_i->want_pltoff = 1;
2681         }
2682       else
2683         {
2684           dyn_i->want_plt = 0;
2685           dyn_i->want_plt2 = 0;
2686         }
2687     }
2688   return TRUE;
2689 }
2690
2691 /* Allocate all the full PLT entries.  */
2692
2693 static bfd_boolean
2694 allocate_plt2_entries (dyn_i, data)
2695      struct elfNN_ia64_dyn_sym_info *dyn_i;
2696      PTR data;
2697 {
2698   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2699
2700   if (dyn_i->want_plt2)
2701     {
2702       struct elf_link_hash_entry *h = dyn_i->h;
2703       bfd_size_type ofs = x->ofs;
2704
2705       dyn_i->plt2_offset = ofs;
2706       x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2707
2708       while (h->root.type == bfd_link_hash_indirect
2709              || h->root.type == bfd_link_hash_warning)
2710         h = (struct elf_link_hash_entry *) h->root.u.i.link;
2711       dyn_i->h->plt.offset = ofs;
2712     }
2713   return TRUE;
2714 }
2715
2716 /* Allocate all the PLTOFF entries requested by relocations and
2717    plt entries.  We can't share space with allocated FPTR entries,
2718    because the latter are not necessarily addressable by the GP.
2719    ??? Relaxation might be able to determine that they are.  */
2720
2721 static bfd_boolean
2722 allocate_pltoff_entries (dyn_i, data)
2723      struct elfNN_ia64_dyn_sym_info *dyn_i;
2724      PTR data;
2725 {
2726   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2727
2728   if (dyn_i->want_pltoff)
2729     {
2730       dyn_i->pltoff_offset = x->ofs;
2731       x->ofs += 16;
2732     }
2733   return TRUE;
2734 }
2735
2736 /* Allocate dynamic relocations for those symbols that turned out
2737    to be dynamic.  */
2738
2739 static bfd_boolean
2740 allocate_dynrel_entries (dyn_i, data)
2741      struct elfNN_ia64_dyn_sym_info *dyn_i;
2742      PTR data;
2743 {
2744   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2745   struct elfNN_ia64_link_hash_table *ia64_info;
2746   struct elfNN_ia64_dyn_reloc_entry *rent;
2747   bfd_boolean dynamic_symbol, shared, resolved_zero;
2748
2749   ia64_info = elfNN_ia64_hash_table (x->info);
2750
2751   /* Note that this can't be used in relation to FPTR relocs below.  */
2752   dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
2753
2754   shared = x->info->shared;
2755   resolved_zero = (dyn_i->h
2756                    && ELF_ST_VISIBILITY (dyn_i->h->other)
2757                    && dyn_i->h->root.type == bfd_link_hash_undefweak);
2758
2759   /* Take care of the normal data relocations.  */
2760
2761   for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2762     {
2763       int count = rent->count;
2764
2765       switch (rent->type)
2766         {
2767         case R_IA64_FPTR32LSB:
2768         case R_IA64_FPTR64LSB:
2769           /* Allocate one iff !want_fptr and not PIE, which by this point
2770              will be true only if we're actually allocating one statically
2771              in the main executable.  Position independent executables
2772              need a relative reloc.  */
2773           if (dyn_i->want_fptr && !x->info->pie)
2774             continue;
2775           break;
2776         case R_IA64_PCREL32LSB:
2777         case R_IA64_PCREL64LSB:
2778           if (!dynamic_symbol)
2779             continue;
2780           break;
2781         case R_IA64_DIR32LSB:
2782         case R_IA64_DIR64LSB:
2783           if (!dynamic_symbol && !shared)
2784             continue;
2785           break;
2786         case R_IA64_IPLTLSB:
2787           if (!dynamic_symbol && !shared)
2788             continue;
2789           /* Use two REL relocations for IPLT relocations
2790              against local symbols.  */
2791           if (!dynamic_symbol)
2792             count *= 2;
2793           break;
2794         case R_IA64_DTPREL32LSB:
2795         case R_IA64_TPREL64LSB:
2796         case R_IA64_DTPREL64LSB:
2797         case R_IA64_DTPMOD64LSB:
2798           break;
2799         default:
2800           abort ();
2801         }
2802       if (rent->reltext)
2803         ia64_info->reltext = 1;
2804       rent->srel->size += sizeof (ElfNN_External_Rela) * count;
2805     }
2806
2807   /* Take care of the GOT and PLT relocations.  */
2808
2809   if ((!resolved_zero
2810        && (dynamic_symbol || shared)
2811        && (dyn_i->want_got || dyn_i->want_gotx))
2812       || (dyn_i->want_ltoff_fptr
2813           && dyn_i->h
2814           && dyn_i->h->dynindx != -1))
2815     {
2816       if (!dyn_i->want_ltoff_fptr
2817           || !x->info->pie
2818           || dyn_i->h == NULL
2819           || dyn_i->h->root.type != bfd_link_hash_undefweak)
2820         ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
2821     }
2822   if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2823     ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
2824   if (dynamic_symbol && dyn_i->want_dtpmod)
2825     ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
2826   if (dynamic_symbol && dyn_i->want_dtprel)
2827     ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
2828   if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
2829     {
2830       if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
2831         ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
2832     }
2833
2834   if (!resolved_zero && dyn_i->want_pltoff)
2835     {
2836       bfd_size_type t = 0;
2837
2838       /* Dynamic symbols get one IPLT relocation.  Local symbols in
2839          shared libraries get two REL relocations.  Local symbols in
2840          main applications get nothing.  */
2841       if (dynamic_symbol)
2842         t = sizeof (ElfNN_External_Rela);
2843       else if (shared)
2844         t = 2 * sizeof (ElfNN_External_Rela);
2845
2846       ia64_info->rel_pltoff_sec->size += t;
2847     }
2848
2849   return TRUE;
2850 }
2851
2852 static bfd_boolean
2853 elfNN_ia64_adjust_dynamic_symbol (info, h)
2854      struct bfd_link_info *info ATTRIBUTE_UNUSED;
2855      struct elf_link_hash_entry *h;
2856 {
2857   /* ??? Undefined symbols with PLT entries should be re-defined
2858      to be the PLT entry.  */
2859
2860   /* If this is a weak symbol, and there is a real definition, the
2861      processor independent code will have arranged for us to see the
2862      real definition first, and we can just use the same value.  */
2863   if (h->u.weakdef != NULL)
2864     {
2865       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2866                   || h->u.weakdef->root.type == bfd_link_hash_defweak);
2867       h->root.u.def.section = h->u.weakdef->root.u.def.section;
2868       h->root.u.def.value = h->u.weakdef->root.u.def.value;
2869       return TRUE;
2870     }
2871
2872   /* If this is a reference to a symbol defined by a dynamic object which
2873      is not a function, we might allocate the symbol in our .dynbss section
2874      and allocate a COPY dynamic relocation.
2875
2876      But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2877      of hackery.  */
2878
2879   return TRUE;
2880 }
2881
2882 static bfd_boolean
2883 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2884      bfd *output_bfd ATTRIBUTE_UNUSED;
2885      struct bfd_link_info *info;
2886 {
2887   struct elfNN_ia64_allocate_data data;
2888   struct elfNN_ia64_link_hash_table *ia64_info;
2889   asection *sec;
2890   bfd *dynobj;
2891   bfd_boolean relplt = FALSE;
2892
2893   dynobj = elf_hash_table(info)->dynobj;
2894   ia64_info = elfNN_ia64_hash_table (info);
2895   ia64_info->self_dtpmod_offset = (bfd_vma) -1;
2896   BFD_ASSERT(dynobj != NULL);
2897   data.info = info;
2898
2899   /* Set the contents of the .interp section to the interpreter.  */
2900   if (ia64_info->root.dynamic_sections_created
2901       && info->executable)
2902     {
2903       sec = bfd_get_section_by_name (dynobj, ".interp");
2904       BFD_ASSERT (sec != NULL);
2905       sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
2906       sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
2907     }
2908
2909   /* Allocate the GOT entries.  */
2910
2911   if (ia64_info->got_sec)
2912     {
2913       data.ofs = 0;
2914       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2915       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2916       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2917       ia64_info->got_sec->size = data.ofs;
2918     }
2919
2920   /* Allocate the FPTR entries.  */
2921
2922   if (ia64_info->fptr_sec)
2923     {
2924       data.ofs = 0;
2925       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2926       ia64_info->fptr_sec->size = data.ofs;
2927     }
2928
2929   /* Now that we've seen all of the input files, we can decide which
2930      symbols need plt entries.  Allocate the minimal PLT entries first.
2931      We do this even though dynamic_sections_created may be FALSE, because
2932      this has the side-effect of clearing want_plt and want_plt2.  */
2933
2934   data.ofs = 0;
2935   elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2936
2937   ia64_info->minplt_entries = 0;
2938   if (data.ofs)
2939     {
2940       ia64_info->minplt_entries
2941         = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2942     }
2943
2944   /* Align the pointer for the plt2 entries.  */
2945   data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2946
2947   elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2948   if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
2949     {
2950       /* FIXME: we always reserve the memory for dynamic linker even if
2951          there are no PLT entries since dynamic linker may assume the
2952          reserved memory always exists.  */
2953
2954       BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2955
2956       ia64_info->plt_sec->size = data.ofs;
2957
2958       /* If we've got a .plt, we need some extra memory for the dynamic
2959          linker.  We stuff these in .got.plt.  */
2960       sec = bfd_get_section_by_name (dynobj, ".got.plt");
2961       sec->size = 8 * PLT_RESERVED_WORDS;
2962     }
2963
2964   /* Allocate the PLTOFF entries.  */
2965
2966   if (ia64_info->pltoff_sec)
2967     {
2968       data.ofs = 0;
2969       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2970       ia64_info->pltoff_sec->size = data.ofs;
2971     }
2972
2973   if (ia64_info->root.dynamic_sections_created)
2974     {
2975       /* Allocate space for the dynamic relocations that turned out to be
2976          required.  */
2977
2978       if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
2979         ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
2980       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2981     }
2982
2983   /* We have now determined the sizes of the various dynamic sections.
2984      Allocate memory for them.  */
2985   for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2986     {
2987       bfd_boolean strip;
2988
2989       if (!(sec->flags & SEC_LINKER_CREATED))
2990         continue;
2991
2992       /* If we don't need this section, strip it from the output file.
2993          There were several sections primarily related to dynamic
2994          linking that must be create before the linker maps input
2995          sections to output sections.  The linker does that before
2996          bfd_elf_size_dynamic_sections is called, and it is that
2997          function which decides whether anything needs to go into
2998          these sections.  */
2999
3000       strip = (sec->size == 0);
3001
3002       if (sec == ia64_info->got_sec)
3003         strip = FALSE;
3004       else if (sec == ia64_info->rel_got_sec)
3005         {
3006           if (strip)
3007             ia64_info->rel_got_sec = NULL;
3008           else
3009             /* We use the reloc_count field as a counter if we need to
3010                copy relocs into the output file.  */
3011             sec->reloc_count = 0;
3012         }
3013       else if (sec == ia64_info->fptr_sec)
3014         {
3015           if (strip)
3016             ia64_info->fptr_sec = NULL;
3017         }
3018       else if (sec == ia64_info->rel_fptr_sec)
3019         {
3020           if (strip)
3021             ia64_info->rel_fptr_sec = NULL;
3022           else
3023             /* We use the reloc_count field as a counter if we need to
3024                copy relocs into the output file.  */
3025             sec->reloc_count = 0;
3026         }
3027       else if (sec == ia64_info->plt_sec)
3028         {
3029           if (strip)
3030             ia64_info->plt_sec = NULL;
3031         }
3032       else if (sec == ia64_info->pltoff_sec)
3033         {
3034           if (strip)
3035             ia64_info->pltoff_sec = NULL;
3036         }
3037       else if (sec == ia64_info->rel_pltoff_sec)
3038         {
3039           if (strip)
3040             ia64_info->rel_pltoff_sec = NULL;
3041           else
3042             {
3043               relplt = TRUE;
3044               /* We use the reloc_count field as a counter if we need to
3045                  copy relocs into the output file.  */
3046               sec->reloc_count = 0;
3047             }
3048         }
3049       else
3050         {
3051           const char *name;
3052
3053           /* It's OK to base decisions on the section name, because none
3054              of the dynobj section names depend upon the input files.  */
3055           name = bfd_get_section_name (dynobj, sec);
3056
3057           if (strcmp (name, ".got.plt") == 0)
3058             strip = FALSE;
3059           else if (strncmp (name, ".rel", 4) == 0)
3060             {
3061               if (!strip)
3062                 {
3063                   /* We use the reloc_count field as a counter if we need to
3064                      copy relocs into the output file.  */
3065                   sec->reloc_count = 0;
3066                 }
3067             }
3068           else
3069             continue;
3070         }
3071
3072       if (strip)
3073         sec->flags |= SEC_EXCLUDE;
3074       else
3075         {
3076           /* Allocate memory for the section contents.  */
3077           sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
3078           if (sec->contents == NULL && sec->size != 0)
3079             return FALSE;
3080         }
3081     }
3082
3083   if (elf_hash_table (info)->dynamic_sections_created)
3084     {
3085       /* Add some entries to the .dynamic section.  We fill in the values
3086          later (in finish_dynamic_sections) but we must add the entries now
3087          so that we get the correct size for the .dynamic section.  */
3088
3089       if (info->executable)
3090         {
3091           /* The DT_DEBUG entry is filled in by the dynamic linker and used
3092              by the debugger.  */
3093 #define add_dynamic_entry(TAG, VAL) \
3094   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3095
3096           if (!add_dynamic_entry (DT_DEBUG, 0))
3097             return FALSE;
3098         }
3099
3100       if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3101         return FALSE;
3102       if (!add_dynamic_entry (DT_PLTGOT, 0))
3103         return FALSE;
3104
3105       if (relplt)
3106         {
3107           if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3108               || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3109               || !add_dynamic_entry (DT_JMPREL, 0))
3110             return FALSE;
3111         }
3112
3113       if (!add_dynamic_entry (DT_RELA, 0)
3114           || !add_dynamic_entry (DT_RELASZ, 0)
3115           || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3116         return FALSE;
3117
3118       if (ia64_info->reltext)
3119         {
3120           if (!add_dynamic_entry (DT_TEXTREL, 0))
3121             return FALSE;
3122           info->flags |= DF_TEXTREL;
3123         }
3124     }
3125
3126   /* ??? Perhaps force __gp local.  */
3127
3128   return TRUE;
3129 }
3130
3131 static bfd_reloc_status_type
3132 elfNN_ia64_install_value (hit_addr, v, r_type)
3133      bfd_byte *hit_addr;
3134      bfd_vma v;
3135      unsigned int r_type;
3136 {
3137   const struct ia64_operand *op;
3138   int bigendian = 0, shift = 0;
3139   bfd_vma t0, t1, dword;
3140   ia64_insn insn;
3141   enum ia64_opnd opnd;
3142   const char *err;
3143   size_t size = 8;
3144 #ifdef BFD_HOST_U_64_BIT
3145   BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3146 #else
3147   bfd_vma val = v;
3148 #endif
3149
3150   opnd = IA64_OPND_NIL;
3151   switch (r_type)
3152     {
3153     case R_IA64_NONE:
3154     case R_IA64_LDXMOV:
3155       return bfd_reloc_ok;
3156
3157       /* Instruction relocations.  */
3158
3159     case R_IA64_IMM14:
3160     case R_IA64_TPREL14:
3161     case R_IA64_DTPREL14:
3162       opnd = IA64_OPND_IMM14;
3163       break;
3164
3165     case R_IA64_PCREL21F:       opnd = IA64_OPND_TGT25; break;
3166     case R_IA64_PCREL21M:       opnd = IA64_OPND_TGT25b; break;
3167     case R_IA64_PCREL60B:       opnd = IA64_OPND_TGT64; break;
3168     case R_IA64_PCREL21B:
3169     case R_IA64_PCREL21BI:
3170       opnd = IA64_OPND_TGT25c;
3171       break;
3172
3173     case R_IA64_IMM22:
3174     case R_IA64_GPREL22:
3175     case R_IA64_LTOFF22:
3176     case R_IA64_LTOFF22X:
3177     case R_IA64_PLTOFF22:
3178     case R_IA64_PCREL22:
3179     case R_IA64_LTOFF_FPTR22:
3180     case R_IA64_TPREL22:
3181     case R_IA64_DTPREL22:
3182     case R_IA64_LTOFF_TPREL22:
3183     case R_IA64_LTOFF_DTPMOD22:
3184     case R_IA64_LTOFF_DTPREL22:
3185       opnd = IA64_OPND_IMM22;
3186       break;
3187
3188     case R_IA64_IMM64:
3189     case R_IA64_GPREL64I:
3190     case R_IA64_LTOFF64I:
3191     case R_IA64_PLTOFF64I:
3192     case R_IA64_PCREL64I:
3193     case R_IA64_FPTR64I:
3194     case R_IA64_LTOFF_FPTR64I:
3195     case R_IA64_TPREL64I:
3196     case R_IA64_DTPREL64I:
3197       opnd = IA64_OPND_IMMU64;
3198       break;
3199
3200       /* Data relocations.  */
3201
3202     case R_IA64_DIR32MSB:
3203     case R_IA64_GPREL32MSB:
3204     case R_IA64_FPTR32MSB:
3205     case R_IA64_PCREL32MSB:
3206     case R_IA64_LTOFF_FPTR32MSB:
3207     case R_IA64_SEGREL32MSB:
3208     case R_IA64_SECREL32MSB:
3209     case R_IA64_LTV32MSB:
3210     case R_IA64_DTPREL32MSB:
3211       size = 4; bigendian = 1;
3212       break;
3213
3214     case R_IA64_DIR32LSB:
3215     case R_IA64_GPREL32LSB:
3216     case R_IA64_FPTR32LSB:
3217     case R_IA64_PCREL32LSB:
3218     case R_IA64_LTOFF_FPTR32LSB:
3219     case R_IA64_SEGREL32LSB:
3220     case R_IA64_SECREL32LSB:
3221     case R_IA64_LTV32LSB:
3222     case R_IA64_DTPREL32LSB:
3223       size = 4; bigendian = 0;
3224       break;
3225
3226     case R_IA64_DIR64MSB:
3227     case R_IA64_GPREL64MSB:
3228     case R_IA64_PLTOFF64MSB:
3229     case R_IA64_FPTR64MSB:
3230     case R_IA64_PCREL64MSB:
3231     case R_IA64_LTOFF_FPTR64MSB:
3232     case R_IA64_SEGREL64MSB:
3233     case R_IA64_SECREL64MSB:
3234     case R_IA64_LTV64MSB:
3235     case R_IA64_TPREL64MSB:
3236     case R_IA64_DTPMOD64MSB:
3237     case R_IA64_DTPREL64MSB:
3238       size = 8; bigendian = 1;
3239       break;
3240
3241     case R_IA64_DIR64LSB:
3242     case R_IA64_GPREL64LSB:
3243     case R_IA64_PLTOFF64LSB:
3244     case R_IA64_FPTR64LSB:
3245     case R_IA64_PCREL64LSB:
3246     case R_IA64_LTOFF_FPTR64LSB:
3247     case R_IA64_SEGREL64LSB:
3248     case R_IA64_SECREL64LSB:
3249     case R_IA64_LTV64LSB:
3250     case R_IA64_TPREL64LSB:
3251     case R_IA64_DTPMOD64LSB:
3252     case R_IA64_DTPREL64LSB:
3253       size = 8; bigendian = 0;
3254       break;
3255
3256       /* Unsupported / Dynamic relocations.  */
3257     default:
3258       return bfd_reloc_notsupported;
3259     }
3260
3261   switch (opnd)
3262     {
3263     case IA64_OPND_IMMU64:
3264       hit_addr -= (long) hit_addr & 0x3;
3265       t0 = bfd_getl64 (hit_addr);
3266       t1 = bfd_getl64 (hit_addr + 8);
3267
3268       /* tmpl/s: bits  0.. 5 in t0
3269          slot 0: bits  5..45 in t0
3270          slot 1: bits 46..63 in t0, bits 0..22 in t1
3271          slot 2: bits 23..63 in t1 */
3272
3273       /* First, clear the bits that form the 64 bit constant.  */
3274       t0 &= ~(0x3ffffLL << 46);
3275       t1 &= ~(0x7fffffLL
3276               | ((  (0x07fLL << 13) | (0x1ffLL << 27)
3277                     | (0x01fLL << 22) | (0x001LL << 21)
3278                     | (0x001LL << 36)) << 23));
3279
3280       t0 |= ((val >> 22) & 0x03ffffLL) << 46;           /* 18 lsbs of imm41 */
3281       t1 |= ((val >> 40) & 0x7fffffLL) <<  0;           /* 23 msbs of imm41 */
3282       t1 |= (  (((val >>  0) & 0x07f) << 13)            /* imm7b */
3283                | (((val >>  7) & 0x1ff) << 27)          /* imm9d */
3284                | (((val >> 16) & 0x01f) << 22)          /* imm5c */
3285                | (((val >> 21) & 0x001) << 21)          /* ic */
3286                | (((val >> 63) & 0x001) << 36)) << 23;  /* i */
3287
3288       bfd_putl64 (t0, hit_addr);
3289       bfd_putl64 (t1, hit_addr + 8);
3290       break;
3291
3292     case IA64_OPND_TGT64:
3293       hit_addr -= (long) hit_addr & 0x3;
3294       t0 = bfd_getl64 (hit_addr);
3295       t1 = bfd_getl64 (hit_addr + 8);
3296
3297       /* tmpl/s: bits  0.. 5 in t0
3298          slot 0: bits  5..45 in t0
3299          slot 1: bits 46..63 in t0, bits 0..22 in t1
3300          slot 2: bits 23..63 in t1 */
3301
3302       /* First, clear the bits that form the 64 bit constant.  */
3303       t0 &= ~(0x3ffffLL << 46);
3304       t1 &= ~(0x7fffffLL
3305               | ((1LL << 36 | 0xfffffLL << 13) << 23));
3306
3307       val >>= 4;
3308       t0 |= ((val >> 20) & 0xffffLL) << 2 << 46;        /* 16 lsbs of imm39 */
3309       t1 |= ((val >> 36) & 0x7fffffLL) << 0;            /* 23 msbs of imm39 */
3310       t1 |= ((((val >> 0) & 0xfffffLL) << 13)           /* imm20b */
3311               | (((val >> 59) & 0x1LL) << 36)) << 23;   /* i */
3312
3313       bfd_putl64 (t0, hit_addr);
3314       bfd_putl64 (t1, hit_addr + 8);
3315       break;
3316
3317     default:
3318       switch ((long) hit_addr & 0x3)
3319         {
3320         case 0: shift =  5; break;
3321         case 1: shift = 14; hit_addr += 3; break;
3322         case 2: shift = 23; hit_addr += 6; break;
3323         case 3: return bfd_reloc_notsupported; /* shouldn't happen...  */
3324         }
3325       dword = bfd_getl64 (hit_addr);
3326       insn = (dword >> shift) & 0x1ffffffffffLL;
3327
3328       op = elf64_ia64_operands + opnd;
3329       err = (*op->insert) (op, val, &insn);
3330       if (err)
3331         return bfd_reloc_overflow;
3332
3333       dword &= ~(0x1ffffffffffLL << shift);
3334       dword |= (insn << shift);
3335       bfd_putl64 (dword, hit_addr);
3336       break;
3337
3338     case IA64_OPND_NIL:
3339       /* A data relocation.  */
3340       if (bigendian)
3341         if (size == 4)
3342           bfd_putb32 (val, hit_addr);
3343         else
3344           bfd_putb64 (val, hit_addr);
3345       else
3346         if (size == 4)
3347           bfd_putl32 (val, hit_addr);
3348         else
3349           bfd_putl64 (val, hit_addr);
3350       break;
3351     }
3352
3353   return bfd_reloc_ok;
3354 }
3355
3356 static void
3357 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3358                               dynindx, addend)
3359      bfd *abfd;
3360      struct bfd_link_info *info;
3361      asection *sec;
3362      asection *srel;
3363      bfd_vma offset;
3364      unsigned int type;
3365      long dynindx;
3366      bfd_vma addend;
3367 {
3368   Elf_Internal_Rela outrel;
3369   bfd_byte *loc;
3370
3371   BFD_ASSERT (dynindx != -1);
3372   outrel.r_info = ELFNN_R_INFO (dynindx, type);
3373   outrel.r_addend = addend;
3374   outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3375   if (outrel.r_offset >= (bfd_vma) -2)
3376     {
3377       /* Run for the hills.  We shouldn't be outputting a relocation
3378          for this.  So do what everyone else does and output a no-op.  */
3379       outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3380       outrel.r_addend = 0;
3381       outrel.r_offset = 0;
3382     }
3383   else
3384     outrel.r_offset += sec->output_section->vma + sec->output_offset;
3385
3386   loc = srel->contents;
3387   loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3388   bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3389   BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
3390 }
3391
3392 /* Store an entry for target address TARGET_ADDR in the linkage table
3393    and return the gp-relative address of the linkage table entry.  */
3394
3395 static bfd_vma
3396 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3397      bfd *abfd;
3398      struct bfd_link_info *info;
3399      struct elfNN_ia64_dyn_sym_info *dyn_i;
3400      long dynindx;
3401      bfd_vma addend;
3402      bfd_vma value;
3403      unsigned int dyn_r_type;
3404 {
3405   struct elfNN_ia64_link_hash_table *ia64_info;
3406   asection *got_sec;
3407   bfd_boolean done;
3408   bfd_vma got_offset;
3409
3410   ia64_info = elfNN_ia64_hash_table (info);
3411   got_sec = ia64_info->got_sec;
3412
3413   switch (dyn_r_type)
3414     {
3415     case R_IA64_TPREL64LSB:
3416       done = dyn_i->tprel_done;
3417       dyn_i->tprel_done = TRUE;
3418       got_offset = dyn_i->tprel_offset;
3419       break;
3420     case R_IA64_DTPMOD64LSB:
3421       if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3422         {
3423           done = dyn_i->dtpmod_done;
3424           dyn_i->dtpmod_done = TRUE;
3425         }
3426       else
3427         {
3428           done = ia64_info->self_dtpmod_done;
3429           ia64_info->self_dtpmod_done = TRUE;
3430           dynindx = 0;
3431         }
3432       got_offset = dyn_i->dtpmod_offset;
3433       break;
3434     case R_IA64_DTPREL32LSB:
3435     case R_IA64_DTPREL64LSB:
3436       done = dyn_i->dtprel_done;
3437       dyn_i->dtprel_done = TRUE;
3438       got_offset = dyn_i->dtprel_offset;
3439       break;
3440     default:
3441       done = dyn_i->got_done;
3442       dyn_i->got_done = TRUE;
3443       got_offset = dyn_i->got_offset;
3444       break;
3445     }
3446
3447   BFD_ASSERT ((got_offset & 7) == 0);
3448
3449   if (! done)
3450     {
3451       /* Store the target address in the linkage table entry.  */
3452       bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3453
3454       /* Install a dynamic relocation if needed.  */
3455       if (((info->shared
3456             && (!dyn_i->h
3457                 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3458                 || dyn_i->h->root.type != bfd_link_hash_undefweak)
3459             && dyn_r_type != R_IA64_DTPREL32LSB
3460             && dyn_r_type != R_IA64_DTPREL64LSB)
3461            || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
3462            || (dynindx != -1
3463                && (dyn_r_type == R_IA64_FPTR32LSB
3464                    || dyn_r_type == R_IA64_FPTR64LSB)))
3465           && (!dyn_i->want_ltoff_fptr
3466               || !info->pie
3467               || !dyn_i->h
3468               || dyn_i->h->root.type != bfd_link_hash_undefweak))
3469         {
3470           if (dynindx == -1
3471               && dyn_r_type != R_IA64_TPREL64LSB
3472               && dyn_r_type != R_IA64_DTPMOD64LSB
3473               && dyn_r_type != R_IA64_DTPREL32LSB
3474               && dyn_r_type != R_IA64_DTPREL64LSB)
3475             {
3476               dyn_r_type = R_IA64_RELNNLSB;
3477               dynindx = 0;
3478               addend = value;
3479             }
3480
3481           if (bfd_big_endian (abfd))
3482             {
3483               switch (dyn_r_type)
3484                 {
3485                 case R_IA64_REL32LSB:
3486                   dyn_r_type = R_IA64_REL32MSB;
3487                   break;
3488                 case R_IA64_DIR32LSB:
3489                   dyn_r_type = R_IA64_DIR32MSB;
3490                   break;
3491                 case R_IA64_FPTR32LSB:
3492                   dyn_r_type = R_IA64_FPTR32MSB;
3493                   break;
3494                 case R_IA64_DTPREL32LSB:
3495                   dyn_r_type = R_IA64_DTPREL32MSB;
3496                   break;
3497                 case R_IA64_REL64LSB:
3498                   dyn_r_type = R_IA64_REL64MSB;
3499                   break;
3500                 case R_IA64_DIR64LSB:
3501                   dyn_r_type = R_IA64_DIR64MSB;
3502                   break;
3503                 case R_IA64_FPTR64LSB:
3504                   dyn_r_type = R_IA64_FPTR64MSB;
3505                   break;
3506                 case R_IA64_TPREL64LSB:
3507                   dyn_r_type = R_IA64_TPREL64MSB;
3508                   break;
3509                 case R_IA64_DTPMOD64LSB:
3510                   dyn_r_type = R_IA64_DTPMOD64MSB;
3511                   break;
3512                 case R_IA64_DTPREL64LSB:
3513                   dyn_r_type = R_IA64_DTPREL64MSB;
3514                   break;
3515                 default:
3516                   BFD_ASSERT (FALSE);
3517                   break;
3518                 }
3519             }
3520
3521           elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3522                                         ia64_info->rel_got_sec,
3523                                         got_offset, dyn_r_type,
3524                                         dynindx, addend);
3525         }
3526     }
3527
3528   /* Return the address of the linkage table entry.  */
3529   value = (got_sec->output_section->vma
3530            + got_sec->output_offset
3531            + got_offset);
3532
3533   return value;
3534 }
3535
3536 /* Fill in a function descriptor consisting of the function's code
3537    address and its global pointer.  Return the descriptor's address.  */
3538
3539 static bfd_vma
3540 set_fptr_entry (abfd, info, dyn_i, value)
3541      bfd *abfd;
3542      struct bfd_link_info *info;
3543      struct elfNN_ia64_dyn_sym_info *dyn_i;
3544      bfd_vma value;
3545 {
3546   struct elfNN_ia64_link_hash_table *ia64_info;
3547   asection *fptr_sec;
3548
3549   ia64_info = elfNN_ia64_hash_table (info);
3550   fptr_sec = ia64_info->fptr_sec;
3551
3552   if (!dyn_i->fptr_done)
3553     {
3554       dyn_i->fptr_done = 1;
3555
3556       /* Fill in the function descriptor.  */
3557       bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3558       bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3559                   fptr_sec->contents + dyn_i->fptr_offset + 8);
3560       if (ia64_info->rel_fptr_sec)
3561         {
3562           Elf_Internal_Rela outrel;
3563           bfd_byte *loc;
3564
3565           if (bfd_little_endian (abfd))
3566             outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
3567           else
3568             outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
3569           outrel.r_addend = value;
3570           outrel.r_offset = (fptr_sec->output_section->vma
3571                              + fptr_sec->output_offset
3572                              + dyn_i->fptr_offset);
3573           loc = ia64_info->rel_fptr_sec->contents;
3574           loc += ia64_info->rel_fptr_sec->reloc_count++
3575                  * sizeof (ElfNN_External_Rela);
3576           bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3577         }
3578     }
3579
3580   /* Return the descriptor's address.  */
3581   value = (fptr_sec->output_section->vma
3582            + fptr_sec->output_offset
3583            + dyn_i->fptr_offset);
3584
3585   return value;
3586 }
3587
3588 /* Fill in a PLTOFF entry consisting of the function's code address
3589    and its global pointer.  Return the descriptor's address.  */
3590
3591 static bfd_vma
3592 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3593      bfd *abfd;
3594      struct bfd_link_info *info;
3595      struct elfNN_ia64_dyn_sym_info *dyn_i;
3596      bfd_vma value;
3597      bfd_boolean is_plt;
3598 {
3599   struct elfNN_ia64_link_hash_table *ia64_info;
3600   asection *pltoff_sec;
3601
3602   ia64_info = elfNN_ia64_hash_table (info);
3603   pltoff_sec = ia64_info->pltoff_sec;
3604
3605   /* Don't do anything if this symbol uses a real PLT entry.  In
3606      that case, we'll fill this in during finish_dynamic_symbol.  */
3607   if ((! dyn_i->want_plt || is_plt)
3608       && !dyn_i->pltoff_done)
3609     {
3610       bfd_vma gp = _bfd_get_gp_value (abfd);
3611
3612       /* Fill in the function descriptor.  */
3613       bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3614       bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3615
3616       /* Install dynamic relocations if needed.  */
3617       if (!is_plt
3618           && info->shared
3619           && (!dyn_i->h
3620               || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3621               || dyn_i->h->root.type != bfd_link_hash_undefweak))
3622         {
3623           unsigned int dyn_r_type;
3624
3625           if (bfd_big_endian (abfd))
3626             dyn_r_type = R_IA64_RELNNMSB;
3627           else
3628             dyn_r_type = R_IA64_RELNNLSB;
3629
3630           elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3631                                         ia64_info->rel_pltoff_sec,
3632                                         dyn_i->pltoff_offset,
3633                                         dyn_r_type, 0, value);
3634           elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3635                                         ia64_info->rel_pltoff_sec,
3636                                         dyn_i->pltoff_offset + ARCH_SIZE / 8,
3637                                         dyn_r_type, 0, gp);
3638         }
3639
3640       dyn_i->pltoff_done = 1;
3641     }
3642
3643   /* Return the descriptor's address.  */
3644   value = (pltoff_sec->output_section->vma
3645            + pltoff_sec->output_offset
3646            + dyn_i->pltoff_offset);
3647
3648   return value;
3649 }
3650
3651 /* Return the base VMA address which should be subtracted from real addresses
3652    when resolving @tprel() relocation.
3653    Main program TLS (whose template starts at PT_TLS p_vaddr)
3654    is assigned offset round(2 * size of pointer, PT_TLS p_align).  */
3655
3656 static bfd_vma
3657 elfNN_ia64_tprel_base (info)
3658      struct bfd_link_info *info;
3659 {
3660   asection *tls_sec = elf_hash_table (info)->tls_sec;
3661
3662   BFD_ASSERT (tls_sec != NULL);
3663   return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
3664                                      tls_sec->alignment_power);
3665 }
3666
3667 /* Return the base VMA address which should be subtracted from real addresses
3668    when resolving @dtprel() relocation.
3669    This is PT_TLS segment p_vaddr.  */
3670
3671 static bfd_vma
3672 elfNN_ia64_dtprel_base (info)
3673      struct bfd_link_info *info;
3674 {
3675   BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
3676   return elf_hash_table (info)->tls_sec->vma;
3677 }
3678
3679 /* Called through qsort to sort the .IA_64.unwind section during a
3680    non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
3681    to the output bfd so we can do proper endianness frobbing.  */
3682
3683 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3684
3685 static int
3686 elfNN_ia64_unwind_entry_compare (a, b)
3687      const PTR a;
3688      const PTR b;
3689 {
3690   bfd_vma av, bv;
3691
3692   av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3693   bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3694
3695   return (av < bv ? -1 : av > bv ? 1 : 0);
3696 }
3697
3698 /* Make sure we've got ourselves a nice fat __gp value.  */
3699 static bfd_boolean
3700 elfNN_ia64_choose_gp (abfd, info)
3701      bfd *abfd;
3702      struct bfd_link_info *info;
3703 {
3704   bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3705   bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3706   struct elf_link_hash_entry *gp;
3707   bfd_vma gp_val;
3708   asection *os;
3709   struct elfNN_ia64_link_hash_table *ia64_info;
3710
3711   ia64_info = elfNN_ia64_hash_table (info);
3712
3713   /* Find the min and max vma of all sections marked short.  Also collect
3714      min and max vma of any type, for use in selecting a nice gp.  */
3715   for (os = abfd->sections; os ; os = os->next)
3716     {
3717       bfd_vma lo, hi;
3718
3719       if ((os->flags & SEC_ALLOC) == 0)
3720         continue;
3721
3722       lo = os->vma;
3723       hi = os->vma + os->size;
3724       if (hi < lo)
3725         hi = (bfd_vma) -1;
3726
3727       if (min_vma > lo)
3728         min_vma = lo;
3729       if (max_vma < hi)
3730         max_vma = hi;
3731       if (os->flags & SEC_SMALL_DATA)
3732         {
3733           if (min_short_vma > lo)
3734             min_short_vma = lo;
3735           if (max_short_vma < hi)
3736             max_short_vma = hi;
3737         }
3738     }
3739
3740   /* See if the user wants to force a value.  */
3741   gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3742                              FALSE, FALSE);
3743
3744   if (gp
3745       && (gp->root.type == bfd_link_hash_defined
3746           || gp->root.type == bfd_link_hash_defweak))
3747     {
3748       asection *gp_sec = gp->root.u.def.section;
3749       gp_val = (gp->root.u.def.value
3750                 + gp_sec->output_section->vma
3751                 + gp_sec->output_offset);
3752     }
3753   else
3754     {
3755       /* Pick a sensible value.  */
3756
3757       asection *got_sec = ia64_info->got_sec;
3758
3759       /* Start with just the address of the .got.  */
3760       if (got_sec)
3761         gp_val = got_sec->output_section->vma;
3762       else if (max_short_vma != 0)
3763         gp_val = min_short_vma;
3764       else
3765         gp_val = min_vma;
3766
3767       /* If it is possible to address the entire image, but we
3768          don't with the choice above, adjust.  */
3769       if (max_vma - min_vma < 0x400000
3770           && max_vma - gp_val <= 0x200000
3771           && gp_val - min_vma > 0x200000)
3772         gp_val = min_vma + 0x200000;
3773       else if (max_short_vma != 0)
3774         {
3775           /* If we don't cover all the short data, adjust.  */
3776           if (max_short_vma - gp_val >= 0x200000)
3777             gp_val = min_short_vma + 0x200000;
3778
3779           /* If we're addressing stuff past the end, adjust back.  */
3780           if (gp_val > max_vma)
3781             gp_val = max_vma - 0x200000 + 8;
3782         }
3783     }
3784
3785   /* Validate whether all SHF_IA_64_SHORT sections are within
3786      range of the chosen GP.  */
3787
3788   if (max_short_vma != 0)
3789     {
3790       if (max_short_vma - min_short_vma >= 0x400000)
3791         {
3792           (*_bfd_error_handler)
3793             (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3794              bfd_get_filename (abfd),
3795              (unsigned long) (max_short_vma - min_short_vma));
3796           return FALSE;
3797         }
3798       else if ((gp_val > min_short_vma
3799                 && gp_val - min_short_vma > 0x200000)
3800                || (gp_val < max_short_vma
3801                    && max_short_vma - gp_val >= 0x200000))
3802         {
3803           (*_bfd_error_handler)
3804             (_("%s: __gp does not cover short data segment"),
3805              bfd_get_filename (abfd));
3806           return FALSE;
3807         }
3808     }
3809
3810   _bfd_set_gp_value (abfd, gp_val);
3811
3812   return TRUE;
3813 }
3814
3815 static bfd_boolean
3816 elfNN_ia64_final_link (abfd, info)
3817      bfd *abfd;
3818      struct bfd_link_info *info;
3819 {
3820   struct elfNN_ia64_link_hash_table *ia64_info;
3821   asection *unwind_output_sec;
3822
3823   ia64_info = elfNN_ia64_hash_table (info);
3824
3825   /* Make sure we've got ourselves a nice fat __gp value.  */
3826   if (!info->relocatable)
3827     {
3828       bfd_vma gp_val = _bfd_get_gp_value (abfd);
3829       struct elf_link_hash_entry *gp;
3830
3831       if (gp_val == 0)
3832         {
3833           if (! elfNN_ia64_choose_gp (abfd, info))
3834             return FALSE;
3835           gp_val = _bfd_get_gp_value (abfd);
3836         }
3837
3838       gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3839                                  FALSE, FALSE);
3840       if (gp)
3841         {
3842           gp->root.type = bfd_link_hash_defined;
3843           gp->root.u.def.value = gp_val;
3844           gp->root.u.def.section = bfd_abs_section_ptr;
3845         }
3846     }
3847
3848   /* If we're producing a final executable, we need to sort the contents
3849      of the .IA_64.unwind section.  Force this section to be relocated
3850      into memory rather than written immediately to the output file.  */
3851   unwind_output_sec = NULL;
3852   if (!info->relocatable)
3853     {
3854       asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3855       if (s)
3856         {
3857           unwind_output_sec = s->output_section;
3858           unwind_output_sec->contents
3859             = bfd_malloc (unwind_output_sec->size);
3860           if (unwind_output_sec->contents == NULL)
3861             return FALSE;
3862         }
3863     }
3864
3865   /* Invoke the regular ELF backend linker to do all the work.  */
3866   if (!bfd_elf_final_link (abfd, info))
3867     return FALSE;
3868
3869   if (unwind_output_sec)
3870     {
3871       elfNN_ia64_unwind_entry_compare_bfd = abfd;
3872       qsort (unwind_output_sec->contents,
3873              (size_t) (unwind_output_sec->size / 24),
3874              24,
3875              elfNN_ia64_unwind_entry_compare);
3876
3877       if (! bfd_set_section_contents (abfd, unwind_output_sec,
3878                                       unwind_output_sec->contents, (bfd_vma) 0,
3879                                       unwind_output_sec->size))
3880         return FALSE;
3881     }
3882
3883   return TRUE;
3884 }
3885
3886 static bfd_boolean
3887 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3888                              contents, relocs, local_syms, local_sections)
3889      bfd *output_bfd;
3890      struct bfd_link_info *info;
3891      bfd *input_bfd;
3892      asection *input_section;
3893      bfd_byte *contents;
3894      Elf_Internal_Rela *relocs;
3895      Elf_Internal_Sym *local_syms;
3896      asection **local_sections;
3897 {
3898   struct elfNN_ia64_link_hash_table *ia64_info;
3899   Elf_Internal_Shdr *symtab_hdr;
3900   Elf_Internal_Rela *rel;
3901   Elf_Internal_Rela *relend;
3902   asection *srel;
3903   bfd_boolean ret_val = TRUE;   /* for non-fatal errors */
3904   bfd_vma gp_val;
3905
3906   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3907   ia64_info = elfNN_ia64_hash_table (info);
3908
3909   /* Infect various flags from the input section to the output section.  */
3910   if (info->relocatable)
3911     {
3912       bfd_vma flags;
3913
3914       flags = elf_section_data(input_section)->this_hdr.sh_flags;
3915       flags &= SHF_IA_64_NORECOV;
3916
3917       elf_section_data(input_section->output_section)
3918         ->this_hdr.sh_flags |= flags;
3919       return TRUE;
3920     }
3921
3922   gp_val = _bfd_get_gp_value (output_bfd);
3923   srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
3924
3925   rel = relocs;
3926   relend = relocs + input_section->reloc_count;
3927   for (; rel < relend; ++rel)
3928     {
3929       struct elf_link_hash_entry *h;
3930       struct elfNN_ia64_dyn_sym_info *dyn_i;
3931       bfd_reloc_status_type r;
3932       reloc_howto_type *howto;
3933       unsigned long r_symndx;
3934       Elf_Internal_Sym *sym;
3935       unsigned int r_type;
3936       bfd_vma value;
3937       asection *sym_sec;
3938       bfd_byte *hit_addr;
3939       bfd_boolean dynamic_symbol_p;
3940       bfd_boolean undef_weak_ref;
3941
3942       r_type = ELFNN_R_TYPE (rel->r_info);
3943       if (r_type > R_IA64_MAX_RELOC_CODE)
3944         {
3945           (*_bfd_error_handler)
3946             (_("%B: unknown relocation type %d"),
3947              input_bfd, (int) r_type);
3948           bfd_set_error (bfd_error_bad_value);
3949           ret_val = FALSE;
3950           continue;
3951         }
3952
3953       howto = lookup_howto (r_type);
3954       r_symndx = ELFNN_R_SYM (rel->r_info);
3955       h = NULL;
3956       sym = NULL;
3957       sym_sec = NULL;
3958       undef_weak_ref = FALSE;
3959
3960       if (r_symndx < symtab_hdr->sh_info)
3961         {
3962           /* Reloc against local symbol.  */
3963           asection *msec;
3964           sym = local_syms + r_symndx;
3965           sym_sec = local_sections[r_symndx];
3966           msec = sym_sec;
3967           value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
3968           if ((sym_sec->flags & SEC_MERGE)
3969               && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3970               && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
3971             {
3972               struct elfNN_ia64_local_hash_entry *loc_h;
3973
3974               loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
3975               if (loc_h && ! loc_h->sec_merge_done)
3976                 {
3977                   struct elfNN_ia64_dyn_sym_info *dynent;
3978
3979                   for (dynent = loc_h->info; dynent; dynent = dynent->next)
3980                     {
3981                       msec = sym_sec;
3982                       dynent->addend =
3983                         _bfd_merged_section_offset (output_bfd, &msec,
3984                                                     elf_section_data (msec)->
3985                                                     sec_info,
3986                                                     sym->st_value
3987                                                     + dynent->addend);
3988                       dynent->addend -= sym->st_value;
3989                       dynent->addend += msec->output_section->vma
3990                                         + msec->output_offset
3991                                         - sym_sec->output_section->vma
3992                                         - sym_sec->output_offset;
3993                     }
3994                   loc_h->sec_merge_done = 1;
3995                 }
3996             }
3997         }
3998       else
3999         {
4000           bfd_boolean unresolved_reloc;
4001           bfd_boolean warned;
4002           struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
4003
4004           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4005                                    r_symndx, symtab_hdr, sym_hashes,
4006                                    h, sym_sec, value,
4007                                    unresolved_reloc, warned);
4008
4009           if (h->root.type == bfd_link_hash_undefweak)
4010             undef_weak_ref = TRUE;
4011           else if (warned)
4012             continue;
4013         }
4014
4015       hit_addr = contents + rel->r_offset;
4016       value += rel->r_addend;
4017       dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
4018
4019       switch (r_type)
4020         {
4021         case R_IA64_NONE:
4022         case R_IA64_LDXMOV:
4023           continue;
4024
4025         case R_IA64_IMM14:
4026         case R_IA64_IMM22:
4027         case R_IA64_IMM64:
4028         case R_IA64_DIR32MSB:
4029         case R_IA64_DIR32LSB:
4030         case R_IA64_DIR64MSB:
4031         case R_IA64_DIR64LSB:
4032           /* Install a dynamic relocation for this reloc.  */
4033           if ((dynamic_symbol_p || info->shared)
4034               && r_symndx != 0
4035               && (input_section->flags & SEC_ALLOC) != 0)
4036             {
4037               unsigned int dyn_r_type;
4038               long dynindx;
4039               bfd_vma addend;
4040
4041               BFD_ASSERT (srel != NULL);
4042
4043               switch (r_type)
4044                 {
4045                 case R_IA64_IMM14:
4046                 case R_IA64_IMM22:
4047                 case R_IA64_IMM64:
4048                   /* ??? People shouldn't be doing non-pic code in
4049                      shared libraries nor dynamic executables.  */
4050                   (*_bfd_error_handler)
4051                     (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4052                      input_bfd,
4053                      h ? h->root.root.string
4054                        : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4055                                            sym_sec));
4056                   ret_val = FALSE;
4057                   continue;
4058
4059                 default:
4060                   break;
4061                 }
4062
4063               /* If we don't need dynamic symbol lookup, find a
4064                  matching RELATIVE relocation.  */
4065               dyn_r_type = r_type;
4066               if (dynamic_symbol_p)
4067                 {
4068                   dynindx = h->dynindx;
4069                   addend = rel->r_addend;
4070                   value = 0;
4071                 }
4072               else
4073                 {
4074                   switch (r_type)
4075                     {
4076                     case R_IA64_DIR32MSB:
4077                       dyn_r_type = R_IA64_REL32MSB;
4078                       break;
4079                     case R_IA64_DIR32LSB:
4080                       dyn_r_type = R_IA64_REL32LSB;
4081                       break;
4082                     case R_IA64_DIR64MSB:
4083                       dyn_r_type = R_IA64_REL64MSB;
4084                       break;
4085                     case R_IA64_DIR64LSB:
4086                       dyn_r_type = R_IA64_REL64LSB;
4087                       break;
4088
4089                     default:
4090                       break;
4091                     }
4092                   dynindx = 0;
4093                   addend = value;
4094                 }
4095
4096               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4097                                             srel, rel->r_offset, dyn_r_type,
4098                                             dynindx, addend);
4099             }
4100           /* Fall through.  */
4101
4102         case R_IA64_LTV32MSB:
4103         case R_IA64_LTV32LSB:
4104         case R_IA64_LTV64MSB:
4105         case R_IA64_LTV64LSB:
4106           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4107           break;
4108
4109         case R_IA64_GPREL22:
4110         case R_IA64_GPREL64I:
4111         case R_IA64_GPREL32MSB:
4112         case R_IA64_GPREL32LSB:
4113         case R_IA64_GPREL64MSB:
4114         case R_IA64_GPREL64LSB:
4115           if (dynamic_symbol_p)
4116             {
4117               (*_bfd_error_handler)
4118                 (_("%B: @gprel relocation against dynamic symbol %s"),
4119                  input_bfd,
4120                  h ? h->root.root.string
4121                    : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4122                                        sym_sec));
4123               ret_val = FALSE;
4124               continue;
4125             }
4126           value -= gp_val;
4127           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4128           break;
4129
4130         case R_IA64_LTOFF22:
4131         case R_IA64_LTOFF22X:
4132         case R_IA64_LTOFF64I:
4133           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4134           value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4135                                  rel->r_addend, value, R_IA64_DIRNNLSB);
4136           value -= gp_val;
4137           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4138           break;
4139
4140         case R_IA64_PLTOFF22:
4141         case R_IA64_PLTOFF64I:
4142         case R_IA64_PLTOFF64MSB:
4143         case R_IA64_PLTOFF64LSB:
4144           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4145           value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4146           value -= gp_val;
4147           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4148           break;
4149
4150         case R_IA64_FPTR64I:
4151         case R_IA64_FPTR32MSB:
4152         case R_IA64_FPTR32LSB:
4153         case R_IA64_FPTR64MSB:
4154         case R_IA64_FPTR64LSB:
4155           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4156           if (dyn_i->want_fptr)
4157             {
4158               if (!undef_weak_ref)
4159                 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4160             }
4161           if (!dyn_i->want_fptr || info->pie)
4162             {
4163               long dynindx;
4164               unsigned int dyn_r_type = r_type;
4165               bfd_vma addend = rel->r_addend;
4166
4167               /* Otherwise, we expect the dynamic linker to create
4168                  the entry.  */
4169
4170               if (dyn_i->want_fptr)
4171                 {
4172                   if (r_type == R_IA64_FPTR64I)
4173                     {
4174                       /* We can't represent this without a dynamic symbol.
4175                          Adjust the relocation to be against an output
4176                          section symbol, which are always present in the
4177                          dynamic symbol table.  */
4178                       /* ??? People shouldn't be doing non-pic code in
4179                          shared libraries.  Hork.  */
4180                       (*_bfd_error_handler)
4181                         (_("%B: linking non-pic code in a position independent executable"),
4182                          input_bfd);
4183                       ret_val = FALSE;
4184                       continue;
4185                     }
4186                   dynindx = 0;
4187                   addend = value;
4188                   dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
4189                 }
4190               else if (h)
4191                 {
4192                   if (h->dynindx != -1)
4193                     dynindx = h->dynindx;
4194                   else
4195                     dynindx = (_bfd_elf_link_lookup_local_dynindx
4196                                (info, h->root.u.def.section->owner,
4197                                 global_sym_index (h)));
4198                   value = 0;
4199                 }
4200               else
4201                 {
4202                   dynindx = (_bfd_elf_link_lookup_local_dynindx
4203                              (info, input_bfd, (long) r_symndx));
4204                   value = 0;
4205                 }
4206
4207               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4208                                             srel, rel->r_offset, dyn_r_type,
4209                                             dynindx, addend);
4210             }
4211
4212           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4213           break;
4214
4215         case R_IA64_LTOFF_FPTR22:
4216         case R_IA64_LTOFF_FPTR64I:
4217         case R_IA64_LTOFF_FPTR32MSB:
4218         case R_IA64_LTOFF_FPTR32LSB:
4219         case R_IA64_LTOFF_FPTR64MSB:
4220         case R_IA64_LTOFF_FPTR64LSB:
4221           {
4222             long dynindx;
4223
4224             dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4225             if (dyn_i->want_fptr)
4226               {
4227                 BFD_ASSERT (h == NULL || h->dynindx == -1);
4228                 if (!undef_weak_ref)
4229                   value = set_fptr_entry (output_bfd, info, dyn_i, value);
4230                 dynindx = -1;
4231               }
4232             else
4233               {
4234                 /* Otherwise, we expect the dynamic linker to create
4235                    the entry.  */
4236                 if (h)
4237                   {
4238                     if (h->dynindx != -1)
4239                       dynindx = h->dynindx;
4240                     else
4241                       dynindx = (_bfd_elf_link_lookup_local_dynindx
4242                                  (info, h->root.u.def.section->owner,
4243                                   global_sym_index (h)));
4244                   }
4245                 else
4246                   dynindx = (_bfd_elf_link_lookup_local_dynindx
4247                              (info, input_bfd, (long) r_symndx));
4248                 value = 0;
4249               }
4250
4251             value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4252                                    rel->r_addend, value, R_IA64_FPTRNNLSB);
4253             value -= gp_val;
4254             r = elfNN_ia64_install_value (hit_addr, value, r_type);
4255           }
4256           break;
4257
4258         case R_IA64_PCREL32MSB:
4259         case R_IA64_PCREL32LSB:
4260         case R_IA64_PCREL64MSB:
4261         case R_IA64_PCREL64LSB:
4262           /* Install a dynamic relocation for this reloc.  */
4263           if (dynamic_symbol_p && r_symndx != 0)
4264             {
4265               BFD_ASSERT (srel != NULL);
4266
4267               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4268                                             srel, rel->r_offset, r_type,
4269                                             h->dynindx, rel->r_addend);
4270             }
4271           goto finish_pcrel;
4272
4273         case R_IA64_PCREL21B:
4274         case R_IA64_PCREL60B:
4275           /* We should have created a PLT entry for any dynamic symbol.  */
4276           dyn_i = NULL;
4277           if (h)
4278             dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4279
4280           if (dyn_i && dyn_i->want_plt2)
4281             {
4282               /* Should have caught this earlier.  */
4283               BFD_ASSERT (rel->r_addend == 0);
4284
4285               value = (ia64_info->plt_sec->output_section->vma
4286                        + ia64_info->plt_sec->output_offset
4287                        + dyn_i->plt2_offset);
4288             }
4289           else
4290             {
4291               /* Since there's no PLT entry, Validate that this is
4292                  locally defined.  */
4293               BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4294
4295               /* If the symbol is undef_weak, we shouldn't be trying
4296                  to call it.  There's every chance that we'd wind up
4297                  with an out-of-range fixup here.  Don't bother setting
4298                  any value at all.  */
4299               if (undef_weak_ref)
4300                 continue;
4301             }
4302           goto finish_pcrel;
4303
4304         case R_IA64_PCREL21BI:
4305         case R_IA64_PCREL21F:
4306         case R_IA64_PCREL21M:
4307         case R_IA64_PCREL22:
4308         case R_IA64_PCREL64I:
4309           /* The PCREL21BI reloc is specifically not intended for use with
4310              dynamic relocs.  PCREL21F and PCREL21M are used for speculation
4311              fixup code, and thus probably ought not be dynamic.  The
4312              PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs.  */
4313           if (dynamic_symbol_p)
4314             {
4315               const char *msg;
4316
4317               if (r_type == R_IA64_PCREL21BI)
4318                 msg = _("%B: @internal branch to dynamic symbol %s");
4319               else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4320                 msg = _("%B: speculation fixup to dynamic symbol %s");
4321               else
4322                 msg = _("%B: @pcrel relocation against dynamic symbol %s");
4323               (*_bfd_error_handler) (msg, input_bfd,
4324                                      h ? h->root.root.string
4325                                        : bfd_elf_sym_name (input_bfd,
4326                                                            symtab_hdr,
4327                                                            sym,
4328                                                            sym_sec));
4329               ret_val = FALSE;
4330               continue;
4331             }
4332           goto finish_pcrel;
4333
4334         finish_pcrel:
4335           /* Make pc-relative.  */
4336           value -= (input_section->output_section->vma
4337                     + input_section->output_offset
4338                     + rel->r_offset) & ~ (bfd_vma) 0x3;
4339           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4340           break;
4341
4342         case R_IA64_SEGREL32MSB:
4343         case R_IA64_SEGREL32LSB:
4344         case R_IA64_SEGREL64MSB:
4345         case R_IA64_SEGREL64LSB:
4346           if (r_symndx == 0)
4347             {
4348               /* If the input section was discarded from the output, then
4349                  do nothing.  */
4350               r = bfd_reloc_ok;
4351             }
4352           else
4353             {
4354               struct elf_segment_map *m;
4355               Elf_Internal_Phdr *p;
4356
4357               /* Find the segment that contains the output_section.  */
4358               for (m = elf_tdata (output_bfd)->segment_map,
4359                      p = elf_tdata (output_bfd)->phdr;
4360                    m != NULL;
4361                    m = m->next, p++)
4362                 {
4363                   int i;
4364                   for (i = m->count - 1; i >= 0; i--)
4365                     if (m->sections[i] == input_section->output_section)
4366                       break;
4367                   if (i >= 0)
4368                     break;
4369                 }
4370
4371               if (m == NULL)
4372                 {
4373                   r = bfd_reloc_notsupported;
4374                 }
4375               else
4376                 {
4377                   /* The VMA of the segment is the vaddr of the associated
4378                      program header.  */
4379                   if (value > p->p_vaddr)
4380                     value -= p->p_vaddr;
4381                   else
4382                     value = 0;
4383                   r = elfNN_ia64_install_value (hit_addr, value, r_type);
4384                 }
4385               break;
4386             }
4387
4388         case R_IA64_SECREL32MSB:
4389         case R_IA64_SECREL32LSB:
4390         case R_IA64_SECREL64MSB:
4391         case R_IA64_SECREL64LSB:
4392           /* Make output-section relative to section where the symbol
4393              is defined. PR 475  */
4394           if (sym_sec)
4395             value -= sym_sec->output_section->vma;
4396           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4397           break;
4398
4399         case R_IA64_IPLTMSB:
4400         case R_IA64_IPLTLSB:
4401           /* Install a dynamic relocation for this reloc.  */
4402           if ((dynamic_symbol_p || info->shared)
4403               && (input_section->flags & SEC_ALLOC) != 0)
4404             {
4405               BFD_ASSERT (srel != NULL);
4406
4407               /* If we don't need dynamic symbol lookup, install two
4408                  RELATIVE relocations.  */
4409               if (!dynamic_symbol_p)
4410                 {
4411                   unsigned int dyn_r_type;
4412
4413                   if (r_type == R_IA64_IPLTMSB)
4414                     dyn_r_type = R_IA64_REL64MSB;
4415                   else
4416                     dyn_r_type = R_IA64_REL64LSB;
4417
4418                   elfNN_ia64_install_dyn_reloc (output_bfd, info,
4419                                                 input_section,
4420                                                 srel, rel->r_offset,
4421                                                 dyn_r_type, 0, value);
4422                   elfNN_ia64_install_dyn_reloc (output_bfd, info,
4423                                                 input_section,
4424                                                 srel, rel->r_offset + 8,
4425                                                 dyn_r_type, 0, gp_val);
4426                 }
4427               else
4428                 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4429                                               srel, rel->r_offset, r_type,
4430                                               h->dynindx, rel->r_addend);
4431             }
4432
4433           if (r_type == R_IA64_IPLTMSB)
4434             r_type = R_IA64_DIR64MSB;
4435           else
4436             r_type = R_IA64_DIR64LSB;
4437           elfNN_ia64_install_value (hit_addr, value, r_type);
4438           r = elfNN_ia64_install_value (hit_addr + 8, gp_val, r_type);
4439           break;
4440
4441         case R_IA64_TPREL14:
4442         case R_IA64_TPREL22:
4443         case R_IA64_TPREL64I:
4444           value -= elfNN_ia64_tprel_base (info);
4445           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4446           break;
4447
4448         case R_IA64_DTPREL14:
4449         case R_IA64_DTPREL22:
4450         case R_IA64_DTPREL64I:
4451         case R_IA64_DTPREL32LSB:
4452         case R_IA64_DTPREL32MSB:
4453         case R_IA64_DTPREL64LSB:
4454         case R_IA64_DTPREL64MSB:
4455           value -= elfNN_ia64_dtprel_base (info);
4456           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4457           break;
4458
4459         case R_IA64_LTOFF_TPREL22:
4460         case R_IA64_LTOFF_DTPMOD22:
4461         case R_IA64_LTOFF_DTPREL22:
4462           {
4463             int got_r_type;
4464             long dynindx = h ? h->dynindx : -1;
4465             bfd_vma r_addend = rel->r_addend;
4466
4467             switch (r_type)
4468               {
4469               default:
4470               case R_IA64_LTOFF_TPREL22:
4471                 if (!dynamic_symbol_p)
4472                   {
4473                     if (!info->shared)
4474                       value -= elfNN_ia64_tprel_base (info);
4475                     else
4476                       {
4477                         r_addend += value - elfNN_ia64_dtprel_base (info);
4478                         dynindx = 0;
4479                       }
4480                   }
4481                 got_r_type = R_IA64_TPREL64LSB;
4482                 break;
4483               case R_IA64_LTOFF_DTPMOD22:
4484                 if (!dynamic_symbol_p && !info->shared)
4485                   value = 1;
4486                 got_r_type = R_IA64_DTPMOD64LSB;
4487                 break;
4488               case R_IA64_LTOFF_DTPREL22:
4489                 if (!dynamic_symbol_p)
4490                   value -= elfNN_ia64_dtprel_base (info);
4491                 got_r_type = R_IA64_DTPRELNNLSB;
4492                 break;
4493               }
4494             dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4495             value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
4496                                    value, got_r_type);
4497             value -= gp_val;
4498             r = elfNN_ia64_install_value (hit_addr, value, r_type);
4499           }
4500           break;
4501
4502         default:
4503           r = bfd_reloc_notsupported;
4504           break;
4505         }
4506
4507       switch (r)
4508         {
4509         case bfd_reloc_ok:
4510           break;
4511
4512         case bfd_reloc_undefined:
4513           /* This can happen for global table relative relocs if
4514              __gp is undefined.  This is a panic situation so we
4515              don't try to continue.  */
4516           (*info->callbacks->undefined_symbol)
4517             (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4518           return FALSE;
4519
4520         case bfd_reloc_notsupported:
4521           {
4522             const char *name;
4523
4524             if (h)
4525               name = h->root.root.string;
4526             else
4527               name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4528                                        sym_sec);
4529             if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4530                                               name, input_bfd,
4531                                               input_section, rel->r_offset))
4532               return FALSE;
4533             ret_val = FALSE;
4534           }
4535           break;
4536
4537         case bfd_reloc_dangerous:
4538         case bfd_reloc_outofrange:
4539         case bfd_reloc_overflow:
4540         default:
4541           {
4542             const char *name;
4543
4544             if (h)
4545               name = h->root.root.string;
4546             else
4547               name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4548                                        sym_sec);
4549
4550             switch (r_type)
4551               {
4552               case R_IA64_PCREL21B:
4553               case R_IA64_PCREL21BI:
4554               case R_IA64_PCREL21M:
4555               case R_IA64_PCREL21F:
4556                 if (is_elf_hash_table (info->hash))
4557                   {
4558                     /* Relaxtion is always performed for ELF output.
4559                        Overflow failures for those relocations mean
4560                        that the section is too big to relax.  */
4561                     (*_bfd_error_handler)
4562                       (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
4563                        input_bfd, input_section, howto->name, name,
4564                        rel->r_offset, input_section->size);
4565                     break;
4566                   }
4567               default:
4568                 if (!(*info->callbacks->reloc_overflow) (info,
4569                                                          &h->root,
4570                                                          name,
4571                                                          howto->name,
4572                                                          (bfd_vma) 0,
4573                                                          input_bfd,
4574                                                          input_section,
4575                                                          rel->r_offset))
4576                   return FALSE;
4577                 break;
4578               }
4579
4580             ret_val = FALSE;
4581           }
4582           break;
4583         }
4584     }
4585
4586   return ret_val;
4587 }
4588
4589 static bfd_boolean
4590 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4591      bfd *output_bfd;
4592      struct bfd_link_info *info;
4593      struct elf_link_hash_entry *h;
4594      Elf_Internal_Sym *sym;
4595 {
4596   struct elfNN_ia64_link_hash_table *ia64_info;
4597   struct elfNN_ia64_dyn_sym_info *dyn_i;
4598
4599   ia64_info = elfNN_ia64_hash_table (info);
4600   dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4601
4602   /* Fill in the PLT data, if required.  */
4603   if (dyn_i && dyn_i->want_plt)
4604     {
4605       Elf_Internal_Rela outrel;
4606       bfd_byte *loc;
4607       asection *plt_sec;
4608       bfd_vma plt_addr, pltoff_addr, gp_val, index;
4609
4610       gp_val = _bfd_get_gp_value (output_bfd);
4611
4612       /* Initialize the minimal PLT entry.  */
4613
4614       index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4615       plt_sec = ia64_info->plt_sec;
4616       loc = plt_sec->contents + dyn_i->plt_offset;
4617
4618       memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4619       elfNN_ia64_install_value (loc, index, R_IA64_IMM22);
4620       elfNN_ia64_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
4621
4622       plt_addr = (plt_sec->output_section->vma
4623                   + plt_sec->output_offset
4624                   + dyn_i->plt_offset);
4625       pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
4626
4627       /* Initialize the FULL PLT entry, if needed.  */
4628       if (dyn_i->want_plt2)
4629         {
4630           loc = plt_sec->contents + dyn_i->plt2_offset;
4631
4632           memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4633           elfNN_ia64_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
4634
4635           /* Mark the symbol as undefined, rather than as defined in the
4636              plt section.  Leave the value alone.  */
4637           /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4638              first place.  But perhaps elflink.c did some for us.  */
4639           if (!h->def_regular)
4640             sym->st_shndx = SHN_UNDEF;
4641         }
4642
4643       /* Create the dynamic relocation.  */
4644       outrel.r_offset = pltoff_addr;
4645       if (bfd_little_endian (output_bfd))
4646         outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4647       else
4648         outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4649       outrel.r_addend = 0;
4650
4651       /* This is fun.  In the .IA_64.pltoff section, we've got entries
4652          that correspond both to real PLT entries, and those that
4653          happened to resolve to local symbols but need to be created
4654          to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
4655          relocations for the real PLT should come at the end of the
4656          section, so that they can be indexed by plt entry at runtime.
4657
4658          We emitted all of the relocations for the non-PLT @pltoff
4659          entries during relocate_section.  So we can consider the
4660          existing sec->reloc_count to be the base of the array of
4661          PLT relocations.  */
4662
4663       loc = ia64_info->rel_pltoff_sec->contents;
4664       loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
4665               * sizeof (ElfNN_External_Rela));
4666       bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4667     }
4668
4669   /* Mark some specially defined symbols as absolute.  */
4670   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4671       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4672       || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4673     sym->st_shndx = SHN_ABS;
4674
4675   return TRUE;
4676 }
4677
4678 static bfd_boolean
4679 elfNN_ia64_finish_dynamic_sections (abfd, info)
4680      bfd *abfd;
4681      struct bfd_link_info *info;
4682 {
4683   struct elfNN_ia64_link_hash_table *ia64_info;
4684   bfd *dynobj;
4685
4686   ia64_info = elfNN_ia64_hash_table (info);
4687   dynobj = ia64_info->root.dynobj;
4688
4689   if (elf_hash_table (info)->dynamic_sections_created)
4690     {
4691       ElfNN_External_Dyn *dyncon, *dynconend;
4692       asection *sdyn, *sgotplt;
4693       bfd_vma gp_val;
4694
4695       sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4696       sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4697       BFD_ASSERT (sdyn != NULL);
4698       dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4699       dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
4700
4701       gp_val = _bfd_get_gp_value (abfd);
4702
4703       for (; dyncon < dynconend; dyncon++)
4704         {
4705           Elf_Internal_Dyn dyn;
4706
4707           bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4708
4709           switch (dyn.d_tag)
4710             {
4711             case DT_PLTGOT:
4712               dyn.d_un.d_ptr = gp_val;
4713               break;
4714
4715             case DT_PLTRELSZ:
4716               dyn.d_un.d_val = (ia64_info->minplt_entries
4717                                 * sizeof (ElfNN_External_Rela));
4718               break;
4719
4720             case DT_JMPREL:
4721               /* See the comment above in finish_dynamic_symbol.  */
4722               dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4723                                 + ia64_info->rel_pltoff_sec->output_offset
4724                                 + (ia64_info->rel_pltoff_sec->reloc_count
4725                                    * sizeof (ElfNN_External_Rela)));
4726               break;
4727
4728             case DT_IA_64_PLT_RESERVE:
4729               dyn.d_un.d_ptr = (sgotplt->output_section->vma
4730                                 + sgotplt->output_offset);
4731               break;
4732
4733             case DT_RELASZ:
4734               /* Do not have RELASZ include JMPREL.  This makes things
4735                  easier on ld.so.  This is not what the rest of BFD set up.  */
4736               dyn.d_un.d_val -= (ia64_info->minplt_entries
4737                                  * sizeof (ElfNN_External_Rela));
4738               break;
4739             }
4740
4741           bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4742         }
4743
4744       /* Initialize the PLT0 entry.  */
4745       if (ia64_info->plt_sec)
4746         {
4747           bfd_byte *loc = ia64_info->plt_sec->contents;
4748           bfd_vma pltres;
4749
4750           memcpy (loc, plt_header, PLT_HEADER_SIZE);
4751
4752           pltres = (sgotplt->output_section->vma
4753                     + sgotplt->output_offset
4754                     - gp_val);
4755
4756           elfNN_ia64_install_value (loc+1, pltres, R_IA64_GPREL22);
4757         }
4758     }
4759
4760   return TRUE;
4761 }
4762 \f
4763 /* ELF file flag handling:  */
4764
4765 /* Function to keep IA-64 specific file flags.  */
4766 static bfd_boolean
4767 elfNN_ia64_set_private_flags (abfd, flags)
4768      bfd *abfd;
4769      flagword flags;
4770 {
4771   BFD_ASSERT (!elf_flags_init (abfd)
4772               || elf_elfheader (abfd)->e_flags == flags);
4773
4774   elf_elfheader (abfd)->e_flags = flags;
4775   elf_flags_init (abfd) = TRUE;
4776   return TRUE;
4777 }
4778
4779 /* Merge backend specific data from an object file to the output
4780    object file when linking.  */
4781 static bfd_boolean
4782 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4783      bfd *ibfd, *obfd;
4784 {
4785   flagword out_flags;
4786   flagword in_flags;
4787   bfd_boolean ok = TRUE;
4788
4789   /* Don't even pretend to support mixed-format linking.  */
4790   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4791       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4792     return FALSE;
4793
4794   in_flags  = elf_elfheader (ibfd)->e_flags;
4795   out_flags = elf_elfheader (obfd)->e_flags;
4796
4797   if (! elf_flags_init (obfd))
4798     {
4799       elf_flags_init (obfd) = TRUE;
4800       elf_elfheader (obfd)->e_flags = in_flags;
4801
4802       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4803           && bfd_get_arch_info (obfd)->the_default)
4804         {
4805           return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4806                                     bfd_get_mach (ibfd));
4807         }
4808
4809       return TRUE;
4810     }
4811
4812   /* Check flag compatibility.  */
4813   if (in_flags == out_flags)
4814     return TRUE;
4815
4816   /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
4817   if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4818     elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4819
4820   if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4821     {
4822       (*_bfd_error_handler)
4823         (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
4824          ibfd);
4825
4826       bfd_set_error (bfd_error_bad_value);
4827       ok = FALSE;
4828     }
4829   if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4830     {
4831       (*_bfd_error_handler)
4832         (_("%B: linking big-endian files with little-endian files"),
4833          ibfd);
4834
4835       bfd_set_error (bfd_error_bad_value);
4836       ok = FALSE;
4837     }
4838   if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4839     {
4840       (*_bfd_error_handler)
4841         (_("%B: linking 64-bit files with 32-bit files"),
4842          ibfd);
4843
4844       bfd_set_error (bfd_error_bad_value);
4845       ok = FALSE;
4846     }
4847   if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4848     {
4849       (*_bfd_error_handler)
4850         (_("%B: linking constant-gp files with non-constant-gp files"),
4851          ibfd);
4852
4853       bfd_set_error (bfd_error_bad_value);
4854       ok = FALSE;
4855     }
4856   if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4857       != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4858     {
4859       (*_bfd_error_handler)
4860         (_("%B: linking auto-pic files with non-auto-pic files"),
4861          ibfd);
4862
4863       bfd_set_error (bfd_error_bad_value);
4864       ok = FALSE;
4865     }
4866
4867   return ok;
4868 }
4869
4870 static bfd_boolean
4871 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4872      bfd *abfd;
4873      PTR ptr;
4874 {
4875   FILE *file = (FILE *) ptr;
4876   flagword flags = elf_elfheader (abfd)->e_flags;
4877
4878   BFD_ASSERT (abfd != NULL && ptr != NULL);
4879
4880   fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4881            (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4882            (flags & EF_IA_64_EXT) ? "EXT, " : "",
4883            (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4884            (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4885            (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4886            (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4887            (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4888            (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4889
4890   _bfd_elf_print_private_bfd_data (abfd, ptr);
4891   return TRUE;
4892 }
4893
4894 static enum elf_reloc_type_class
4895 elfNN_ia64_reloc_type_class (rela)
4896      const Elf_Internal_Rela *rela;
4897 {
4898   switch ((int) ELFNN_R_TYPE (rela->r_info))
4899     {
4900     case R_IA64_REL32MSB:
4901     case R_IA64_REL32LSB:
4902     case R_IA64_REL64MSB:
4903     case R_IA64_REL64LSB:
4904       return reloc_class_relative;
4905     case R_IA64_IPLTMSB:
4906     case R_IA64_IPLTLSB:
4907       return reloc_class_plt;
4908     case R_IA64_COPY:
4909       return reloc_class_copy;
4910     default:
4911       return reloc_class_normal;
4912     }
4913 }
4914
4915 static struct bfd_elf_special_section const elfNN_ia64_special_sections[]=
4916 {
4917   { ".sbss",  5, -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4918   { ".sdata", 6, -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4919   { NULL,     0,  0, 0,            0 }
4920 };
4921
4922 static bfd_boolean
4923 elfNN_ia64_object_p (bfd *abfd)
4924 {
4925   asection *sec;
4926   asection *group, *unwi, *unw;
4927   flagword flags;
4928   const char *name;
4929   char *unwi_name, *unw_name;
4930   bfd_size_type amt;
4931
4932   if (abfd->flags & DYNAMIC)
4933     return TRUE;
4934
4935   /* Flags for fake group section.  */
4936   flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
4937            | SEC_EXCLUDE);
4938
4939   /* We add a fake section group for each .gnu.linkonce.t.* section,
4940      which isn't in a section group, and its unwind sections.  */
4941   for (sec = abfd->sections; sec != NULL; sec = sec->next)
4942     {
4943       if (elf_sec_group (sec) == NULL
4944           && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
4945               == (SEC_LINK_ONCE | SEC_CODE))
4946           && strncmp (sec->name, ".gnu.linkonce.t.", 16) == 0)
4947         {
4948           name = sec->name + 16;
4949
4950           amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
4951           unwi_name = bfd_alloc (abfd, amt);
4952           if (!unwi_name)
4953             return FALSE;
4954
4955           strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
4956           unwi = bfd_get_section_by_name (abfd, unwi_name);
4957
4958           amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
4959           unw_name = bfd_alloc (abfd, amt);
4960           if (!unw_name)
4961             return FALSE;
4962
4963           strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
4964           unw = bfd_get_section_by_name (abfd, unw_name);
4965
4966           /* We need to create a fake group section for it and its
4967              unwind sections.  */
4968           group = bfd_make_section_anyway (abfd, name);
4969           if (group == NULL
4970               || ! bfd_set_section_flags (abfd, group, flags))
4971             return FALSE;
4972
4973           /* Move the fake group section to the beginning.  */
4974           bfd_section_list_remove (abfd, group);
4975           bfd_section_list_prepend (abfd, group);
4976
4977           elf_next_in_group (group) = sec;
4978
4979           elf_group_name (sec) = name;
4980           elf_next_in_group (sec) = sec;
4981           elf_sec_group (sec) = group;
4982
4983           if (unwi)
4984             {
4985               elf_group_name (unwi) = name;
4986               elf_next_in_group (unwi) = sec;
4987               elf_next_in_group (sec) = unwi;
4988               elf_sec_group (unwi) = group;
4989             }
4990
4991            if (unw)
4992              {
4993                elf_group_name (unw) = name;
4994                if (unwi)
4995                  {
4996                    elf_next_in_group (unw) = elf_next_in_group (unwi);
4997                    elf_next_in_group (unwi) = unw;
4998                  }
4999                else
5000                  {
5001                    elf_next_in_group (unw) = sec;
5002                    elf_next_in_group (sec) = unw;
5003                  }
5004                elf_sec_group (unw) = group;
5005              }
5006
5007            /* Fake SHT_GROUP section header.  */
5008           elf_section_data (group)->this_hdr.bfd_section = group;
5009           elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
5010         }
5011     }
5012   return TRUE;
5013 }
5014
5015 static bfd_boolean
5016 elfNN_ia64_hpux_vec (const bfd_target *vec)
5017 {
5018   extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
5019   return (vec == & bfd_elfNN_ia64_hpux_big_vec);
5020 }
5021
5022 static void
5023 elfNN_hpux_post_process_headers (abfd, info)
5024         bfd *abfd;
5025         struct bfd_link_info *info ATTRIBUTE_UNUSED;
5026 {
5027   Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5028
5029   i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
5030   i_ehdrp->e_ident[EI_ABIVERSION] = 1;
5031 }
5032
5033 bfd_boolean
5034 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
5035         bfd *abfd ATTRIBUTE_UNUSED;
5036         asection *sec;
5037         int *retval;
5038 {
5039   if (bfd_is_com_section (sec))
5040     {
5041       *retval = SHN_IA_64_ANSI_COMMON;
5042       return TRUE;
5043     }
5044   return FALSE;
5045 }
5046
5047 static void
5048 elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5049                                       asymbol *asym)
5050 {
5051   elf_symbol_type *elfsym = (elf_symbol_type *) asym;;
5052
5053   switch (elfsym->internal_elf_sym.st_shndx)
5054     {
5055     case SHN_IA_64_ANSI_COMMON:
5056       asym->section = bfd_com_section_ptr;
5057       asym->value = elfsym->internal_elf_sym.st_size;
5058       asym->flags &= ~BSF_GLOBAL;
5059       break;
5060     }
5061 }
5062
5063 \f
5064 #define TARGET_LITTLE_SYM               bfd_elfNN_ia64_little_vec
5065 #define TARGET_LITTLE_NAME              "elfNN-ia64-little"
5066 #define TARGET_BIG_SYM                  bfd_elfNN_ia64_big_vec
5067 #define TARGET_BIG_NAME                 "elfNN-ia64-big"
5068 #define ELF_ARCH                        bfd_arch_ia64
5069 #define ELF_MACHINE_CODE                EM_IA_64
5070 #define ELF_MACHINE_ALT1                1999    /* EAS2.3 */
5071 #define ELF_MACHINE_ALT2                1998    /* EAS2.2 */
5072 #define ELF_MAXPAGESIZE                 0x10000 /* 64KB */
5073
5074 #define elf_backend_section_from_shdr \
5075         elfNN_ia64_section_from_shdr
5076 #define elf_backend_section_flags \
5077         elfNN_ia64_section_flags
5078 #define elf_backend_fake_sections \
5079         elfNN_ia64_fake_sections
5080 #define elf_backend_final_write_processing \
5081         elfNN_ia64_final_write_processing
5082 #define elf_backend_add_symbol_hook \
5083         elfNN_ia64_add_symbol_hook
5084 #define elf_backend_additional_program_headers \
5085         elfNN_ia64_additional_program_headers
5086 #define elf_backend_modify_segment_map \
5087         elfNN_ia64_modify_segment_map
5088 #define elf_info_to_howto \
5089         elfNN_ia64_info_to_howto
5090
5091 #define bfd_elfNN_bfd_reloc_type_lookup \
5092         elfNN_ia64_reloc_type_lookup
5093 #define bfd_elfNN_bfd_is_local_label_name \
5094         elfNN_ia64_is_local_label_name
5095 #define bfd_elfNN_bfd_relax_section \
5096         elfNN_ia64_relax_section
5097
5098 #define elf_backend_object_p \
5099         elfNN_ia64_object_p
5100
5101 /* Stuff for the BFD linker: */
5102 #define bfd_elfNN_bfd_link_hash_table_create \
5103         elfNN_ia64_hash_table_create
5104 #define bfd_elfNN_bfd_link_hash_table_free \
5105         elfNN_ia64_hash_table_free
5106 #define elf_backend_create_dynamic_sections \
5107         elfNN_ia64_create_dynamic_sections
5108 #define elf_backend_check_relocs \
5109         elfNN_ia64_check_relocs
5110 #define elf_backend_adjust_dynamic_symbol \
5111         elfNN_ia64_adjust_dynamic_symbol
5112 #define elf_backend_size_dynamic_sections \
5113         elfNN_ia64_size_dynamic_sections
5114 #define elf_backend_relocate_section \
5115         elfNN_ia64_relocate_section
5116 #define elf_backend_finish_dynamic_symbol \
5117         elfNN_ia64_finish_dynamic_symbol
5118 #define elf_backend_finish_dynamic_sections \
5119         elfNN_ia64_finish_dynamic_sections
5120 #define bfd_elfNN_bfd_final_link \
5121         elfNN_ia64_final_link
5122
5123 #define bfd_elfNN_bfd_merge_private_bfd_data \
5124         elfNN_ia64_merge_private_bfd_data
5125 #define bfd_elfNN_bfd_set_private_flags \
5126         elfNN_ia64_set_private_flags
5127 #define bfd_elfNN_bfd_print_private_bfd_data \
5128         elfNN_ia64_print_private_bfd_data
5129
5130 #define elf_backend_plt_readonly        1
5131 #define elf_backend_want_plt_sym        0
5132 #define elf_backend_plt_alignment       5
5133 #define elf_backend_got_header_size     0
5134 #define elf_backend_want_got_plt        1
5135 #define elf_backend_may_use_rel_p       1
5136 #define elf_backend_may_use_rela_p      1
5137 #define elf_backend_default_use_rela_p  1
5138 #define elf_backend_want_dynbss         0
5139 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5140 #define elf_backend_hide_symbol         elfNN_ia64_hash_hide_symbol
5141 #define elf_backend_reloc_type_class    elfNN_ia64_reloc_type_class
5142 #define elf_backend_rela_normal         1
5143 #define elf_backend_special_sections    elfNN_ia64_special_sections
5144
5145 /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5146    SHF_LINK_ORDER. But it doesn't set theh sh_link or sh_info fields.
5147    We don't want to flood users with so many error messages. We turn
5148    off the warning for now. It will be turned on later when the Intel
5149    compiler is fixed.   */
5150 #define elf_backend_link_order_error_handler NULL
5151
5152 #include "elfNN-target.h"
5153
5154 /* HPUX-specific vectors.  */
5155
5156 #undef  TARGET_LITTLE_SYM
5157 #undef  TARGET_LITTLE_NAME
5158 #undef  TARGET_BIG_SYM
5159 #define TARGET_BIG_SYM                  bfd_elfNN_ia64_hpux_big_vec
5160 #undef  TARGET_BIG_NAME
5161 #define TARGET_BIG_NAME                 "elfNN-ia64-hpux-big"
5162
5163 /* These are HP-UX specific functions.  */
5164
5165 #undef  elf_backend_post_process_headers
5166 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5167
5168 #undef  elf_backend_section_from_bfd_section
5169 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5170
5171 #undef elf_backend_symbol_processing
5172 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5173
5174 #undef  elf_backend_want_p_paddr_set_to_zero
5175 #define elf_backend_want_p_paddr_set_to_zero 1
5176
5177 #undef  ELF_MAXPAGESIZE
5178 #define ELF_MAXPAGESIZE                 0x1000  /* 1K */
5179
5180 #undef  elfNN_bed
5181 #define elfNN_bed elfNN_ia64_hpux_bed
5182
5183 #include "elfNN-target.h"
5184
5185 #undef  elf_backend_want_p_paddr_set_to_zero