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