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