2001-03-22 Philip Blundell <philb@gnu.org>
[binutils.git] / bfd / elfxx-ia64.c
blob200b8da19493f2ca1d4b1189481b2245d955e9d3
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>
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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"
29 * THE RULES for all the stuff the linker creates --
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.
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.
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.
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.
54 * MIN_PLT Created by PLTOFF entries against dynamic symbols. This
55 * does not reqire dynamic relocations.
58 #define USE_RELA /* we want RELA relocs, not REL */
60 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
62 typedef struct bfd_hash_entry *(*new_hash_entry_func)
63 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
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. */
69 struct elfNN_ia64_dyn_sym_info
71 /* The addend for which this entry is relevant. */
72 bfd_vma addend;
74 /* Next addend in the list. */
75 struct elfNN_ia64_dyn_sym_info *next;
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;
83 /* The symbol table entry, if any, that this was derrived from. */
84 struct elf_link_hash_entry *h;
86 /* Used to count non-got, non-plt relocations for delayed sizing
87 of relocation sections. */
88 struct elfNN_ia64_dyn_reloc_entry
90 struct elfNN_ia64_dyn_reloc_entry *next;
91 asection *srel;
92 int type;
93 int count;
94 } *reloc_entries;
96 /* True when the section contents have been updated. */
97 unsigned got_done : 1;
98 unsigned fptr_done : 1;
99 unsigned pltoff_done : 1;
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;
110 struct elfNN_ia64_local_hash_entry
112 struct bfd_hash_entry root;
113 struct elfNN_ia64_dyn_sym_info *info;
116 struct elfNN_ia64_local_hash_table
118 struct bfd_hash_table root;
119 /* No additional fields for now. */
122 struct elfNN_ia64_link_hash_entry
124 struct elf_link_hash_entry root;
125 struct elfNN_ia64_dyn_sym_info *info;
128 struct elfNN_ia64_link_hash_table
130 /* The main hash table */
131 struct elf_link_hash_table root;
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 */
140 bfd_size_type minplt_entries; /* number of minplt entries */
142 struct elfNN_ia64_local_hash_table loc_hash_table;
145 #define elfNN_ia64_hash_table(p) \
146 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
148 static 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));
151 static reloc_howto_type * lookup_howto
152 PARAMS ((unsigned int rtype));
153 static reloc_howto_type *elfNN_ia64_reloc_type_lookup
154 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
155 static void elfNN_ia64_info_to_howto
156 PARAMS ((bfd *abfd, arelent *bfd_reloc, ElfNN_Internal_Rela *elf_reloc));
157 static boolean elfNN_ia64_relax_section
158 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
159 boolean *again));
160 static boolean is_unwind_section_name
161 PARAMS ((const char *));
162 static boolean elfNN_ia64_section_from_shdr
163 PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *));
164 static boolean elfNN_ia64_fake_sections
165 PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec));
166 static void elfNN_ia64_final_write_processing
167 PARAMS ((bfd *abfd, boolean linker));
168 static 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));
172 static int elfNN_ia64_additional_program_headers
173 PARAMS ((bfd *abfd));
174 static boolean elfNN_ia64_is_local_label_name
175 PARAMS ((bfd *abfd, const char *name));
176 static boolean elfNN_ia64_dynamic_symbol_p
177 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
178 static boolean elfNN_ia64_local_hash_table_init
179 PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
180 new_hash_entry_func new));
181 static 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));
184 static 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));
187 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
188 PARAMS ((bfd *abfd));
189 static 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));
192 static 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));
196 static boolean elfNN_ia64_create_dynamic_sections
197 PARAMS ((bfd *abfd, struct bfd_link_info *info));
198 static 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));
202 static asection *get_got
203 PARAMS ((bfd *abfd, struct bfd_link_info *info,
204 struct elfNN_ia64_link_hash_table *ia64_info));
205 static asection *get_fptr
206 PARAMS ((bfd *abfd, struct bfd_link_info *info,
207 struct elfNN_ia64_link_hash_table *ia64_info));
208 static asection *get_pltoff
209 PARAMS ((bfd *abfd, struct bfd_link_info *info,
210 struct elfNN_ia64_link_hash_table *ia64_info));
211 static asection *get_reloc_section
212 PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
213 asection *sec, boolean create));
214 static boolean count_dyn_reloc
215 PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
216 asection *srel, int type));
217 static boolean elfNN_ia64_check_relocs
218 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
219 const Elf_Internal_Rela *relocs));
220 static boolean elfNN_ia64_adjust_dynamic_symbol
221 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
222 static unsigned long global_sym_index
223 PARAMS ((struct elf_link_hash_entry *h));
224 static boolean allocate_fptr
225 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
226 static boolean allocate_global_data_got
227 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
228 static boolean allocate_global_fptr_got
229 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
230 static boolean allocate_local_got
231 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
232 static boolean allocate_pltoff_entries
233 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
234 static boolean allocate_plt_entries
235 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
236 static boolean allocate_plt2_entries
237 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
238 static boolean allocate_dynrel_entries
239 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
240 static boolean elfNN_ia64_size_dynamic_sections
241 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
242 static bfd_reloc_status_type elfNN_ia64_install_value
243 PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
244 static 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));
248 static 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));
252 static 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));
256 static 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));
260 static boolean elfNN_ia64_final_link
261 PARAMS ((bfd *abfd, struct bfd_link_info *info));
262 static 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));
267 static 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));
270 static boolean elfNN_ia64_finish_dynamic_sections
271 PARAMS ((bfd *abfd, struct bfd_link_info *info));
272 static boolean elfNN_ia64_set_private_flags
273 PARAMS ((bfd *abfd, flagword flags));
274 static boolean elfNN_ia64_copy_private_bfd_data
275 PARAMS ((bfd *ibfd, bfd *obfd));
276 static boolean elfNN_ia64_merge_private_bfd_data
277 PARAMS ((bfd *ibfd, bfd *obfd));
278 static boolean elfNN_ia64_print_private_bfd_data
279 PARAMS ((bfd *abfd, PTR ptr));
281 /* ia64-specific relocation */
283 /* Perform a relocation. Not much to do here as all the hard work is
284 done in elfNN_ia64_final_link_relocate. */
285 static bfd_reloc_status_type
286 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
287 output_bfd, error_message)
288 bfd *abfd ATTRIBUTE_UNUSED;
289 arelent *reloc;
290 asymbol *sym ATTRIBUTE_UNUSED;
291 PTR data ATTRIBUTE_UNUSED;
292 asection *input_section;
293 bfd *output_bfd;
294 char **error_message;
296 if (output_bfd)
298 reloc->address += input_section->output_offset;
299 return bfd_reloc_ok;
301 *error_message = "Unsupported call to elfNN_ia64_reloc";
302 return bfd_reloc_notsupported;
305 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
306 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
307 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
309 /* This table has to be sorted according to increasing number of the
310 TYPE field. */
311 static reloc_howto_type ia64_howto_table[] =
313 IA64_HOWTO (R_IA64_NONE, "NONE", 0, false, true),
315 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, false, true),
316 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, false, true),
317 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, false, true),
318 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, false, true),
319 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, false, true),
320 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, false, true),
321 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, false, true),
323 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, false, true),
324 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, false, true),
325 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, false, true),
326 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, false, true),
327 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, false, true),
328 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, false, true),
330 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, false, true),
331 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, false, true),
333 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, false, true),
334 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, false, true),
335 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, false, true),
336 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, false, true),
338 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, false, true),
339 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, false, true),
340 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, false, true),
341 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, false, true),
342 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, false, true),
344 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, true, true),
345 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, true, true),
346 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, true, true),
347 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, true, true),
348 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, true, true),
349 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, true, true),
350 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, true, true),
351 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, true, true),
353 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true),
354 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true),
355 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
356 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
358 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
359 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
360 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
361 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, false, true),
363 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, false, true),
364 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, false, true),
365 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, false, true),
366 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, false, true),
368 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, false, true),
369 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, false, true),
370 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, false, true),
371 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, false, true),
373 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, false, true),
374 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, false, true),
375 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, false, true),
376 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, false, true),
378 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, true, true),
379 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, true, true),
380 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, true, true),
382 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, false, true),
383 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, false, true),
384 IA64_HOWTO (R_IA64_COPY, "COPY", 4, false, true),
385 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, false, true),
386 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, false, true),
388 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, false, false),
389 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 8, false, false),
390 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 8, false, false),
391 IA64_HOWTO (R_IA64_LTOFF_TP22, "LTOFF_TP22", 0, false, false),
394 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
396 /* Given a BFD reloc type, return the matching HOWTO structure. */
398 static reloc_howto_type*
399 lookup_howto (rtype)
400 unsigned int rtype;
402 static int inited = 0;
403 int i;
405 if (!inited)
407 inited = 1;
409 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
410 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
411 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
414 BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
415 i = elf_code_to_howto_index[rtype];
416 if (i >= NELEMS (ia64_howto_table))
417 return 0;
418 return ia64_howto_table + i;
421 static reloc_howto_type*
422 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
423 bfd *abfd ATTRIBUTE_UNUSED;
424 bfd_reloc_code_real_type bfd_code;
426 unsigned int rtype;
428 switch (bfd_code)
430 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
432 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
433 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
434 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
436 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
437 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
438 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
439 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
441 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
442 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
443 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
444 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
445 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
446 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
448 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
449 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
451 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
452 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
453 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
454 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
455 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
456 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
457 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
458 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
459 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
461 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
462 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
463 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
464 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
465 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
466 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
467 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
468 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
469 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
470 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
471 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
473 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
474 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
475 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
476 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
478 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
479 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
480 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
481 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
483 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
484 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
485 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
486 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
488 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
489 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
490 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
491 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
493 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
494 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
495 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
496 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
498 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
499 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
500 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
501 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
502 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
504 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
505 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
506 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
507 case BFD_RELOC_IA64_LTOFF_TP22: rtype = R_IA64_LTOFF_TP22; break;
509 default: return 0;
511 return lookup_howto (rtype);
514 /* Given a ELF reloc, return the matching HOWTO structure. */
516 static void
517 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
518 bfd *abfd ATTRIBUTE_UNUSED;
519 arelent *bfd_reloc;
520 ElfNN_Internal_Rela *elf_reloc;
522 bfd_reloc->howto = lookup_howto (ELFNN_R_TYPE (elf_reloc->r_info));
525 #define PLT_HEADER_SIZE (3 * 16)
526 #define PLT_MIN_ENTRY_SIZE (1 * 16)
527 #define PLT_FULL_ENTRY_SIZE (2 * 16)
528 #define PLT_RESERVED_WORDS 3
530 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
532 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
533 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
534 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
535 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
536 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
537 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
538 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
539 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
540 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
543 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
545 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
546 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
547 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
550 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
552 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
553 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
554 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
555 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
556 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
557 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
560 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
562 /* Select out of range branch fixup type. Note that Itanium does
563 not support brl, and so it gets emulated by the kernel. */
564 #undef USE_BRL
566 static const bfd_byte oor_brl[16] =
568 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
570 0x00, 0x00, 0x00, 0xc0
573 static const bfd_byte oor_ip[48] =
575 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
576 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
577 0x01, 0x00, 0x00, 0x60,
578 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
579 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
580 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
581 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
582 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
583 0x60, 0x00, 0x80, 0x00 /* br b6;; */
586 /* These functions do relaxation for IA-64 ELF.
588 This is primarily to support branches to targets out of range;
589 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
591 static boolean
592 elfNN_ia64_relax_section (abfd, sec, link_info, again)
593 bfd *abfd;
594 asection *sec;
595 struct bfd_link_info *link_info;
596 boolean *again;
598 struct one_fixup
600 struct one_fixup *next;
601 asection *tsec;
602 bfd_vma toff;
603 bfd_vma trampoff;
606 Elf_Internal_Shdr *symtab_hdr;
607 Elf_Internal_Rela *internal_relocs;
608 Elf_Internal_Rela *free_relocs = NULL;
609 Elf_Internal_Rela *irel, *irelend;
610 bfd_byte *contents;
611 bfd_byte *free_contents = NULL;
612 ElfNN_External_Sym *extsyms;
613 ElfNN_External_Sym *free_extsyms = NULL;
614 struct elfNN_ia64_link_hash_table *ia64_info;
615 struct one_fixup *fixups = NULL;
616 boolean changed_contents = false;
617 boolean changed_relocs = false;
619 /* Assume we're not going to change any sizes, and we'll only need
620 one pass. */
621 *again = false;
623 /* Nothing to do if there are no relocations. */
624 if ((sec->flags & SEC_RELOC) == 0
625 || sec->reloc_count == 0)
626 return true;
628 /* If this is the first time we have been called for this section,
629 initialize the cooked size. */
630 if (sec->_cooked_size == 0)
631 sec->_cooked_size = sec->_raw_size;
633 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
635 /* Load the relocations for this section. */
636 internal_relocs = (_bfd_elfNN_link_read_relocs
637 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
638 link_info->keep_memory));
639 if (internal_relocs == NULL)
640 goto error_return;
642 if (! link_info->keep_memory)
643 free_relocs = internal_relocs;
645 ia64_info = elfNN_ia64_hash_table (link_info);
646 irelend = internal_relocs + sec->reloc_count;
648 for (irel = internal_relocs; irel < irelend; irel++)
649 if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
650 break;
652 /* No branch-type relocations. */
653 if (irel == irelend)
655 if (free_relocs != NULL)
656 free (free_relocs);
657 return true;
660 /* Get the section contents. */
661 if (elf_section_data (sec)->this_hdr.contents != NULL)
662 contents = elf_section_data (sec)->this_hdr.contents;
663 else
665 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
666 if (contents == NULL)
667 goto error_return;
668 free_contents = contents;
670 if (! bfd_get_section_contents (abfd, sec, contents,
671 (file_ptr) 0, sec->_raw_size))
672 goto error_return;
675 /* Read this BFD's symbols. */
676 if (symtab_hdr->contents != NULL)
677 extsyms = (ElfNN_External_Sym *) symtab_hdr->contents;
678 else
680 extsyms = (ElfNN_External_Sym *) bfd_malloc (symtab_hdr->sh_size);
681 if (extsyms == NULL)
682 goto error_return;
683 free_extsyms = extsyms;
684 if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
685 || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
686 != symtab_hdr->sh_size))
687 goto error_return;
690 for (; irel < irelend; irel++)
692 bfd_vma symaddr, reladdr, trampoff, toff, roff;
693 Elf_Internal_Sym isym;
694 asection *tsec;
695 struct one_fixup *f;
697 if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
698 continue;
700 /* Get the value of the symbol referred to by the reloc. */
701 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
703 /* A local symbol. */
704 bfd_elfNN_swap_symbol_in (abfd,
705 extsyms + ELFNN_R_SYM (irel->r_info),
706 &isym);
707 if (isym.st_shndx == SHN_UNDEF)
708 continue; /* We can't do anthing with undefined symbols. */
709 else if (isym.st_shndx == SHN_ABS)
710 tsec = bfd_abs_section_ptr;
711 else if (isym.st_shndx == SHN_COMMON)
712 tsec = bfd_com_section_ptr;
713 else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
714 tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
715 else
716 continue; /* who knows. */
718 toff = isym.st_value;
720 else
722 unsigned long indx;
723 struct elf_link_hash_entry *h;
724 struct elfNN_ia64_dyn_sym_info *dyn_i;
726 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
727 h = elf_sym_hashes (abfd)[indx];
728 BFD_ASSERT (h != NULL);
730 while (h->root.type == bfd_link_hash_indirect
731 || h->root.type == bfd_link_hash_warning)
732 h = (struct elf_link_hash_entry *) h->root.u.i.link;
734 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
736 /* For branches to dynamic symbols, we're interested instead
737 in a branch to the PLT entry. */
738 if (dyn_i && dyn_i->want_plt2)
740 tsec = ia64_info->plt_sec;
741 toff = dyn_i->plt2_offset;
743 else
745 /* We can't do anthing with undefined symbols. */
746 if (h->root.type == bfd_link_hash_undefined
747 || h->root.type == bfd_link_hash_undefweak)
748 continue;
750 tsec = h->root.u.def.section;
751 toff = h->root.u.def.value;
755 symaddr = (tsec->output_section->vma
756 + tsec->output_offset
757 + toff
758 + irel->r_addend);
760 roff = irel->r_offset;
761 reladdr = (sec->output_section->vma
762 + sec->output_offset
763 + roff) & -4;
765 /* If the branch is in range, no need to do anything. */
766 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
767 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
768 continue;
770 /* If the branch and target are in the same section, you've
771 got one honking big section and we can't help you. You'll
772 get an error message later. */
773 if (tsec == sec)
774 continue;
776 /* Look for an existing fixup to this address. */
777 for (f = fixups; f ; f = f->next)
778 if (f->tsec == tsec && f->toff == toff)
779 break;
781 if (f == NULL)
783 /* Two alternatives: If it's a branch to a PLT entry, we can
784 make a copy of the FULL_PLT entry. Otherwise, we'll have
785 to use a `brl' insn to get where we're going. */
787 int size;
789 if (tsec == ia64_info->plt_sec)
790 size = sizeof (plt_full_entry);
791 else
793 #ifdef USE_BRL
794 size = sizeof (oor_brl);
795 #else
796 size = sizeof (oor_ip);
797 #endif
800 /* Resize the current section to make room for the new branch. */
801 trampoff = (sec->_cooked_size + 15) & -16;
802 contents = (bfd_byte *) bfd_realloc (contents, trampoff + size);
803 if (contents == NULL)
804 goto error_return;
805 sec->_cooked_size = trampoff + size;
807 if (tsec == ia64_info->plt_sec)
809 memcpy (contents + trampoff, plt_full_entry, size);
811 /* Hijack the old relocation for use as the PLTOFF reloc. */
812 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
813 R_IA64_PLTOFF22);
814 irel->r_offset = trampoff;
816 else
818 #ifdef USE_BRL
819 memcpy (contents + trampoff, oor_brl, size);
820 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
821 R_IA64_PCREL60B);
822 irel->r_offset = trampoff + 2;
823 #else
824 memcpy (contents + trampoff, oor_ip, size);
825 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
826 R_IA64_PCREL64I);
827 irel->r_addend -= 16;
828 irel->r_offset = trampoff + 2;
829 #endif
832 /* Record the fixup so we don't do it again this section. */
833 f = (struct one_fixup *) bfd_malloc (sizeof (*f));
834 f->next = fixups;
835 f->tsec = tsec;
836 f->toff = toff;
837 f->trampoff = trampoff;
838 fixups = f;
840 else
842 /* Nop out the reloc, since we're finalizing things here. */
843 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
846 /* Fix up the existing branch to hit the trampoline. Hope like
847 hell this doesn't overflow too. */
848 if (elfNN_ia64_install_value (abfd, contents + roff,
849 f->trampoff - (roff & -4),
850 R_IA64_PCREL21B) != bfd_reloc_ok)
851 goto error_return;
853 changed_contents = true;
854 changed_relocs = true;
857 /* Clean up and go home. */
858 while (fixups)
860 struct one_fixup *f = fixups;
861 fixups = fixups->next;
862 free (f);
865 if (changed_relocs)
866 elf_section_data (sec)->relocs = internal_relocs;
867 else if (free_relocs != NULL)
868 free (free_relocs);
870 if (changed_contents)
871 elf_section_data (sec)->this_hdr.contents = contents;
872 else if (free_contents != NULL)
874 if (! link_info->keep_memory)
875 free (free_contents);
876 else
878 /* Cache the section contents for elf_link_input_bfd. */
879 elf_section_data (sec)->this_hdr.contents = contents;
883 if (free_extsyms != NULL)
885 if (! link_info->keep_memory)
886 free (free_extsyms);
887 else
889 /* Cache the symbols for elf_link_input_bfd. */
890 symtab_hdr->contents = extsyms;
894 *again = changed_contents || changed_relocs;
895 return true;
897 error_return:
898 if (free_relocs != NULL)
899 free (free_relocs);
900 if (free_contents != NULL)
901 free (free_contents);
902 if (free_extsyms != NULL)
903 free (free_extsyms);
904 return false;
907 /* Return true if NAME is an unwind table section name. */
909 static inline boolean
910 is_unwind_section_name (name)
911 const char *name;
913 size_t len1, len2;
915 len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
916 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
917 return (strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
918 && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0);
921 /* Handle an IA-64 specific section when reading an object file. This
922 is called when elfcode.h finds a section with an unknown type. */
924 static boolean
925 elfNN_ia64_section_from_shdr (abfd, hdr, name)
926 bfd *abfd;
927 ElfNN_Internal_Shdr *hdr;
928 char *name;
930 asection *newsect;
932 /* There ought to be a place to keep ELF backend specific flags, but
933 at the moment there isn't one. We just keep track of the
934 sections by their name, instead. Fortunately, the ABI gives
935 suggested names for all the MIPS specific sections, so we will
936 probably get away with this. */
937 switch (hdr->sh_type)
939 case SHT_IA_64_UNWIND:
940 break;
942 case SHT_IA_64_EXT:
943 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
944 return false;
945 break;
947 default:
948 return false;
951 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
952 return false;
953 newsect = hdr->bfd_section;
955 return true;
958 /* Convert IA-64 specific section flags to bfd internal section flags. */
960 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
961 flag. */
963 static boolean
964 elfNN_ia64_section_flags (flags, hdr)
965 flagword *flags;
966 ElfNN_Internal_Shdr *hdr;
968 if (hdr->sh_flags & SHF_IA_64_SHORT)
969 *flags |= SEC_SMALL_DATA;
971 return true;
974 /* Set the correct type for an IA-64 ELF section. We do this by the
975 section name, which is a hack, but ought to work. */
977 static boolean
978 elfNN_ia64_fake_sections (abfd, hdr, sec)
979 bfd *abfd ATTRIBUTE_UNUSED;
980 ElfNN_Internal_Shdr *hdr;
981 asection *sec;
983 register const char *name;
985 name = bfd_get_section_name (abfd, sec);
987 if (is_unwind_section_name (name))
989 /* We don't have the sections numbered at this point, so sh_info
990 is set later, in elfNN_ia64_final_write_processing. */
991 hdr->sh_type = SHT_IA_64_UNWIND;
992 hdr->sh_flags |= SHF_LINK_ORDER;
994 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
995 hdr->sh_type = SHT_IA_64_EXT;
996 else if (strcmp (name, ".reloc") == 0)
998 * This is an ugly, but unfortunately necessary hack that is
999 * needed when producing EFI binaries on IA-64. It tells
1000 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1001 * containing ELF relocation info. We need this hack in order to
1002 * be able to generate ELF binaries that can be translated into
1003 * EFI applications (which are essentially COFF objects). Those
1004 * files contain a COFF ".reloc" section inside an ELFNN object,
1005 * which would normally cause BFD to segfault because it would
1006 * attempt to interpret this section as containing relocation
1007 * entries for section "oc". With this hack enabled, ".reloc"
1008 * will be treated as a normal data section, which will avoid the
1009 * segfault. However, you won't be able to create an ELFNN binary
1010 * with a section named "oc" that needs relocations, but that's
1011 * the kind of ugly side-effects you get when detecting section
1012 * types based on their names... In practice, this limitation is
1013 * unlikely to bite.
1015 hdr->sh_type = SHT_PROGBITS;
1017 if (sec->flags & SEC_SMALL_DATA)
1018 hdr->sh_flags |= SHF_IA_64_SHORT;
1020 return true;
1023 /* The final processing done just before writing out an IA-64 ELF
1024 object file. */
1026 static void
1027 elfNN_ia64_final_write_processing (abfd, linker)
1028 bfd *abfd;
1029 boolean linker ATTRIBUTE_UNUSED;
1031 Elf_Internal_Shdr *hdr;
1032 const char *sname;
1033 asection *text_sect, *s;
1034 size_t len;
1036 for (s = abfd->sections; s; s = s->next)
1038 hdr = &elf_section_data (s)->this_hdr;
1039 switch (hdr->sh_type)
1041 case SHT_IA_64_UNWIND:
1042 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1043 have to do this. */
1044 sname = bfd_get_section_name (abfd, s);
1045 len = sizeof (ELF_STRING_ia64_unwind) - 1;
1046 if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0)
1048 sname += len;
1050 if (sname[0] == '\0')
1051 /* .IA_64.unwind -> .text */
1052 text_sect = bfd_get_section_by_name (abfd, ".text");
1053 else
1054 /* .IA_64.unwindFOO -> FOO */
1055 text_sect = bfd_get_section_by_name (abfd, sname);
1057 else
1058 /* last resort: fall back on .text */
1059 text_sect = bfd_get_section_by_name (abfd, ".text");
1061 if (text_sect)
1063 /* The IA-64 processor-specific ABI requires setting
1064 sh_link to the unwind section, whereas HP-UX requires
1065 sh_info to do so. For maximum compatibility, we'll
1066 set both for now... */
1067 hdr->sh_link = elf_section_data (text_sect)->this_idx;
1068 hdr->sh_info = elf_section_data (text_sect)->this_idx;
1070 break;
1075 /* Hook called by the linker routine which adds symbols from an object
1076 file. We use it to put .comm items in .sbss, and not .bss. */
1078 static boolean
1079 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1080 bfd *abfd;
1081 struct bfd_link_info *info;
1082 const Elf_Internal_Sym *sym;
1083 const char **namep ATTRIBUTE_UNUSED;
1084 flagword *flagsp ATTRIBUTE_UNUSED;
1085 asection **secp;
1086 bfd_vma *valp;
1088 if (sym->st_shndx == SHN_COMMON
1089 && !info->relocateable
1090 && sym->st_size <= (unsigned) bfd_get_gp_size (abfd))
1092 /* Common symbols less than or equal to -G nn bytes are
1093 automatically put into .sbss. */
1095 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1097 if (scomm == NULL)
1099 scomm = bfd_make_section (abfd, ".scommon");
1100 if (scomm == NULL
1101 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1102 | SEC_IS_COMMON
1103 | SEC_LINKER_CREATED)))
1104 return false;
1107 *secp = scomm;
1108 *valp = sym->st_size;
1111 return true;
1114 /* Return the number of additional phdrs we will need. */
1116 static int
1117 elfNN_ia64_additional_program_headers (abfd)
1118 bfd *abfd;
1120 asection *s;
1121 int ret = 0;
1123 /* See if we need a PT_IA_64_ARCHEXT segment. */
1124 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1125 if (s && (s->flags & SEC_LOAD))
1126 ++ret;
1128 /* Count how many PT_IA_64_UNWIND segments we need. */
1129 for (s = abfd->sections; s; s = s->next)
1130 if (is_unwind_section_name(s->name) && (s->flags & SEC_LOAD))
1131 ++ret;
1133 return ret;
1136 static boolean
1137 elfNN_ia64_modify_segment_map (abfd)
1138 bfd *abfd;
1140 struct elf_segment_map *m, **pm;
1141 Elf_Internal_Shdr *hdr;
1142 asection *s;
1144 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1145 all PT_LOAD segments. */
1146 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1147 if (s && (s->flags & SEC_LOAD))
1149 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1150 if (m->p_type == PT_IA_64_ARCHEXT)
1151 break;
1152 if (m == NULL)
1154 m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1155 if (m == NULL)
1156 return false;
1158 m->p_type = PT_IA_64_ARCHEXT;
1159 m->count = 1;
1160 m->sections[0] = s;
1162 /* We want to put it after the PHDR and INTERP segments. */
1163 pm = &elf_tdata (abfd)->segment_map;
1164 while (*pm != NULL
1165 && ((*pm)->p_type == PT_PHDR
1166 || (*pm)->p_type == PT_INTERP))
1167 pm = &(*pm)->next;
1169 m->next = *pm;
1170 *pm = m;
1174 /* Install PT_IA_64_UNWIND segments, if needed. */
1175 for (s = abfd->sections; s; s = s->next)
1177 hdr = &elf_section_data (s)->this_hdr;
1178 if (hdr->sh_type != SHT_IA_64_UNWIND)
1179 continue;
1181 if (s && (s->flags & SEC_LOAD))
1183 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1184 if (m->p_type == PT_IA_64_UNWIND && m->sections[0] == s)
1185 break;
1187 if (m == NULL)
1189 m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1190 if (m == NULL)
1191 return false;
1193 m->p_type = PT_IA_64_UNWIND;
1194 m->count = 1;
1195 m->sections[0] = s;
1196 m->next = NULL;
1198 /* We want to put it last. */
1199 pm = &elf_tdata (abfd)->segment_map;
1200 while (*pm != NULL)
1201 pm = &(*pm)->next;
1202 *pm = m;
1207 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1208 the input sections for each output section in the segment and testing
1209 for SHF_IA_64_NORECOV on each. */
1210 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1211 if (m->p_type == PT_LOAD)
1213 int i;
1214 for (i = m->count - 1; i >= 0; --i)
1216 struct bfd_link_order *order = m->sections[i]->link_order_head;
1217 while (order)
1219 if (order->type == bfd_indirect_link_order)
1221 asection *is = order->u.indirect.section;
1222 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1223 if (flags & SHF_IA_64_NORECOV)
1225 m->p_flags |= PF_IA_64_NORECOV;
1226 goto found;
1229 order = order->next;
1232 found:;
1235 return true;
1238 /* According to the Tahoe assembler spec, all labels starting with a
1239 '.' are local. */
1241 static boolean
1242 elfNN_ia64_is_local_label_name (abfd, name)
1243 bfd *abfd ATTRIBUTE_UNUSED;
1244 const char *name;
1246 return name[0] == '.';
1249 /* Should we do dynamic things to this symbol? */
1251 static boolean
1252 elfNN_ia64_dynamic_symbol_p (h, info)
1253 struct elf_link_hash_entry *h;
1254 struct bfd_link_info *info;
1256 if (h == NULL)
1257 return false;
1259 while (h->root.type == bfd_link_hash_indirect
1260 || h->root.type == bfd_link_hash_warning)
1261 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1263 if (h->dynindx == -1)
1264 return false;
1265 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
1266 return false;
1268 if (h->root.type == bfd_link_hash_undefweak
1269 || h->root.type == bfd_link_hash_defweak)
1270 return true;
1272 if ((info->shared && !info->symbolic)
1273 || ((h->elf_link_hash_flags
1274 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1275 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1276 return true;
1278 return false;
1281 static boolean
1282 elfNN_ia64_local_hash_table_init (ht, abfd, new)
1283 struct elfNN_ia64_local_hash_table *ht;
1284 bfd *abfd ATTRIBUTE_UNUSED;
1285 new_hash_entry_func new;
1287 memset (ht, 0, sizeof (*ht));
1288 return bfd_hash_table_init (&ht->root, new);
1291 static struct bfd_hash_entry*
1292 elfNN_ia64_new_loc_hash_entry (entry, table, string)
1293 struct bfd_hash_entry *entry;
1294 struct bfd_hash_table *table;
1295 const char *string;
1297 struct elfNN_ia64_local_hash_entry *ret;
1298 ret = (struct elfNN_ia64_local_hash_entry *) entry;
1300 /* Allocate the structure if it has not already been allocated by a
1301 subclass. */
1302 if (!ret)
1303 ret = bfd_hash_allocate (table, sizeof (*ret));
1305 if (!ret)
1306 return 0;
1308 /* Initialize our local data. All zeros, and definitely easier
1309 than setting a handful of bit fields. */
1310 memset (ret, 0, sizeof (*ret));
1312 /* Call the allocation method of the superclass. */
1313 ret = ((struct elfNN_ia64_local_hash_entry *)
1314 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1316 return (struct bfd_hash_entry *) ret;
1319 static struct bfd_hash_entry*
1320 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1321 struct bfd_hash_entry *entry;
1322 struct bfd_hash_table *table;
1323 const char *string;
1325 struct elfNN_ia64_link_hash_entry *ret;
1326 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1328 /* Allocate the structure if it has not already been allocated by a
1329 subclass. */
1330 if (!ret)
1331 ret = bfd_hash_allocate (table, sizeof (*ret));
1333 if (!ret)
1334 return 0;
1336 /* Initialize our local data. All zeros, and definitely easier
1337 than setting a handful of bit fields. */
1338 memset (ret, 0, sizeof (*ret));
1340 /* Call the allocation method of the superclass. */
1341 ret = ((struct elfNN_ia64_link_hash_entry *)
1342 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1343 table, string));
1345 return (struct bfd_hash_entry *) ret;
1348 static void
1349 elfNN_ia64_hash_copy_indirect (xdir, xind)
1350 struct elf_link_hash_entry *xdir, *xind;
1352 struct elfNN_ia64_link_hash_entry *dir, *ind;
1354 dir = (struct elfNN_ia64_link_hash_entry *)xdir;
1355 ind = (struct elfNN_ia64_link_hash_entry *)xind;
1357 /* Copy down any references that we may have already seen to the
1358 symbol which just became indirect. */
1360 dir->root.elf_link_hash_flags |=
1361 (ind->root.elf_link_hash_flags
1362 & (ELF_LINK_HASH_REF_DYNAMIC
1363 | ELF_LINK_HASH_REF_REGULAR
1364 | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1366 /* Copy over the got and plt data. This would have been done
1367 by check_relocs. */
1369 if (dir->info == NULL)
1371 struct elfNN_ia64_dyn_sym_info *dyn_i;
1373 dir->info = dyn_i = ind->info;
1374 ind->info = NULL;
1376 /* Fix up the dyn_sym_info pointers to the global symbol. */
1377 for (; dyn_i; dyn_i = dyn_i->next)
1378 dyn_i->h = &dir->root;
1380 BFD_ASSERT (ind->info == NULL);
1382 /* Copy over the dynindx. */
1384 if (dir->root.dynindx == -1)
1386 dir->root.dynindx = ind->root.dynindx;
1387 dir->root.dynstr_index = ind->root.dynstr_index;
1388 ind->root.dynindx = -1;
1389 ind->root.dynstr_index = 0;
1391 BFD_ASSERT (ind->root.dynindx == -1);
1394 static void
1395 elfNN_ia64_hash_hide_symbol (info, xh)
1396 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1397 struct elf_link_hash_entry *xh;
1399 struct elfNN_ia64_link_hash_entry *h;
1400 struct elfNN_ia64_dyn_sym_info *dyn_i;
1402 h = (struct elfNN_ia64_link_hash_entry *)xh;
1404 h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
1405 h->root.dynindx = -1;
1407 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1408 dyn_i->want_plt2 = 0;
1411 /* Create the derived linker hash table. The IA-64 ELF port uses this
1412 derived hash table to keep information specific to the IA-64 ElF
1413 linker (without using static variables). */
1415 static struct bfd_link_hash_table*
1416 elfNN_ia64_hash_table_create (abfd)
1417 bfd *abfd;
1419 struct elfNN_ia64_link_hash_table *ret;
1421 ret = bfd_alloc (abfd, sizeof (*ret));
1422 if (!ret)
1423 return 0;
1424 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1425 elfNN_ia64_new_elf_hash_entry))
1427 bfd_release (abfd, ret);
1428 return 0;
1431 if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1432 elfNN_ia64_new_loc_hash_entry))
1433 return 0;
1434 return &ret->root.root;
1437 /* Look up an entry in a Alpha ELF linker hash table. */
1439 static INLINE struct elfNN_ia64_local_hash_entry *
1440 elfNN_ia64_local_hash_lookup(table, string, create, copy)
1441 struct elfNN_ia64_local_hash_table *table;
1442 const char *string;
1443 boolean create, copy;
1445 return ((struct elfNN_ia64_local_hash_entry *)
1446 bfd_hash_lookup (&table->root, string, create, copy));
1449 /* Traverse both local and global hash tables. */
1451 struct elfNN_ia64_dyn_sym_traverse_data
1453 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1454 PTR data;
1457 static boolean
1458 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1459 struct bfd_hash_entry *xentry;
1460 PTR xdata;
1462 struct elfNN_ia64_link_hash_entry *entry
1463 = (struct elfNN_ia64_link_hash_entry *) xentry;
1464 struct elfNN_ia64_dyn_sym_traverse_data *data
1465 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1466 struct elfNN_ia64_dyn_sym_info *dyn_i;
1468 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1469 if (! (*data->func) (dyn_i, data->data))
1470 return false;
1471 return true;
1474 static boolean
1475 elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1476 struct bfd_hash_entry *xentry;
1477 PTR xdata;
1479 struct elfNN_ia64_local_hash_entry *entry
1480 = (struct elfNN_ia64_local_hash_entry *) xentry;
1481 struct elfNN_ia64_dyn_sym_traverse_data *data
1482 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1483 struct elfNN_ia64_dyn_sym_info *dyn_i;
1485 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1486 if (! (*data->func) (dyn_i, data->data))
1487 return false;
1488 return true;
1491 static void
1492 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1493 struct elfNN_ia64_link_hash_table *ia64_info;
1494 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1495 PTR data;
1497 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1499 xdata.func = func;
1500 xdata.data = data;
1502 elf_link_hash_traverse (&ia64_info->root,
1503 elfNN_ia64_global_dyn_sym_thunk, &xdata);
1504 bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1505 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1508 static boolean
1509 elfNN_ia64_create_dynamic_sections (abfd, info)
1510 bfd *abfd;
1511 struct bfd_link_info *info;
1513 struct elfNN_ia64_link_hash_table *ia64_info;
1514 asection *s;
1516 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1517 return false;
1519 ia64_info = elfNN_ia64_hash_table (info);
1521 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1522 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1525 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1526 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1529 if (!get_pltoff (abfd, info, ia64_info))
1530 return false;
1532 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1533 if (s == NULL
1534 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1535 | SEC_HAS_CONTENTS
1536 | SEC_IN_MEMORY
1537 | SEC_LINKER_CREATED
1538 | SEC_READONLY))
1539 || !bfd_set_section_alignment (abfd, s, 3))
1540 return false;
1541 ia64_info->rel_pltoff_sec = s;
1543 s = bfd_make_section(abfd, ".rela.got");
1544 if (s == NULL
1545 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1546 | SEC_HAS_CONTENTS
1547 | SEC_IN_MEMORY
1548 | SEC_LINKER_CREATED
1549 | SEC_READONLY))
1550 || !bfd_set_section_alignment (abfd, s, 3))
1551 return false;
1552 ia64_info->rel_got_sec = s;
1554 return true;
1557 /* Find and/or create a descriptor for dynamic symbol info. This will
1558 vary based on global or local symbol, and the addend to the reloc. */
1560 static struct elfNN_ia64_dyn_sym_info *
1561 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1562 struct elfNN_ia64_link_hash_table *ia64_info;
1563 struct elf_link_hash_entry *h;
1564 bfd *abfd;
1565 const Elf_Internal_Rela *rel;
1566 boolean create;
1568 struct elfNN_ia64_dyn_sym_info **pp;
1569 struct elfNN_ia64_dyn_sym_info *dyn_i;
1570 bfd_vma addend = rel ? rel->r_addend : 0;
1572 if (h)
1573 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1574 else
1576 struct elfNN_ia64_local_hash_entry *loc_h;
1577 char *addr_name;
1578 size_t len;
1580 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1581 The name describes what was once anonymous memory. */
1583 len = sizeof (void*)*2 + 1 + sizeof (bfd_vma)*4 + 1 + 1;
1584 len += 10; /* %p slop */
1586 addr_name = alloca (len);
1587 sprintf (addr_name, "%p:%lx", (void *) abfd, ELFNN_R_SYM (rel->r_info));
1589 /* Collect the canonical entry data for this address. */
1590 loc_h = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1591 addr_name, create, create);
1592 BFD_ASSERT (loc_h);
1594 pp = &loc_h->info;
1597 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1598 pp = &dyn_i->next;
1600 if (dyn_i == NULL && create)
1602 dyn_i = (struct elfNN_ia64_dyn_sym_info *)
1603 bfd_zalloc (abfd, sizeof *dyn_i);
1604 *pp = dyn_i;
1605 dyn_i->addend = addend;
1608 return dyn_i;
1611 static asection *
1612 get_got (abfd, info, ia64_info)
1613 bfd *abfd;
1614 struct bfd_link_info *info;
1615 struct elfNN_ia64_link_hash_table *ia64_info;
1617 asection *got;
1618 bfd *dynobj;
1620 got = ia64_info->got_sec;
1621 if (!got)
1623 flagword flags;
1625 dynobj = ia64_info->root.dynobj;
1626 if (!dynobj)
1627 ia64_info->root.dynobj = dynobj = abfd;
1628 if (!_bfd_elf_create_got_section (dynobj, info))
1629 return 0;
1631 got = bfd_get_section_by_name (dynobj, ".got");
1632 BFD_ASSERT (got);
1633 ia64_info->got_sec = got;
1635 flags = bfd_get_section_flags (abfd, got);
1636 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1639 return got;
1642 /* Create function descriptor section (.opd). This section is called .opd
1643 because it contains "official prodecure descriptors". The "official"
1644 refers to the fact that these descriptors are used when taking the address
1645 of a procedure, thus ensuring a unique address for each procedure. */
1647 static asection *
1648 get_fptr (abfd, info, ia64_info)
1649 bfd *abfd;
1650 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1651 struct elfNN_ia64_link_hash_table *ia64_info;
1653 asection *fptr;
1654 bfd *dynobj;
1656 fptr = ia64_info->fptr_sec;
1657 if (!fptr)
1659 dynobj = ia64_info->root.dynobj;
1660 if (!dynobj)
1661 ia64_info->root.dynobj = dynobj = abfd;
1663 fptr = bfd_make_section (dynobj, ".opd");
1664 if (!fptr
1665 || !bfd_set_section_flags (dynobj, fptr,
1666 (SEC_ALLOC
1667 | SEC_LOAD
1668 | SEC_HAS_CONTENTS
1669 | SEC_IN_MEMORY
1670 | SEC_READONLY
1671 | SEC_LINKER_CREATED))
1672 || !bfd_set_section_alignment (abfd, fptr, 4))
1674 BFD_ASSERT (0);
1675 return NULL;
1678 ia64_info->fptr_sec = fptr;
1681 return fptr;
1684 static asection *
1685 get_pltoff (abfd, info, ia64_info)
1686 bfd *abfd;
1687 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1688 struct elfNN_ia64_link_hash_table *ia64_info;
1690 asection *pltoff;
1691 bfd *dynobj;
1693 pltoff = ia64_info->pltoff_sec;
1694 if (!pltoff)
1696 dynobj = ia64_info->root.dynobj;
1697 if (!dynobj)
1698 ia64_info->root.dynobj = dynobj = abfd;
1700 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
1701 if (!pltoff
1702 || !bfd_set_section_flags (dynobj, pltoff,
1703 (SEC_ALLOC
1704 | SEC_LOAD
1705 | SEC_HAS_CONTENTS
1706 | SEC_IN_MEMORY
1707 | SEC_SMALL_DATA
1708 | SEC_LINKER_CREATED))
1709 || !bfd_set_section_alignment (abfd, pltoff, 4))
1711 BFD_ASSERT (0);
1712 return NULL;
1715 ia64_info->pltoff_sec = pltoff;
1718 return pltoff;
1721 static asection *
1722 get_reloc_section (abfd, ia64_info, sec, create)
1723 bfd *abfd;
1724 struct elfNN_ia64_link_hash_table *ia64_info;
1725 asection *sec;
1726 boolean create;
1728 const char *srel_name;
1729 asection *srel;
1730 bfd *dynobj;
1732 srel_name = (bfd_elf_string_from_elf_section
1733 (abfd, elf_elfheader(abfd)->e_shstrndx,
1734 elf_section_data(sec)->rel_hdr.sh_name));
1735 if (srel_name == NULL)
1736 return NULL;
1738 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
1739 && strcmp (bfd_get_section_name (abfd, sec),
1740 srel_name+5) == 0)
1741 || (strncmp (srel_name, ".rel", 4) == 0
1742 && strcmp (bfd_get_section_name (abfd, sec),
1743 srel_name+4) == 0));
1745 dynobj = ia64_info->root.dynobj;
1746 if (!dynobj)
1747 ia64_info->root.dynobj = dynobj = abfd;
1749 srel = bfd_get_section_by_name (dynobj, srel_name);
1750 if (srel == NULL && create)
1752 srel = bfd_make_section (dynobj, srel_name);
1753 if (srel == NULL
1754 || !bfd_set_section_flags (dynobj, srel,
1755 (SEC_ALLOC
1756 | SEC_LOAD
1757 | SEC_HAS_CONTENTS
1758 | SEC_IN_MEMORY
1759 | SEC_LINKER_CREATED
1760 | SEC_READONLY))
1761 || !bfd_set_section_alignment (dynobj, srel, 3))
1762 return NULL;
1765 return srel;
1768 static boolean
1769 count_dyn_reloc (abfd, dyn_i, srel, type)
1770 bfd *abfd;
1771 struct elfNN_ia64_dyn_sym_info *dyn_i;
1772 asection *srel;
1773 int type;
1775 struct elfNN_ia64_dyn_reloc_entry *rent;
1777 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
1778 if (rent->srel == srel && rent->type == type)
1779 break;
1781 if (!rent)
1783 rent = (struct elfNN_ia64_dyn_reloc_entry *)
1784 bfd_alloc (abfd, sizeof (*rent));
1785 if (!rent)
1786 return false;
1788 rent->next = dyn_i->reloc_entries;
1789 rent->srel = srel;
1790 rent->type = type;
1791 rent->count = 0;
1792 dyn_i->reloc_entries = rent;
1794 rent->count++;
1796 return true;
1799 static boolean
1800 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
1801 bfd *abfd;
1802 struct bfd_link_info *info;
1803 asection *sec;
1804 const Elf_Internal_Rela *relocs;
1806 struct elfNN_ia64_link_hash_table *ia64_info;
1807 const Elf_Internal_Rela *relend;
1808 Elf_Internal_Shdr *symtab_hdr;
1809 const Elf_Internal_Rela *rel;
1810 asection *got, *fptr, *srel;
1812 if (info->relocateable)
1813 return true;
1815 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1816 ia64_info = elfNN_ia64_hash_table (info);
1818 got = fptr = srel = NULL;
1820 relend = relocs + sec->reloc_count;
1821 for (rel = relocs; rel < relend; ++rel)
1823 enum {
1824 NEED_GOT = 1,
1825 NEED_FPTR = 2,
1826 NEED_PLTOFF = 4,
1827 NEED_MIN_PLT = 8,
1828 NEED_FULL_PLT = 16,
1829 NEED_DYNREL = 32,
1830 NEED_LTOFF_FPTR = 64,
1833 struct elf_link_hash_entry *h = NULL;
1834 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
1835 struct elfNN_ia64_dyn_sym_info *dyn_i;
1836 int need_entry;
1837 boolean maybe_dynamic;
1838 int dynrel_type = R_IA64_NONE;
1840 if (r_symndx >= symtab_hdr->sh_info)
1842 /* We're dealing with a global symbol -- find its hash entry
1843 and mark it as being referenced. */
1844 long indx = r_symndx - symtab_hdr->sh_info;
1845 h = elf_sym_hashes (abfd)[indx];
1846 while (h->root.type == bfd_link_hash_indirect
1847 || h->root.type == bfd_link_hash_warning)
1848 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1850 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
1853 /* We can only get preliminary data on whether a symbol is
1854 locally or externally defined, as not all of the input files
1855 have yet been processed. Do something with what we know, as
1856 this may help reduce memory usage and processing time later. */
1857 maybe_dynamic = false;
1858 if (h && ((info->shared && ! info->symbolic)
1859 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
1860 || h->root.type == bfd_link_hash_defweak))
1861 maybe_dynamic = true;
1863 need_entry = 0;
1864 switch (ELFNN_R_TYPE (rel->r_info))
1866 case R_IA64_TPREL22:
1867 case R_IA64_TPREL64MSB:
1868 case R_IA64_TPREL64LSB:
1869 case R_IA64_LTOFF_TP22:
1870 return false;
1872 case R_IA64_LTOFF_FPTR22:
1873 case R_IA64_LTOFF_FPTR64I:
1874 case R_IA64_LTOFF_FPTR64MSB:
1875 case R_IA64_LTOFF_FPTR64LSB:
1876 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
1877 break;
1879 case R_IA64_FPTR64I:
1880 case R_IA64_FPTR32MSB:
1881 case R_IA64_FPTR32LSB:
1882 case R_IA64_FPTR64MSB:
1883 case R_IA64_FPTR64LSB:
1884 if (info->shared || h)
1885 need_entry = NEED_FPTR | NEED_DYNREL;
1886 else
1887 need_entry = NEED_FPTR;
1888 dynrel_type = R_IA64_FPTR64LSB;
1889 break;
1891 case R_IA64_LTOFF22:
1892 case R_IA64_LTOFF22X:
1893 case R_IA64_LTOFF64I:
1894 need_entry = NEED_GOT;
1895 break;
1897 case R_IA64_PLTOFF22:
1898 case R_IA64_PLTOFF64I:
1899 case R_IA64_PLTOFF64MSB:
1900 case R_IA64_PLTOFF64LSB:
1901 need_entry = NEED_PLTOFF;
1902 if (h)
1904 if (maybe_dynamic)
1905 need_entry |= NEED_MIN_PLT;
1907 else
1909 (*info->callbacks->warning)
1910 (info, _("@pltoff reloc against local symbol"), 0,
1911 abfd, 0, 0);
1913 break;
1915 case R_IA64_PCREL21B:
1916 case R_IA64_PCREL60B:
1917 /* Depending on where this symbol is defined, we may or may not
1918 need a full plt entry. Only skip if we know we'll not need
1919 the entry -- static or symbolic, and the symbol definition
1920 has already been seen. */
1921 if (maybe_dynamic && rel->r_addend == 0)
1922 need_entry = NEED_FULL_PLT;
1923 break;
1925 case R_IA64_IMM14:
1926 case R_IA64_IMM22:
1927 case R_IA64_IMM64:
1928 case R_IA64_DIR32MSB:
1929 case R_IA64_DIR32LSB:
1930 case R_IA64_DIR64MSB:
1931 case R_IA64_DIR64LSB:
1932 /* Shared objects will always need at least a REL relocation. */
1933 if (info->shared || maybe_dynamic)
1934 need_entry = NEED_DYNREL;
1935 dynrel_type = R_IA64_DIR64LSB;
1936 break;
1938 case R_IA64_IPLTMSB:
1939 case R_IA64_IPLTLSB:
1940 /* Shared objects will always need at least a REL relocation. */
1941 if (info->shared || maybe_dynamic)
1942 need_entry = NEED_DYNREL;
1943 dynrel_type = R_IA64_IPLTLSB;
1944 break;
1946 case R_IA64_PCREL22:
1947 case R_IA64_PCREL64I:
1948 case R_IA64_PCREL32MSB:
1949 case R_IA64_PCREL32LSB:
1950 case R_IA64_PCREL64MSB:
1951 case R_IA64_PCREL64LSB:
1952 if (maybe_dynamic)
1953 need_entry = NEED_DYNREL;
1954 dynrel_type = R_IA64_PCREL64LSB;
1955 break;
1958 if (!need_entry)
1959 continue;
1961 if ((need_entry & NEED_FPTR) != 0
1962 && rel->r_addend)
1964 (*info->callbacks->warning)
1965 (info, _("non-zero addend in @fptr reloc"), 0,
1966 abfd, 0, 0);
1969 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
1971 /* Record whether or not this is a local symbol. */
1972 dyn_i->h = h;
1974 /* Create what's needed. */
1975 if (need_entry & NEED_GOT)
1977 if (!got)
1979 got = get_got (abfd, info, ia64_info);
1980 if (!got)
1981 return false;
1983 dyn_i->want_got = 1;
1985 if (need_entry & NEED_FPTR)
1987 if (!fptr)
1989 fptr = get_fptr (abfd, info, ia64_info);
1990 if (!fptr)
1991 return false;
1994 /* FPTRs for shared libraries are allocated by the dynamic
1995 linker. Make sure this local symbol will appear in the
1996 dynamic symbol table. */
1997 if (!h && info->shared)
1999 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2000 (info, abfd, r_symndx)))
2001 return false;
2004 dyn_i->want_fptr = 1;
2006 if (need_entry & NEED_LTOFF_FPTR)
2007 dyn_i->want_ltoff_fptr = 1;
2008 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2010 if (!ia64_info->root.dynobj)
2011 ia64_info->root.dynobj = abfd;
2012 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2013 dyn_i->want_plt = 1;
2015 if (need_entry & NEED_FULL_PLT)
2016 dyn_i->want_plt2 = 1;
2017 if (need_entry & NEED_PLTOFF)
2018 dyn_i->want_pltoff = 1;
2019 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2021 if (!srel)
2023 srel = get_reloc_section (abfd, ia64_info, sec, true);
2024 if (!srel)
2025 return false;
2027 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2028 return false;
2032 return true;
2035 struct elfNN_ia64_allocate_data
2037 struct bfd_link_info *info;
2038 bfd_size_type ofs;
2041 /* For cleanliness, and potentially faster dynamic loading, allocate
2042 external GOT entries first. */
2044 static boolean
2045 allocate_global_data_got (dyn_i, data)
2046 struct elfNN_ia64_dyn_sym_info *dyn_i;
2047 PTR data;
2049 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2051 if (dyn_i->want_got
2052 && ! dyn_i->want_fptr
2053 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
2055 dyn_i->got_offset = x->ofs;
2056 x->ofs += 8;
2058 return true;
2061 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2063 static boolean
2064 allocate_global_fptr_got (dyn_i, data)
2065 struct elfNN_ia64_dyn_sym_info *dyn_i;
2066 PTR data;
2068 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2070 if (dyn_i->want_got
2071 && dyn_i->want_fptr
2072 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
2074 dyn_i->got_offset = x->ofs;
2075 x->ofs += 8;
2077 return true;
2080 /* Lastly, allocate all the GOT entries for local data. */
2082 static boolean
2083 allocate_local_got (dyn_i, data)
2084 struct elfNN_ia64_dyn_sym_info *dyn_i;
2085 PTR data;
2087 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2089 if (dyn_i->want_got
2090 && ! elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
2092 dyn_i->got_offset = x->ofs;
2093 x->ofs += 8;
2095 return true;
2098 /* Search for the index of a global symbol in it's defining object file. */
2100 static unsigned long
2101 global_sym_index (h)
2102 struct elf_link_hash_entry *h;
2104 struct elf_link_hash_entry **p;
2105 bfd *obj;
2107 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2108 || h->root.type == bfd_link_hash_defweak);
2110 obj = h->root.u.def.section->owner;
2111 for (p = elf_sym_hashes (obj); *p != h; ++p)
2112 continue;
2114 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2117 /* Allocate function descriptors. We can do these for every function
2118 in a main executable that is not exported. */
2120 static boolean
2121 allocate_fptr (dyn_i, data)
2122 struct elfNN_ia64_dyn_sym_info *dyn_i;
2123 PTR data;
2125 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2127 if (dyn_i->want_fptr)
2129 struct elf_link_hash_entry *h = dyn_i->h;
2131 if (h)
2132 while (h->root.type == bfd_link_hash_indirect
2133 || h->root.type == bfd_link_hash_warning)
2134 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2136 if (x->info->shared)
2138 if (h && h->dynindx == -1)
2140 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2141 || (h->root.type == bfd_link_hash_defweak));
2143 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2144 (x->info, h->root.u.def.section->owner,
2145 global_sym_index (h)))
2146 return false;
2149 dyn_i->want_fptr = 0;
2151 else if (h == NULL || h->dynindx == -1)
2153 dyn_i->fptr_offset = x->ofs;
2154 x->ofs += 16;
2156 else
2157 dyn_i->want_fptr = 0;
2159 return true;
2162 /* Allocate all the minimal PLT entries. */
2164 static boolean
2165 allocate_plt_entries (dyn_i, data)
2166 struct elfNN_ia64_dyn_sym_info *dyn_i;
2167 PTR data;
2169 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2171 if (dyn_i->want_plt)
2173 struct elf_link_hash_entry *h = dyn_i->h;
2175 if (h)
2176 while (h->root.type == bfd_link_hash_indirect
2177 || h->root.type == bfd_link_hash_warning)
2178 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2180 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2181 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2183 bfd_size_type offset = x->ofs;
2184 if (offset == 0)
2185 offset = PLT_HEADER_SIZE;
2186 dyn_i->plt_offset = offset;
2187 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2189 dyn_i->want_pltoff = 1;
2191 else
2193 dyn_i->want_plt = 0;
2194 dyn_i->want_plt2 = 0;
2197 return true;
2200 /* Allocate all the full PLT entries. */
2202 static boolean
2203 allocate_plt2_entries (dyn_i, data)
2204 struct elfNN_ia64_dyn_sym_info *dyn_i;
2205 PTR data;
2207 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2209 if (dyn_i->want_plt2)
2211 struct elf_link_hash_entry *h = dyn_i->h;
2212 bfd_size_type ofs = x->ofs;
2214 dyn_i->plt2_offset = ofs;
2215 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2217 while (h->root.type == bfd_link_hash_indirect
2218 || h->root.type == bfd_link_hash_warning)
2219 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2220 dyn_i->h->plt.offset = ofs;
2222 return true;
2225 /* Allocate all the PLTOFF entries requested by relocations and
2226 plt entries. We can't share space with allocated FPTR entries,
2227 because the latter are not necessarily addressable by the GP.
2228 ??? Relaxation might be able to determine that they are. */
2230 static boolean
2231 allocate_pltoff_entries (dyn_i, data)
2232 struct elfNN_ia64_dyn_sym_info *dyn_i;
2233 PTR data;
2235 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2237 if (dyn_i->want_pltoff)
2239 dyn_i->pltoff_offset = x->ofs;
2240 x->ofs += 16;
2242 return true;
2245 /* Allocate dynamic relocations for those symbols that turned out
2246 to be dynamic. */
2248 static boolean
2249 allocate_dynrel_entries (dyn_i, data)
2250 struct elfNN_ia64_dyn_sym_info *dyn_i;
2251 PTR data;
2253 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2254 struct elfNN_ia64_link_hash_table *ia64_info;
2255 struct elfNN_ia64_dyn_reloc_entry *rent;
2256 boolean dynamic_symbol, shared;
2258 ia64_info = elfNN_ia64_hash_table (x->info);
2259 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info);
2260 shared = x->info->shared;
2262 /* Take care of the normal data relocations. */
2264 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2266 int count = rent->count;
2268 switch (rent->type)
2270 case R_IA64_FPTR64LSB:
2271 /* Allocate one iff !want_fptr, which by this point will
2272 be true only if we're actually allocating one statically
2273 in the main executable. */
2274 if (dyn_i->want_fptr)
2275 continue;
2276 break;
2277 case R_IA64_PCREL64LSB:
2278 if (!dynamic_symbol)
2279 continue;
2280 break;
2281 case R_IA64_DIR64LSB:
2282 if (!dynamic_symbol && !shared)
2283 continue;
2284 break;
2285 case R_IA64_IPLTLSB:
2286 if (!dynamic_symbol && !shared)
2287 continue;
2288 /* Use two REL relocations for IPLT relocations
2289 against local symbols. */
2290 if (!dynamic_symbol)
2291 count *= 2;
2292 break;
2293 default:
2294 abort ();
2296 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2299 /* Take care of the GOT and PLT relocations. */
2301 if (((dynamic_symbol || shared) && dyn_i->want_got)
2302 || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2303 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2305 if (dyn_i->want_pltoff)
2307 bfd_size_type t = 0;
2309 /* Dynamic symbols get one IPLT relocation. Local symbols in
2310 shared libraries get two REL relocations. Local symbols in
2311 main applications get nothing. */
2312 if (dynamic_symbol)
2313 t = sizeof (ElfNN_External_Rela);
2314 else if (shared)
2315 t = 2 * sizeof (ElfNN_External_Rela);
2317 ia64_info->rel_pltoff_sec->_raw_size += t;
2320 return true;
2323 static boolean
2324 elfNN_ia64_adjust_dynamic_symbol (info, h)
2325 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2326 struct elf_link_hash_entry *h;
2328 /* ??? Undefined symbols with PLT entries should be re-defined
2329 to be the PLT entry. */
2331 /* If this is a weak symbol, and there is a real definition, the
2332 processor independent code will have arranged for us to see the
2333 real definition first, and we can just use the same value. */
2334 if (h->weakdef != NULL)
2336 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2337 || h->weakdef->root.type == bfd_link_hash_defweak);
2338 h->root.u.def.section = h->weakdef->root.u.def.section;
2339 h->root.u.def.value = h->weakdef->root.u.def.value;
2340 return true;
2343 /* If this is a reference to a symbol defined by a dynamic object which
2344 is not a function, we might allocate the symbol in our .dynbss section
2345 and allocate a COPY dynamic relocation.
2347 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2348 of hackery. */
2350 return true;
2353 static boolean
2354 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2355 bfd *output_bfd;
2356 struct bfd_link_info *info;
2358 struct elfNN_ia64_allocate_data data;
2359 struct elfNN_ia64_link_hash_table *ia64_info;
2360 asection *sec;
2361 bfd *dynobj;
2362 boolean reltext = false;
2363 boolean relplt = false;
2365 dynobj = elf_hash_table(info)->dynobj;
2366 ia64_info = elfNN_ia64_hash_table (info);
2367 BFD_ASSERT(dynobj != NULL);
2368 data.info = info;
2370 /* Set the contents of the .interp section to the interpreter. */
2371 if (ia64_info->root.dynamic_sections_created
2372 && !info->shared)
2374 sec = bfd_get_section_by_name (dynobj, ".interp");
2375 BFD_ASSERT (sec != NULL);
2376 sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
2377 sec->_raw_size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
2380 /* Allocate the GOT entries. */
2382 if (ia64_info->got_sec)
2384 data.ofs = 0;
2385 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2386 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2387 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2388 ia64_info->got_sec->_raw_size = data.ofs;
2391 /* Allocate the FPTR entries. */
2393 if (ia64_info->fptr_sec)
2395 data.ofs = 0;
2396 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2397 ia64_info->fptr_sec->_raw_size = data.ofs;
2400 /* Now that we've seen all of the input files, we can decide which
2401 symbols need plt entries. Allocate the minimal PLT entries first.
2402 We do this even though dynamic_sections_created may be false, because
2403 this has the side-effect of clearing want_plt and want_plt2. */
2405 data.ofs = 0;
2406 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2408 ia64_info->minplt_entries = 0;
2409 if (data.ofs)
2411 ia64_info->minplt_entries
2412 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2415 /* Align the pointer for the plt2 entries. */
2416 data.ofs = (data.ofs + 31) & -32;
2418 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2419 if (data.ofs != 0)
2421 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2423 ia64_info->plt_sec->_raw_size = data.ofs;
2425 /* If we've got a .plt, we need some extra memory for the dynamic
2426 linker. We stuff these in .got.plt. */
2427 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2428 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2431 /* Allocate the PLTOFF entries. */
2433 if (ia64_info->pltoff_sec)
2435 data.ofs = 0;
2436 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2437 ia64_info->pltoff_sec->_raw_size = data.ofs;
2440 if (ia64_info->root.dynamic_sections_created)
2442 /* Allocate space for the dynamic relocations that turned out to be
2443 required. */
2445 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2448 /* We have now determined the sizes of the various dynamic sections.
2449 Allocate memory for them. */
2450 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2452 boolean strip;
2454 if (!(sec->flags & SEC_LINKER_CREATED))
2455 continue;
2457 /* If we don't need this section, strip it from the output file.
2458 There were several sections primarily related to dynamic
2459 linking that must be create before the linker maps input
2460 sections to output sections. The linker does that before
2461 bfd_elf_size_dynamic_sections is called, and it is that
2462 function which decides whether anything needs to go into
2463 these sections. */
2465 strip = (sec->_raw_size == 0);
2467 if (sec == ia64_info->got_sec)
2468 strip = false;
2469 else if (sec == ia64_info->rel_got_sec)
2471 if (strip)
2472 ia64_info->rel_got_sec = NULL;
2473 else
2474 /* We use the reloc_count field as a counter if we need to
2475 copy relocs into the output file. */
2476 sec->reloc_count = 0;
2478 else if (sec == ia64_info->fptr_sec)
2480 if (strip)
2481 ia64_info->fptr_sec = NULL;
2483 else if (sec == ia64_info->plt_sec)
2485 if (strip)
2486 ia64_info->plt_sec = NULL;
2488 else if (sec == ia64_info->pltoff_sec)
2490 if (strip)
2491 ia64_info->pltoff_sec = NULL;
2493 else if (sec == ia64_info->rel_pltoff_sec)
2495 if (strip)
2496 ia64_info->rel_pltoff_sec = NULL;
2497 else
2499 relplt = true;
2500 /* We use the reloc_count field as a counter if we need to
2501 copy relocs into the output file. */
2502 sec->reloc_count = 0;
2505 else
2507 const char *name;
2509 /* It's OK to base decisions on the section name, because none
2510 of the dynobj section names depend upon the input files. */
2511 name = bfd_get_section_name (dynobj, sec);
2513 if (strcmp (name, ".got.plt") == 0)
2514 strip = false;
2515 else if (strncmp (name, ".rel", 4) == 0)
2517 if (!strip)
2519 const char *outname;
2520 asection *target;
2522 /* If this relocation section applies to a read only
2523 section, then we probably need a DT_TEXTREL entry. */
2524 outname = bfd_get_section_name (output_bfd,
2525 sec->output_section);
2526 if (outname[4] == 'a')
2527 outname += 5;
2528 else
2529 outname += 4;
2531 target = bfd_get_section_by_name (output_bfd, outname);
2532 if (target != NULL
2533 && (target->flags & SEC_READONLY) != 0
2534 && (target->flags & SEC_ALLOC) != 0)
2535 reltext = true;
2537 /* We use the reloc_count field as a counter if we need to
2538 copy relocs into the output file. */
2539 sec->reloc_count = 0;
2542 else
2543 continue;
2546 if (strip)
2547 _bfd_strip_section_from_output (info, sec);
2548 else
2550 /* Allocate memory for the section contents. */
2551 sec->contents = (bfd_byte *) bfd_zalloc(dynobj, sec->_raw_size);
2552 if (sec->contents == NULL && sec->_raw_size != 0)
2553 return false;
2557 if (elf_hash_table (info)->dynamic_sections_created)
2559 /* Add some entries to the .dynamic section. We fill in the values
2560 later (in finish_dynamic_sections) but we must add the entries now
2561 so that we get the correct size for the .dynamic section. */
2563 if (!info->shared)
2565 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2566 by the debugger. */
2567 if (!bfd_elfNN_add_dynamic_entry (info, DT_DEBUG, 0))
2568 return false;
2571 if (! bfd_elfNN_add_dynamic_entry (info, DT_IA_64_PLT_RESERVE, 0))
2572 return false;
2573 if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTGOT, 0))
2574 return false;
2576 if (relplt)
2578 if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2579 || ! bfd_elfNN_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2580 || ! bfd_elfNN_add_dynamic_entry (info, DT_JMPREL, 0))
2581 return false;
2584 if (! bfd_elfNN_add_dynamic_entry (info, DT_RELA, 0)
2585 || ! bfd_elfNN_add_dynamic_entry (info, DT_RELASZ, 0)
2586 || ! bfd_elfNN_add_dynamic_entry (info, DT_RELAENT,
2587 sizeof (ElfNN_External_Rela)))
2588 return false;
2590 if (reltext)
2592 if (! bfd_elfNN_add_dynamic_entry (info, DT_TEXTREL, 0))
2593 return false;
2594 info->flags |= DF_TEXTREL;
2598 /* ??? Perhaps force __gp local. */
2600 return true;
2603 static bfd_reloc_status_type
2604 elfNN_ia64_install_value (abfd, hit_addr, val, r_type)
2605 bfd *abfd;
2606 bfd_byte *hit_addr;
2607 bfd_vma val;
2608 unsigned int r_type;
2610 const struct ia64_operand *op;
2611 int bigendian = 0, shift = 0;
2612 bfd_vma t0, t1, insn, dword;
2613 enum ia64_opnd opnd;
2614 const char *err;
2615 size_t size = 8;
2617 opnd = IA64_OPND_NIL;
2618 switch (r_type)
2620 case R_IA64_NONE:
2621 case R_IA64_LDXMOV:
2622 return bfd_reloc_ok;
2624 /* Instruction relocations. */
2626 case R_IA64_IMM14: opnd = IA64_OPND_IMM14; break;
2628 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
2629 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
2630 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
2631 case R_IA64_PCREL21B:
2632 case R_IA64_PCREL21BI:
2633 opnd = IA64_OPND_TGT25c;
2634 break;
2636 case R_IA64_IMM22:
2637 case R_IA64_GPREL22:
2638 case R_IA64_LTOFF22:
2639 case R_IA64_LTOFF22X:
2640 case R_IA64_PLTOFF22:
2641 case R_IA64_PCREL22:
2642 case R_IA64_LTOFF_FPTR22:
2643 opnd = IA64_OPND_IMM22;
2644 break;
2646 case R_IA64_IMM64:
2647 case R_IA64_GPREL64I:
2648 case R_IA64_LTOFF64I:
2649 case R_IA64_PLTOFF64I:
2650 case R_IA64_PCREL64I:
2651 case R_IA64_FPTR64I:
2652 case R_IA64_LTOFF_FPTR64I:
2653 opnd = IA64_OPND_IMMU64;
2654 break;
2656 /* Data relocations. */
2658 case R_IA64_DIR32MSB:
2659 case R_IA64_GPREL32MSB:
2660 case R_IA64_FPTR32MSB:
2661 case R_IA64_PCREL32MSB:
2662 case R_IA64_SEGREL32MSB:
2663 case R_IA64_SECREL32MSB:
2664 case R_IA64_LTV32MSB:
2665 size = 4; bigendian = 1;
2666 break;
2668 case R_IA64_DIR32LSB:
2669 case R_IA64_GPREL32LSB:
2670 case R_IA64_FPTR32LSB:
2671 case R_IA64_PCREL32LSB:
2672 case R_IA64_SEGREL32LSB:
2673 case R_IA64_SECREL32LSB:
2674 case R_IA64_LTV32LSB:
2675 size = 4; bigendian = 0;
2676 break;
2678 case R_IA64_DIR64MSB:
2679 case R_IA64_GPREL64MSB:
2680 case R_IA64_PLTOFF64MSB:
2681 case R_IA64_FPTR64MSB:
2682 case R_IA64_PCREL64MSB:
2683 case R_IA64_LTOFF_FPTR64MSB:
2684 case R_IA64_SEGREL64MSB:
2685 case R_IA64_SECREL64MSB:
2686 case R_IA64_LTV64MSB:
2687 size = 8; bigendian = 1;
2688 break;
2690 case R_IA64_DIR64LSB:
2691 case R_IA64_GPREL64LSB:
2692 case R_IA64_PLTOFF64LSB:
2693 case R_IA64_FPTR64LSB:
2694 case R_IA64_PCREL64LSB:
2695 case R_IA64_LTOFF_FPTR64LSB:
2696 case R_IA64_SEGREL64LSB:
2697 case R_IA64_SECREL64LSB:
2698 case R_IA64_LTV64LSB:
2699 size = 8; bigendian = 0;
2700 break;
2702 /* Unsupported / Dynamic relocations. */
2703 default:
2704 return bfd_reloc_notsupported;
2707 switch (opnd)
2709 case IA64_OPND_IMMU64:
2710 hit_addr -= (long) hit_addr & 0x3;
2711 t0 = bfd_get_64 (abfd, hit_addr);
2712 t1 = bfd_get_64 (abfd, hit_addr + 8);
2714 /* tmpl/s: bits 0.. 5 in t0
2715 slot 0: bits 5..45 in t0
2716 slot 1: bits 46..63 in t0, bits 0..22 in t1
2717 slot 2: bits 23..63 in t1 */
2719 /* First, clear the bits that form the 64 bit constant. */
2720 t0 &= ~(0x3ffffLL << 46);
2721 t1 &= ~(0x7fffffLL
2722 | (( (0x07fLL << 13) | (0x1ffLL << 27)
2723 | (0x01fLL << 22) | (0x001LL << 21)
2724 | (0x001LL << 36)) << 23));
2726 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
2727 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
2728 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
2729 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
2730 | (((val >> 16) & 0x01f) << 22) /* imm5c */
2731 | (((val >> 21) & 0x001) << 21) /* ic */
2732 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
2734 bfd_put_64 (abfd, t0, hit_addr);
2735 bfd_put_64 (abfd, t1, hit_addr + 8);
2736 break;
2738 case IA64_OPND_TGT64:
2739 hit_addr -= (long) hit_addr & 0x3;
2740 t0 = bfd_get_64 (abfd, hit_addr);
2741 t1 = bfd_get_64 (abfd, hit_addr + 8);
2743 /* tmpl/s: bits 0.. 5 in t0
2744 slot 0: bits 5..45 in t0
2745 slot 1: bits 46..63 in t0, bits 0..22 in t1
2746 slot 2: bits 23..63 in t1 */
2748 /* First, clear the bits that form the 64 bit constant. */
2749 t0 &= ~(0x3ffffLL << 46);
2750 t1 &= ~(0x7fffffLL
2751 | ((1LL << 36 | 0xfffffLL << 13) << 23));
2753 val >>= 4;
2754 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
2755 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
2756 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
2757 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
2759 bfd_put_64 (abfd, t0, hit_addr);
2760 bfd_put_64 (abfd, t1, hit_addr + 8);
2761 break;
2763 default:
2764 switch ((long) hit_addr & 0x3)
2766 case 0: shift = 5; break;
2767 case 1: shift = 14; hit_addr += 3; break;
2768 case 2: shift = 23; hit_addr += 6; break;
2769 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
2771 dword = bfd_get_64 (abfd, hit_addr);
2772 insn = (dword >> shift) & 0x1ffffffffffLL;
2774 op = elf64_ia64_operands + opnd;
2775 err = (*op->insert) (op, val, &insn);
2776 if (err)
2777 return bfd_reloc_overflow;
2779 dword &= ~(0x1ffffffffffLL << shift);
2780 dword |= (insn << shift);
2781 bfd_put_64 (abfd, dword, hit_addr);
2782 break;
2784 case IA64_OPND_NIL:
2785 /* A data relocation. */
2786 if (bigendian)
2787 if (size == 4)
2788 bfd_putb32 (val, hit_addr);
2789 else
2790 bfd_putb64 (val, hit_addr);
2791 else
2792 if (size == 4)
2793 bfd_putl32 (val, hit_addr);
2794 else
2795 bfd_putl64 (val, hit_addr);
2796 break;
2799 return bfd_reloc_ok;
2802 static void
2803 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
2804 dynindx, addend)
2805 bfd *abfd;
2806 struct bfd_link_info *info;
2807 asection *sec;
2808 asection *srel;
2809 bfd_vma offset;
2810 unsigned int type;
2811 long dynindx;
2812 bfd_vma addend;
2814 Elf_Internal_Rela outrel;
2816 outrel.r_offset = (sec->output_section->vma
2817 + sec->output_offset
2818 + offset);
2820 BFD_ASSERT (dynindx != -1);
2821 outrel.r_info = ELFNN_R_INFO (dynindx, type);
2822 outrel.r_addend = addend;
2824 if (elf_section_data (sec)->stab_info != NULL)
2826 /* This may be NULL for linker-generated relocations, as it is
2827 inconvenient to pass all the bits around. And this shouldn't
2828 happen. */
2829 BFD_ASSERT (info != NULL);
2831 offset = (_bfd_stab_section_offset
2832 (abfd, &elf_hash_table (info)->stab_info, sec,
2833 &elf_section_data (sec)->stab_info, offset));
2834 if (offset == (bfd_vma) -1)
2836 /* Run for the hills. We shouldn't be outputting a relocation
2837 for this. So do what everyone else does and output a no-op. */
2838 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
2839 outrel.r_addend = 0;
2840 offset = 0;
2842 outrel.r_offset = offset;
2845 bfd_elfNN_swap_reloca_out (abfd, &outrel,
2846 ((ElfNN_External_Rela *) srel->contents
2847 + srel->reloc_count++));
2848 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
2849 <= srel->_cooked_size);
2852 /* Store an entry for target address TARGET_ADDR in the linkage table
2853 and return the gp-relative address of the linkage table entry. */
2855 static bfd_vma
2856 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
2857 bfd *abfd;
2858 struct bfd_link_info *info;
2859 struct elfNN_ia64_dyn_sym_info *dyn_i;
2860 long dynindx;
2861 bfd_vma addend;
2862 bfd_vma value;
2863 unsigned int dyn_r_type;
2865 struct elfNN_ia64_link_hash_table *ia64_info;
2866 asection *got_sec;
2868 ia64_info = elfNN_ia64_hash_table (info);
2869 got_sec = ia64_info->got_sec;
2871 BFD_ASSERT ((dyn_i->got_offset & 7) == 0);
2873 if (! dyn_i->got_done)
2875 dyn_i->got_done = true;
2877 /* Store the target address in the linkage table entry. */
2878 bfd_put_64 (abfd, value, got_sec->contents + dyn_i->got_offset);
2880 /* Install a dynamic relocation if needed. */
2881 if (info->shared
2882 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
2883 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
2885 if (dynindx == -1)
2887 dyn_r_type = R_IA64_REL64LSB;
2888 dynindx = 0;
2889 addend = value;
2892 if (bfd_big_endian (abfd))
2894 switch (dyn_r_type)
2896 case R_IA64_REL64LSB:
2897 dyn_r_type = R_IA64_REL64MSB;
2898 break;
2899 case R_IA64_DIR64LSB:
2900 dyn_r_type = R_IA64_DIR64MSB;
2901 break;
2902 case R_IA64_FPTR64LSB:
2903 dyn_r_type = R_IA64_FPTR64MSB;
2904 break;
2905 default:
2906 BFD_ASSERT (false);
2907 break;
2911 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
2912 ia64_info->rel_got_sec,
2913 dyn_i->got_offset, dyn_r_type,
2914 dynindx, addend);
2918 /* Return the address of the linkage table entry. */
2919 value = (got_sec->output_section->vma
2920 + got_sec->output_offset
2921 + dyn_i->got_offset);
2923 return value;
2926 /* Fill in a function descriptor consisting of the function's code
2927 address and its global pointer. Return the descriptor's address. */
2929 static bfd_vma
2930 set_fptr_entry (abfd, info, dyn_i, value)
2931 bfd *abfd;
2932 struct bfd_link_info *info;
2933 struct elfNN_ia64_dyn_sym_info *dyn_i;
2934 bfd_vma value;
2936 struct elfNN_ia64_link_hash_table *ia64_info;
2937 asection *fptr_sec;
2939 ia64_info = elfNN_ia64_hash_table (info);
2940 fptr_sec = ia64_info->fptr_sec;
2942 if (!dyn_i->fptr_done)
2944 dyn_i->fptr_done = 1;
2946 /* Fill in the function descriptor. */
2947 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
2948 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
2949 fptr_sec->contents + dyn_i->fptr_offset + 8);
2952 /* Return the descriptor's address. */
2953 value = (fptr_sec->output_section->vma
2954 + fptr_sec->output_offset
2955 + dyn_i->fptr_offset);
2957 return value;
2960 /* Fill in a PLTOFF entry consisting of the function's code address
2961 and its global pointer. Return the descriptor's address. */
2963 static bfd_vma
2964 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
2965 bfd *abfd;
2966 struct bfd_link_info *info;
2967 struct elfNN_ia64_dyn_sym_info *dyn_i;
2968 bfd_vma value;
2969 boolean is_plt;
2971 struct elfNN_ia64_link_hash_table *ia64_info;
2972 asection *pltoff_sec;
2974 ia64_info = elfNN_ia64_hash_table (info);
2975 pltoff_sec = ia64_info->pltoff_sec;
2977 /* Don't do anything if this symbol uses a real PLT entry. In
2978 that case, we'll fill this in during finish_dynamic_symbol. */
2979 if ((! dyn_i->want_plt || is_plt)
2980 && !dyn_i->pltoff_done)
2982 bfd_vma gp = _bfd_get_gp_value (abfd);
2984 /* Fill in the function descriptor. */
2985 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
2986 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
2988 /* Install dynamic relocations if needed. */
2989 if (!is_plt && info->shared)
2991 unsigned int dyn_r_type;
2993 if (bfd_big_endian (abfd))
2994 dyn_r_type = R_IA64_REL64MSB;
2995 else
2996 dyn_r_type = R_IA64_REL64LSB;
2998 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
2999 ia64_info->rel_pltoff_sec,
3000 dyn_i->pltoff_offset,
3001 dyn_r_type, 0, value);
3002 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3003 ia64_info->rel_pltoff_sec,
3004 dyn_i->pltoff_offset + 8,
3005 dyn_r_type, 0, gp);
3008 dyn_i->pltoff_done = 1;
3011 /* Return the descriptor's address. */
3012 value = (pltoff_sec->output_section->vma
3013 + pltoff_sec->output_offset
3014 + dyn_i->pltoff_offset);
3016 return value;
3019 /* Called through qsort to sort the .IA_64.unwind section during a
3020 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3021 to the output bfd so we can do proper endianness frobbing. */
3023 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3025 static int
3026 elfNN_ia64_unwind_entry_compare (a, b)
3027 PTR a;
3028 PTR b;
3030 bfd_vma av, bv;
3032 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3033 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3035 return (av < bv ? -1 : av > bv ? 1 : 0);
3038 static boolean
3039 elfNN_ia64_final_link (abfd, info)
3040 bfd *abfd;
3041 struct bfd_link_info *info;
3043 struct elfNN_ia64_link_hash_table *ia64_info;
3044 asection *unwind_output_sec;
3046 ia64_info = elfNN_ia64_hash_table (info);
3048 /* Make sure we've got ourselves a nice fat __gp value. */
3049 if (!info->relocateable)
3051 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3052 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3053 struct elf_link_hash_entry *gp;
3054 bfd_vma gp_val;
3055 asection *os;
3057 /* Find the min and max vma of all sections marked short. Also
3058 collect min and max vma of any type, for use in selecting a
3059 nice gp. */
3060 for (os = abfd->sections; os ; os = os->next)
3062 bfd_vma lo, hi;
3064 if ((os->flags & SEC_ALLOC) == 0)
3065 continue;
3067 lo = os->vma;
3068 hi = os->vma + os->_raw_size;
3069 if (hi < lo)
3070 hi = (bfd_vma) -1;
3072 if (min_vma > lo)
3073 min_vma = lo;
3074 if (max_vma < hi)
3075 max_vma = hi;
3076 if (os->flags & SEC_SMALL_DATA)
3078 if (min_short_vma > lo)
3079 min_short_vma = lo;
3080 if (max_short_vma < hi)
3081 max_short_vma = hi;
3085 /* See if the user wants to force a value. */
3086 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
3087 false, false);
3089 if (gp
3090 && (gp->root.type == bfd_link_hash_defined
3091 || gp->root.type == bfd_link_hash_defweak))
3093 asection *gp_sec = gp->root.u.def.section;
3094 gp_val = (gp->root.u.def.value
3095 + gp_sec->output_section->vma
3096 + gp_sec->output_offset);
3098 else
3100 /* Pick a sensible value. */
3102 asection *got_sec = ia64_info->got_sec;
3104 /* Start with just the address of the .got. */
3105 if (got_sec)
3106 gp_val = got_sec->output_section->vma;
3107 else if (max_short_vma != 0)
3108 gp_val = min_short_vma;
3109 else
3110 gp_val = min_vma;
3112 /* If it is possible to address the entire image, but we
3113 don't with the choice above, adjust. */
3114 if (max_vma - min_vma < 0x400000
3115 && max_vma - gp_val <= 0x200000
3116 && gp_val - min_vma > 0x200000)
3117 gp_val = min_vma + 0x200000;
3118 else if (max_short_vma != 0)
3120 /* If we don't cover all the short data, adjust. */
3121 if (max_short_vma - gp_val >= 0x200000)
3122 gp_val = min_short_vma + 0x200000;
3124 /* If we're addressing stuff past the end, adjust back. */
3125 if (gp_val > max_vma)
3126 gp_val = max_vma - 0x200000 + 8;
3130 /* Validate whether all SHF_IA_64_SHORT sections are within
3131 range of the chosen GP. */
3133 if (max_short_vma != 0)
3135 if (max_short_vma - min_short_vma >= 0x400000)
3137 (*_bfd_error_handler)
3138 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3139 bfd_get_filename (abfd),
3140 (unsigned long) (max_short_vma - min_short_vma));
3141 return false;
3143 else if ((gp_val > min_short_vma
3144 && gp_val - min_short_vma > 0x200000)
3145 || (gp_val < max_short_vma
3146 && max_short_vma - gp_val >= 0x200000))
3148 (*_bfd_error_handler)
3149 (_("%s: __gp does not cover short data segment"),
3150 bfd_get_filename (abfd));
3151 return false;
3155 _bfd_set_gp_value (abfd, gp_val);
3157 if (gp)
3159 gp->root.type = bfd_link_hash_defined;
3160 gp->root.u.def.value = gp_val;
3161 gp->root.u.def.section = bfd_abs_section_ptr;
3165 /* If we're producing a final executable, we need to sort the contents
3166 of the .IA_64.unwind section. Force this section to be relocated
3167 into memory rather than written immediately to the output file. */
3168 unwind_output_sec = NULL;
3169 if (!info->relocateable)
3171 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3172 if (s)
3174 unwind_output_sec = s->output_section;
3175 unwind_output_sec->contents
3176 = bfd_malloc (unwind_output_sec->_raw_size);
3177 if (unwind_output_sec->contents == NULL)
3178 return false;
3182 /* Invoke the regular ELF backend linker to do all the work. */
3183 if (!bfd_elfNN_bfd_final_link (abfd, info))
3184 return false;
3186 if (unwind_output_sec)
3188 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3189 qsort (unwind_output_sec->contents, unwind_output_sec->_raw_size / 24,
3190 24, elfNN_ia64_unwind_entry_compare);
3192 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3193 unwind_output_sec->contents, 0,
3194 unwind_output_sec->_raw_size))
3195 return false;
3198 return true;
3201 static boolean
3202 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3203 contents, relocs, local_syms, local_sections)
3204 bfd *output_bfd;
3205 struct bfd_link_info *info;
3206 bfd *input_bfd;
3207 asection *input_section;
3208 bfd_byte *contents;
3209 Elf_Internal_Rela *relocs;
3210 Elf_Internal_Sym *local_syms;
3211 asection **local_sections;
3213 struct elfNN_ia64_link_hash_table *ia64_info;
3214 Elf_Internal_Shdr *symtab_hdr;
3215 Elf_Internal_Rela *rel;
3216 Elf_Internal_Rela *relend;
3217 asection *srel;
3218 boolean ret_val = true; /* for non-fatal errors */
3219 bfd_vma gp_val;
3221 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3222 ia64_info = elfNN_ia64_hash_table (info);
3224 /* Infect various flags from the input section to the output section. */
3225 if (info->relocateable)
3227 bfd_vma flags;
3229 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3230 flags &= SHF_IA_64_NORECOV;
3232 elf_section_data(input_section->output_section)
3233 ->this_hdr.sh_flags |= flags;
3236 gp_val = _bfd_get_gp_value (output_bfd);
3237 srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3239 rel = relocs;
3240 relend = relocs + input_section->reloc_count;
3241 for (; rel < relend; ++rel)
3243 struct elf_link_hash_entry *h;
3244 struct elfNN_ia64_dyn_sym_info *dyn_i;
3245 bfd_reloc_status_type r;
3246 reloc_howto_type *howto;
3247 unsigned long r_symndx;
3248 Elf_Internal_Sym *sym;
3249 unsigned int r_type;
3250 bfd_vma value;
3251 asection *sym_sec;
3252 bfd_byte *hit_addr;
3253 boolean dynamic_symbol_p;
3254 boolean undef_weak_ref;
3256 r_type = ELFNN_R_TYPE (rel->r_info);
3257 if (r_type > R_IA64_MAX_RELOC_CODE)
3259 (*_bfd_error_handler)
3260 (_("%s: unknown relocation type %d"),
3261 bfd_get_filename (input_bfd), (int)r_type);
3262 bfd_set_error (bfd_error_bad_value);
3263 ret_val = false;
3264 continue;
3266 howto = lookup_howto (r_type);
3267 r_symndx = ELFNN_R_SYM (rel->r_info);
3269 if (info->relocateable)
3271 /* This is a relocateable link. We don't have to change
3272 anything, unless the reloc is against a section symbol,
3273 in which case we have to adjust according to where the
3274 section symbol winds up in the output section. */
3275 if (r_symndx < symtab_hdr->sh_info)
3277 sym = local_syms + r_symndx;
3278 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3280 sym_sec = local_sections[r_symndx];
3281 rel->r_addend += sym_sec->output_offset;
3284 continue;
3287 /* This is a final link. */
3289 h = NULL;
3290 sym = NULL;
3291 sym_sec = NULL;
3292 undef_weak_ref = false;
3294 if (r_symndx < symtab_hdr->sh_info)
3296 /* Reloc against local symbol. */
3297 sym = local_syms + r_symndx;
3298 sym_sec = local_sections[r_symndx];
3299 value = (sym_sec->output_section->vma
3300 + sym_sec->output_offset
3301 + sym->st_value);
3303 else
3305 long indx;
3307 /* Reloc against global symbol. */
3308 indx = r_symndx - symtab_hdr->sh_info;
3309 h = elf_sym_hashes (input_bfd)[indx];
3310 while (h->root.type == bfd_link_hash_indirect
3311 || h->root.type == bfd_link_hash_warning)
3312 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3314 value = 0;
3315 if (h->root.type == bfd_link_hash_defined
3316 || h->root.type == bfd_link_hash_defweak)
3318 sym_sec = h->root.u.def.section;
3320 /* Detect the cases that sym_sec->output_section is
3321 expected to be NULL -- all cases in which the symbol
3322 is defined in another shared module. This includes
3323 PLT relocs for which we've created a PLT entry and
3324 other relocs for which we're prepared to create
3325 dynamic relocations. */
3326 /* ??? Just accept it NULL and continue. */
3328 if (sym_sec->output_section != NULL)
3330 value = (h->root.u.def.value
3331 + sym_sec->output_section->vma
3332 + sym_sec->output_offset);
3335 else if (h->root.type == bfd_link_hash_undefweak)
3336 undef_weak_ref = true;
3337 else if (info->shared && !info->symbolic
3338 && !info->no_undefined
3339 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3341 else
3343 if (! ((*info->callbacks->undefined_symbol)
3344 (info, h->root.root.string, input_bfd,
3345 input_section, rel->r_offset,
3346 (!info->shared || info->no_undefined
3347 || ELF_ST_VISIBILITY (h->other)))))
3348 return false;
3349 ret_val = false;
3350 continue;
3354 hit_addr = contents + rel->r_offset;
3355 value += rel->r_addend;
3356 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3358 switch (r_type)
3360 case R_IA64_NONE:
3361 case R_IA64_LDXMOV:
3362 continue;
3364 case R_IA64_IMM14:
3365 case R_IA64_IMM22:
3366 case R_IA64_IMM64:
3367 case R_IA64_DIR32MSB:
3368 case R_IA64_DIR32LSB:
3369 case R_IA64_DIR64MSB:
3370 case R_IA64_DIR64LSB:
3371 /* Install a dynamic relocation for this reloc. */
3372 if ((dynamic_symbol_p || info->shared)
3373 && (input_section->flags & SEC_ALLOC) != 0)
3375 unsigned int dyn_r_type;
3376 long dynindx;
3377 bfd_vma addend;
3379 BFD_ASSERT (srel != NULL);
3381 /* If we don't need dynamic symbol lookup, find a
3382 matching RELATIVE relocation. */
3383 dyn_r_type = r_type;
3384 if (dynamic_symbol_p)
3386 dynindx = h->dynindx;
3387 addend = rel->r_addend;
3388 value = 0;
3390 else
3392 switch (r_type)
3394 case R_IA64_DIR32MSB:
3395 dyn_r_type = R_IA64_REL32MSB;
3396 break;
3397 case R_IA64_DIR32LSB:
3398 dyn_r_type = R_IA64_REL32LSB;
3399 break;
3400 case R_IA64_DIR64MSB:
3401 dyn_r_type = R_IA64_REL64MSB;
3402 break;
3403 case R_IA64_DIR64LSB:
3404 dyn_r_type = R_IA64_REL64LSB;
3405 break;
3407 default:
3408 /* We can't represent this without a dynamic symbol.
3409 Adjust the relocation to be against an output
3410 section symbol, which are always present in the
3411 dynamic symbol table. */
3412 /* ??? People shouldn't be doing non-pic code in
3413 shared libraries. Hork. */
3414 (*_bfd_error_handler)
3415 (_("%s: linking non-pic code in a shared library"),
3416 bfd_get_filename (input_bfd));
3417 ret_val = false;
3418 continue;
3420 dynindx = 0;
3421 addend = value;
3424 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3425 srel, rel->r_offset, dyn_r_type,
3426 dynindx, addend);
3428 /* FALLTHRU */
3430 case R_IA64_LTV32MSB:
3431 case R_IA64_LTV32LSB:
3432 case R_IA64_LTV64MSB:
3433 case R_IA64_LTV64LSB:
3434 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3435 break;
3437 case R_IA64_GPREL22:
3438 case R_IA64_GPREL64I:
3439 case R_IA64_GPREL32MSB:
3440 case R_IA64_GPREL32LSB:
3441 case R_IA64_GPREL64MSB:
3442 case R_IA64_GPREL64LSB:
3443 if (dynamic_symbol_p)
3445 (*_bfd_error_handler)
3446 (_("%s: @gprel relocation against dynamic symbol %s"),
3447 bfd_get_filename (input_bfd), h->root.root.string);
3448 ret_val = false;
3449 continue;
3451 value -= gp_val;
3452 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3453 break;
3455 case R_IA64_LTOFF22:
3456 case R_IA64_LTOFF22X:
3457 case R_IA64_LTOFF64I:
3458 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3459 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
3460 rel->r_addend, value, R_IA64_DIR64LSB);
3461 value -= gp_val;
3462 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3463 break;
3465 case R_IA64_PLTOFF22:
3466 case R_IA64_PLTOFF64I:
3467 case R_IA64_PLTOFF64MSB:
3468 case R_IA64_PLTOFF64LSB:
3469 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3470 value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
3471 value -= gp_val;
3472 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3473 break;
3475 case R_IA64_FPTR64I:
3476 case R_IA64_FPTR32MSB:
3477 case R_IA64_FPTR32LSB:
3478 case R_IA64_FPTR64MSB:
3479 case R_IA64_FPTR64LSB:
3480 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3481 if (dyn_i->want_fptr)
3483 if (!undef_weak_ref)
3484 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3486 else
3488 long dynindx;
3490 /* Otherwise, we expect the dynamic linker to create
3491 the entry. */
3493 if (h)
3495 if (h->dynindx != -1)
3496 dynindx = h->dynindx;
3497 else
3498 dynindx = (_bfd_elf_link_lookup_local_dynindx
3499 (info, h->root.u.def.section->owner,
3500 global_sym_index (h)));
3502 else
3504 dynindx = (_bfd_elf_link_lookup_local_dynindx
3505 (info, input_bfd, r_symndx));
3508 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3509 srel, rel->r_offset, r_type,
3510 dynindx, rel->r_addend);
3511 value = 0;
3514 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3515 break;
3517 case R_IA64_LTOFF_FPTR22:
3518 case R_IA64_LTOFF_FPTR64I:
3519 case R_IA64_LTOFF_FPTR64MSB:
3520 case R_IA64_LTOFF_FPTR64LSB:
3522 long dynindx;
3524 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3525 if (dyn_i->want_fptr)
3527 BFD_ASSERT (h == NULL || h->dynindx == -1)
3528 if (!undef_weak_ref)
3529 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3530 dynindx = -1;
3532 else
3534 /* Otherwise, we expect the dynamic linker to create
3535 the entry. */
3536 if (h)
3538 if (h->dynindx != -1)
3539 dynindx = h->dynindx;
3540 else
3541 dynindx = (_bfd_elf_link_lookup_local_dynindx
3542 (info, h->root.u.def.section->owner,
3543 global_sym_index (h)));
3545 else
3546 dynindx = (_bfd_elf_link_lookup_local_dynindx
3547 (info, input_bfd, r_symndx));
3548 value = 0;
3551 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
3552 rel->r_addend, value, R_IA64_FPTR64LSB);
3553 value -= gp_val;
3554 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3556 break;
3558 case R_IA64_PCREL32MSB:
3559 case R_IA64_PCREL32LSB:
3560 case R_IA64_PCREL64MSB:
3561 case R_IA64_PCREL64LSB:
3562 /* Install a dynamic relocation for this reloc. */
3563 if (dynamic_symbol_p)
3565 BFD_ASSERT (srel != NULL);
3567 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3568 srel, rel->r_offset, r_type,
3569 h->dynindx, rel->r_addend);
3571 goto finish_pcrel;
3573 case R_IA64_PCREL21BI:
3574 case R_IA64_PCREL21F:
3575 case R_IA64_PCREL21M:
3576 /* ??? These two are only used for speculation fixup code.
3577 They should never be dynamic. */
3578 if (dynamic_symbol_p)
3580 (*_bfd_error_handler)
3581 (_("%s: dynamic relocation against speculation fixup"),
3582 bfd_get_filename (input_bfd));
3583 ret_val = false;
3584 continue;
3586 if (undef_weak_ref)
3588 (*_bfd_error_handler)
3589 (_("%s: speculation fixup against undefined weak symbol"),
3590 bfd_get_filename (input_bfd));
3591 ret_val = false;
3592 continue;
3594 goto finish_pcrel;
3596 case R_IA64_PCREL21B:
3597 case R_IA64_PCREL60B:
3598 /* We should have created a PLT entry for any dynamic symbol. */
3599 dyn_i = NULL;
3600 if (h)
3601 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3603 if (dyn_i && dyn_i->want_plt2)
3605 /* Should have caught this earlier. */
3606 BFD_ASSERT (rel->r_addend == 0);
3608 value = (ia64_info->plt_sec->output_section->vma
3609 + ia64_info->plt_sec->output_offset
3610 + dyn_i->plt2_offset);
3612 else
3614 /* Since there's no PLT entry, Validate that this is
3615 locally defined. */
3616 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
3618 /* If the symbol is undef_weak, we shouldn't be trying
3619 to call it. There's every chance that we'd wind up
3620 with an out-of-range fixup here. Don't bother setting
3621 any value at all. */
3622 if (undef_weak_ref)
3623 continue;
3625 goto finish_pcrel;
3627 case R_IA64_PCREL22:
3628 case R_IA64_PCREL64I:
3629 finish_pcrel:
3630 /* Make pc-relative. */
3631 value -= (input_section->output_section->vma
3632 + input_section->output_offset
3633 + rel->r_offset) & ~ (bfd_vma) 0x3;
3634 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3635 break;
3637 case R_IA64_SEGREL32MSB:
3638 case R_IA64_SEGREL32LSB:
3639 case R_IA64_SEGREL64MSB:
3640 case R_IA64_SEGREL64LSB:
3642 struct elf_segment_map *m;
3643 Elf_Internal_Phdr *p;
3645 /* Find the segment that contains the output_section. */
3646 for (m = elf_tdata (output_bfd)->segment_map,
3647 p = elf_tdata (output_bfd)->phdr;
3648 m != NULL;
3649 m = m->next, p++)
3651 int i;
3652 for (i = m->count - 1; i >= 0; i--)
3653 if (m->sections[i] == sym_sec->output_section)
3654 break;
3655 if (i >= 0)
3656 break;
3659 if (m == NULL)
3661 /* If the input section was discarded from the output, then
3662 do nothing. */
3664 if (bfd_is_abs_section (sym_sec->output_section))
3665 r = bfd_reloc_ok;
3666 else
3667 r = bfd_reloc_notsupported;
3669 else
3671 /* The VMA of the segment is the vaddr of the associated
3672 program header. */
3673 if (value > p->p_vaddr)
3674 value -= p->p_vaddr;
3675 else
3676 value = 0;
3677 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
3678 r_type);
3680 break;
3683 case R_IA64_SECREL32MSB:
3684 case R_IA64_SECREL32LSB:
3685 case R_IA64_SECREL64MSB:
3686 case R_IA64_SECREL64LSB:
3687 /* Make output-section relative. */
3688 if (value > input_section->output_section->vma)
3689 value -= input_section->output_section->vma;
3690 else
3691 value = 0;
3692 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3693 break;
3695 case R_IA64_IPLTMSB:
3696 case R_IA64_IPLTLSB:
3697 /* Install a dynamic relocation for this reloc. */
3698 if ((dynamic_symbol_p || info->shared)
3699 && (input_section->flags & SEC_ALLOC) != 0)
3701 BFD_ASSERT (srel != NULL);
3703 /* If we don't need dynamic symbol lookup, install two
3704 RELATIVE relocations. */
3705 if (! dynamic_symbol_p)
3707 unsigned int dyn_r_type;
3709 if (r_type == R_IA64_IPLTMSB)
3710 dyn_r_type = R_IA64_REL64MSB;
3711 else
3712 dyn_r_type = R_IA64_REL64LSB;
3714 elfNN_ia64_install_dyn_reloc (output_bfd, info,
3715 input_section,
3716 srel, rel->r_offset,
3717 dyn_r_type, 0, value);
3718 elfNN_ia64_install_dyn_reloc (output_bfd, info,
3719 input_section,
3720 srel, rel->r_offset + 8,
3721 dyn_r_type, 0, gp_val);
3723 else
3724 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3725 srel, rel->r_offset, r_type,
3726 h->dynindx, rel->r_addend);
3729 if (r_type == R_IA64_IPLTMSB)
3730 r_type = R_IA64_DIR64MSB;
3731 else
3732 r_type = R_IA64_DIR64LSB;
3733 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3734 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
3735 r_type);
3736 break;
3738 default:
3739 r = bfd_reloc_notsupported;
3740 break;
3743 switch (r)
3745 case bfd_reloc_ok:
3746 break;
3748 case bfd_reloc_undefined:
3749 /* This can happen for global table relative relocs if
3750 __gp is undefined. This is a panic situation so we
3751 don't try to continue. */
3752 (*info->callbacks->undefined_symbol)
3753 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
3754 return false;
3756 case bfd_reloc_notsupported:
3758 const char *name;
3760 if (h)
3761 name = h->root.root.string;
3762 else
3764 name = bfd_elf_string_from_elf_section (input_bfd,
3765 symtab_hdr->sh_link,
3766 sym->st_name);
3767 if (name == NULL)
3768 return false;
3769 if (*name == '\0')
3770 name = bfd_section_name (input_bfd, input_section);
3772 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
3773 name, input_bfd,
3774 input_section, rel->r_offset))
3775 return false;
3776 ret_val = false;
3778 break;
3780 case bfd_reloc_dangerous:
3781 case bfd_reloc_outofrange:
3782 case bfd_reloc_overflow:
3783 default:
3785 const char *name;
3787 if (h)
3788 name = h->root.root.string;
3789 else
3791 name = bfd_elf_string_from_elf_section (input_bfd,
3792 symtab_hdr->sh_link,
3793 sym->st_name);
3794 if (name == NULL)
3795 return false;
3796 if (*name == '\0')
3797 name = bfd_section_name (input_bfd, input_section);
3799 if (!(*info->callbacks->reloc_overflow) (info, name,
3800 howto->name, 0,
3801 input_bfd,
3802 input_section,
3803 rel->r_offset))
3804 return false;
3805 ret_val = false;
3807 break;
3811 return ret_val;
3814 static boolean
3815 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
3816 bfd *output_bfd;
3817 struct bfd_link_info *info;
3818 struct elf_link_hash_entry *h;
3819 Elf_Internal_Sym *sym;
3821 struct elfNN_ia64_link_hash_table *ia64_info;
3822 struct elfNN_ia64_dyn_sym_info *dyn_i;
3824 ia64_info = elfNN_ia64_hash_table (info);
3825 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3827 /* Fill in the PLT data, if required. */
3828 if (dyn_i && dyn_i->want_plt)
3830 Elf_Internal_Rela outrel;
3831 bfd_byte *loc;
3832 asection *plt_sec;
3833 bfd_vma plt_addr, pltoff_addr, gp_val, index;
3834 ElfNN_External_Rela *rel;
3836 gp_val = _bfd_get_gp_value (output_bfd);
3838 /* Initialize the minimal PLT entry. */
3840 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3841 plt_sec = ia64_info->plt_sec;
3842 loc = plt_sec->contents + dyn_i->plt_offset;
3844 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
3845 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
3846 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
3847 R_IA64_PCREL21B);
3849 plt_addr = (plt_sec->output_section->vma
3850 + plt_sec->output_offset
3851 + dyn_i->plt_offset);
3852 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
3854 /* Initialize the FULL PLT entry, if needed. */
3855 if (dyn_i->want_plt2)
3857 loc = plt_sec->contents + dyn_i->plt2_offset;
3859 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
3860 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
3861 R_IA64_IMM22);
3863 /* Mark the symbol as undefined, rather than as defined in the
3864 plt section. Leave the value alone. */
3865 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
3866 first place. But perhaps elflink.h did some for us. */
3867 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
3868 sym->st_shndx = SHN_UNDEF;
3871 /* Create the dynamic relocation. */
3872 outrel.r_offset = pltoff_addr;
3873 if (bfd_little_endian (output_bfd))
3874 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
3875 else
3876 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
3877 outrel.r_addend = 0;
3879 /* This is fun. In the .IA_64.pltoff section, we've got entries
3880 that correspond both to real PLT entries, and those that
3881 happened to resolve to local symbols but need to be created
3882 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
3883 relocations for the real PLT should come at the end of the
3884 section, so that they can be indexed by plt entry at runtime.
3886 We emitted all of the relocations for the non-PLT @pltoff
3887 entries during relocate_section. So we can consider the
3888 existing sec->reloc_count to be the base of the array of
3889 PLT relocations. */
3891 rel = (ElfNN_External_Rela *)ia64_info->rel_pltoff_sec->contents;
3892 rel += ia64_info->rel_pltoff_sec->reloc_count;
3894 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, rel + index);
3897 /* Mark some specially defined symbols as absolute. */
3898 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
3899 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
3900 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
3901 sym->st_shndx = SHN_ABS;
3903 return true;
3906 static boolean
3907 elfNN_ia64_finish_dynamic_sections (abfd, info)
3908 bfd *abfd;
3909 struct bfd_link_info *info;
3911 struct elfNN_ia64_link_hash_table *ia64_info;
3912 bfd *dynobj;
3914 ia64_info = elfNN_ia64_hash_table (info);
3915 dynobj = ia64_info->root.dynobj;
3917 if (elf_hash_table (info)->dynamic_sections_created)
3919 ElfNN_External_Dyn *dyncon, *dynconend;
3920 asection *sdyn, *sgotplt;
3921 bfd_vma gp_val;
3923 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3924 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
3925 BFD_ASSERT (sdyn != NULL);
3926 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
3927 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
3929 gp_val = _bfd_get_gp_value (abfd);
3931 for (; dyncon < dynconend; dyncon++)
3933 Elf_Internal_Dyn dyn;
3935 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
3937 switch (dyn.d_tag)
3939 case DT_PLTGOT:
3940 dyn.d_un.d_ptr = gp_val;
3941 break;
3943 case DT_PLTRELSZ:
3944 dyn.d_un.d_val = (ia64_info->minplt_entries
3945 * sizeof (ElfNN_External_Rela));
3946 break;
3948 case DT_JMPREL:
3949 /* See the comment above in finish_dynamic_symbol. */
3950 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
3951 + ia64_info->rel_pltoff_sec->output_offset
3952 + (ia64_info->rel_pltoff_sec->reloc_count
3953 * sizeof (ElfNN_External_Rela)));
3954 break;
3956 case DT_IA_64_PLT_RESERVE:
3957 dyn.d_un.d_ptr = (sgotplt->output_section->vma
3958 + sgotplt->output_offset);
3959 break;
3961 case DT_RELASZ:
3962 /* Do not have RELASZ include JMPREL. This makes things
3963 easier on ld.so. This is not what the rest of BFD set up. */
3964 dyn.d_un.d_val -= (ia64_info->minplt_entries
3965 * sizeof (ElfNN_External_Rela));
3966 break;
3969 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
3972 /* Initialize the PLT0 entry */
3973 if (ia64_info->plt_sec)
3975 bfd_byte *loc = ia64_info->plt_sec->contents;
3976 bfd_vma pltres;
3978 memcpy (loc, plt_header, PLT_HEADER_SIZE);
3980 pltres = (sgotplt->output_section->vma
3981 + sgotplt->output_offset
3982 - gp_val);
3984 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
3988 return true;
3991 /* ELF file flag handling: */
3993 /* Function to keep IA-64 specific file flags. */
3994 static boolean
3995 elfNN_ia64_set_private_flags (abfd, flags)
3996 bfd *abfd;
3997 flagword flags;
3999 BFD_ASSERT (!elf_flags_init (abfd)
4000 || elf_elfheader (abfd)->e_flags == flags);
4002 elf_elfheader (abfd)->e_flags = flags;
4003 elf_flags_init (abfd) = true;
4004 return true;
4007 /* Copy backend specific data from one object module to another */
4008 static boolean
4009 elfNN_ia64_copy_private_bfd_data (ibfd, obfd)
4010 bfd *ibfd, *obfd;
4012 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4013 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4014 return true;
4016 BFD_ASSERT (!elf_flags_init (obfd)
4017 || (elf_elfheader (obfd)->e_flags
4018 == elf_elfheader (ibfd)->e_flags));
4020 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
4021 elf_flags_init (obfd) = true;
4022 return true;
4025 /* Merge backend specific data from an object file to the output
4026 object file when linking. */
4027 static boolean
4028 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4029 bfd *ibfd, *obfd;
4031 flagword out_flags;
4032 flagword in_flags;
4033 boolean ok = true;
4035 /* Don't even pretend to support mixed-format linking. */
4036 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4037 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4038 return false;
4040 in_flags = elf_elfheader (ibfd)->e_flags;
4041 out_flags = elf_elfheader (obfd)->e_flags;
4043 if (! elf_flags_init (obfd))
4045 elf_flags_init (obfd) = true;
4046 elf_elfheader (obfd)->e_flags = in_flags;
4048 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4049 && bfd_get_arch_info (obfd)->the_default)
4051 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4052 bfd_get_mach (ibfd));
4055 return true;
4058 /* Check flag compatibility. */
4059 if (in_flags == out_flags)
4060 return true;
4062 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4063 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4064 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4066 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4068 (*_bfd_error_handler)
4069 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4070 bfd_get_filename (ibfd));
4072 bfd_set_error (bfd_error_bad_value);
4073 ok = false;
4075 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4077 (*_bfd_error_handler)
4078 (_("%s: linking big-endian files with little-endian files"),
4079 bfd_get_filename (ibfd));
4081 bfd_set_error (bfd_error_bad_value);
4082 ok = false;
4084 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4086 (*_bfd_error_handler)
4087 (_("%s: linking 64-bit files with 32-bit files"),
4088 bfd_get_filename (ibfd));
4090 bfd_set_error (bfd_error_bad_value);
4091 ok = false;
4093 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4095 (*_bfd_error_handler)
4096 (_("%s: linking constant-gp files with non-constant-gp files"),
4097 bfd_get_filename (ibfd));
4099 bfd_set_error (bfd_error_bad_value);
4100 ok = false;
4102 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4103 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4105 (*_bfd_error_handler)
4106 (_("%s: linking auto-pic files with non-auto-pic files"),
4107 bfd_get_filename (ibfd));
4109 bfd_set_error (bfd_error_bad_value);
4110 ok = false;
4113 return ok;
4116 static boolean
4117 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4118 bfd *abfd;
4119 PTR ptr;
4121 FILE *file = (FILE *) ptr;
4122 flagword flags = elf_elfheader (abfd)->e_flags;
4124 BFD_ASSERT (abfd != NULL && ptr != NULL);
4126 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4127 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4128 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4129 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4130 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4131 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4132 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4133 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4134 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4136 _bfd_elf_print_private_bfd_data (abfd, ptr);
4137 return true;
4140 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4141 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4142 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4143 #define TARGET_BIG_NAME "elfNN-ia64-big"
4144 #define ELF_ARCH bfd_arch_ia64
4145 #define ELF_MACHINE_CODE EM_IA_64
4146 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4147 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4148 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4150 #define elf_backend_section_from_shdr \
4151 elfNN_ia64_section_from_shdr
4152 #define elf_backend_section_flags \
4153 elfNN_ia64_section_flags
4154 #define elf_backend_fake_sections \
4155 elfNN_ia64_fake_sections
4156 #define elf_backend_final_write_processing \
4157 elfNN_ia64_final_write_processing
4158 #define elf_backend_add_symbol_hook \
4159 elfNN_ia64_add_symbol_hook
4160 #define elf_backend_additional_program_headers \
4161 elfNN_ia64_additional_program_headers
4162 #define elf_backend_modify_segment_map \
4163 elfNN_ia64_modify_segment_map
4164 #define elf_info_to_howto \
4165 elfNN_ia64_info_to_howto
4167 #define bfd_elfNN_bfd_reloc_type_lookup \
4168 elfNN_ia64_reloc_type_lookup
4169 #define bfd_elfNN_bfd_is_local_label_name \
4170 elfNN_ia64_is_local_label_name
4171 #define bfd_elfNN_bfd_relax_section \
4172 elfNN_ia64_relax_section
4174 /* Stuff for the BFD linker: */
4175 #define bfd_elfNN_bfd_link_hash_table_create \
4176 elfNN_ia64_hash_table_create
4177 #define elf_backend_create_dynamic_sections \
4178 elfNN_ia64_create_dynamic_sections
4179 #define elf_backend_check_relocs \
4180 elfNN_ia64_check_relocs
4181 #define elf_backend_adjust_dynamic_symbol \
4182 elfNN_ia64_adjust_dynamic_symbol
4183 #define elf_backend_size_dynamic_sections \
4184 elfNN_ia64_size_dynamic_sections
4185 #define elf_backend_relocate_section \
4186 elfNN_ia64_relocate_section
4187 #define elf_backend_finish_dynamic_symbol \
4188 elfNN_ia64_finish_dynamic_symbol
4189 #define elf_backend_finish_dynamic_sections \
4190 elfNN_ia64_finish_dynamic_sections
4191 #define bfd_elfNN_bfd_final_link \
4192 elfNN_ia64_final_link
4194 #define bfd_elfNN_bfd_copy_private_bfd_data \
4195 elfNN_ia64_copy_private_bfd_data
4196 #define bfd_elfNN_bfd_merge_private_bfd_data \
4197 elfNN_ia64_merge_private_bfd_data
4198 #define bfd_elfNN_bfd_set_private_flags \
4199 elfNN_ia64_set_private_flags
4200 #define bfd_elfNN_bfd_print_private_bfd_data \
4201 elfNN_ia64_print_private_bfd_data
4203 #define elf_backend_plt_readonly 1
4204 #define elf_backend_want_plt_sym 0
4205 #define elf_backend_plt_alignment 5
4206 #define elf_backend_got_header_size 0
4207 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4208 #define elf_backend_want_got_plt 1
4209 #define elf_backend_may_use_rel_p 1
4210 #define elf_backend_may_use_rela_p 1
4211 #define elf_backend_default_use_rela_p 1
4212 #define elf_backend_want_dynbss 0
4213 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4214 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4216 #include "elfNN-target.h"