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