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