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