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