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