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