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