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