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