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