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