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