Add missing entries for the last checkin.
[deliverable/binutils-gdb.git] / bfd / elfxx-ia64.c
CommitLineData
800eeca4 1/* IA-64 support for 64-bit ELF
b3dfd7fe 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
800eeca4
JW
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5e8d7549 5 This file is part of BFD, the Binary File Descriptor library.
800eeca4 6
5e8d7549
NC
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
800eeca4 11
5e8d7549
NC
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
800eeca4 16
5e8d7549
NC
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
800eeca4
JW
20
21#include "bfd.h"
22#include "sysdep.h"
23#include "libbfd.h"
24#include "elf-bfd.h"
25#include "opcode/ia64.h"
26#include "elf/ia64.h"
27
5e8d7549 28/* THE RULES for all the stuff the linker creates --
b34976b6 29
5e8d7549
NC
30 GOT Entries created in response to LTOFF or LTOFF_FPTR
31 relocations. Dynamic relocs created for dynamic
32 symbols in an application; REL relocs for locals
33 in a shared library.
b34976b6 34
5e8d7549
NC
35 FPTR The canonical function descriptor. Created for local
36 symbols in applications. Descriptors for dynamic symbols
37 and local symbols in shared libraries are created by
38 ld.so. Thus there are no dynamic relocs against these
39 objects. The FPTR relocs for such _are_ passed through
40 to the dynamic relocation tables.
b34976b6 41
5e8d7549
NC
42 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
43 Requires the creation of a PLTOFF entry. This does not
44 require any dynamic relocations.
b34976b6 45
5e8d7549
NC
46 PLTOFF Created by PLTOFF relocations. For local symbols, this
47 is an alternate function descriptor, and in shared libraries
48 requires two REL relocations. Note that this cannot be
49 transformed into an FPTR relocation, since it must be in
50 range of the GP. For dynamic symbols, this is a function
51 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
b34976b6 52
5e8d7549
NC
53 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
54 does not reqire dynamic relocations. */
800eeca4 55
800eeca4
JW
56#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
57
58typedef struct bfd_hash_entry *(*new_hash_entry_func)
59 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
60
61/* In dynamically (linker-) created sections, we generally need to keep track
62 of the place a symbol or expression got allocated to. This is done via hash
63 tables that store entries of the following type. */
64
bbe66d08 65struct elfNN_ia64_dyn_sym_info
800eeca4
JW
66{
67 /* The addend for which this entry is relevant. */
68 bfd_vma addend;
69
70 /* Next addend in the list. */
bbe66d08 71 struct elfNN_ia64_dyn_sym_info *next;
800eeca4
JW
72
73 bfd_vma got_offset;
74 bfd_vma fptr_offset;
75 bfd_vma pltoff_offset;
76 bfd_vma plt_offset;
77 bfd_vma plt2_offset;
13ae64f3
JJ
78 bfd_vma tprel_offset;
79 bfd_vma dtpmod_offset;
80 bfd_vma dtprel_offset;
800eeca4
JW
81
82 /* The symbol table entry, if any, that this was derrived from. */
83 struct elf_link_hash_entry *h;
3e932841 84
800eeca4
JW
85 /* Used to count non-got, non-plt relocations for delayed sizing
86 of relocation sections. */
bbe66d08 87 struct elfNN_ia64_dyn_reloc_entry
800eeca4 88 {
bbe66d08 89 struct elfNN_ia64_dyn_reloc_entry *next;
800eeca4
JW
90 asection *srel;
91 int type;
92 int count;
93 } *reloc_entries;
94
b34976b6 95 /* TRUE when the section contents have been updated. */
800eeca4
JW
96 unsigned got_done : 1;
97 unsigned fptr_done : 1;
98 unsigned pltoff_done : 1;
13ae64f3
JJ
99 unsigned tprel_done : 1;
100 unsigned dtpmod_done : 1;
101 unsigned dtprel_done : 1;
800eeca4 102
b34976b6 103 /* TRUE for the different kinds of linker data we want created. */
800eeca4 104 unsigned want_got : 1;
2c4c2bc0 105 unsigned want_gotx : 1;
800eeca4
JW
106 unsigned want_fptr : 1;
107 unsigned want_ltoff_fptr : 1;
108 unsigned want_plt : 1;
109 unsigned want_plt2 : 1;
110 unsigned want_pltoff : 1;
13ae64f3
JJ
111 unsigned want_tprel : 1;
112 unsigned want_dtpmod : 1;
113 unsigned want_dtprel : 1;
800eeca4
JW
114};
115
bbe66d08 116struct elfNN_ia64_local_hash_entry
800eeca4
JW
117{
118 struct bfd_hash_entry root;
bbe66d08 119 struct elfNN_ia64_dyn_sym_info *info;
f7460f5f 120
b34976b6 121 /* TRUE if this hash entry's addends was translated for
f7460f5f
JJ
122 SHF_MERGE optimization. */
123 unsigned sec_merge_done : 1;
800eeca4
JW
124};
125
bbe66d08 126struct elfNN_ia64_local_hash_table
800eeca4
JW
127{
128 struct bfd_hash_table root;
129 /* No additional fields for now. */
130};
131
bbe66d08 132struct elfNN_ia64_link_hash_entry
800eeca4
JW
133{
134 struct elf_link_hash_entry root;
bbe66d08 135 struct elfNN_ia64_dyn_sym_info *info;
800eeca4
JW
136};
137
bbe66d08 138struct elfNN_ia64_link_hash_table
800eeca4 139{
5e8d7549 140 /* The main hash table. */
800eeca4
JW
141 struct elf_link_hash_table root;
142
143 asection *got_sec; /* the linkage table section (or NULL) */
144 asection *rel_got_sec; /* dynamic relocation section for same */
145 asection *fptr_sec; /* function descriptor table (or NULL) */
146 asection *plt_sec; /* the primary plt section (or NULL) */
147 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
148 asection *rel_pltoff_sec; /* dynamic relocation section for same */
149
150 bfd_size_type minplt_entries; /* number of minplt entries */
db6751f2 151 unsigned reltext : 1; /* are there relocs against readonly sections? */
b3dfd7fe
JJ
152 unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
153 bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry */
800eeca4 154
bbe66d08 155 struct elfNN_ia64_local_hash_table loc_hash_table;
800eeca4
JW
156};
157
2c4c2bc0
RH
158struct elfNN_ia64_allocate_data
159{
160 struct bfd_link_info *info;
161 bfd_size_type ofs;
162};
163
bbe66d08
JW
164#define elfNN_ia64_hash_table(p) \
165 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
800eeca4 166
bbe66d08 167static bfd_reloc_status_type elfNN_ia64_reloc
800eeca4
JW
168 PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
169 asection *input_section, bfd *output_bfd, char **error_message));
170static reloc_howto_type * lookup_howto
171 PARAMS ((unsigned int rtype));
bbe66d08 172static reloc_howto_type *elfNN_ia64_reloc_type_lookup
800eeca4 173 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
bbe66d08 174static void elfNN_ia64_info_to_howto
947216bf 175 PARAMS ((bfd *abfd, arelent *bfd_reloc, Elf_Internal_Rela *elf_reloc));
b34976b6 176static bfd_boolean elfNN_ia64_relax_section
748abff6 177 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
b34976b6 178 bfd_boolean *again));
2c4c2bc0
RH
179static void elfNN_ia64_relax_ldxmov
180 PARAMS((bfd *abfd, bfd_byte *contents, bfd_vma off));
b34976b6 181static bfd_boolean is_unwind_section_name
d9cf1b54 182 PARAMS ((bfd *abfd, const char *));
b34976b6 183static bfd_boolean elfNN_ia64_section_from_shdr
947216bf 184 PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
b34976b6 185static bfd_boolean elfNN_ia64_section_flags
947216bf 186 PARAMS ((flagword *, Elf_Internal_Shdr *));
b34976b6 187static bfd_boolean elfNN_ia64_fake_sections
947216bf 188 PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec));
81545d45 189static void elfNN_ia64_final_write_processing
b34976b6
AM
190 PARAMS ((bfd *abfd, bfd_boolean linker));
191static bfd_boolean elfNN_ia64_add_symbol_hook
800eeca4
JW
192 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
193 const char **namep, flagword *flagsp, asection **secp,
194 bfd_vma *valp));
b34976b6 195static bfd_boolean elfNN_ia64_aix_vec
7b6dab7f 196 PARAMS ((const bfd_target *vec));
b34976b6 197static bfd_boolean elfNN_ia64_aix_add_symbol_hook
7b6dab7f
TW
198 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
199 const char **namep, flagword *flagsp, asection **secp,
200 bfd_vma *valp));
b34976b6 201static bfd_boolean elfNN_ia64_aix_link_add_symbols
7b6dab7f 202 PARAMS ((bfd *abfd, struct bfd_link_info *info));
bbe66d08 203static int elfNN_ia64_additional_program_headers
800eeca4 204 PARAMS ((bfd *abfd));
b34976b6 205static bfd_boolean elfNN_ia64_modify_segment_map
cea4409c 206 PARAMS ((bfd *));
b34976b6 207static bfd_boolean elfNN_ia64_is_local_label_name
800eeca4 208 PARAMS ((bfd *abfd, const char *name));
b34976b6 209static bfd_boolean elfNN_ia64_dynamic_symbol_p
800eeca4 210 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
b34976b6 211static bfd_boolean elfNN_ia64_local_hash_table_init
bbe66d08 212 PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
800eeca4 213 new_hash_entry_func new));
bbe66d08 214static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
800eeca4
JW
215 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
216 const char *string));
bbe66d08 217static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
800eeca4
JW
218 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
219 const char *string));
cea4409c 220static void elfNN_ia64_hash_copy_indirect
b48fa14c
AM
221 PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
222 struct elf_link_hash_entry *));
cea4409c 223static void elfNN_ia64_hash_hide_symbol
b34976b6 224 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
bbe66d08 225static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
800eeca4 226 PARAMS ((bfd *abfd));
bbe66d08
JW
227static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
228 PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
b34976b6
AM
229 bfd_boolean create, bfd_boolean copy));
230static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
cea4409c 231 PARAMS ((struct bfd_hash_entry *, PTR));
b34976b6 232static bfd_boolean elfNN_ia64_local_dyn_sym_thunk
cea4409c 233 PARAMS ((struct bfd_hash_entry *, PTR));
bbe66d08
JW
234static void elfNN_ia64_dyn_sym_traverse
235 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
b34976b6 236 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
800eeca4 237 PTR info));
b34976b6 238static bfd_boolean elfNN_ia64_create_dynamic_sections
800eeca4 239 PARAMS ((bfd *abfd, struct bfd_link_info *info));
f7460f5f
JJ
240static struct elfNN_ia64_local_hash_entry * get_local_sym_hash
241 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
b34976b6 242 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
bbe66d08
JW
243static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
244 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
800eeca4 245 struct elf_link_hash_entry *h,
b34976b6 246 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
800eeca4
JW
247static asection *get_got
248 PARAMS ((bfd *abfd, struct bfd_link_info *info,
bbe66d08 249 struct elfNN_ia64_link_hash_table *ia64_info));
800eeca4
JW
250static asection *get_fptr
251 PARAMS ((bfd *abfd, struct bfd_link_info *info,
bbe66d08 252 struct elfNN_ia64_link_hash_table *ia64_info));
800eeca4
JW
253static asection *get_pltoff
254 PARAMS ((bfd *abfd, struct bfd_link_info *info,
bbe66d08 255 struct elfNN_ia64_link_hash_table *ia64_info));
800eeca4 256static asection *get_reloc_section
bbe66d08 257 PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
b34976b6
AM
258 asection *sec, bfd_boolean create));
259static bfd_boolean count_dyn_reloc
bbe66d08 260 PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
800eeca4 261 asection *srel, int type));
b34976b6 262static bfd_boolean elfNN_ia64_check_relocs
800eeca4
JW
263 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
264 const Elf_Internal_Rela *relocs));
b34976b6 265static bfd_boolean elfNN_ia64_adjust_dynamic_symbol
800eeca4 266 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
dc810e39 267static long global_sym_index
800eeca4 268 PARAMS ((struct elf_link_hash_entry *h));
b34976b6 269static bfd_boolean allocate_fptr
bbe66d08 270 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
b34976b6 271static bfd_boolean allocate_global_data_got
bbe66d08 272 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
b34976b6 273static bfd_boolean allocate_global_fptr_got
bbe66d08 274 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
b34976b6 275static bfd_boolean allocate_local_got
bbe66d08 276 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
b34976b6 277static bfd_boolean allocate_pltoff_entries
bbe66d08 278 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
b34976b6 279static bfd_boolean allocate_plt_entries
bbe66d08 280 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
b34976b6 281static bfd_boolean allocate_plt2_entries
bbe66d08 282 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
b34976b6 283static bfd_boolean allocate_dynrel_entries
bbe66d08 284 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
b34976b6 285static bfd_boolean elfNN_ia64_size_dynamic_sections
800eeca4 286 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
bbe66d08 287static bfd_reloc_status_type elfNN_ia64_install_value
800eeca4 288 PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
bbe66d08 289static void elfNN_ia64_install_dyn_reloc
800eeca4
JW
290 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
291 asection *srel, bfd_vma offset, unsigned int type,
292 long dynindx, bfd_vma addend));
293static bfd_vma set_got_entry
294 PARAMS ((bfd *abfd, struct bfd_link_info *info,
bbe66d08 295 struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
800eeca4
JW
296 bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
297static bfd_vma set_fptr_entry
298 PARAMS ((bfd *abfd, struct bfd_link_info *info,
bbe66d08 299 struct elfNN_ia64_dyn_sym_info *dyn_i,
800eeca4
JW
300 bfd_vma value));
301static bfd_vma set_pltoff_entry
302 PARAMS ((bfd *abfd, struct bfd_link_info *info,
bbe66d08 303 struct elfNN_ia64_dyn_sym_info *dyn_i,
b34976b6 304 bfd_vma value, bfd_boolean));
13ae64f3
JJ
305static bfd_vma elfNN_ia64_tprel_base
306 PARAMS ((struct bfd_link_info *info));
307static bfd_vma elfNN_ia64_dtprel_base
308 PARAMS ((struct bfd_link_info *info));
cea4409c
AM
309static int elfNN_ia64_unwind_entry_compare
310 PARAMS ((const PTR, const PTR));
2c4c2bc0
RH
311static bfd_boolean elfNN_ia64_choose_gp
312 PARAMS ((bfd *abfd, struct bfd_link_info *info));
b34976b6 313static bfd_boolean elfNN_ia64_final_link
800eeca4 314 PARAMS ((bfd *abfd, struct bfd_link_info *info));
b34976b6 315static bfd_boolean elfNN_ia64_relocate_section
800eeca4
JW
316 PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
317 asection *input_section, bfd_byte *contents,
318 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
319 asection **local_sections));
b34976b6 320static bfd_boolean elfNN_ia64_finish_dynamic_symbol
800eeca4
JW
321 PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
322 struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
b34976b6 323static bfd_boolean elfNN_ia64_finish_dynamic_sections
800eeca4 324 PARAMS ((bfd *abfd, struct bfd_link_info *info));
b34976b6 325static bfd_boolean elfNN_ia64_set_private_flags
800eeca4 326 PARAMS ((bfd *abfd, flagword flags));
b34976b6 327static bfd_boolean elfNN_ia64_merge_private_bfd_data
800eeca4 328 PARAMS ((bfd *ibfd, bfd *obfd));
b34976b6 329static bfd_boolean elfNN_ia64_print_private_bfd_data
800eeca4 330 PARAMS ((bfd *abfd, PTR ptr));
db6751f2 331static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
f51e552e 332 PARAMS ((const Elf_Internal_Rela *));
b34976b6 333static bfd_boolean elfNN_ia64_hpux_vec
d9cf1b54 334 PARAMS ((const bfd_target *vec));
fcf12726
AM
335static void elfNN_hpux_post_process_headers
336 PARAMS ((bfd *abfd, struct bfd_link_info *info));
b34976b6 337bfd_boolean elfNN_hpux_backend_section_from_bfd_section
af746e92 338 PARAMS ((bfd *abfd, asection *sec, int *retval));
800eeca4 339\f
5e8d7549 340/* ia64-specific relocation. */
800eeca4
JW
341
342/* Perform a relocation. Not much to do here as all the hard work is
bbe66d08 343 done in elfNN_ia64_final_link_relocate. */
800eeca4 344static bfd_reloc_status_type
bbe66d08 345elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
800eeca4 346 output_bfd, error_message)
64bf6ae6 347 bfd *abfd ATTRIBUTE_UNUSED;
800eeca4 348 arelent *reloc;
64bf6ae6
JW
349 asymbol *sym ATTRIBUTE_UNUSED;
350 PTR data ATTRIBUTE_UNUSED;
800eeca4
JW
351 asection *input_section;
352 bfd *output_bfd;
353 char **error_message;
354{
355 if (output_bfd)
356 {
357 reloc->address += input_section->output_offset;
358 return bfd_reloc_ok;
359 }
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. */
bbe66d08 723 internal_relocs = (_bfd_elfNN_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 {
1469 if (! bfd_elfNN_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)
1795 dyn_i->want_plt2 = 0;
1796}
1797
1798/* Create the derived linker hash table. The IA-64 ELF port uses this
1799 derived hash table to keep information specific to the IA-64 ElF
1800 linker (without using static variables). */
1801
1802static struct bfd_link_hash_table*
bbe66d08 1803elfNN_ia64_hash_table_create (abfd)
800eeca4
JW
1804 bfd *abfd;
1805{
bbe66d08 1806 struct elfNN_ia64_link_hash_table *ret;
800eeca4 1807
6e84a906 1808 ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
800eeca4
JW
1809 if (!ret)
1810 return 0;
6e84a906 1811
800eeca4 1812 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
bbe66d08 1813 elfNN_ia64_new_elf_hash_entry))
800eeca4 1814 {
6e84a906 1815 free (ret);
800eeca4
JW
1816 return 0;
1817 }
1818
bbe66d08
JW
1819 if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1820 elfNN_ia64_new_loc_hash_entry))
6e84a906
DJ
1821 {
1822 free (ret);
1823 return 0;
1824 }
1825
800eeca4
JW
1826 return &ret->root.root;
1827}
1828
1829/* Look up an entry in a Alpha ELF linker hash table. */
1830
bbe66d08
JW
1831static INLINE struct elfNN_ia64_local_hash_entry *
1832elfNN_ia64_local_hash_lookup(table, string, create, copy)
1833 struct elfNN_ia64_local_hash_table *table;
800eeca4 1834 const char *string;
b34976b6 1835 bfd_boolean create, copy;
800eeca4 1836{
bbe66d08 1837 return ((struct elfNN_ia64_local_hash_entry *)
800eeca4
JW
1838 bfd_hash_lookup (&table->root, string, create, copy));
1839}
1840
1841/* Traverse both local and global hash tables. */
1842
bbe66d08 1843struct elfNN_ia64_dyn_sym_traverse_data
800eeca4 1844{
b34976b6 1845 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
800eeca4
JW
1846 PTR data;
1847};
1848
b34976b6 1849static bfd_boolean
bbe66d08 1850elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
800eeca4
JW
1851 struct bfd_hash_entry *xentry;
1852 PTR xdata;
1853{
bbe66d08
JW
1854 struct elfNN_ia64_link_hash_entry *entry
1855 = (struct elfNN_ia64_link_hash_entry *) xentry;
1856 struct elfNN_ia64_dyn_sym_traverse_data *data
1857 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1858 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4 1859
e92d460e
AM
1860 if (entry->root.root.type == bfd_link_hash_warning)
1861 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1862
800eeca4
JW
1863 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1864 if (! (*data->func) (dyn_i, data->data))
b34976b6
AM
1865 return FALSE;
1866 return TRUE;
800eeca4
JW
1867}
1868
b34976b6 1869static bfd_boolean
bbe66d08 1870elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
800eeca4
JW
1871 struct bfd_hash_entry *xentry;
1872 PTR xdata;
1873{
bbe66d08
JW
1874 struct elfNN_ia64_local_hash_entry *entry
1875 = (struct elfNN_ia64_local_hash_entry *) xentry;
1876 struct elfNN_ia64_dyn_sym_traverse_data *data
1877 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1878 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
1879
1880 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1881 if (! (*data->func) (dyn_i, data->data))
b34976b6
AM
1882 return FALSE;
1883 return TRUE;
800eeca4
JW
1884}
1885
1886static void
bbe66d08
JW
1887elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1888 struct elfNN_ia64_link_hash_table *ia64_info;
b34976b6 1889 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
800eeca4
JW
1890 PTR data;
1891{
bbe66d08 1892 struct elfNN_ia64_dyn_sym_traverse_data xdata;
800eeca4
JW
1893
1894 xdata.func = func;
1895 xdata.data = data;
1896
1897 elf_link_hash_traverse (&ia64_info->root,
bbe66d08 1898 elfNN_ia64_global_dyn_sym_thunk, &xdata);
800eeca4 1899 bfd_hash_traverse (&ia64_info->loc_hash_table.root,
bbe66d08 1900 elfNN_ia64_local_dyn_sym_thunk, &xdata);
800eeca4
JW
1901}
1902\f
b34976b6 1903static bfd_boolean
bbe66d08 1904elfNN_ia64_create_dynamic_sections (abfd, info)
800eeca4
JW
1905 bfd *abfd;
1906 struct bfd_link_info *info;
1907{
bbe66d08 1908 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
1909 asection *s;
1910
1911 if (! _bfd_elf_create_dynamic_sections (abfd, info))
b34976b6 1912 return FALSE;
800eeca4 1913
bbe66d08 1914 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
1915
1916 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1917 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1918
1919 {
1920 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1921 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1922 }
1923
1924 if (!get_pltoff (abfd, info, ia64_info))
b34976b6 1925 return FALSE;
800eeca4
JW
1926
1927 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1928 if (s == NULL
1929 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1930 | SEC_HAS_CONTENTS
1931 | SEC_IN_MEMORY
1932 | SEC_LINKER_CREATED
1933 | SEC_READONLY))
1934 || !bfd_set_section_alignment (abfd, s, 3))
b34976b6 1935 return FALSE;
800eeca4
JW
1936 ia64_info->rel_pltoff_sec = s;
1937
1938 s = bfd_make_section(abfd, ".rela.got");
1939 if (s == NULL
1940 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1941 | SEC_HAS_CONTENTS
1942 | SEC_IN_MEMORY
1943 | SEC_LINKER_CREATED
1944 | SEC_READONLY))
1945 || !bfd_set_section_alignment (abfd, s, 3))
b34976b6 1946 return FALSE;
800eeca4
JW
1947 ia64_info->rel_got_sec = s;
1948
b34976b6 1949 return TRUE;
800eeca4
JW
1950}
1951
f7460f5f
JJ
1952/* Find and/or create a hash entry for local symbol. */
1953static struct elfNN_ia64_local_hash_entry *
1954get_local_sym_hash (ia64_info, abfd, rel, create)
1955 struct elfNN_ia64_link_hash_table *ia64_info;
1956 bfd *abfd;
1957 const Elf_Internal_Rela *rel;
b34976b6 1958 bfd_boolean create;
f7460f5f 1959{
fcf12726 1960 struct elfNN_ia64_local_hash_entry *ret;
d48770d4
L
1961 asection *sec = abfd->sections;
1962 char addr_name [34];
1963
1964 BFD_ASSERT ((sizeof (sec->id)*2 + 1 + sizeof (unsigned long)*2 + 1) <= 34);
1965 BFD_ASSERT (sec);
f7460f5f
JJ
1966
1967 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1968 name describes what was once anonymous memory. */
1969
d48770d4
L
1970 sprintf (addr_name, "%x:%lx",
1971 sec->id, (unsigned long) ELFNN_R_SYM (rel->r_info));
f7460f5f
JJ
1972
1973 /* Collect the canonical entry data for this address. */
fcf12726
AM
1974 ret = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1975 addr_name, create, create);
fcf12726 1976 return ret;
f7460f5f
JJ
1977}
1978
800eeca4
JW
1979/* Find and/or create a descriptor for dynamic symbol info. This will
1980 vary based on global or local symbol, and the addend to the reloc. */
1981
bbe66d08 1982static struct elfNN_ia64_dyn_sym_info *
800eeca4 1983get_dyn_sym_info (ia64_info, h, abfd, rel, create)
bbe66d08 1984 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
1985 struct elf_link_hash_entry *h;
1986 bfd *abfd;
1987 const Elf_Internal_Rela *rel;
b34976b6 1988 bfd_boolean create;
800eeca4 1989{
bbe66d08
JW
1990 struct elfNN_ia64_dyn_sym_info **pp;
1991 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4 1992 bfd_vma addend = rel ? rel->r_addend : 0;
3e932841 1993
800eeca4 1994 if (h)
bbe66d08 1995 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
800eeca4
JW
1996 else
1997 {
bbe66d08 1998 struct elfNN_ia64_local_hash_entry *loc_h;
800eeca4 1999
f7460f5f 2000 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
f86b235a
RH
2001 if (!loc_h)
2002 {
2003 BFD_ASSERT (!create);
2004 return NULL;
2005 }
800eeca4
JW
2006
2007 pp = &loc_h->info;
3e932841 2008 }
800eeca4
JW
2009
2010 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
2011 pp = &dyn_i->next;
2012
2013 if (dyn_i == NULL && create)
2014 {
dc810e39
AM
2015 dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
2016 bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
800eeca4
JW
2017 *pp = dyn_i;
2018 dyn_i->addend = addend;
2019 }
2020
2021 return dyn_i;
2022}
2023
2024static asection *
2025get_got (abfd, info, ia64_info)
2026 bfd *abfd;
2027 struct bfd_link_info *info;
bbe66d08 2028 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4 2029{
64bf6ae6 2030 asection *got;
800eeca4
JW
2031 bfd *dynobj;
2032
2033 got = ia64_info->got_sec;
2034 if (!got)
2035 {
2036 flagword flags;
2037
2038 dynobj = ia64_info->root.dynobj;
2039 if (!dynobj)
2040 ia64_info->root.dynobj = dynobj = abfd;
2041 if (!_bfd_elf_create_got_section (dynobj, info))
2042 return 0;
2043
2044 got = bfd_get_section_by_name (dynobj, ".got");
2045 BFD_ASSERT (got);
2046 ia64_info->got_sec = got;
2047
2048 flags = bfd_get_section_flags (abfd, got);
2049 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2050 }
2051
2052 return got;
2053}
2054
2055/* Create function descriptor section (.opd). This section is called .opd
2056 because it contains "official prodecure descriptors". The "official"
2057 refers to the fact that these descriptors are used when taking the address
2058 of a procedure, thus ensuring a unique address for each procedure. */
2059
2060static asection *
2061get_fptr (abfd, info, ia64_info)
2062 bfd *abfd;
64bf6ae6 2063 struct bfd_link_info *info ATTRIBUTE_UNUSED;
bbe66d08 2064 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
2065{
2066 asection *fptr;
2067 bfd *dynobj;
2068
2069 fptr = ia64_info->fptr_sec;
2070 if (!fptr)
2071 {
2072 dynobj = ia64_info->root.dynobj;
2073 if (!dynobj)
2074 ia64_info->root.dynobj = dynobj = abfd;
2075
2076 fptr = bfd_make_section (dynobj, ".opd");
2077 if (!fptr
2078 || !bfd_set_section_flags (dynobj, fptr,
2079 (SEC_ALLOC
2080 | SEC_LOAD
2081 | SEC_HAS_CONTENTS
2082 | SEC_IN_MEMORY
2083 | SEC_READONLY
2084 | SEC_LINKER_CREATED))
2085 || !bfd_set_section_alignment (abfd, fptr, 4))
2086 {
2087 BFD_ASSERT (0);
2088 return NULL;
2089 }
2090
2091 ia64_info->fptr_sec = fptr;
2092 }
2093
2094 return fptr;
2095}
2096
2097static asection *
2098get_pltoff (abfd, info, ia64_info)
2099 bfd *abfd;
64bf6ae6 2100 struct bfd_link_info *info ATTRIBUTE_UNUSED;
bbe66d08 2101 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
2102{
2103 asection *pltoff;
2104 bfd *dynobj;
2105
2106 pltoff = ia64_info->pltoff_sec;
2107 if (!pltoff)
2108 {
2109 dynobj = ia64_info->root.dynobj;
2110 if (!dynobj)
2111 ia64_info->root.dynobj = dynobj = abfd;
2112
2113 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
2114 if (!pltoff
2115 || !bfd_set_section_flags (dynobj, pltoff,
2116 (SEC_ALLOC
2117 | SEC_LOAD
2118 | SEC_HAS_CONTENTS
2119 | SEC_IN_MEMORY
2120 | SEC_SMALL_DATA
2121 | SEC_LINKER_CREATED))
2122 || !bfd_set_section_alignment (abfd, pltoff, 4))
2123 {
2124 BFD_ASSERT (0);
2125 return NULL;
2126 }
2127
2128 ia64_info->pltoff_sec = pltoff;
2129 }
2130
2131 return pltoff;
2132}
2133
2134static asection *
2135get_reloc_section (abfd, ia64_info, sec, create)
2136 bfd *abfd;
bbe66d08 2137 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4 2138 asection *sec;
b34976b6 2139 bfd_boolean create;
800eeca4
JW
2140{
2141 const char *srel_name;
2142 asection *srel;
2143 bfd *dynobj;
2144
2145 srel_name = (bfd_elf_string_from_elf_section
2146 (abfd, elf_elfheader(abfd)->e_shstrndx,
2147 elf_section_data(sec)->rel_hdr.sh_name));
2148 if (srel_name == NULL)
2149 return NULL;
2150
2151 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2152 && strcmp (bfd_get_section_name (abfd, sec),
2153 srel_name+5) == 0)
2154 || (strncmp (srel_name, ".rel", 4) == 0
2155 && strcmp (bfd_get_section_name (abfd, sec),
2156 srel_name+4) == 0));
2157
2158 dynobj = ia64_info->root.dynobj;
2159 if (!dynobj)
2160 ia64_info->root.dynobj = dynobj = abfd;
2161
2162 srel = bfd_get_section_by_name (dynobj, srel_name);
2163 if (srel == NULL && create)
2164 {
2165 srel = bfd_make_section (dynobj, srel_name);
2166 if (srel == NULL
2167 || !bfd_set_section_flags (dynobj, srel,
2168 (SEC_ALLOC
2169 | SEC_LOAD
2170 | SEC_HAS_CONTENTS
2171 | SEC_IN_MEMORY
2172 | SEC_LINKER_CREATED
2173 | SEC_READONLY))
2174 || !bfd_set_section_alignment (dynobj, srel, 3))
2175 return NULL;
2176 }
2177
db6751f2
JJ
2178 if (sec->flags & SEC_READONLY)
2179 ia64_info->reltext = 1;
2180
800eeca4
JW
2181 return srel;
2182}
2183
b34976b6 2184static bfd_boolean
800eeca4
JW
2185count_dyn_reloc (abfd, dyn_i, srel, type)
2186 bfd *abfd;
bbe66d08 2187 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
2188 asection *srel;
2189 int type;
2190{
bbe66d08 2191 struct elfNN_ia64_dyn_reloc_entry *rent;
800eeca4
JW
2192
2193 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2194 if (rent->srel == srel && rent->type == type)
2195 break;
2196
2197 if (!rent)
2198 {
dc810e39
AM
2199 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2200 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
800eeca4 2201 if (!rent)
b34976b6 2202 return FALSE;
800eeca4
JW
2203
2204 rent->next = dyn_i->reloc_entries;
2205 rent->srel = srel;
2206 rent->type = type;
2207 rent->count = 0;
2208 dyn_i->reloc_entries = rent;
2209 }
2210 rent->count++;
2211
b34976b6 2212 return TRUE;
800eeca4
JW
2213}
2214
b34976b6 2215static bfd_boolean
bbe66d08 2216elfNN_ia64_check_relocs (abfd, info, sec, relocs)
800eeca4
JW
2217 bfd *abfd;
2218 struct bfd_link_info *info;
2219 asection *sec;
2220 const Elf_Internal_Rela *relocs;
2221{
bbe66d08 2222 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
2223 const Elf_Internal_Rela *relend;
2224 Elf_Internal_Shdr *symtab_hdr;
2225 const Elf_Internal_Rela *rel;
2226 asection *got, *fptr, *srel;
2227
2228 if (info->relocateable)
b34976b6 2229 return TRUE;
800eeca4
JW
2230
2231 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
bbe66d08 2232 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
2233
2234 got = fptr = srel = NULL;
2235
2236 relend = relocs + sec->reloc_count;
2237 for (rel = relocs; rel < relend; ++rel)
2238 {
2239 enum {
2240 NEED_GOT = 1,
2c4c2bc0
RH
2241 NEED_GOTX = 2,
2242 NEED_FPTR = 4,
2243 NEED_PLTOFF = 8,
2244 NEED_MIN_PLT = 16,
2245 NEED_FULL_PLT = 32,
2246 NEED_DYNREL = 64,
2247 NEED_LTOFF_FPTR = 128,
2248 NEED_TPREL = 256,
2249 NEED_DTPMOD = 512,
2250 NEED_DTPREL = 1024
800eeca4
JW
2251 };
2252
2253 struct elf_link_hash_entry *h = NULL;
bbe66d08
JW
2254 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2255 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4 2256 int need_entry;
b34976b6 2257 bfd_boolean maybe_dynamic;
64bf6ae6 2258 int dynrel_type = R_IA64_NONE;
800eeca4
JW
2259
2260 if (r_symndx >= symtab_hdr->sh_info)
2261 {
2262 /* We're dealing with a global symbol -- find its hash entry
2263 and mark it as being referenced. */
2264 long indx = r_symndx - symtab_hdr->sh_info;
2265 h = elf_sym_hashes (abfd)[indx];
2266 while (h->root.type == bfd_link_hash_indirect
2267 || h->root.type == bfd_link_hash_warning)
2268 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2269
2270 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2271 }
2272
2273 /* We can only get preliminary data on whether a symbol is
2274 locally or externally defined, as not all of the input files
2275 have yet been processed. Do something with what we know, as
2276 this may help reduce memory usage and processing time later. */
b34976b6 2277 maybe_dynamic = FALSE;
671bae9c
NC
2278 if (h && ((info->shared
2279 && (!info->symbolic || info->allow_shlib_undefined))
800eeca4 2280 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
7b6dab7f
TW
2281 || h->root.type == bfd_link_hash_defweak
2282 || elfNN_ia64_aix_vec (abfd->xvec)))
b34976b6 2283 maybe_dynamic = TRUE;
800eeca4
JW
2284
2285 need_entry = 0;
bbe66d08 2286 switch (ELFNN_R_TYPE (rel->r_info))
800eeca4 2287 {
800eeca4
JW
2288 case R_IA64_TPREL64MSB:
2289 case R_IA64_TPREL64LSB:
13ae64f3
JJ
2290 if (info->shared || maybe_dynamic)
2291 need_entry = NEED_DYNREL;
2292 dynrel_type = R_IA64_TPREL64LSB;
2293 if (info->shared)
2294 info->flags |= DF_STATIC_TLS;
2295 break;
2296
2297 case R_IA64_LTOFF_TPREL22:
2298 need_entry = NEED_TPREL;
2299 if (info->shared)
2300 info->flags |= DF_STATIC_TLS;
2301 break;
2302
2303 case R_IA64_DTPREL64MSB:
2304 case R_IA64_DTPREL64LSB:
2305 if (info->shared || maybe_dynamic)
2306 need_entry = NEED_DYNREL;
2307 dynrel_type = R_IA64_DTPREL64LSB;
2308 break;
2309
2310 case R_IA64_LTOFF_DTPREL22:
2311 need_entry = NEED_DTPREL;
2312 break;
2313
2314 case R_IA64_DTPMOD64MSB:
2315 case R_IA64_DTPMOD64LSB:
2316 if (info->shared || maybe_dynamic)
2317 need_entry = NEED_DYNREL;
2318 dynrel_type = R_IA64_DTPMOD64LSB;
2319 break;
2320
2321 case R_IA64_LTOFF_DTPMOD22:
2322 need_entry = NEED_DTPMOD;
2323 break;
800eeca4
JW
2324
2325 case R_IA64_LTOFF_FPTR22:
2326 case R_IA64_LTOFF_FPTR64I:
a4bd8390
JW
2327 case R_IA64_LTOFF_FPTR32MSB:
2328 case R_IA64_LTOFF_FPTR32LSB:
800eeca4
JW
2329 case R_IA64_LTOFF_FPTR64MSB:
2330 case R_IA64_LTOFF_FPTR64LSB:
2331 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2332 break;
2333
2334 case R_IA64_FPTR64I:
2335 case R_IA64_FPTR32MSB:
2336 case R_IA64_FPTR32LSB:
2337 case R_IA64_FPTR64MSB:
2338 case R_IA64_FPTR64LSB:
64e9ece0 2339 if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
800eeca4
JW
2340 need_entry = NEED_FPTR | NEED_DYNREL;
2341 else
2342 need_entry = NEED_FPTR;
2343 dynrel_type = R_IA64_FPTR64LSB;
2344 break;
2345
2346 case R_IA64_LTOFF22:
800eeca4
JW
2347 case R_IA64_LTOFF64I:
2348 need_entry = NEED_GOT;
2349 break;
2350
2c4c2bc0
RH
2351 case R_IA64_LTOFF22X:
2352 need_entry = NEED_GOTX;
2353 break;
2354
800eeca4
JW
2355 case R_IA64_PLTOFF22:
2356 case R_IA64_PLTOFF64I:
2357 case R_IA64_PLTOFF64MSB:
2358 case R_IA64_PLTOFF64LSB:
2359 need_entry = NEED_PLTOFF;
2360 if (h)
2361 {
2362 if (maybe_dynamic)
2363 need_entry |= NEED_MIN_PLT;
2364 }
2365 else
2366 {
2367 (*info->callbacks->warning)
2368 (info, _("@pltoff reloc against local symbol"), 0,
dc810e39 2369 abfd, 0, (bfd_vma) 0);
800eeca4
JW
2370 }
2371 break;
2372
2373 case R_IA64_PCREL21B:
748abff6 2374 case R_IA64_PCREL60B:
800eeca4
JW
2375 /* Depending on where this symbol is defined, we may or may not
2376 need a full plt entry. Only skip if we know we'll not need
2377 the entry -- static or symbolic, and the symbol definition
2378 has already been seen. */
2379 if (maybe_dynamic && rel->r_addend == 0)
2380 need_entry = NEED_FULL_PLT;
2381 break;
2382
2383 case R_IA64_IMM14:
2384 case R_IA64_IMM22:
2385 case R_IA64_IMM64:
2386 case R_IA64_DIR32MSB:
2387 case R_IA64_DIR32LSB:
2388 case R_IA64_DIR64MSB:
2389 case R_IA64_DIR64LSB:
2390 /* Shared objects will always need at least a REL relocation. */
7b6dab7f 2391 if (info->shared || maybe_dynamic
7b6dab7f 2392 || (elfNN_ia64_aix_vec (abfd->xvec)
64e9ece0 2393 && (!h || strcmp (h->root.root.string,
7b6dab7f 2394 "__GLOB_DATA_PTR") != 0)))
800eeca4
JW
2395 need_entry = NEED_DYNREL;
2396 dynrel_type = R_IA64_DIR64LSB;
2397 break;
2398
18b27f17
RH
2399 case R_IA64_IPLTMSB:
2400 case R_IA64_IPLTLSB:
2401 /* Shared objects will always need at least a REL relocation. */
2402 if (info->shared || maybe_dynamic)
2403 need_entry = NEED_DYNREL;
2404 dynrel_type = R_IA64_IPLTLSB;
2405 break;
2406
748abff6
RH
2407 case R_IA64_PCREL22:
2408 case R_IA64_PCREL64I:
800eeca4
JW
2409 case R_IA64_PCREL32MSB:
2410 case R_IA64_PCREL32LSB:
2411 case R_IA64_PCREL64MSB:
2412 case R_IA64_PCREL64LSB:
2413 if (maybe_dynamic)
2414 need_entry = NEED_DYNREL;
2415 dynrel_type = R_IA64_PCREL64LSB;
2416 break;
2417 }
2418
2419 if (!need_entry)
2420 continue;
2421
2422 if ((need_entry & NEED_FPTR) != 0
2423 && rel->r_addend)
2424 {
2425 (*info->callbacks->warning)
2426 (info, _("non-zero addend in @fptr reloc"), 0,
dc810e39 2427 abfd, 0, (bfd_vma) 0);
800eeca4
JW
2428 }
2429
b34976b6 2430 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE);
800eeca4
JW
2431
2432 /* Record whether or not this is a local symbol. */
2433 dyn_i->h = h;
2434
2435 /* Create what's needed. */
2c4c2bc0
RH
2436 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2437 | NEED_DTPMOD | NEED_DTPREL))
800eeca4
JW
2438 {
2439 if (!got)
2440 {
2441 got = get_got (abfd, info, ia64_info);
2442 if (!got)
b34976b6 2443 return FALSE;
800eeca4 2444 }
13ae64f3
JJ
2445 if (need_entry & NEED_GOT)
2446 dyn_i->want_got = 1;
2c4c2bc0
RH
2447 if (need_entry & NEED_GOTX)
2448 dyn_i->want_gotx = 1;
13ae64f3
JJ
2449 if (need_entry & NEED_TPREL)
2450 dyn_i->want_tprel = 1;
2451 if (need_entry & NEED_DTPMOD)
2452 dyn_i->want_dtpmod = 1;
2453 if (need_entry & NEED_DTPREL)
2454 dyn_i->want_dtprel = 1;
800eeca4
JW
2455 }
2456 if (need_entry & NEED_FPTR)
2457 {
2458 if (!fptr)
2459 {
2460 fptr = get_fptr (abfd, info, ia64_info);
2461 if (!fptr)
b34976b6 2462 return FALSE;
800eeca4
JW
2463 }
2464
2465 /* FPTRs for shared libraries are allocated by the dynamic
2466 linker. Make sure this local symbol will appear in the
2467 dynamic symbol table. */
7b6dab7f
TW
2468 if (!h && (info->shared
2469 /* AIX also needs one */
2470 || elfNN_ia64_aix_vec (abfd->xvec)))
800eeca4 2471 {
bbe66d08 2472 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
dc810e39 2473 (info, abfd, (long) r_symndx)))
b34976b6 2474 return FALSE;
800eeca4
JW
2475 }
2476
2477 dyn_i->want_fptr = 1;
2478 }
2479 if (need_entry & NEED_LTOFF_FPTR)
2480 dyn_i->want_ltoff_fptr = 1;
2481 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2482 {
2483 if (!ia64_info->root.dynobj)
2484 ia64_info->root.dynobj = abfd;
2485 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2486 dyn_i->want_plt = 1;
2487 }
2488 if (need_entry & NEED_FULL_PLT)
2489 dyn_i->want_plt2 = 1;
2490 if (need_entry & NEED_PLTOFF)
2491 dyn_i->want_pltoff = 1;
2492 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2493 {
2494 if (!srel)
2495 {
b34976b6 2496 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
800eeca4 2497 if (!srel)
b34976b6 2498 return FALSE;
800eeca4
JW
2499 }
2500 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
b34976b6 2501 return FALSE;
800eeca4
JW
2502 }
2503 }
2504
b34976b6 2505 return TRUE;
800eeca4
JW
2506}
2507
800eeca4
JW
2508/* For cleanliness, and potentially faster dynamic loading, allocate
2509 external GOT entries first. */
2510
b34976b6 2511static bfd_boolean
800eeca4 2512allocate_global_data_got (dyn_i, data)
bbe66d08 2513 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
2514 PTR data;
2515{
bbe66d08 2516 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4 2517
2c4c2bc0 2518 if ((dyn_i->want_got || dyn_i->want_gotx)
800eeca4 2519 && ! dyn_i->want_fptr
7b6dab7f 2520 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
64e9ece0
TW
2521 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2522 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2523 "__GLOB_DATA_PTR") != 0))))
800eeca4
JW
2524 {
2525 dyn_i->got_offset = x->ofs;
2526 x->ofs += 8;
2527 }
13ae64f3
JJ
2528 if (dyn_i->want_tprel)
2529 {
2530 dyn_i->tprel_offset = x->ofs;
2531 x->ofs += 8;
2532 }
2533 if (dyn_i->want_dtpmod)
2534 {
b3dfd7fe
JJ
2535 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
2536 {
2537 dyn_i->dtpmod_offset = x->ofs;
2538 x->ofs += 8;
2539 }
2540 else
2541 {
2542 struct elfNN_ia64_link_hash_table *ia64_info;
2543
2544 ia64_info = elfNN_ia64_hash_table (x->info);
2545 if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
2546 {
2547 ia64_info->self_dtpmod_offset = x->ofs;
2548 x->ofs += 8;
2549 }
2550 dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
2551 }
13ae64f3
JJ
2552 }
2553 if (dyn_i->want_dtprel)
2554 {
2555 dyn_i->dtprel_offset = x->ofs;
2556 x->ofs += 8;
2557 }
b34976b6 2558 return TRUE;
800eeca4
JW
2559}
2560
2561/* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2562
b34976b6 2563static bfd_boolean
800eeca4 2564allocate_global_fptr_got (dyn_i, data)
bbe66d08 2565 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
2566 PTR data;
2567{
bbe66d08 2568 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4
JW
2569
2570 if (dyn_i->want_got
2571 && dyn_i->want_fptr
7b6dab7f
TW
2572 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2573 || elfNN_ia64_aix_vec (x->info->hash->creator)))
800eeca4
JW
2574 {
2575 dyn_i->got_offset = x->ofs;
2576 x->ofs += 8;
2577 }
b34976b6 2578 return TRUE;
800eeca4
JW
2579}
2580
2581/* Lastly, allocate all the GOT entries for local data. */
2582
b34976b6 2583static bfd_boolean
800eeca4 2584allocate_local_got (dyn_i, data)
bbe66d08 2585 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
2586 PTR data;
2587{
bbe66d08 2588 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4 2589
2c4c2bc0 2590 if ((dyn_i->want_got || dyn_i->want_gotx)
7b6dab7f
TW
2591 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2592 || elfNN_ia64_aix_vec (x->info->hash->creator)))
800eeca4
JW
2593 {
2594 dyn_i->got_offset = x->ofs;
2595 x->ofs += 8;
2596 }
b34976b6 2597 return TRUE;
800eeca4
JW
2598}
2599
2600/* Search for the index of a global symbol in it's defining object file. */
2601
dc810e39 2602static long
800eeca4
JW
2603global_sym_index (h)
2604 struct elf_link_hash_entry *h;
2605{
2606 struct elf_link_hash_entry **p;
2607 bfd *obj;
2608
2609 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2610 || h->root.type == bfd_link_hash_defweak);
2611
2612 obj = h->root.u.def.section->owner;
2613 for (p = elf_sym_hashes (obj); *p != h; ++p)
2614 continue;
2615
2616 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2617}
2618
2619/* Allocate function descriptors. We can do these for every function
2620 in a main executable that is not exported. */
2621
b34976b6 2622static bfd_boolean
800eeca4 2623allocate_fptr (dyn_i, data)
bbe66d08 2624 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
2625 PTR data;
2626{
bbe66d08 2627 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4
JW
2628
2629 if (dyn_i->want_fptr)
2630 {
2631 struct elf_link_hash_entry *h = dyn_i->h;
3e932841 2632
800eeca4
JW
2633 if (h)
2634 while (h->root.type == bfd_link_hash_indirect
2635 || h->root.type == bfd_link_hash_warning)
2636 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2637
7b6dab7f
TW
2638 if (x->info->shared
2639 /* AIX needs an FPTR in this case. */
2640 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2641 && (!h
2642 || h->root.type == bfd_link_hash_defined
2643 || h->root.type == bfd_link_hash_defweak)))
800eeca4
JW
2644 {
2645 if (h && h->dynindx == -1)
2646 {
2647 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2648 || (h->root.type == bfd_link_hash_defweak));
2649
bbe66d08 2650 if (!_bfd_elfNN_link_record_local_dynamic_symbol
800eeca4
JW
2651 (x->info, h->root.u.def.section->owner,
2652 global_sym_index (h)))
b34976b6 2653 return FALSE;
800eeca4
JW
2654 }
2655
2656 dyn_i->want_fptr = 0;
2657 }
2658 else if (h == NULL || h->dynindx == -1)
2659 {
2660 dyn_i->fptr_offset = x->ofs;
2661 x->ofs += 16;
2662 }
2663 else
2664 dyn_i->want_fptr = 0;
2665 }
b34976b6 2666 return TRUE;
800eeca4
JW
2667}
2668
2669/* Allocate all the minimal PLT entries. */
2670
b34976b6 2671static bfd_boolean
800eeca4 2672allocate_plt_entries (dyn_i, data)
bbe66d08 2673 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
2674 PTR data;
2675{
bbe66d08 2676 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4
JW
2677
2678 if (dyn_i->want_plt)
2679 {
2680 struct elf_link_hash_entry *h = dyn_i->h;
2681
2682 if (h)
2683 while (h->root.type == bfd_link_hash_indirect
2684 || h->root.type == bfd_link_hash_warning)
2685 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2686
2687 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
bbe66d08 2688 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
800eeca4
JW
2689 {
2690 bfd_size_type offset = x->ofs;
2691 if (offset == 0)
2692 offset = PLT_HEADER_SIZE;
2693 dyn_i->plt_offset = offset;
2694 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2695
2696 dyn_i->want_pltoff = 1;
2697 }
2698 else
2699 {
2700 dyn_i->want_plt = 0;
2701 dyn_i->want_plt2 = 0;
2702 }
2703 }
b34976b6 2704 return TRUE;
800eeca4
JW
2705}
2706
2707/* Allocate all the full PLT entries. */
2708
b34976b6 2709static bfd_boolean
800eeca4 2710allocate_plt2_entries (dyn_i, data)
bbe66d08 2711 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
2712 PTR data;
2713{
bbe66d08 2714 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4
JW
2715
2716 if (dyn_i->want_plt2)
2717 {
2718 struct elf_link_hash_entry *h = dyn_i->h;
2719 bfd_size_type ofs = x->ofs;
2720
2721 dyn_i->plt2_offset = ofs;
2722 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2723
2724 while (h->root.type == bfd_link_hash_indirect
2725 || h->root.type == bfd_link_hash_warning)
2726 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2727 dyn_i->h->plt.offset = ofs;
2728 }
b34976b6 2729 return TRUE;
800eeca4
JW
2730}
2731
2732/* Allocate all the PLTOFF entries requested by relocations and
2733 plt entries. We can't share space with allocated FPTR entries,
2734 because the latter are not necessarily addressable by the GP.
2735 ??? Relaxation might be able to determine that they are. */
2736
b34976b6 2737static bfd_boolean
800eeca4 2738allocate_pltoff_entries (dyn_i, data)
bbe66d08 2739 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
2740 PTR data;
2741{
bbe66d08 2742 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4
JW
2743
2744 if (dyn_i->want_pltoff)
2745 {
2746 dyn_i->pltoff_offset = x->ofs;
2747 x->ofs += 16;
2748 }
b34976b6 2749 return TRUE;
800eeca4
JW
2750}
2751
2752/* Allocate dynamic relocations for those symbols that turned out
2753 to be dynamic. */
2754
b34976b6 2755static bfd_boolean
800eeca4 2756allocate_dynrel_entries (dyn_i, data)
bbe66d08 2757 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
2758 PTR data;
2759{
bbe66d08
JW
2760 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2761 struct elfNN_ia64_link_hash_table *ia64_info;
2762 struct elfNN_ia64_dyn_reloc_entry *rent;
b34976b6 2763 bfd_boolean dynamic_symbol, shared;
800eeca4 2764
bbe66d08 2765 ia64_info = elfNN_ia64_hash_table (x->info);
7b6dab7f 2766 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
64e9ece0
TW
2767 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2768 /* Don't allocate an entry for __GLOB_DATA_PTR */
2769 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2770 "__GLOB_DATA_PTR") != 0));
800eeca4
JW
2771 shared = x->info->shared;
2772
2773 /* Take care of the normal data relocations. */
2774
2775 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2776 {
18b27f17
RH
2777 int count = rent->count;
2778
800eeca4
JW
2779 switch (rent->type)
2780 {
2781 case R_IA64_FPTR64LSB:
2782 /* Allocate one iff !want_fptr, which by this point will
2783 be true only if we're actually allocating one statically
2784 in the main executable. */
2785 if (dyn_i->want_fptr)
2786 continue;
2787 break;
2788 case R_IA64_PCREL64LSB:
2789 if (!dynamic_symbol)
2790 continue;
2791 break;
2792 case R_IA64_DIR64LSB:
2793 if (!dynamic_symbol && !shared)
2794 continue;
2795 break;
18b27f17
RH
2796 case R_IA64_IPLTLSB:
2797 if (!dynamic_symbol && !shared)
2798 continue;
2799 /* Use two REL relocations for IPLT relocations
2800 against local symbols. */
2801 if (!dynamic_symbol)
2802 count *= 2;
2803 break;
13ae64f3
JJ
2804 case R_IA64_TPREL64LSB:
2805 case R_IA64_DTPREL64LSB:
2806 case R_IA64_DTPMOD64LSB:
2807 break;
18b27f17
RH
2808 default:
2809 abort ();
800eeca4 2810 }
18b27f17 2811 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
800eeca4
JW
2812 }
2813
2814 /* Take care of the GOT and PLT relocations. */
2815
2c4c2bc0 2816 if (((dynamic_symbol || shared) && (dyn_i->want_got || dyn_i->want_gotx))
800eeca4 2817 || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
bbe66d08 2818 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
13ae64f3
JJ
2819 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2820 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
b3dfd7fe 2821 if (dynamic_symbol && dyn_i->want_dtpmod)
13ae64f3
JJ
2822 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2823 if (dynamic_symbol && dyn_i->want_dtprel)
2824 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
800eeca4
JW
2825
2826 if (dyn_i->want_pltoff)
2827 {
2828 bfd_size_type t = 0;
2829
2830 /* Dynamic symbols get one IPLT relocation. Local symbols in
2831 shared libraries get two REL relocations. Local symbols in
2832 main applications get nothing. */
2833 if (dynamic_symbol)
bbe66d08 2834 t = sizeof (ElfNN_External_Rela);
800eeca4 2835 else if (shared)
bbe66d08 2836 t = 2 * sizeof (ElfNN_External_Rela);
800eeca4
JW
2837
2838 ia64_info->rel_pltoff_sec->_raw_size += t;
2839 }
2840
b34976b6 2841 return TRUE;
800eeca4
JW
2842}
2843
b34976b6 2844static bfd_boolean
bbe66d08 2845elfNN_ia64_adjust_dynamic_symbol (info, h)
64bf6ae6 2846 struct bfd_link_info *info ATTRIBUTE_UNUSED;
800eeca4
JW
2847 struct elf_link_hash_entry *h;
2848{
2849 /* ??? Undefined symbols with PLT entries should be re-defined
2850 to be the PLT entry. */
2851
2852 /* If this is a weak symbol, and there is a real definition, the
2853 processor independent code will have arranged for us to see the
2854 real definition first, and we can just use the same value. */
2855 if (h->weakdef != NULL)
2856 {
2857 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2858 || h->weakdef->root.type == bfd_link_hash_defweak);
2859 h->root.u.def.section = h->weakdef->root.u.def.section;
2860 h->root.u.def.value = h->weakdef->root.u.def.value;
b34976b6 2861 return TRUE;
800eeca4
JW
2862 }
2863
2864 /* If this is a reference to a symbol defined by a dynamic object which
2865 is not a function, we might allocate the symbol in our .dynbss section
2866 and allocate a COPY dynamic relocation.
2867
2868 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2869 of hackery. */
2870
b34976b6 2871 return TRUE;
800eeca4
JW
2872}
2873
b34976b6 2874static bfd_boolean
bbe66d08 2875elfNN_ia64_size_dynamic_sections (output_bfd, info)
800eeca4
JW
2876 bfd *output_bfd;
2877 struct bfd_link_info *info;
2878{
bbe66d08
JW
2879 struct elfNN_ia64_allocate_data data;
2880 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
2881 asection *sec;
2882 bfd *dynobj;
b34976b6 2883 bfd_boolean relplt = FALSE;
800eeca4
JW
2884
2885 dynobj = elf_hash_table(info)->dynobj;
bbe66d08 2886 ia64_info = elfNN_ia64_hash_table (info);
b3dfd7fe 2887 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
800eeca4
JW
2888 BFD_ASSERT(dynobj != NULL);
2889 data.info = info;
2890
2891 /* Set the contents of the .interp section to the interpreter. */
2892 if (ia64_info->root.dynamic_sections_created
2893 && !info->shared)
2894 {
2895 sec = bfd_get_section_by_name (dynobj, ".interp");
2896 BFD_ASSERT (sec != NULL);
7b6dab7f
TW
2897 sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd);
2898 sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1;
800eeca4
JW
2899 }
2900
800eeca4
JW
2901 /* Allocate the GOT entries. */
2902
2903 if (ia64_info->got_sec)
2904 {
2905 data.ofs = 0;
bbe66d08
JW
2906 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2907 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2908 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
800eeca4
JW
2909 ia64_info->got_sec->_raw_size = data.ofs;
2910 }
2911
2912 /* Allocate the FPTR entries. */
2913
2914 if (ia64_info->fptr_sec)
2915 {
2916 data.ofs = 0;
bbe66d08 2917 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
800eeca4
JW
2918 ia64_info->fptr_sec->_raw_size = data.ofs;
2919 }
2920
2921 /* Now that we've seen all of the input files, we can decide which
2922 symbols need plt entries. Allocate the minimal PLT entries first.
b34976b6 2923 We do this even though dynamic_sections_created may be FALSE, because
800eeca4
JW
2924 this has the side-effect of clearing want_plt and want_plt2. */
2925
2926 data.ofs = 0;
bbe66d08 2927 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
800eeca4
JW
2928
2929 ia64_info->minplt_entries = 0;
2930 if (data.ofs)
2931 {
2932 ia64_info->minplt_entries
2933 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2934 }
2935
2936 /* Align the pointer for the plt2 entries. */
dc810e39 2937 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
800eeca4 2938
bbe66d08 2939 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
800eeca4
JW
2940 if (data.ofs != 0)
2941 {
2942 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2943
2944 ia64_info->plt_sec->_raw_size = data.ofs;
2945
2946 /* If we've got a .plt, we need some extra memory for the dynamic
2947 linker. We stuff these in .got.plt. */
2948 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2949 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2950 }
2951
2952 /* Allocate the PLTOFF entries. */
2953
2954 if (ia64_info->pltoff_sec)
2955 {
2956 data.ofs = 0;
bbe66d08 2957 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
800eeca4
JW
2958 ia64_info->pltoff_sec->_raw_size = data.ofs;
2959 }
2960
2961 if (ia64_info->root.dynamic_sections_created)
2962 {
2963 /* Allocate space for the dynamic relocations that turned out to be
2964 required. */
2965
b3dfd7fe
JJ
2966 if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
2967 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
bbe66d08 2968 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
800eeca4
JW
2969 }
2970
2971 /* We have now determined the sizes of the various dynamic sections.
2972 Allocate memory for them. */
2973 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2974 {
b34976b6 2975 bfd_boolean strip;
800eeca4
JW
2976
2977 if (!(sec->flags & SEC_LINKER_CREATED))
2978 continue;
2979
2980 /* If we don't need this section, strip it from the output file.
2981 There were several sections primarily related to dynamic
2982 linking that must be create before the linker maps input
2983 sections to output sections. The linker does that before
2984 bfd_elf_size_dynamic_sections is called, and it is that
2985 function which decides whether anything needs to go into
2986 these sections. */
2987
2988 strip = (sec->_raw_size == 0);
2989
2990 if (sec == ia64_info->got_sec)
b34976b6 2991 strip = FALSE;
800eeca4
JW
2992 else if (sec == ia64_info->rel_got_sec)
2993 {
2994 if (strip)
2995 ia64_info->rel_got_sec = NULL;
2996 else
2997 /* We use the reloc_count field as a counter if we need to
2998 copy relocs into the output file. */
2999 sec->reloc_count = 0;
3000 }
3001 else if (sec == ia64_info->fptr_sec)
3002 {
3003 if (strip)
3004 ia64_info->fptr_sec = NULL;
3005 }
3006 else if (sec == ia64_info->plt_sec)
3007 {
3008 if (strip)
3009 ia64_info->plt_sec = NULL;
3010 }
3011 else if (sec == ia64_info->pltoff_sec)
3012 {
3013 if (strip)
3014 ia64_info->pltoff_sec = NULL;
3015 }
3016 else if (sec == ia64_info->rel_pltoff_sec)
3017 {
3018 if (strip)
3019 ia64_info->rel_pltoff_sec = NULL;
3020 else
3021 {
b34976b6 3022 relplt = TRUE;
800eeca4
JW
3023 /* We use the reloc_count field as a counter if we need to
3024 copy relocs into the output file. */
3025 sec->reloc_count = 0;
3026 }
3027 }
3028 else
3029 {
3030 const char *name;
3031
3032 /* It's OK to base decisions on the section name, because none
3033 of the dynobj section names depend upon the input files. */
3034 name = bfd_get_section_name (dynobj, sec);
3035
3036 if (strcmp (name, ".got.plt") == 0)
b34976b6 3037 strip = FALSE;
800eeca4
JW
3038 else if (strncmp (name, ".rel", 4) == 0)
3039 {
3040 if (!strip)
3041 {
800eeca4
JW
3042 /* We use the reloc_count field as a counter if we need to
3043 copy relocs into the output file. */
3044 sec->reloc_count = 0;
3045 }
3046 }
3047 else
3048 continue;
3049 }
3050
3051 if (strip)
3052 _bfd_strip_section_from_output (info, sec);
3053 else
3054 {
3055 /* Allocate memory for the section contents. */
dc810e39 3056 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
800eeca4 3057 if (sec->contents == NULL && sec->_raw_size != 0)
b34976b6 3058 return FALSE;
800eeca4
JW
3059 }
3060 }
3061
3062 if (elf_hash_table (info)->dynamic_sections_created)
3063 {
3064 /* Add some entries to the .dynamic section. We fill in the values
3065 later (in finish_dynamic_sections) but we must add the entries now
3066 so that we get the correct size for the .dynamic section. */
3067
3068 if (!info->shared)
3069 {
3070 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3071 by the debugger. */
dc810e39
AM
3072#define add_dynamic_entry(TAG, VAL) \
3073 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
3074
3075 if (!add_dynamic_entry (DT_DEBUG, 0))
b34976b6 3076 return FALSE;
800eeca4
JW
3077 }
3078
dc810e39 3079 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
b34976b6 3080 return FALSE;
dc810e39 3081 if (!add_dynamic_entry (DT_PLTGOT, 0))
b34976b6 3082 return FALSE;
800eeca4
JW
3083
3084 if (relplt)
3085 {
dc810e39
AM
3086 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3087 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3088 || !add_dynamic_entry (DT_JMPREL, 0))
b34976b6 3089 return FALSE;
800eeca4
JW
3090 }
3091
dc810e39
AM
3092 if (!add_dynamic_entry (DT_RELA, 0)
3093 || !add_dynamic_entry (DT_RELASZ, 0)
3094 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
b34976b6 3095 return FALSE;
800eeca4 3096
db6751f2 3097 if (ia64_info->reltext)
800eeca4 3098 {
dc810e39 3099 if (!add_dynamic_entry (DT_TEXTREL, 0))
b34976b6 3100 return FALSE;
d6cf2879 3101 info->flags |= DF_TEXTREL;
800eeca4
JW
3102 }
3103 }
3104
3105 /* ??? Perhaps force __gp local. */
3106
b34976b6 3107 return TRUE;
800eeca4
JW
3108}
3109
3110static bfd_reloc_status_type
1e738b87 3111elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
800eeca4
JW
3112 bfd *abfd;
3113 bfd_byte *hit_addr;
1e738b87 3114 bfd_vma v;
800eeca4
JW
3115 unsigned int r_type;
3116{
3117 const struct ia64_operand *op;
3118 int bigendian = 0, shift = 0;
3119 bfd_vma t0, t1, insn, dword;
3120 enum ia64_opnd opnd;
3121 const char *err;
3122 size_t size = 8;
1e738b87
NC
3123#ifdef BFD_HOST_U_64_BIT
3124 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3125#else
3126 bfd_vma val = v;
3127#endif
800eeca4
JW
3128
3129 opnd = IA64_OPND_NIL;
3130 switch (r_type)
3131 {
3132 case R_IA64_NONE:
3133 case R_IA64_LDXMOV:
3134 return bfd_reloc_ok;
3135
3e932841 3136 /* Instruction relocations. */
800eeca4 3137
13ae64f3
JJ
3138 case R_IA64_IMM14:
3139 case R_IA64_TPREL14:
3140 case R_IA64_DTPREL14:
3141 opnd = IA64_OPND_IMM14;
3142 break;
748abff6 3143
800eeca4
JW
3144 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
3145 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
748abff6
RH
3146 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
3147 case R_IA64_PCREL21B:
3148 case R_IA64_PCREL21BI:
3149 opnd = IA64_OPND_TGT25c;
3150 break;
800eeca4
JW
3151
3152 case R_IA64_IMM22:
3153 case R_IA64_GPREL22:
3154 case R_IA64_LTOFF22:
3155 case R_IA64_LTOFF22X:
3156 case R_IA64_PLTOFF22:
748abff6 3157 case R_IA64_PCREL22:
800eeca4 3158 case R_IA64_LTOFF_FPTR22:
13ae64f3
JJ
3159 case R_IA64_TPREL22:
3160 case R_IA64_DTPREL22:
3161 case R_IA64_LTOFF_TPREL22:
3162 case R_IA64_LTOFF_DTPMOD22:
3163 case R_IA64_LTOFF_DTPREL22:
800eeca4
JW
3164 opnd = IA64_OPND_IMM22;
3165 break;
3166
3167 case R_IA64_IMM64:
3168 case R_IA64_GPREL64I:
3169 case R_IA64_LTOFF64I:
3170 case R_IA64_PLTOFF64I:
748abff6 3171 case R_IA64_PCREL64I:
800eeca4
JW
3172 case R_IA64_FPTR64I:
3173 case R_IA64_LTOFF_FPTR64I:
13ae64f3
JJ
3174 case R_IA64_TPREL64I:
3175 case R_IA64_DTPREL64I:
800eeca4
JW
3176 opnd = IA64_OPND_IMMU64;
3177 break;
3178
3179 /* Data relocations. */
3180
3181 case R_IA64_DIR32MSB:
3182 case R_IA64_GPREL32MSB:
3183 case R_IA64_FPTR32MSB:
3184 case R_IA64_PCREL32MSB:
a4bd8390 3185 case R_IA64_LTOFF_FPTR32MSB:
800eeca4
JW
3186 case R_IA64_SEGREL32MSB:
3187 case R_IA64_SECREL32MSB:
3188 case R_IA64_LTV32MSB:
13ae64f3 3189 case R_IA64_DTPREL32MSB:
800eeca4
JW
3190 size = 4; bigendian = 1;
3191 break;
3192
3193 case R_IA64_DIR32LSB:
3194 case R_IA64_GPREL32LSB:
3195 case R_IA64_FPTR32LSB:
3196 case R_IA64_PCREL32LSB:
a4bd8390 3197 case R_IA64_LTOFF_FPTR32LSB:
800eeca4
JW
3198 case R_IA64_SEGREL32LSB:
3199 case R_IA64_SECREL32LSB:
3200 case R_IA64_LTV32LSB:
13ae64f3 3201 case R_IA64_DTPREL32LSB:
800eeca4
JW
3202 size = 4; bigendian = 0;
3203 break;
3204
3205 case R_IA64_DIR64MSB:
3206 case R_IA64_GPREL64MSB:
3207 case R_IA64_PLTOFF64MSB:
3208 case R_IA64_FPTR64MSB:
3209 case R_IA64_PCREL64MSB:
3210 case R_IA64_LTOFF_FPTR64MSB:
3211 case R_IA64_SEGREL64MSB:
3212 case R_IA64_SECREL64MSB:
3213 case R_IA64_LTV64MSB:
13ae64f3
JJ
3214 case R_IA64_TPREL64MSB:
3215 case R_IA64_DTPMOD64MSB:
3216 case R_IA64_DTPREL64MSB:
800eeca4
JW
3217 size = 8; bigendian = 1;
3218 break;
3219
3220 case R_IA64_DIR64LSB:
3221 case R_IA64_GPREL64LSB:
3222 case R_IA64_PLTOFF64LSB:
3223 case R_IA64_FPTR64LSB:
3224 case R_IA64_PCREL64LSB:
3225 case R_IA64_LTOFF_FPTR64LSB:
3226 case R_IA64_SEGREL64LSB:
3227 case R_IA64_SECREL64LSB:
3228 case R_IA64_LTV64LSB:
13ae64f3
JJ
3229 case R_IA64_TPREL64LSB:
3230 case R_IA64_DTPMOD64LSB:
3231 case R_IA64_DTPREL64LSB:
800eeca4
JW
3232 size = 8; bigendian = 0;
3233 break;
3234
3235 /* Unsupported / Dynamic relocations. */
800eeca4
JW
3236 default:
3237 return bfd_reloc_notsupported;
3238 }
3239
3240 switch (opnd)
3241 {
3242 case IA64_OPND_IMMU64:
3243 hit_addr -= (long) hit_addr & 0x3;
3244 t0 = bfd_get_64 (abfd, hit_addr);
3245 t1 = bfd_get_64 (abfd, hit_addr + 8);
3246
3247 /* tmpl/s: bits 0.. 5 in t0
3248 slot 0: bits 5..45 in t0
3249 slot 1: bits 46..63 in t0, bits 0..22 in t1
3250 slot 2: bits 23..63 in t1 */
3251
3252 /* First, clear the bits that form the 64 bit constant. */
3253 t0 &= ~(0x3ffffLL << 46);
3254 t1 &= ~(0x7fffffLL
3255 | (( (0x07fLL << 13) | (0x1ffLL << 27)
3256 | (0x01fLL << 22) | (0x001LL << 21)
3257 | (0x001LL << 36)) << 23));
3258
3259 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
3260 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
3261 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
3262 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
3263 | (((val >> 16) & 0x01f) << 22) /* imm5c */
3264 | (((val >> 21) & 0x001) << 21) /* ic */
3265 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
3266
3267 bfd_put_64 (abfd, t0, hit_addr);
3268 bfd_put_64 (abfd, t1, hit_addr + 8);
3269 break;
3270
748abff6
RH
3271 case IA64_OPND_TGT64:
3272 hit_addr -= (long) hit_addr & 0x3;
3273 t0 = bfd_get_64 (abfd, hit_addr);
3274 t1 = bfd_get_64 (abfd, hit_addr + 8);
3275
3276 /* tmpl/s: bits 0.. 5 in t0
3277 slot 0: bits 5..45 in t0
3278 slot 1: bits 46..63 in t0, bits 0..22 in t1
3279 slot 2: bits 23..63 in t1 */
3280
3281 /* First, clear the bits that form the 64 bit constant. */
3282 t0 &= ~(0x3ffffLL << 46);
3283 t1 &= ~(0x7fffffLL
3284 | ((1LL << 36 | 0xfffffLL << 13) << 23));
3285
3286 val >>= 4;
3287 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
3288 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
3289 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
3290 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
3291
3292 bfd_put_64 (abfd, t0, hit_addr);
3293 bfd_put_64 (abfd, t1, hit_addr + 8);
3294 break;
3295
800eeca4
JW
3296 default:
3297 switch ((long) hit_addr & 0x3)
3298 {
3299 case 0: shift = 5; break;
3300 case 1: shift = 14; hit_addr += 3; break;
3301 case 2: shift = 23; hit_addr += 6; break;
3e932841 3302 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
800eeca4
JW
3303 }
3304 dword = bfd_get_64 (abfd, hit_addr);
3305 insn = (dword >> shift) & 0x1ffffffffffLL;
3306
3307 op = elf64_ia64_operands + opnd;
1e738b87 3308 err = (*op->insert) (op, val, (ia64_insn *)& insn);
800eeca4
JW
3309 if (err)
3310 return bfd_reloc_overflow;
3311
3312 dword &= ~(0x1ffffffffffLL << shift);
3313 dword |= (insn << shift);
3314 bfd_put_64 (abfd, dword, hit_addr);
3315 break;
3316
3317 case IA64_OPND_NIL:
3318 /* A data relocation. */
3319 if (bigendian)
3320 if (size == 4)
3321 bfd_putb32 (val, hit_addr);
3322 else
3323 bfd_putb64 (val, hit_addr);
3324 else
3325 if (size == 4)
3326 bfd_putl32 (val, hit_addr);
3327 else
3328 bfd_putl64 (val, hit_addr);
3329 break;
3330 }
3331
3332 return bfd_reloc_ok;
3333}
3334
3335static void
bbe66d08 3336elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
800eeca4
JW
3337 dynindx, addend)
3338 bfd *abfd;
3339 struct bfd_link_info *info;
3340 asection *sec;
3341 asection *srel;
3342 bfd_vma offset;
3343 unsigned int type;
3344 long dynindx;
3345 bfd_vma addend;
3346{
3347 Elf_Internal_Rela outrel;
947216bf 3348 bfd_byte *loc;
800eeca4 3349
800eeca4 3350 BFD_ASSERT (dynindx != -1);
bbe66d08 3351 outrel.r_info = ELFNN_R_INFO (dynindx, type);
800eeca4 3352 outrel.r_addend = addend;
c629eae0 3353 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
99eb2ac8 3354 if (outrel.r_offset >= (bfd_vma) -2)
800eeca4 3355 {
c629eae0
JJ
3356 /* Run for the hills. We shouldn't be outputting a relocation
3357 for this. So do what everyone else does and output a no-op. */
3358 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3359 outrel.r_addend = 0;
3360 outrel.r_offset = 0;
800eeca4 3361 }
99eb2ac8
AM
3362 else
3363 outrel.r_offset += sec->output_section->vma + sec->output_offset;
800eeca4 3364
947216bf
AM
3365 loc = srel->contents;
3366 loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3367 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3e932841 3368 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
800eeca4
JW
3369 <= srel->_cooked_size);
3370}
3371
3372/* Store an entry for target address TARGET_ADDR in the linkage table
3373 and return the gp-relative address of the linkage table entry. */
3374
3375static bfd_vma
3376set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3377 bfd *abfd;
3378 struct bfd_link_info *info;
bbe66d08 3379 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
3380 long dynindx;
3381 bfd_vma addend;
3382 bfd_vma value;
3383 unsigned int dyn_r_type;
3384{
bbe66d08 3385 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4 3386 asection *got_sec;
b34976b6 3387 bfd_boolean done;
13ae64f3 3388 bfd_vma got_offset;
800eeca4 3389
bbe66d08 3390 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
3391 got_sec = ia64_info->got_sec;
3392
13ae64f3 3393 switch (dyn_r_type)
800eeca4 3394 {
13ae64f3
JJ
3395 case R_IA64_TPREL64LSB:
3396 done = dyn_i->tprel_done;
b34976b6 3397 dyn_i->tprel_done = TRUE;
13ae64f3
JJ
3398 got_offset = dyn_i->tprel_offset;
3399 break;
3400 case R_IA64_DTPMOD64LSB:
b3dfd7fe
JJ
3401 if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3402 {
3403 done = dyn_i->dtpmod_done;
3404 dyn_i->dtpmod_done = TRUE;
3405 }
3406 else
3407 {
3408 done = ia64_info->self_dtpmod_done;
3409 ia64_info->self_dtpmod_done = TRUE;
3410 dynindx = 0;
3411 }
13ae64f3
JJ
3412 got_offset = dyn_i->dtpmod_offset;
3413 break;
3414 case R_IA64_DTPREL64LSB:
3415 done = dyn_i->dtprel_done;
b34976b6 3416 dyn_i->dtprel_done = TRUE;
13ae64f3
JJ
3417 got_offset = dyn_i->dtprel_offset;
3418 break;
3419 default:
3420 done = dyn_i->got_done;
b34976b6 3421 dyn_i->got_done = TRUE;
13ae64f3
JJ
3422 got_offset = dyn_i->got_offset;
3423 break;
3424 }
800eeca4 3425
13ae64f3
JJ
3426 BFD_ASSERT ((got_offset & 7) == 0);
3427
3428 if (! done)
3429 {
800eeca4 3430 /* Store the target address in the linkage table entry. */
13ae64f3 3431 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
800eeca4
JW
3432
3433 /* Install a dynamic relocation if needed. */
13ae64f3 3434 if ((info->shared && dyn_r_type != R_IA64_DTPREL64LSB)
bbe66d08 3435 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
7b6dab7f 3436 || elfNN_ia64_aix_vec (abfd->xvec)
800eeca4
JW
3437 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3438 {
13ae64f3
JJ
3439 if (dynindx == -1
3440 && dyn_r_type != R_IA64_TPREL64LSB
3441 && dyn_r_type != R_IA64_DTPMOD64LSB
3442 && dyn_r_type != R_IA64_DTPREL64LSB)
800eeca4
JW
3443 {
3444 dyn_r_type = R_IA64_REL64LSB;
3445 dynindx = 0;
3446 addend = value;
3447 }
3448
3449 if (bfd_big_endian (abfd))
3450 {
3451 switch (dyn_r_type)
3452 {
3453 case R_IA64_REL64LSB:
3454 dyn_r_type = R_IA64_REL64MSB;
3455 break;
3456 case R_IA64_DIR64LSB:
3457 dyn_r_type = R_IA64_DIR64MSB;
3458 break;
3459 case R_IA64_FPTR64LSB:
3460 dyn_r_type = R_IA64_FPTR64MSB;
3461 break;
13ae64f3
JJ
3462 case R_IA64_TPREL64LSB:
3463 dyn_r_type = R_IA64_TPREL64MSB;
3464 break;
3465 case R_IA64_DTPMOD64LSB:
3466 dyn_r_type = R_IA64_DTPMOD64MSB;
3467 break;
3468 case R_IA64_DTPREL64LSB:
3469 dyn_r_type = R_IA64_DTPREL64MSB;
3470 break;
800eeca4 3471 default:
b34976b6 3472 BFD_ASSERT (FALSE);
800eeca4
JW
3473 break;
3474 }
3475 }
3476
bbe66d08 3477 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
800eeca4 3478 ia64_info->rel_got_sec,
13ae64f3 3479 got_offset, dyn_r_type,
800eeca4
JW
3480 dynindx, addend);
3481 }
3482 }
3483
3484 /* Return the address of the linkage table entry. */
3485 value = (got_sec->output_section->vma
3486 + got_sec->output_offset
13ae64f3 3487 + got_offset);
800eeca4
JW
3488
3489 return value;
3490}
3491
3492/* Fill in a function descriptor consisting of the function's code
3493 address and its global pointer. Return the descriptor's address. */
3494
3495static bfd_vma
3496set_fptr_entry (abfd, info, dyn_i, value)
3497 bfd *abfd;
3498 struct bfd_link_info *info;
bbe66d08 3499 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
3500 bfd_vma value;
3501{
bbe66d08 3502 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
3503 asection *fptr_sec;
3504
bbe66d08 3505 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
3506 fptr_sec = ia64_info->fptr_sec;
3507
3508 if (!dyn_i->fptr_done)
3509 {
3510 dyn_i->fptr_done = 1;
3511
3512 /* Fill in the function descriptor. */
3513 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3514 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3515 fptr_sec->contents + dyn_i->fptr_offset + 8);
3516 }
3517
3518 /* Return the descriptor's address. */
3519 value = (fptr_sec->output_section->vma
3520 + fptr_sec->output_offset
3521 + dyn_i->fptr_offset);
3522
3523 return value;
3524}
3525
3526/* Fill in a PLTOFF entry consisting of the function's code address
3527 and its global pointer. Return the descriptor's address. */
3528
3529static bfd_vma
3530set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3531 bfd *abfd;
3532 struct bfd_link_info *info;
bbe66d08 3533 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4 3534 bfd_vma value;
b34976b6 3535 bfd_boolean is_plt;
800eeca4 3536{
bbe66d08 3537 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
3538 asection *pltoff_sec;
3539
bbe66d08 3540 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
3541 pltoff_sec = ia64_info->pltoff_sec;
3542
3543 /* Don't do anything if this symbol uses a real PLT entry. In
3544 that case, we'll fill this in during finish_dynamic_symbol. */
3545 if ((! dyn_i->want_plt || is_plt)
3546 && !dyn_i->pltoff_done)
3547 {
18b27f17
RH
3548 bfd_vma gp = _bfd_get_gp_value (abfd);
3549
800eeca4
JW
3550 /* Fill in the function descriptor. */
3551 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
18b27f17 3552 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
800eeca4
JW
3553
3554 /* Install dynamic relocations if needed. */
3555 if (!is_plt && info->shared)
3556 {
3557 unsigned int dyn_r_type;
3558
3559 if (bfd_big_endian (abfd))
3560 dyn_r_type = R_IA64_REL64MSB;
3561 else
3562 dyn_r_type = R_IA64_REL64LSB;
3563
bbe66d08 3564 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
800eeca4
JW
3565 ia64_info->rel_pltoff_sec,
3566 dyn_i->pltoff_offset,
18b27f17 3567 dyn_r_type, 0, value);
bbe66d08 3568 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
800eeca4
JW
3569 ia64_info->rel_pltoff_sec,
3570 dyn_i->pltoff_offset + 8,
18b27f17 3571 dyn_r_type, 0, gp);
800eeca4
JW
3572 }
3573
3574 dyn_i->pltoff_done = 1;
3575 }
3576
3577 /* Return the descriptor's address. */
3578 value = (pltoff_sec->output_section->vma
3579 + pltoff_sec->output_offset
3580 + dyn_i->pltoff_offset);
3581
3582 return value;
3583}
3584
13ae64f3
JJ
3585/* Return the base VMA address which should be subtracted from real addresses
3586 when resolving @tprel() relocation.
3587 Main program TLS (whose template starts at PT_TLS p_vaddr)
3588 is assigned offset round(16, PT_TLS p_align). */
3589
3590static bfd_vma
3591elfNN_ia64_tprel_base (info)
3592 struct bfd_link_info *info;
3593{
3594 struct elf_link_tls_segment *tls_segment
3595 = elf_hash_table (info)->tls_segment;
3596
3597 BFD_ASSERT (tls_segment != NULL);
3598 return (tls_segment->start
3599 - align_power ((bfd_vma) 16, tls_segment->align));
3600}
3601
3602/* Return the base VMA address which should be subtracted from real addresses
3603 when resolving @dtprel() relocation.
3604 This is PT_TLS segment p_vaddr. */
3605
3606static bfd_vma
3607elfNN_ia64_dtprel_base (info)
3608 struct bfd_link_info *info;
3609{
3610 BFD_ASSERT (elf_hash_table (info)->tls_segment != NULL);
3611 return elf_hash_table (info)->tls_segment->start;
3612}
3613
f3b6f7c3 3614/* Called through qsort to sort the .IA_64.unwind section during a
bbe66d08 3615 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
f3b6f7c3
RH
3616 to the output bfd so we can do proper endianness frobbing. */
3617
bbe66d08 3618static bfd *elfNN_ia64_unwind_entry_compare_bfd;
f3b6f7c3
RH
3619
3620static int
bbe66d08 3621elfNN_ia64_unwind_entry_compare (a, b)
cea4409c
AM
3622 const PTR a;
3623 const PTR b;
f3b6f7c3
RH
3624{
3625 bfd_vma av, bv;
3626
bbe66d08
JW
3627 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3628 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
f3b6f7c3
RH
3629
3630 return (av < bv ? -1 : av > bv ? 1 : 0);
3631}
3632
2c4c2bc0 3633/* Make sure we've got ourselves a nice fat __gp value. */
b34976b6 3634static bfd_boolean
2c4c2bc0 3635elfNN_ia64_choose_gp (abfd, info)
800eeca4
JW
3636 bfd *abfd;
3637 struct bfd_link_info *info;
3638{
2c4c2bc0
RH
3639 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3640 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3641 struct elf_link_hash_entry *gp;
3642 bfd_vma gp_val;
3643 asection *os;
bbe66d08 3644 struct elfNN_ia64_link_hash_table *ia64_info;
9a951beb 3645
bbe66d08 3646 ia64_info = elfNN_ia64_hash_table (info);
800eeca4 3647
2c4c2bc0
RH
3648 /* Find the min and max vma of all sections marked short. Also collect
3649 min and max vma of any type, for use in selecting a nice gp. */
3650 for (os = abfd->sections; os ; os = os->next)
800eeca4 3651 {
2c4c2bc0 3652 bfd_vma lo, hi;
800eeca4 3653
2c4c2bc0
RH
3654 if ((os->flags & SEC_ALLOC) == 0)
3655 continue;
3656
3657 lo = os->vma;
3658 hi = os->vma + os->_raw_size;
3659 if (hi < lo)
3660 hi = (bfd_vma) -1;
3661
3662 if (min_vma > lo)
3663 min_vma = lo;
3664 if (max_vma < hi)
3665 max_vma = hi;
3666 if (os->flags & SEC_SMALL_DATA)
800eeca4 3667 {
2c4c2bc0
RH
3668 if (min_short_vma > lo)
3669 min_short_vma = lo;
3670 if (max_short_vma < hi)
3671 max_short_vma = hi;
3672 }
3673 }
800eeca4 3674
2c4c2bc0
RH
3675 /* See if the user wants to force a value. */
3676 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3677 FALSE, FALSE);
800eeca4 3678
2c4c2bc0
RH
3679 if (gp
3680 && (gp->root.type == bfd_link_hash_defined
3681 || gp->root.type == bfd_link_hash_defweak))
3682 {
3683 asection *gp_sec = gp->root.u.def.section;
3684 gp_val = (gp->root.u.def.value
3685 + gp_sec->output_section->vma
3686 + gp_sec->output_offset);
3687 }
3688 else
3689 {
3690 /* Pick a sensible value. */
800eeca4 3691
2c4c2bc0
RH
3692 asection *got_sec = ia64_info->got_sec;
3693
3694 /* Start with just the address of the .got. */
3695 if (got_sec)
3696 gp_val = got_sec->output_section->vma;
3697 else if (max_short_vma != 0)
3698 gp_val = min_short_vma;
3699 else
3700 gp_val = min_vma;
3701
3702 /* If it is possible to address the entire image, but we
3703 don't with the choice above, adjust. */
3704 if (max_vma - min_vma < 0x400000
3705 && max_vma - gp_val <= 0x200000
3706 && gp_val - min_vma > 0x200000)
3707 gp_val = min_vma + 0x200000;
3708 else if (max_short_vma != 0)
3709 {
3710 /* If we don't cover all the short data, adjust. */
3711 if (max_short_vma - gp_val >= 0x200000)
3712 gp_val = min_short_vma + 0x200000;
3713
3714 /* If we're addressing stuff past the end, adjust back. */
3715 if (gp_val > max_vma)
3716 gp_val = max_vma - 0x200000 + 8;
800eeca4 3717 }
2c4c2bc0 3718 }
800eeca4 3719
2c4c2bc0
RH
3720 /* Validate whether all SHF_IA_64_SHORT sections are within
3721 range of the chosen GP. */
800eeca4 3722
2c4c2bc0
RH
3723 if (max_short_vma != 0)
3724 {
3725 if (max_short_vma - min_short_vma >= 0x400000)
800eeca4 3726 {
2c4c2bc0
RH
3727 (*_bfd_error_handler)
3728 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3729 bfd_get_filename (abfd),
3730 (unsigned long) (max_short_vma - min_short_vma));
3731 return FALSE;
800eeca4 3732 }
2c4c2bc0
RH
3733 else if ((gp_val > min_short_vma
3734 && gp_val - min_short_vma > 0x200000)
3735 || (gp_val < max_short_vma
3736 && max_short_vma - gp_val >= 0x200000))
800eeca4 3737 {
2c4c2bc0
RH
3738 (*_bfd_error_handler)
3739 (_("%s: __gp does not cover short data segment"),
3740 bfd_get_filename (abfd));
3741 return FALSE;
3742 }
3743 }
800eeca4 3744
2c4c2bc0 3745 _bfd_set_gp_value (abfd, gp_val);
800eeca4 3746
2c4c2bc0
RH
3747 return TRUE;
3748}
800eeca4 3749
2c4c2bc0
RH
3750static bfd_boolean
3751elfNN_ia64_final_link (abfd, info)
3752 bfd *abfd;
3753 struct bfd_link_info *info;
3754{
3755 struct elfNN_ia64_link_hash_table *ia64_info;
3756 asection *unwind_output_sec;
800eeca4 3757
2c4c2bc0 3758 ia64_info = elfNN_ia64_hash_table (info);
800eeca4 3759
2c4c2bc0
RH
3760 /* Make sure we've got ourselves a nice fat __gp value. */
3761 if (!info->relocateable)
3762 {
3763 bfd_vma gp_val = _bfd_get_gp_value (abfd);
3764 struct elf_link_hash_entry *gp;
3765
3766 if (gp_val == 0)
800eeca4 3767 {
2c4c2bc0
RH
3768 if (! elfNN_ia64_choose_gp (abfd, info))
3769 return FALSE;
3770 gp_val = _bfd_get_gp_value (abfd);
800eeca4
JW
3771 }
3772
2c4c2bc0
RH
3773 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3774 FALSE, FALSE);
b4adccfd
RH
3775 if (gp)
3776 {
3777 gp->root.type = bfd_link_hash_defined;
3778 gp->root.u.def.value = gp_val;
3779 gp->root.u.def.section = bfd_abs_section_ptr;
3780 }
800eeca4
JW
3781 }
3782
f3b6f7c3 3783 /* If we're producing a final executable, we need to sort the contents
9a951beb
RH
3784 of the .IA_64.unwind section. Force this section to be relocated
3785 into memory rather than written immediately to the output file. */
3786 unwind_output_sec = NULL;
f3b6f7c3
RH
3787 if (!info->relocateable)
3788 {
3789 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3790 if (s)
3791 {
9a951beb
RH
3792 unwind_output_sec = s->output_section;
3793 unwind_output_sec->contents
3794 = bfd_malloc (unwind_output_sec->_raw_size);
3795 if (unwind_output_sec->contents == NULL)
b34976b6 3796 return FALSE;
9a951beb
RH
3797 }
3798 }
f3b6f7c3 3799
9a951beb
RH
3800 /* Invoke the regular ELF backend linker to do all the work. */
3801 if (!bfd_elfNN_bfd_final_link (abfd, info))
b34976b6 3802 return FALSE;
f3b6f7c3 3803
9a951beb
RH
3804 if (unwind_output_sec)
3805 {
3806 elfNN_ia64_unwind_entry_compare_bfd = abfd;
dc810e39
AM
3807 qsort (unwind_output_sec->contents,
3808 (size_t) (unwind_output_sec->_raw_size / 24),
3809 24,
3810 elfNN_ia64_unwind_entry_compare);
9a951beb
RH
3811
3812 if (! bfd_set_section_contents (abfd, unwind_output_sec,
dc810e39 3813 unwind_output_sec->contents, (bfd_vma) 0,
9a951beb 3814 unwind_output_sec->_raw_size))
b34976b6 3815 return FALSE;
f3b6f7c3
RH
3816 }
3817
b34976b6 3818 return TRUE;
800eeca4
JW
3819}
3820
b34976b6 3821static bfd_boolean
bbe66d08 3822elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
800eeca4
JW
3823 contents, relocs, local_syms, local_sections)
3824 bfd *output_bfd;
3825 struct bfd_link_info *info;
3826 bfd *input_bfd;
3827 asection *input_section;
3828 bfd_byte *contents;
3829 Elf_Internal_Rela *relocs;
3830 Elf_Internal_Sym *local_syms;
3831 asection **local_sections;
3832{
bbe66d08 3833 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
3834 Elf_Internal_Shdr *symtab_hdr;
3835 Elf_Internal_Rela *rel;
3836 Elf_Internal_Rela *relend;
3837 asection *srel;
b34976b6 3838 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
800eeca4
JW
3839 bfd_vma gp_val;
3840
3841 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
bbe66d08 3842 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
3843
3844 /* Infect various flags from the input section to the output section. */
3845 if (info->relocateable)
3846 {
3847 bfd_vma flags;
3848
3849 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3850 flags &= SHF_IA_64_NORECOV;
3851
3852 elf_section_data(input_section->output_section)
3853 ->this_hdr.sh_flags |= flags;
b34976b6 3854 return TRUE;
800eeca4
JW
3855 }
3856
3857 gp_val = _bfd_get_gp_value (output_bfd);
b34976b6 3858 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
800eeca4
JW
3859
3860 rel = relocs;
3861 relend = relocs + input_section->reloc_count;
3862 for (; rel < relend; ++rel)
3863 {
3864 struct elf_link_hash_entry *h;
bbe66d08 3865 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
3866 bfd_reloc_status_type r;
3867 reloc_howto_type *howto;
3868 unsigned long r_symndx;
3869 Elf_Internal_Sym *sym;
3870 unsigned int r_type;
3871 bfd_vma value;
3872 asection *sym_sec;
3873 bfd_byte *hit_addr;
b34976b6
AM
3874 bfd_boolean dynamic_symbol_p;
3875 bfd_boolean undef_weak_ref;
800eeca4 3876
bbe66d08 3877 r_type = ELFNN_R_TYPE (rel->r_info);
800eeca4
JW
3878 if (r_type > R_IA64_MAX_RELOC_CODE)
3879 {
3880 (*_bfd_error_handler)
3881 (_("%s: unknown relocation type %d"),
8f615d07 3882 bfd_archive_filename (input_bfd), (int)r_type);
800eeca4 3883 bfd_set_error (bfd_error_bad_value);
b34976b6 3884 ret_val = FALSE;
800eeca4
JW
3885 continue;
3886 }
b491616a 3887
800eeca4 3888 howto = lookup_howto (r_type);
bbe66d08 3889 r_symndx = ELFNN_R_SYM (rel->r_info);
800eeca4
JW
3890 h = NULL;
3891 sym = NULL;
3892 sym_sec = NULL;
b34976b6 3893 undef_weak_ref = FALSE;
800eeca4
JW
3894
3895 if (r_symndx < symtab_hdr->sh_info)
3896 {
3897 /* Reloc against local symbol. */
3898 sym = local_syms + r_symndx;
3899 sym_sec = local_sections[r_symndx];
f8df10f4 3900 value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel);
f7460f5f
JJ
3901 if ((sym_sec->flags & SEC_MERGE)
3902 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
68bfbfcc 3903 && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
f7460f5f
JJ
3904 {
3905 struct elfNN_ia64_local_hash_entry *loc_h;
b34976b6
AM
3906
3907 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
f7460f5f
JJ
3908 if (loc_h && ! loc_h->sec_merge_done)
3909 {
3910 struct elfNN_ia64_dyn_sym_info *dynent;
3911 asection *msec;
3912
3913 for (dynent = loc_h->info; dynent; dynent = dynent->next)
3914 {
3915 msec = sym_sec;
3916 dynent->addend =
3917 _bfd_merged_section_offset (output_bfd, &msec,
3918 elf_section_data (msec)->
65765700 3919 sec_info,
f7460f5f
JJ
3920 sym->st_value
3921 + dynent->addend,
3922 (bfd_vma) 0);
3923 dynent->addend -= sym->st_value;
3924 dynent->addend += msec->output_section->vma
3925 + msec->output_offset
3926 - sym_sec->output_section->vma
3927 - sym_sec->output_offset;
3928 }
3929 loc_h->sec_merge_done = 1;
3930 }
3931 }
800eeca4
JW
3932 }
3933 else
3934 {
3935 long indx;
3936
3937 /* Reloc against global symbol. */
3938 indx = r_symndx - symtab_hdr->sh_info;
3939 h = elf_sym_hashes (input_bfd)[indx];
3940 while (h->root.type == bfd_link_hash_indirect
3941 || h->root.type == bfd_link_hash_warning)
3942 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3943
3944 value = 0;
3945 if (h->root.type == bfd_link_hash_defined
3946 || h->root.type == bfd_link_hash_defweak)
3947 {
3948 sym_sec = h->root.u.def.section;
3949
3950 /* Detect the cases that sym_sec->output_section is
3951 expected to be NULL -- all cases in which the symbol
3952 is defined in another shared module. This includes
3953 PLT relocs for which we've created a PLT entry and
3954 other relocs for which we're prepared to create
3955 dynamic relocations. */
3956 /* ??? Just accept it NULL and continue. */
3957
3958 if (sym_sec->output_section != NULL)
3959 {
3960 value = (h->root.u.def.value
3961 + sym_sec->output_section->vma
3962 + sym_sec->output_offset);
3963 }
3964 }
3965 else if (h->root.type == bfd_link_hash_undefweak)
b34976b6 3966 undef_weak_ref = TRUE;
671bae9c 3967 else if (info->shared
3a27a730
L
3968 && !info->no_undefined
3969 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
800eeca4
JW
3970 ;
3971 else
3972 {
3973 if (! ((*info->callbacks->undefined_symbol)
3974 (info, h->root.root.string, input_bfd,
3975 input_section, rel->r_offset,
3a27a730
L
3976 (!info->shared || info->no_undefined
3977 || ELF_ST_VISIBILITY (h->other)))))
b34976b6 3978 return FALSE;
800eeca4
JW
3979 continue;
3980 }
3981 }
3982
3983 hit_addr = contents + rel->r_offset;
3984 value += rel->r_addend;
bbe66d08 3985 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
800eeca4
JW
3986
3987 switch (r_type)
3988 {
3989 case R_IA64_NONE:
3990 case R_IA64_LDXMOV:
3991 continue;
3992
3993 case R_IA64_IMM14:
3994 case R_IA64_IMM22:
3995 case R_IA64_IMM64:
3996 case R_IA64_DIR32MSB:
3997 case R_IA64_DIR32LSB:
3998 case R_IA64_DIR64MSB:
3999 case R_IA64_DIR64LSB:
4000 /* Install a dynamic relocation for this reloc. */
7b6dab7f
TW
4001 if ((dynamic_symbol_p || info->shared
4002 || (elfNN_ia64_aix_vec (info->hash->creator)
64e9ece0 4003 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
dc810e39 4004 && (!h || strcmp (h->root.root.string,
64e9ece0 4005 "__GLOB_DATA_PTR") != 0)))
ec338859 4006 && r_symndx != 0
800eeca4
JW
4007 && (input_section->flags & SEC_ALLOC) != 0)
4008 {
4009 unsigned int dyn_r_type;
4010 long dynindx;
18b27f17 4011 bfd_vma addend;
800eeca4
JW
4012
4013 BFD_ASSERT (srel != NULL);
4014
4015 /* If we don't need dynamic symbol lookup, find a
4016 matching RELATIVE relocation. */
4017 dyn_r_type = r_type;
4018 if (dynamic_symbol_p)
18b27f17
RH
4019 {
4020 dynindx = h->dynindx;
4021 addend = rel->r_addend;
4022 value = 0;
4023 }
800eeca4
JW
4024 else
4025 {
4026 switch (r_type)
4027 {
4028 case R_IA64_DIR32MSB:
4029 dyn_r_type = R_IA64_REL32MSB;
4030 break;
4031 case R_IA64_DIR32LSB:
4032 dyn_r_type = R_IA64_REL32LSB;
4033 break;
4034 case R_IA64_DIR64MSB:
4035 dyn_r_type = R_IA64_REL64MSB;
4036 break;
4037 case R_IA64_DIR64LSB:
4038 dyn_r_type = R_IA64_REL64LSB;
4039 break;
4040
4041 default:
4042 /* We can't represent this without a dynamic symbol.
4043 Adjust the relocation to be against an output
4044 section symbol, which are always present in the
4045 dynamic symbol table. */
4046 /* ??? People shouldn't be doing non-pic code in
4047 shared libraries. Hork. */
4048 (*_bfd_error_handler)
4049 (_("%s: linking non-pic code in a shared library"),
8f615d07 4050 bfd_archive_filename (input_bfd));
b34976b6 4051 ret_val = FALSE;
800eeca4
JW
4052 continue;
4053 }
4054 dynindx = 0;
18b27f17 4055 addend = value;
800eeca4
JW
4056 }
4057
7b6dab7f
TW
4058 if (elfNN_ia64_aix_vec (info->hash->creator))
4059 rel->r_addend = value;
bbe66d08 4060 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
800eeca4 4061 srel, rel->r_offset, dyn_r_type,
18b27f17 4062 dynindx, addend);
800eeca4 4063 }
ae9a127f 4064 /* Fall through. */
800eeca4
JW
4065
4066 case R_IA64_LTV32MSB:
4067 case R_IA64_LTV32LSB:
4068 case R_IA64_LTV64MSB:
4069 case R_IA64_LTV64LSB:
bbe66d08 4070 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
800eeca4
JW
4071 break;
4072
4073 case R_IA64_GPREL22:
4074 case R_IA64_GPREL64I:
4075 case R_IA64_GPREL32MSB:
4076 case R_IA64_GPREL32LSB:
4077 case R_IA64_GPREL64MSB:
4078 case R_IA64_GPREL64LSB:
4079 if (dynamic_symbol_p)
4080 {
4081 (*_bfd_error_handler)
4082 (_("%s: @gprel relocation against dynamic symbol %s"),
8f615d07 4083 bfd_archive_filename (input_bfd), h->root.root.string);
b34976b6 4084 ret_val = FALSE;
800eeca4
JW
4085 continue;
4086 }
4087 value -= gp_val;
bbe66d08 4088 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
800eeca4
JW
4089 break;
4090
4091 case R_IA64_LTOFF22:
4092 case R_IA64_LTOFF22X:
4093 case R_IA64_LTOFF64I:
b34976b6 4094 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
800eeca4
JW
4095 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4096 rel->r_addend, value, R_IA64_DIR64LSB);
4097 value -= gp_val;
bbe66d08 4098 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
800eeca4
JW
4099 break;
4100
4101 case R_IA64_PLTOFF22:
4102 case R_IA64_PLTOFF64I:
4103 case R_IA64_PLTOFF64MSB:
4104 case R_IA64_PLTOFF64LSB:
b34976b6
AM
4105 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4106 value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
800eeca4 4107 value -= gp_val;
bbe66d08 4108 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
800eeca4
JW
4109 break;
4110
4111 case R_IA64_FPTR64I:
4112 case R_IA64_FPTR32MSB:
4113 case R_IA64_FPTR32LSB:
4114 case R_IA64_FPTR64MSB:
4115 case R_IA64_FPTR64LSB:
b34976b6 4116 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
800eeca4
JW
4117 if (dyn_i->want_fptr)
4118 {
4119 if (!undef_weak_ref)
4120 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4121 }
4122 else
4123 {
4124 long dynindx;
4125
4126 /* Otherwise, we expect the dynamic linker to create
4127 the entry. */
4128
4129 if (h)
4130 {
4131 if (h->dynindx != -1)
4132 dynindx = h->dynindx;
4133 else
4134 dynindx = (_bfd_elf_link_lookup_local_dynindx
4135 (info, h->root.u.def.section->owner,
4136 global_sym_index (h)));
4137 }
4138 else
4139 {
4140 dynindx = (_bfd_elf_link_lookup_local_dynindx
dc810e39 4141 (info, input_bfd, (long) r_symndx));
800eeca4
JW
4142 }
4143
bbe66d08 4144 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
800eeca4
JW
4145 srel, rel->r_offset, r_type,
4146 dynindx, rel->r_addend);
4147 value = 0;
4148 }
4149
bbe66d08 4150 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
800eeca4
JW
4151 break;
4152
4153 case R_IA64_LTOFF_FPTR22:
4154 case R_IA64_LTOFF_FPTR64I:
a4bd8390
JW
4155 case R_IA64_LTOFF_FPTR32MSB:
4156 case R_IA64_LTOFF_FPTR32LSB:
800eeca4
JW
4157 case R_IA64_LTOFF_FPTR64MSB:
4158 case R_IA64_LTOFF_FPTR64LSB:
4159 {
4160 long dynindx;
4161
b34976b6 4162 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
800eeca4
JW
4163 if (dyn_i->want_fptr)
4164 {
4165 BFD_ASSERT (h == NULL || h->dynindx == -1)
4166 if (!undef_weak_ref)
4167 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4168 dynindx = -1;
4169 }
4170 else
4171 {
4172 /* Otherwise, we expect the dynamic linker to create
4173 the entry. */
4174 if (h)
4175 {
4176 if (h->dynindx != -1)
4177 dynindx = h->dynindx;
4178 else
4179 dynindx = (_bfd_elf_link_lookup_local_dynindx
4180 (info, h->root.u.def.section->owner,
4181 global_sym_index (h)));
4182 }
4183 else
4184 dynindx = (_bfd_elf_link_lookup_local_dynindx
dc810e39 4185 (info, input_bfd, (long) r_symndx));
800eeca4
JW
4186 value = 0;
4187 }
4188
4189 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4190 rel->r_addend, value, R_IA64_FPTR64LSB);
4191 value -= gp_val;
bbe66d08 4192 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
800eeca4
JW
4193 }
4194 break;
4195
4196 case R_IA64_PCREL32MSB:
4197 case R_IA64_PCREL32LSB:
4198 case R_IA64_PCREL64MSB:
4199 case R_IA64_PCREL64LSB:
4200 /* Install a dynamic relocation for this reloc. */
ec338859
AM
4201 if ((dynamic_symbol_p
4202 || elfNN_ia64_aix_vec (info->hash->creator))
4203 && r_symndx != 0)
800eeca4
JW
4204 {
4205 BFD_ASSERT (srel != NULL);
4206
bbe66d08 4207 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
800eeca4
JW
4208 srel, rel->r_offset, r_type,
4209 h->dynindx, rel->r_addend);
4210 }
4211 goto finish_pcrel;
4212
800eeca4 4213 case R_IA64_PCREL21B:
748abff6 4214 case R_IA64_PCREL60B:
800eeca4 4215 /* We should have created a PLT entry for any dynamic symbol. */
800eeca4
JW
4216 dyn_i = NULL;
4217 if (h)
b34976b6 4218 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
800eeca4
JW
4219
4220 if (dyn_i && dyn_i->want_plt2)
4221 {
4222 /* Should have caught this earlier. */
4223 BFD_ASSERT (rel->r_addend == 0);
4224
4225 value = (ia64_info->plt_sec->output_section->vma
4226 + ia64_info->plt_sec->output_offset
4227 + dyn_i->plt2_offset);
4228 }
4229 else
4230 {
4231 /* Since there's no PLT entry, Validate that this is
4232 locally defined. */
4233 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4234
4235 /* If the symbol is undef_weak, we shouldn't be trying
4236 to call it. There's every chance that we'd wind up
4237 with an out-of-range fixup here. Don't bother setting
4238 any value at all. */
4239 if (undef_weak_ref)
4240 continue;
4241 }
4242 goto finish_pcrel;
4243
2f9bd3f6
RH
4244 case R_IA64_PCREL21BI:
4245 case R_IA64_PCREL21F:
4246 case R_IA64_PCREL21M:
748abff6
RH
4247 case R_IA64_PCREL22:
4248 case R_IA64_PCREL64I:
2f9bd3f6
RH
4249 /* The PCREL21BI reloc is specifically not intended for use with
4250 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4251 fixup code, and thus probably ought not be dynamic. The
4252 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4253 if (dynamic_symbol_p)
4254 {
4255 const char *msg;
4256
4257 if (r_type == R_IA64_PCREL21BI)
4258 msg = _("%s: @internal branch to dynamic symbol %s");
4259 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4260 msg = _("%s: speculation fixup to dynamic symbol %s");
4261 else
4262 msg = _("%s: @pcrel relocation against dynamic symbol %s");
4263 (*_bfd_error_handler) (msg, bfd_archive_filename (input_bfd),
4264 h->root.root.string);
4265 ret_val = FALSE;
4266 continue;
4267 }
4268 goto finish_pcrel;
4269
800eeca4
JW
4270 finish_pcrel:
4271 /* Make pc-relative. */
4272 value -= (input_section->output_section->vma
4273 + input_section->output_offset
4274 + rel->r_offset) & ~ (bfd_vma) 0x3;
bbe66d08 4275 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
800eeca4
JW
4276 break;
4277
4278 case R_IA64_SEGREL32MSB:
4279 case R_IA64_SEGREL32LSB:
4280 case R_IA64_SEGREL64MSB:
4281 case R_IA64_SEGREL64LSB:
d7458677
AM
4282 if (r_symndx == 0)
4283 {
4284 /* If the input section was discarded from the output, then
4285 do nothing. */
4286 r = bfd_reloc_ok;
4287 }
4288 else
4289 {
4290 struct elf_segment_map *m;
4291 Elf_Internal_Phdr *p;
4292
4293 /* Find the segment that contains the output_section. */
4294 for (m = elf_tdata (output_bfd)->segment_map,
4295 p = elf_tdata (output_bfd)->phdr;
4296 m != NULL;
4297 m = m->next, p++)
4298 {
4299 int i;
4300 for (i = m->count - 1; i >= 0; i--)
4301 if (m->sections[i] == sym_sec->output_section)
4302 break;
4303 if (i >= 0)
800eeca4 4304 break;
d7458677 4305 }
800eeca4 4306
d7458677
AM
4307 if (m == NULL)
4308 {
800eeca4 4309 r = bfd_reloc_notsupported;
d7458677
AM
4310 }
4311 else
4312 {
4313 /* The VMA of the segment is the vaddr of the associated
4314 program header. */
4315 if (value > p->p_vaddr)
4316 value -= p->p_vaddr;
4317 else
4318 value = 0;
4319 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4320 r_type);
4321 }
4322 break;
4323 }
800eeca4
JW
4324
4325 case R_IA64_SECREL32MSB:
4326 case R_IA64_SECREL32LSB:
4327 case R_IA64_SECREL64MSB:
4328 case R_IA64_SECREL64LSB:
4329 /* Make output-section relative. */
4330 if (value > input_section->output_section->vma)
4331 value -= input_section->output_section->vma;
4332 else
4333 value = 0;
bbe66d08 4334 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
800eeca4
JW
4335 break;
4336
800eeca4
JW
4337 case R_IA64_IPLTMSB:
4338 case R_IA64_IPLTLSB:
18b27f17
RH
4339 /* Install a dynamic relocation for this reloc. */
4340 if ((dynamic_symbol_p || info->shared)
4341 && (input_section->flags & SEC_ALLOC) != 0)
4342 {
18b27f17
RH
4343 BFD_ASSERT (srel != NULL);
4344
4345 /* If we don't need dynamic symbol lookup, install two
4346 RELATIVE relocations. */
4347 if (! dynamic_symbol_p)
4348 {
4349 unsigned int dyn_r_type;
3e932841 4350
18b27f17
RH
4351 if (r_type == R_IA64_IPLTMSB)
4352 dyn_r_type = R_IA64_REL64MSB;
4353 else
4354 dyn_r_type = R_IA64_REL64LSB;
4355
4356 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4357 input_section,
4358 srel, rel->r_offset,
4359 dyn_r_type, 0, value);
4360 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4361 input_section,
4362 srel, rel->r_offset + 8,
4363 dyn_r_type, 0, gp_val);
4364 }
4365 else
4366 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4367 srel, rel->r_offset, r_type,
4368 h->dynindx, rel->r_addend);
4369 }
4370
4371 if (r_type == R_IA64_IPLTMSB)
4372 r_type = R_IA64_DIR64MSB;
4373 else
4374 r_type = R_IA64_DIR64LSB;
4375 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4376 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
4377 r_type);
4378 break;
800eeca4 4379
13ae64f3
JJ
4380 case R_IA64_TPREL14:
4381 case R_IA64_TPREL22:
4382 case R_IA64_TPREL64I:
4383 value -= elfNN_ia64_tprel_base (info);
4384 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4385 break;
4386
4387 case R_IA64_DTPREL14:
4388 case R_IA64_DTPREL22:
4389 case R_IA64_DTPREL64I:
b3dfd7fe
JJ
4390 case R_IA64_DTPREL64LSB:
4391 case R_IA64_DTPREL64MSB:
13ae64f3
JJ
4392 value -= elfNN_ia64_dtprel_base (info);
4393 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4394 break;
4395
4396 case R_IA64_LTOFF_TPREL22:
4397 case R_IA64_LTOFF_DTPMOD22:
4398 case R_IA64_LTOFF_DTPREL22:
4399 {
4400 int got_r_type;
a823975a
JJ
4401 long dynindx = h ? h->dynindx : -1;
4402 bfd_vma r_addend = rel->r_addend;
13ae64f3
JJ
4403
4404 switch (r_type)
4405 {
4406 default:
4407 case R_IA64_LTOFF_TPREL22:
a823975a
JJ
4408 if (!dynamic_symbol_p)
4409 {
4410 if (!info->shared)
4411 value -= elfNN_ia64_tprel_base (info);
4412 else
4413 {
4414 r_addend += value - elfNN_ia64_dtprel_base (info);
4415 dynindx = 0;
4416 }
4417 }
13ae64f3
JJ
4418 got_r_type = R_IA64_TPREL64LSB;
4419 break;
4420 case R_IA64_LTOFF_DTPMOD22:
4421 if (!dynamic_symbol_p && !info->shared)
4422 value = 1;
4423 got_r_type = R_IA64_DTPMOD64LSB;
4424 break;
4425 case R_IA64_LTOFF_DTPREL22:
4426 if (!dynamic_symbol_p)
4427 value -= elfNN_ia64_dtprel_base (info);
4428 got_r_type = R_IA64_DTPREL64LSB;
4429 break;
4430 }
b34976b6 4431 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
a823975a 4432 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
13ae64f3
JJ
4433 value, got_r_type);
4434 value -= gp_val;
4435 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4436 r_type);
4437 }
4438 break;
4439
800eeca4
JW
4440 default:
4441 r = bfd_reloc_notsupported;
4442 break;
4443 }
4444
4445 switch (r)
4446 {
4447 case bfd_reloc_ok:
4448 break;
4449
4450 case bfd_reloc_undefined:
4451 /* This can happen for global table relative relocs if
4452 __gp is undefined. This is a panic situation so we
4453 don't try to continue. */
4454 (*info->callbacks->undefined_symbol)
4455 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
b34976b6 4456 return FALSE;
800eeca4
JW
4457
4458 case bfd_reloc_notsupported:
4459 {
4460 const char *name;
4461
4462 if (h)
4463 name = h->root.root.string;
4464 else
4465 {
4466 name = bfd_elf_string_from_elf_section (input_bfd,
4467 symtab_hdr->sh_link,
4468 sym->st_name);
4469 if (name == NULL)
b34976b6 4470 return FALSE;
800eeca4
JW
4471 if (*name == '\0')
4472 name = bfd_section_name (input_bfd, input_section);
4473 }
4474 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4475 name, input_bfd,
4476 input_section, rel->r_offset))
b34976b6
AM
4477 return FALSE;
4478 ret_val = FALSE;
800eeca4
JW
4479 }
4480 break;
4481
4482 case bfd_reloc_dangerous:
4483 case bfd_reloc_outofrange:
4484 case bfd_reloc_overflow:
4485 default:
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->reloc_overflow) (info, name,
dc810e39
AM
4502 howto->name,
4503 (bfd_vma) 0,
800eeca4
JW
4504 input_bfd,
4505 input_section,
4506 rel->r_offset))
b34976b6
AM
4507 return FALSE;
4508 ret_val = FALSE;
800eeca4
JW
4509 }
4510 break;
4511 }
4512 }
4513
4514 return ret_val;
4515}
4516
b34976b6 4517static bfd_boolean
bbe66d08 4518elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
800eeca4
JW
4519 bfd *output_bfd;
4520 struct bfd_link_info *info;
4521 struct elf_link_hash_entry *h;
4522 Elf_Internal_Sym *sym;
4523{
bbe66d08
JW
4524 struct elfNN_ia64_link_hash_table *ia64_info;
4525 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4 4526
bbe66d08 4527 ia64_info = elfNN_ia64_hash_table (info);
b34976b6 4528 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
800eeca4
JW
4529
4530 /* Fill in the PLT data, if required. */
4531 if (dyn_i && dyn_i->want_plt)
4532 {
4533 Elf_Internal_Rela outrel;
4534 bfd_byte *loc;
4535 asection *plt_sec;
4536 bfd_vma plt_addr, pltoff_addr, gp_val, index;
800eeca4
JW
4537
4538 gp_val = _bfd_get_gp_value (output_bfd);
4539
4540 /* Initialize the minimal PLT entry. */
4541
4542 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4543 plt_sec = ia64_info->plt_sec;
4544 loc = plt_sec->contents + dyn_i->plt_offset;
4545
4546 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
bbe66d08
JW
4547 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4548 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
800eeca4
JW
4549 R_IA64_PCREL21B);
4550
4551 plt_addr = (plt_sec->output_section->vma
4552 + plt_sec->output_offset
4553 + dyn_i->plt_offset);
b34976b6 4554 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
800eeca4
JW
4555
4556 /* Initialize the FULL PLT entry, if needed. */
4557 if (dyn_i->want_plt2)
4558 {
4559 loc = plt_sec->contents + dyn_i->plt2_offset;
4560
4561 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
bbe66d08 4562 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
800eeca4
JW
4563 R_IA64_IMM22);
4564
4565 /* Mark the symbol as undefined, rather than as defined in the
4566 plt section. Leave the value alone. */
4567 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4568 first place. But perhaps elflink.h did some for us. */
4569 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4570 sym->st_shndx = SHN_UNDEF;
4571 }
4572
4573 /* Create the dynamic relocation. */
4574 outrel.r_offset = pltoff_addr;
4575 if (bfd_little_endian (output_bfd))
bbe66d08 4576 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
800eeca4 4577 else
bbe66d08 4578 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
800eeca4
JW
4579 outrel.r_addend = 0;
4580
4581 /* This is fun. In the .IA_64.pltoff section, we've got entries
4582 that correspond both to real PLT entries, and those that
4583 happened to resolve to local symbols but need to be created
4584 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4585 relocations for the real PLT should come at the end of the
4586 section, so that they can be indexed by plt entry at runtime.
4587
4588 We emitted all of the relocations for the non-PLT @pltoff
4589 entries during relocate_section. So we can consider the
4590 existing sec->reloc_count to be the base of the array of
4591 PLT relocations. */
4592
947216bf
AM
4593 loc = ia64_info->rel_pltoff_sec->contents;
4594 loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
4595 * sizeof (Elf64_External_Rela));
4596 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
800eeca4
JW
4597 }
4598
4599 /* Mark some specially defined symbols as absolute. */
4600 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4601 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4602 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4603 sym->st_shndx = SHN_ABS;
4604
b34976b6 4605 return TRUE;
800eeca4
JW
4606}
4607
b34976b6 4608static bfd_boolean
bbe66d08 4609elfNN_ia64_finish_dynamic_sections (abfd, info)
800eeca4
JW
4610 bfd *abfd;
4611 struct bfd_link_info *info;
4612{
bbe66d08 4613 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
4614 bfd *dynobj;
4615
bbe66d08 4616 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
4617 dynobj = ia64_info->root.dynobj;
4618
4619 if (elf_hash_table (info)->dynamic_sections_created)
4620 {
bbe66d08 4621 ElfNN_External_Dyn *dyncon, *dynconend;
800eeca4
JW
4622 asection *sdyn, *sgotplt;
4623 bfd_vma gp_val;
4624
4625 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4626 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4627 BFD_ASSERT (sdyn != NULL);
bbe66d08
JW
4628 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4629 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
800eeca4
JW
4630
4631 gp_val = _bfd_get_gp_value (abfd);
4632
4633 for (; dyncon < dynconend; dyncon++)
4634 {
4635 Elf_Internal_Dyn dyn;
800eeca4 4636
bbe66d08 4637 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
800eeca4
JW
4638
4639 switch (dyn.d_tag)
4640 {
4641 case DT_PLTGOT:
4642 dyn.d_un.d_ptr = gp_val;
4643 break;
4644
4645 case DT_PLTRELSZ:
4646 dyn.d_un.d_val = (ia64_info->minplt_entries
bbe66d08 4647 * sizeof (ElfNN_External_Rela));
800eeca4
JW
4648 break;
4649
4650 case DT_JMPREL:
4651 /* See the comment above in finish_dynamic_symbol. */
4652 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4653 + ia64_info->rel_pltoff_sec->output_offset
4654 + (ia64_info->rel_pltoff_sec->reloc_count
bbe66d08 4655 * sizeof (ElfNN_External_Rela)));
800eeca4
JW
4656 break;
4657
4658 case DT_IA_64_PLT_RESERVE:
4659 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4660 + sgotplt->output_offset);
4661 break;
4662
4663 case DT_RELASZ:
4664 /* Do not have RELASZ include JMPREL. This makes things
3e932841 4665 easier on ld.so. This is not what the rest of BFD set up. */
800eeca4 4666 dyn.d_un.d_val -= (ia64_info->minplt_entries
bbe66d08 4667 * sizeof (ElfNN_External_Rela));
800eeca4 4668 break;
800eeca4
JW
4669 }
4670
bbe66d08 4671 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
800eeca4
JW
4672 }
4673
ae9a127f 4674 /* Initialize the PLT0 entry. */
800eeca4
JW
4675 if (ia64_info->plt_sec)
4676 {
4677 bfd_byte *loc = ia64_info->plt_sec->contents;
4678 bfd_vma pltres;
4679
4680 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4681
4682 pltres = (sgotplt->output_section->vma
4683 + sgotplt->output_offset
4684 - gp_val);
4685
bbe66d08 4686 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
800eeca4
JW
4687 }
4688 }
4689
b34976b6 4690 return TRUE;
800eeca4
JW
4691}
4692\f
ae9a127f 4693/* ELF file flag handling: */
800eeca4 4694
3e932841 4695/* Function to keep IA-64 specific file flags. */
b34976b6 4696static bfd_boolean
bbe66d08 4697elfNN_ia64_set_private_flags (abfd, flags)
800eeca4
JW
4698 bfd *abfd;
4699 flagword flags;
4700{
4701 BFD_ASSERT (!elf_flags_init (abfd)
4702 || elf_elfheader (abfd)->e_flags == flags);
4703
4704 elf_elfheader (abfd)->e_flags = flags;
b34976b6
AM
4705 elf_flags_init (abfd) = TRUE;
4706 return TRUE;
800eeca4
JW
4707}
4708
800eeca4
JW
4709/* Merge backend specific data from an object file to the output
4710 object file when linking. */
b34976b6 4711static bfd_boolean
bbe66d08 4712elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
800eeca4
JW
4713 bfd *ibfd, *obfd;
4714{
4715 flagword out_flags;
4716 flagword in_flags;
b34976b6 4717 bfd_boolean ok = TRUE;
800eeca4
JW
4718
4719 /* Don't even pretend to support mixed-format linking. */
4720 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4721 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
b34976b6 4722 return FALSE;
800eeca4
JW
4723
4724 in_flags = elf_elfheader (ibfd)->e_flags;
4725 out_flags = elf_elfheader (obfd)->e_flags;
4726
4727 if (! elf_flags_init (obfd))
4728 {
b34976b6 4729 elf_flags_init (obfd) = TRUE;
800eeca4
JW
4730 elf_elfheader (obfd)->e_flags = in_flags;
4731
4732 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4733 && bfd_get_arch_info (obfd)->the_default)
4734 {
4735 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4736 bfd_get_mach (ibfd));
4737 }
4738
b34976b6 4739 return TRUE;
800eeca4
JW
4740 }
4741
4742 /* Check flag compatibility. */
4743 if (in_flags == out_flags)
b34976b6 4744 return TRUE;
800eeca4 4745
c43c2cc5
JW
4746 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4747 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4748 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4749
800eeca4
JW
4750 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4751 {
4752 (*_bfd_error_handler)
4753 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
8f615d07 4754 bfd_archive_filename (ibfd));
800eeca4
JW
4755
4756 bfd_set_error (bfd_error_bad_value);
b34976b6 4757 ok = FALSE;
800eeca4
JW
4758 }
4759 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4760 {
4761 (*_bfd_error_handler)
4762 (_("%s: linking big-endian files with little-endian files"),
8f615d07 4763 bfd_archive_filename (ibfd));
800eeca4
JW
4764
4765 bfd_set_error (bfd_error_bad_value);
b34976b6 4766 ok = FALSE;
800eeca4
JW
4767 }
4768 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4769 {
4770 (*_bfd_error_handler)
4771 (_("%s: linking 64-bit files with 32-bit files"),
8f615d07 4772 bfd_archive_filename (ibfd));
800eeca4
JW
4773
4774 bfd_set_error (bfd_error_bad_value);
b34976b6 4775 ok = FALSE;
800eeca4 4776 }
c43c2cc5
JW
4777 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4778 {
4779 (*_bfd_error_handler)
4780 (_("%s: linking constant-gp files with non-constant-gp files"),
8f615d07 4781 bfd_archive_filename (ibfd));
c43c2cc5
JW
4782
4783 bfd_set_error (bfd_error_bad_value);
b34976b6 4784 ok = FALSE;
c43c2cc5
JW
4785 }
4786 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4787 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4788 {
4789 (*_bfd_error_handler)
4790 (_("%s: linking auto-pic files with non-auto-pic files"),
8f615d07 4791 bfd_archive_filename (ibfd));
c43c2cc5
JW
4792
4793 bfd_set_error (bfd_error_bad_value);
b34976b6 4794 ok = FALSE;
c43c2cc5 4795 }
800eeca4
JW
4796
4797 return ok;
4798}
4799
b34976b6 4800static bfd_boolean
bbe66d08 4801elfNN_ia64_print_private_bfd_data (abfd, ptr)
800eeca4
JW
4802 bfd *abfd;
4803 PTR ptr;
4804{
4805 FILE *file = (FILE *) ptr;
4806 flagword flags = elf_elfheader (abfd)->e_flags;
4807
4808 BFD_ASSERT (abfd != NULL && ptr != NULL);
4809
c43c2cc5 4810 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
800eeca4
JW
4811 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4812 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4813 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
c43c2cc5
JW
4814 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4815 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4816 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4817 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
800eeca4 4818 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
3e932841 4819
800eeca4 4820 _bfd_elf_print_private_bfd_data (abfd, ptr);
b34976b6 4821 return TRUE;
800eeca4 4822}
db6751f2
JJ
4823
4824static enum elf_reloc_type_class
f51e552e
AM
4825elfNN_ia64_reloc_type_class (rela)
4826 const Elf_Internal_Rela *rela;
db6751f2 4827{
f51e552e 4828 switch ((int) ELFNN_R_TYPE (rela->r_info))
db6751f2
JJ
4829 {
4830 case R_IA64_REL32MSB:
4831 case R_IA64_REL32LSB:
4832 case R_IA64_REL64MSB:
4833 case R_IA64_REL64LSB:
4834 return reloc_class_relative;
4835 case R_IA64_IPLTMSB:
4836 case R_IA64_IPLTLSB:
4837 return reloc_class_plt;
4838 case R_IA64_COPY:
4839 return reloc_class_copy;
4840 default:
4841 return reloc_class_normal;
4842 }
4843}
fcf12726 4844
b34976b6 4845static bfd_boolean
d9cf1b54
AM
4846elfNN_ia64_hpux_vec (const bfd_target *vec)
4847{
4848 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4849 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4850}
4851
fcf12726
AM
4852static void
4853elfNN_hpux_post_process_headers (abfd, info)
4854 bfd *abfd;
4855 struct bfd_link_info *info ATTRIBUTE_UNUSED;
4856{
4857 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4858
4859 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4860 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4861}
d9cf1b54 4862
b34976b6 4863bfd_boolean
af746e92 4864elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
d9cf1b54 4865 bfd *abfd ATTRIBUTE_UNUSED;
d9cf1b54
AM
4866 asection *sec;
4867 int *retval;
4868{
4869 if (bfd_is_com_section (sec))
4870 {
4871 *retval = SHN_IA_64_ANSI_COMMON;
b34976b6 4872 return TRUE;
d9cf1b54 4873 }
b34976b6 4874 return FALSE;
d9cf1b54 4875}
800eeca4 4876\f
bbe66d08
JW
4877#define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4878#define TARGET_LITTLE_NAME "elfNN-ia64-little"
4879#define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4880#define TARGET_BIG_NAME "elfNN-ia64-big"
800eeca4
JW
4881#define ELF_ARCH bfd_arch_ia64
4882#define ELF_MACHINE_CODE EM_IA_64
4883#define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4884#define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4885#define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4886
4887#define elf_backend_section_from_shdr \
bbe66d08 4888 elfNN_ia64_section_from_shdr
fa152c49 4889#define elf_backend_section_flags \
bbe66d08 4890 elfNN_ia64_section_flags
800eeca4 4891#define elf_backend_fake_sections \
bbe66d08 4892 elfNN_ia64_fake_sections
81545d45
RH
4893#define elf_backend_final_write_processing \
4894 elfNN_ia64_final_write_processing
800eeca4 4895#define elf_backend_add_symbol_hook \
bbe66d08 4896 elfNN_ia64_add_symbol_hook
800eeca4 4897#define elf_backend_additional_program_headers \
bbe66d08 4898 elfNN_ia64_additional_program_headers
800eeca4 4899#define elf_backend_modify_segment_map \
bbe66d08 4900 elfNN_ia64_modify_segment_map
800eeca4 4901#define elf_info_to_howto \
bbe66d08 4902 elfNN_ia64_info_to_howto
800eeca4 4903
bbe66d08
JW
4904#define bfd_elfNN_bfd_reloc_type_lookup \
4905 elfNN_ia64_reloc_type_lookup
4906#define bfd_elfNN_bfd_is_local_label_name \
4907 elfNN_ia64_is_local_label_name
4908#define bfd_elfNN_bfd_relax_section \
4909 elfNN_ia64_relax_section
800eeca4
JW
4910
4911/* Stuff for the BFD linker: */
bbe66d08
JW
4912#define bfd_elfNN_bfd_link_hash_table_create \
4913 elfNN_ia64_hash_table_create
800eeca4 4914#define elf_backend_create_dynamic_sections \
bbe66d08 4915 elfNN_ia64_create_dynamic_sections
800eeca4 4916#define elf_backend_check_relocs \
bbe66d08 4917 elfNN_ia64_check_relocs
800eeca4 4918#define elf_backend_adjust_dynamic_symbol \
bbe66d08 4919 elfNN_ia64_adjust_dynamic_symbol
800eeca4 4920#define elf_backend_size_dynamic_sections \
bbe66d08 4921 elfNN_ia64_size_dynamic_sections
800eeca4 4922#define elf_backend_relocate_section \
bbe66d08 4923 elfNN_ia64_relocate_section
800eeca4 4924#define elf_backend_finish_dynamic_symbol \
bbe66d08 4925 elfNN_ia64_finish_dynamic_symbol
800eeca4 4926#define elf_backend_finish_dynamic_sections \
bbe66d08
JW
4927 elfNN_ia64_finish_dynamic_sections
4928#define bfd_elfNN_bfd_final_link \
4929 elfNN_ia64_final_link
4930
bbe66d08
JW
4931#define bfd_elfNN_bfd_merge_private_bfd_data \
4932 elfNN_ia64_merge_private_bfd_data
4933#define bfd_elfNN_bfd_set_private_flags \
4934 elfNN_ia64_set_private_flags
4935#define bfd_elfNN_bfd_print_private_bfd_data \
4936 elfNN_ia64_print_private_bfd_data
800eeca4
JW
4937
4938#define elf_backend_plt_readonly 1
4939#define elf_backend_want_plt_sym 0
4940#define elf_backend_plt_alignment 5
4941#define elf_backend_got_header_size 0
4942#define elf_backend_plt_header_size PLT_HEADER_SIZE
4943#define elf_backend_want_got_plt 1
4944#define elf_backend_may_use_rel_p 1
4945#define elf_backend_may_use_rela_p 1
4946#define elf_backend_default_use_rela_p 1
4947#define elf_backend_want_dynbss 0
bbe66d08
JW
4948#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4949#define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
db6751f2 4950#define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
b491616a 4951#define elf_backend_rela_normal 1
800eeca4 4952
bbe66d08 4953#include "elfNN-target.h"
7b6dab7f
TW
4954
4955/* AIX-specific vectors. */
4956
4957#undef TARGET_LITTLE_SYM
4958#define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4959#undef TARGET_LITTLE_NAME
4960#define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4961#undef TARGET_BIG_SYM
4962#define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4963#undef TARGET_BIG_NAME
4964#define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4965
4966#undef elf_backend_add_symbol_hook
4967#define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4968
4969#undef bfd_elfNN_bfd_link_add_symbols
4970#define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4971
4972#define elfNN_bed elfNN_ia64_aix_bed
4973
4974#include "elfNN-target.h"
fcf12726
AM
4975
4976/* HPUX-specific vectors. */
4977
4978#undef TARGET_LITTLE_SYM
4979#undef TARGET_LITTLE_NAME
4980#undef TARGET_BIG_SYM
4981#define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4982#undef TARGET_BIG_NAME
4983#define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4984
254ed743
NC
4985/* We need to undo the AIX specific functions. */
4986
4987#undef elf_backend_add_symbol_hook
4988#define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
4989
4990#undef bfd_elfNN_bfd_link_add_symbols
4991#define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
4992
4993/* These are HP-UX specific functions. */
4994
fcf12726
AM
4995#undef elf_backend_post_process_headers
4996#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4997
d9cf1b54
AM
4998#undef elf_backend_section_from_bfd_section
4999#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5000
5e8d7549
NC
5001#undef elf_backend_want_p_paddr_set_to_zero
5002#define elf_backend_want_p_paddr_set_to_zero 1
5003
fcf12726
AM
5004#undef ELF_MAXPAGESIZE
5005#define ELF_MAXPAGESIZE 0x1000 /* 1K */
5006
5007#undef elfNN_bed
5008#define elfNN_bed elfNN_ia64_hpux_bed
5009
5010#include "elfNN-target.h"
5e8d7549
NC
5011
5012#undef elf_backend_want_p_paddr_set_to_zero
This page took 0.439356 seconds and 4 git commands to generate.