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