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