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