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