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