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