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