source: trunk/src/binutils/bfd/elfxx-ia64.c@ 201

Last change on this file since 201 was 10, checked in by bird, 22 years ago

Initial revision

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