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