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