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