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