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