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