Fix file corrupted before initial checkin.
[binutils.git] / bfd / elf64-ia64.c
blobf1ea331b6c068c6ba29285e7b945f4e98e591a1c
1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000 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"
30 * THE RULES for all the stuff the linker creates --
32 * GOT Entries created in response to LTOFF or LTOFF_FPTR
33 * relocations. Dynamic relocs created for dynamic
34 * symbols in an application; REL relocs for locals
35 * in a shared library.
37 * FPTR The canonical function descriptor. Created for local
38 * symbols in applications. Descriptors for dynamic symbols
39 * and local symbols in shared libraries are created by
40 * ld.so. Thus there are no dynamic relocs against these
41 * objects. The FPTR relocs for such _are_ passed through
42 * to the dynamic relocation tables.
44 * FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
45 * Requires the creation of a PLTOFF entry. This does not
46 * require any dynamic relocations.
48 * PLTOFF Created by PLTOFF relocations. For local symbols, this
49 * is an alternate function descriptor, and in shared libraries
50 * requires two REL relocations. Note that this cannot be
51 * transformed into an FPTR relocation, since it must be in
52 * range of the GP. For dynamic symbols, this is a function
53 * descriptor for a MIN_PLT entry, and requires one IPLT reloc.
55 * MIN_PLT Created by PLTOFF entries against dynamic symbols. This
56 * does not reqire dynamic relocations.
59 #define USE_RELA /* we want RELA relocs, not REL */
61 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
63 typedef struct bfd_hash_entry *(*new_hash_entry_func)
64 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
66 /* In dynamically (linker-) created sections, we generally need to keep track
67 of the place a symbol or expression got allocated to. This is done via hash
68 tables that store entries of the following type. */
70 struct elf64_ia64_dyn_sym_info
72 /* The addend for which this entry is relevant. */
73 bfd_vma addend;
75 /* Next addend in the list. */
76 struct elf64_ia64_dyn_sym_info *next;
78 bfd_vma got_offset;
79 bfd_vma fptr_offset;
80 bfd_vma pltoff_offset;
81 bfd_vma plt_offset;
82 bfd_vma plt2_offset;
84 /* The symbol table entry, if any, that this was derrived from. */
85 struct elf_link_hash_entry *h;
87 /* Used to count non-got, non-plt relocations for delayed sizing
88 of relocation sections. */
89 struct elf64_ia64_dyn_reloc_entry
91 struct elf64_ia64_dyn_reloc_entry *next;
92 asection *srel;
93 int type;
94 int count;
95 } *reloc_entries;
97 /* True when the section contents have been updated. */
98 unsigned got_done : 1;
99 unsigned fptr_done : 1;
100 unsigned pltoff_done : 1;
102 /* True for the different kinds of linker data we want created. */
103 unsigned want_got : 1;
104 unsigned want_fptr : 1;
105 unsigned want_ltoff_fptr : 1;
106 unsigned want_plt : 1;
107 unsigned want_plt2 : 1;
108 unsigned want_pltoff : 1;
111 struct elf64_ia64_local_hash_entry
113 struct bfd_hash_entry root;
114 struct elf64_ia64_dyn_sym_info *info;
117 struct elf64_ia64_local_hash_table
119 struct bfd_hash_table root;
120 /* No additional fields for now. */
123 struct elf64_ia64_link_hash_entry
125 struct elf_link_hash_entry root;
126 struct elf64_ia64_dyn_sym_info *info;
129 struct elf64_ia64_link_hash_table
131 /* The main hash table */
132 struct elf_link_hash_table root;
134 asection *got_sec; /* the linkage table section (or NULL) */
135 asection *rel_got_sec; /* dynamic relocation section for same */
136 asection *fptr_sec; /* function descriptor table (or NULL) */
137 asection *plt_sec; /* the primary plt section (or NULL) */
138 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
139 asection *rel_pltoff_sec; /* dynamic relocation section for same */
141 bfd_size_type minplt_entries; /* number of minplt entries */
143 struct elf64_ia64_local_hash_table loc_hash_table;
146 #define elf64_ia64_hash_table(p) \
147 ((struct elf64_ia64_link_hash_table *) ((p)->hash))
149 static bfd_reloc_status_type elf64_ia64_reloc
150 PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
151 asection *input_section, bfd *output_bfd, char **error_message));
152 static reloc_howto_type * lookup_howto
153 PARAMS ((unsigned int rtype));
154 static reloc_howto_type *elf64_ia64_reloc_type_lookup
155 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
156 static void elf64_ia64_info_to_howto
157 PARAMS ((bfd *abfd, arelent *bfd_reloc, Elf64_Internal_Rela *elf_reloc));
158 static boolean elf64_ia64_relax_section
159 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
160 boolean *again));
161 static boolean elf64_ia64_section_from_shdr
162 PARAMS ((bfd *, Elf64_Internal_Shdr *, char *));
163 static boolean elf64_ia64_fake_sections
164 PARAMS ((bfd *abfd, Elf64_Internal_Shdr *hdr, asection *sec));
165 static boolean elf64_ia64_add_symbol_hook
166 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
167 const char **namep, flagword *flagsp, asection **secp,
168 bfd_vma *valp));
169 static int elf64_ia64_additional_program_headers
170 PARAMS ((bfd *abfd));
171 static boolean elf64_ia64_is_local_label_name
172 PARAMS ((bfd *abfd, const char *name));
173 static boolean elf64_ia64_dynamic_symbol_p
174 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
175 static boolean elf64_ia64_local_hash_table_init
176 PARAMS ((struct elf64_ia64_local_hash_table *ht, bfd *abfd,
177 new_hash_entry_func new));
178 static struct bfd_hash_entry *elf64_ia64_new_loc_hash_entry
179 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
180 const char *string));
181 static struct bfd_hash_entry *elf64_ia64_new_elf_hash_entry
182 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
183 const char *string));
184 static struct bfd_link_hash_table *elf64_ia64_hash_table_create
185 PARAMS ((bfd *abfd));
186 static struct elf64_ia64_local_hash_entry *elf64_ia64_local_hash_lookup
187 PARAMS ((struct elf64_ia64_local_hash_table *table, const char *string,
188 boolean create, boolean copy));
189 static void elf64_ia64_dyn_sym_traverse
190 PARAMS ((struct elf64_ia64_link_hash_table *ia64_info,
191 boolean (*func)(struct elf64_ia64_dyn_sym_info *, PTR),
192 PTR info));
193 static boolean elf64_ia64_create_dynamic_sections
194 PARAMS ((bfd *abfd, struct bfd_link_info *info));
195 static struct elf64_ia64_dyn_sym_info * get_dyn_sym_info
196 PARAMS ((struct elf64_ia64_link_hash_table *ia64_info,
197 struct elf_link_hash_entry *h,
198 bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
199 static asection *get_got
200 PARAMS ((bfd *abfd, struct bfd_link_info *info,
201 struct elf64_ia64_link_hash_table *ia64_info));
202 static asection *get_fptr
203 PARAMS ((bfd *abfd, struct bfd_link_info *info,
204 struct elf64_ia64_link_hash_table *ia64_info));
205 static asection *get_pltoff
206 PARAMS ((bfd *abfd, struct bfd_link_info *info,
207 struct elf64_ia64_link_hash_table *ia64_info));
208 static asection *get_reloc_section
209 PARAMS ((bfd *abfd, struct elf64_ia64_link_hash_table *ia64_info,
210 asection *sec, boolean create));
211 static boolean count_dyn_reloc
212 PARAMS ((bfd *abfd, struct elf64_ia64_dyn_sym_info *dyn_i,
213 asection *srel, int type));
214 static boolean elf64_ia64_check_relocs
215 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
216 const Elf_Internal_Rela *relocs));
217 static boolean elf64_ia64_adjust_dynamic_symbol
218 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
219 static unsigned long global_sym_index
220 PARAMS ((struct elf_link_hash_entry *h));
221 static boolean allocate_fptr
222 PARAMS ((struct elf64_ia64_dyn_sym_info *dyn_i, PTR data));
223 static boolean allocate_global_data_got
224 PARAMS ((struct elf64_ia64_dyn_sym_info *dyn_i, PTR data));
225 static boolean allocate_global_fptr_got
226 PARAMS ((struct elf64_ia64_dyn_sym_info *dyn_i, PTR data));
227 static boolean allocate_local_got
228 PARAMS ((struct elf64_ia64_dyn_sym_info *dyn_i, PTR data));
229 static boolean allocate_pltoff_entries
230 PARAMS ((struct elf64_ia64_dyn_sym_info *dyn_i, PTR data));
231 static boolean allocate_plt_entries
232 PARAMS ((struct elf64_ia64_dyn_sym_info *dyn_i, PTR data));
233 static boolean allocate_plt2_entries
234 PARAMS ((struct elf64_ia64_dyn_sym_info *dyn_i, PTR data));
235 static boolean allocate_dynrel_entries
236 PARAMS ((struct elf64_ia64_dyn_sym_info *dyn_i, PTR data));
237 static boolean elf64_ia64_size_dynamic_sections
238 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
239 static bfd_reloc_status_type elf64_ia64_install_value
240 PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
241 static void elf64_ia64_install_dyn_reloc
242 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
243 asection *srel, bfd_vma offset, unsigned int type,
244 long dynindx, bfd_vma addend));
245 static bfd_vma set_got_entry
246 PARAMS ((bfd *abfd, struct bfd_link_info *info,
247 struct elf64_ia64_dyn_sym_info *dyn_i, long dynindx,
248 bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
249 static bfd_vma set_fptr_entry
250 PARAMS ((bfd *abfd, struct bfd_link_info *info,
251 struct elf64_ia64_dyn_sym_info *dyn_i,
252 bfd_vma value));
253 static bfd_vma set_pltoff_entry
254 PARAMS ((bfd *abfd, struct bfd_link_info *info,
255 struct elf64_ia64_dyn_sym_info *dyn_i,
256 bfd_vma value, boolean));
257 static boolean elf64_ia64_final_link
258 PARAMS ((bfd *abfd, struct bfd_link_info *info));
259 static boolean elf64_ia64_relocate_section
260 PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
261 asection *input_section, bfd_byte *contents,
262 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
263 asection **local_sections));
264 static boolean elf64_ia64_finish_dynamic_symbol
265 PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
266 struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
267 static boolean elf64_ia64_finish_dynamic_sections
268 PARAMS ((bfd *abfd, struct bfd_link_info *info));
269 static boolean elf64_ia64_set_private_flags
270 PARAMS ((bfd *abfd, flagword flags));
271 static boolean elf64_ia64_copy_private_bfd_data
272 PARAMS ((bfd *ibfd, bfd *obfd));
273 static boolean elf64_ia64_merge_private_bfd_data
274 PARAMS ((bfd *ibfd, bfd *obfd));
275 static boolean elf64_ia64_print_private_bfd_data
276 PARAMS ((bfd *abfd, PTR ptr));
279 /* ia64-specific relocation */
281 /* Perform a relocation. Not much to do here as all the hard work is
282 done in elf64_ia64_final_link_relocate. */
283 static bfd_reloc_status_type
284 elf64_ia64_reloc (abfd, reloc, sym, data, input_section,
285 output_bfd, error_message)
286 bfd *abfd;
287 arelent *reloc;
288 asymbol *sym;
289 PTR data;
290 asection *input_section;
291 bfd *output_bfd;
292 char **error_message;
294 if (output_bfd)
296 reloc->address += input_section->output_offset;
297 return bfd_reloc_ok;
299 *error_message = "Unsupported call to elf64_ia64_reloc";
300 return bfd_reloc_notsupported;
303 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
304 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
305 elf64_ia64_reloc, NAME, false, 0, 0, IN)
307 /* This table has to be sorted according to increasing number of the
308 TYPE field. */
309 static reloc_howto_type ia64_howto_table[] =
311 IA64_HOWTO (R_IA64_NONE, "NONE", 0, false, true),
313 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, false, true),
314 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, false, true),
315 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, false, true),
316 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, false, true),
317 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, false, true),
318 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, false, true),
319 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, false, true),
321 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, false, true),
322 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, false, true),
323 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, false, true),
324 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, false, true),
325 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, false, true),
326 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, false, true),
328 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, false, true),
329 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, false, true),
331 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, false, true),
332 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, false, true),
333 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, false, true),
334 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, false, true),
336 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, false, true),
337 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, false, true),
338 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, false, true),
339 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, false, true),
340 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, false, true),
342 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, true, true),
343 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, true, true),
344 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, true, true),
345 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, true, true),
346 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, true, true),
347 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, true, true),
348 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, true, true),
349 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, true, true),
351 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true),
352 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true),
353 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
354 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
356 IA64_HOWTO (R_IA64_SEGBASE, "SEGBASE", 4, false, true),
357 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
358 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
359 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
360 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, false, true),
362 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, false, true),
363 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, false, true),
364 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, false, true),
365 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, false, true),
367 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, false, true),
368 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, false, true),
369 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, false, true),
370 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, false, true),
372 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, false, true),
373 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, false, true),
374 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, false, true),
375 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, false, true),
377 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, true, true),
378 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, true, true),
379 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, true, true),
381 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, false, true),
382 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, false, true),
383 IA64_HOWTO (R_IA64_EPLTMSB, "EPLTMSB", 4, false, true),
384 IA64_HOWTO (R_IA64_EPLTLSB, "EPLTLSB", 4, false, true),
385 IA64_HOWTO (R_IA64_COPY, "COPY", 4, false, true),
386 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, false, true),
387 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, false, true),
389 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, false, false),
390 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 8, false, false),
391 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 8, false, false),
392 IA64_HOWTO (R_IA64_LTOFF_TP22, "LTOFF_TP22", 0, false, false),
395 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
397 /* Given a BFD reloc type, return the matching HOWTO structure. */
399 static reloc_howto_type*
400 lookup_howto (rtype)
401 unsigned int rtype;
403 static int inited = 0;
404 int i;
406 if (!inited)
408 inited = 1;
410 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
411 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
412 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
415 BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
416 i = elf_code_to_howto_index[rtype];
417 if (i >= NELEMS (ia64_howto_table))
418 return 0;
419 return ia64_howto_table + i;
422 static reloc_howto_type*
423 elf64_ia64_reloc_type_lookup (abfd, bfd_code)
424 bfd *abfd;
425 bfd_reloc_code_real_type bfd_code;
427 unsigned int rtype;
429 switch (bfd_code)
431 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
433 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
434 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
435 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
437 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
438 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
439 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
440 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
442 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
443 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
444 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
445 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
446 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
447 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
449 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
450 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
452 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
453 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
454 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
455 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
456 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
457 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
458 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
459 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
460 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
462 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
463 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
464 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
465 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
466 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
467 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
468 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
469 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
470 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
471 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
472 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
474 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
475 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
476 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
477 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
479 case BFD_RELOC_IA64_SEGBASE: rtype = R_IA64_SEGBASE; break;
480 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
481 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
482 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
483 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
485 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
486 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
487 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
488 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
490 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
491 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
492 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
493 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
495 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
496 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
497 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
498 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
500 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
501 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
502 case BFD_RELOC_IA64_EPLTMSB: rtype = R_IA64_EPLTMSB; break;
503 case BFD_RELOC_IA64_EPLTLSB: rtype = R_IA64_EPLTLSB; break;
504 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
505 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
506 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
508 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
509 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
510 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
511 case BFD_RELOC_IA64_LTOFF_TP22: rtype = R_IA64_LTOFF_TP22; break;
513 default: return 0;
515 return lookup_howto (rtype);
518 /* Given a ELF reloc, return the matching HOWTO structure. */
520 static void
521 elf64_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
522 bfd *abfd;
523 arelent *bfd_reloc;
524 Elf64_Internal_Rela *elf_reloc;
526 bfd_reloc->howto = lookup_howto (ELF64_R_TYPE (elf_reloc->r_info));
529 #define PLT_HEADER_SIZE (3 * 16)
530 #define PLT_MIN_ENTRY_SIZE (1 * 16)
531 #define PLT_FULL_ENTRY_SIZE (2 * 16)
532 #define PLT_RESERVED_WORDS 3
534 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
536 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
537 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
538 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
539 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
540 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
541 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
542 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
543 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
544 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
547 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
549 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
550 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
551 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
554 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
556 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
557 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
558 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
559 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
560 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
561 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
564 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
566 /* Select out of range branch fixup type. Note that Itanium does
567 not support brl, and so it gets emulated by the kernel. */
568 #undef USE_BRL
570 static const bfd_byte oor_brl[16] =
572 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
574 0x00, 0x00, 0x00, 0xc0
577 static const bfd_byte oor_ip[48] =
579 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
580 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
581 0x01, 0x00, 0x00, 0x60,
582 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
583 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
584 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
585 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
586 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
587 0x60, 0x00, 0x80, 0x00 /* br b6;; */
590 /* These functions do relaxation for IA-64 ELF.
592 This is primarily to support branches to targets out of range;
593 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
595 static boolean
596 elf64_ia64_relax_section (abfd, sec, link_info, again)
597 bfd *abfd;
598 asection *sec;
599 struct bfd_link_info *link_info;
600 boolean *again;
602 struct one_fixup
604 struct one_fixup *next;
605 asection *tsec;
606 bfd_vma toff;
607 bfd_vma trampoff;
610 Elf_Internal_Shdr *symtab_hdr;
611 Elf_Internal_Rela *internal_relocs;
612 Elf_Internal_Rela *free_relocs;
613 Elf_Internal_Rela *irel, *irelend;
614 bfd_byte *contents;
615 bfd_byte *free_contents;
616 Elf64_External_Sym *extsyms;
617 Elf64_External_Sym *free_extsyms;
618 struct elf64_ia64_link_hash_table *ia64_info;
619 struct one_fixup *fixups = NULL;
620 boolean changed_contents = false;
621 boolean changed_relocs = false;
623 /* Assume we're not going to change any sizes, and we'll only need
624 one pass. */
625 *again = false;
627 /* Nothing to do if there are no relocations. */
628 if ((sec->flags & SEC_RELOC) == 0
629 || sec->reloc_count == 0)
630 return true;
632 /* If this is the first time we have been called for this section,
633 initialize the cooked size. */
634 if (sec->_cooked_size == 0)
635 sec->_cooked_size = sec->_raw_size;
637 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
639 /* Load the relocations for this section. */
640 internal_relocs = (_bfd_elf64_link_read_relocs
641 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
642 link_info->keep_memory));
643 if (internal_relocs == NULL)
644 goto error_return;
645 free_relocs = NULL;
646 if (! link_info->keep_memory)
647 free_relocs = internal_relocs;
649 ia64_info = elf64_ia64_hash_table (link_info);
650 irelend = internal_relocs + sec->reloc_count;
652 for (irel = internal_relocs; irel < irelend; irel++)
653 if (ELF64_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
654 break;
656 /* No branch-type relocations. */
657 if (irel == irelend)
659 if (free_relocs != NULL)
660 free (free_relocs);
661 return true;
664 /* Get the section contents. */
665 free_contents = NULL;
666 if (elf_section_data (sec)->this_hdr.contents != NULL)
667 contents = elf_section_data (sec)->this_hdr.contents;
668 else
670 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
671 if (contents == NULL)
672 goto error_return;
673 free_contents = contents;
675 if (! bfd_get_section_contents (abfd, sec, contents,
676 (file_ptr) 0, sec->_raw_size))
677 goto error_return;
680 /* Read this BFD's symbols. */
681 free_extsyms = NULL;
682 if (symtab_hdr->contents != NULL)
683 extsyms = (Elf64_External_Sym *) symtab_hdr->contents;
684 else
686 extsyms = (Elf64_External_Sym *) bfd_malloc (symtab_hdr->sh_size);
687 if (extsyms == NULL)
688 goto error_return;
689 free_extsyms = extsyms;
690 if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
691 || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
692 != symtab_hdr->sh_size))
693 goto error_return;
696 for (; irel < irelend; irel++)
698 bfd_vma symaddr, reladdr, trampoff, toff, roff;
699 Elf_Internal_Sym isym;
700 asection *tsec;
701 struct one_fixup *f;
703 if (ELF64_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
704 continue;
706 /* Get the value of the symbol referred to by the reloc. */
707 if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
709 /* A local symbol. */
710 bfd_elf64_swap_symbol_in (abfd,
711 extsyms + ELF64_R_SYM (irel->r_info),
712 &isym);
713 if (isym.st_shndx == SHN_UNDEF)
714 continue; /* We can't do anthing with undefined symbols. */
715 else if (isym.st_shndx == SHN_ABS)
716 tsec = bfd_abs_section_ptr;
717 else if (isym.st_shndx == SHN_COMMON)
718 tsec = bfd_com_section_ptr;
719 else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
720 tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
721 else
722 continue; /* who knows. */
724 toff = isym.st_value;
726 else
728 unsigned long indx;
729 struct elf_link_hash_entry *h;
730 struct elf64_ia64_dyn_sym_info *dyn_i;
732 indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
733 h = elf_sym_hashes (abfd)[indx];
734 BFD_ASSERT (h != NULL);
736 while (h->root.type == bfd_link_hash_indirect
737 || h->root.type == bfd_link_hash_warning)
738 h = (struct elf_link_hash_entry *) h->root.u.i.link;
740 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
742 /* For branches to dynamic symbols, we're interested instead
743 in a branch to the PLT entry. */
744 if (dyn_i && dyn_i->want_plt2)
746 tsec = ia64_info->plt_sec;
747 toff = dyn_i->plt2_offset;
749 else
751 /* We can't do anthing with undefined symbols. */
752 if (h->root.type == bfd_link_hash_undefined
753 || h->root.type == bfd_link_hash_undefweak)
754 continue;
756 tsec = h->root.u.def.section;
757 toff = h->root.u.def.value;
761 symaddr = (tsec->output_section->vma
762 + tsec->output_offset
763 + toff
764 + irel->r_addend);
766 roff = irel->r_offset;
767 reladdr = (sec->output_section->vma
768 + sec->output_offset
769 + roff) & -4;
771 /* If the branch is in range, no need to do anything. */
772 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
773 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
774 continue;
776 /* If the branch and target are in the same section, you've
777 got one honking big section and we can't help you. You'll
778 get an error message later. */
779 if (tsec == sec)
780 continue;
782 /* Look for an existing fixup to this address. */
783 for (f = fixups; f ; f = f->next)
784 if (f->tsec == tsec && f->toff == toff)
785 break;
787 if (f == NULL)
789 /* Two alternatives: If it's a branch to a PLT entry, we can
790 make a copy of the FULL_PLT entry. Otherwise, we'll have
791 to use a `brl' insn to get where we're going. */
793 int size;
795 if (tsec == ia64_info->plt_sec)
796 size = sizeof (plt_full_entry);
797 else
799 #ifdef USE_BRL
800 size = sizeof (oor_brl);
801 #else
802 size = sizeof (oor_ip);
803 #endif
806 /* Resize the current section to make room for the new branch. */
807 trampoff = (sec->_cooked_size + 15) & -16;
808 contents = (bfd_byte *) bfd_realloc (contents, trampoff + size);
809 if (contents == NULL)
810 goto error_return;
811 sec->_cooked_size = trampoff + size;
813 if (tsec == ia64_info->plt_sec)
815 memcpy (contents + trampoff, plt_full_entry, size);
817 /* Hijack the old relocation for use as the PLTOFF reloc. */
818 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
819 R_IA64_PLTOFF22);
820 irel->r_offset = trampoff;
822 else
824 #ifdef USE_BRL
825 memcpy (contents + trampoff, oor_brl, size);
826 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
827 R_IA64_PCREL60B);
828 irel->r_offset = trampoff + 2;
829 #else
830 memcpy (contents + trampoff, oor_ip, size);
831 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
832 R_IA64_PCREL64I);
833 irel->r_addend -= 16;
834 irel->r_offset = trampoff + 2;
835 #endif
838 /* Record the fixup so we don't do it again this section. */
839 f = (struct one_fixup *) bfd_malloc (sizeof (*f));
840 f->next = fixups;
841 f->tsec = tsec;
842 f->toff = toff;
843 f->trampoff = trampoff;
844 fixups = f;
846 else
848 /* Nop out the reloc, since we're finalizing things here. */
849 irel->r_info = ELF64_R_INFO (0, R_IA64_NONE);
852 /* Fix up the existing branch to hit the trampoline. Hope like
853 hell this doesn't overflow too. */
854 if (elf64_ia64_install_value (abfd, contents + roff,
855 f->trampoff - (roff & -4),
856 R_IA64_PCREL21B) != bfd_reloc_ok)
857 goto error_return;
859 changed_contents = true;
860 changed_relocs = true;
863 /* Clean up and go home. */
864 while (fixups)
866 struct one_fixup *f = fixups;
867 fixups = fixups->next;
868 free (f);
871 if (changed_relocs)
872 elf_section_data (sec)->relocs = internal_relocs;
873 else if (free_relocs != NULL)
874 free (free_relocs);
876 if (changed_contents)
877 elf_section_data (sec)->this_hdr.contents = contents;
878 else if (free_contents != NULL)
880 if (! link_info->keep_memory)
881 free (free_contents);
882 else
884 /* Cache the section contents for elf_link_input_bfd. */
885 elf_section_data (sec)->this_hdr.contents = contents;
889 if (free_extsyms != NULL)
891 if (! link_info->keep_memory)
892 free (free_extsyms);
893 else
895 /* Cache the symbols for elf_link_input_bfd. */
896 symtab_hdr->contents = extsyms;
900 *again = changed_contents || changed_relocs;
901 return true;
903 error_return:
904 if (free_relocs != NULL)
905 free (free_relocs);
906 if (free_contents != NULL)
907 free (free_contents);
908 if (free_extsyms != NULL)
909 free (free_extsyms);
910 return false;
913 /* Handle an IA-64 specific section when reading an object file. This
914 is called when elfcode.h finds a section with an unknown type. */
916 static boolean
917 elf64_ia64_section_from_shdr (abfd, hdr, name)
918 bfd *abfd;
919 Elf64_Internal_Shdr *hdr;
920 char *name;
922 asection *newsect;
924 /* There ought to be a place to keep ELF backend specific flags, but
925 at the moment there isn't one. We just keep track of the
926 sections by their name, instead. Fortunately, the ABI gives
927 suggested names for all the MIPS specific sections, so we will
928 probably get away with this. */
929 switch (hdr->sh_type)
931 case SHT_IA_64_UNWIND:
932 if (strcmp (name, ELF_STRING_ia64_unwind) != 0)
933 return false;
934 break;
936 case SHT_IA_64_EXT:
937 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
938 return false;
939 break;
941 default:
942 return false;
945 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
946 return false;
947 newsect = hdr->bfd_section;
949 if (hdr->sh_flags & SHF_IA_64_SHORT)
950 newsect->flags |= SEC_SMALL_DATA;
952 return true;
955 /* Set the correct type for an IA-64 ELF section. We do this by the
956 section name, which is a hack, but ought to work. */
958 static boolean
959 elf64_ia64_fake_sections (abfd, hdr, sec)
960 bfd *abfd;
961 Elf64_Internal_Shdr *hdr;
962 asection *sec;
964 register const char *name;
966 name = bfd_get_section_name (abfd, sec);
968 if (strcmp (name, ELF_STRING_ia64_unwind) == 0)
969 hdr->sh_type = SHT_IA_64_UNWIND;
970 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
971 hdr->sh_type = SHT_IA_64_EXT;
972 else if (strcmp (name, ".reloc") == 0)
974 * This is an ugly, but unfortunately necessary hack that is
975 * needed when producing EFI binaries on IA-64. It tells
976 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
977 * containing ELF relocation info. We need this hack in order to
978 * be able to generate ELF binaries that can be translated into
979 * EFI applications (which are essentially COFF objects). Those
980 * files contain a COFF ".reloc" section inside an ELF64 object,
981 * which would normally cause BFD to segfault because it would
982 * attempt to interpret this section as containing relocation
983 * entries for section "oc". With this hack enabled, ".reloc"
984 * will be treated as a normal data section, which will avoid the
985 * segfault. However, you won't be able to create an ELF64 binary
986 * with a section named "oc" that needs relocations, but that's
987 * the kind of ugly side-effects you get when detecting section
988 * types based on their names... In practice, this limitation is
989 * unlikely to bite.
991 hdr->sh_type = SHT_PROGBITS;
993 if (sec->flags & SEC_SMALL_DATA)
994 hdr->sh_flags |= SHF_IA_64_SHORT;
996 return true;
999 /* Hook called by the linker routine which adds symbols from an object
1000 file. We use it to put .comm items in .sbss, and not .bss. */
1002 static boolean
1003 elf64_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1004 bfd *abfd;
1005 struct bfd_link_info *info;
1006 const Elf_Internal_Sym *sym;
1007 const char **namep;
1008 flagword *flagsp;
1009 asection **secp;
1010 bfd_vma *valp;
1012 if (sym->st_shndx == SHN_COMMON
1013 && !info->relocateable
1014 && sym->st_size <= bfd_get_gp_size (abfd))
1016 /* Common symbols less than or equal to -G nn bytes are
1017 automatically put into .sbss. */
1019 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1021 if (scomm == NULL)
1023 scomm = bfd_make_section (abfd, ".scommon");
1024 if (scomm == NULL
1025 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1026 | SEC_IS_COMMON
1027 | SEC_LINKER_CREATED)))
1028 return false;
1031 *secp = scomm;
1032 *valp = sym->st_size;
1035 return true;
1038 /* Return the number of additional phdrs we will need. */
1040 static int
1041 elf64_ia64_additional_program_headers (abfd)
1042 bfd *abfd;
1044 asection *s;
1045 int ret = 0;
1047 /* See if we need a PT_IA_64_ARCHEXT segment. */
1048 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1049 if (s && (s->flags & SEC_LOAD))
1050 ++ret;
1052 /* See if we need a PT_IA_64_UNWIND segment. */
1053 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
1054 if (s && (s->flags & SEC_LOAD))
1055 ++ret;
1057 return ret;
1060 static boolean
1061 elf64_ia64_modify_segment_map (abfd)
1062 bfd *abfd;
1064 struct elf_segment_map *m, **pm;
1065 asection *s;
1067 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1068 all PT_LOAD segments. */
1069 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1070 if (s && (s->flags & SEC_LOAD))
1072 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1073 if (m->p_type == PT_IA_64_ARCHEXT)
1074 break;
1075 if (m == NULL)
1077 m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1078 if (m == NULL)
1079 return false;
1081 m->p_type = PT_IA_64_ARCHEXT;
1082 m->count = 1;
1083 m->sections[0] = s;
1085 /* We want to put it after the PHDR and INTERP segments. */
1086 pm = &elf_tdata (abfd)->segment_map;
1087 while (*pm != NULL
1088 && ((*pm)->p_type == PT_PHDR
1089 || (*pm)->p_type == PT_INTERP))
1090 pm = &(*pm)->next;
1092 m->next = *pm;
1093 *pm = m;
1097 /* Install the PT_IA_64_UNWIND segment, if needed. */
1098 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
1099 if (s && (s->flags & SEC_LOAD))
1101 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1102 if (m->p_type == PT_IA_64_UNWIND)
1103 break;
1104 if (m == NULL)
1106 m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1107 if (m == NULL)
1108 return false;
1110 m->p_type = PT_IA_64_UNWIND;
1111 m->count = 1;
1112 m->sections[0] = s;
1113 m->next = NULL;
1115 /* We want to put it last. */
1116 pm = &elf_tdata (abfd)->segment_map;
1117 while (*pm != NULL)
1118 pm = &(*pm)->next;
1119 *pm = m;
1123 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1124 the input sections for each output section in the segment and testing
1125 for SHF_IA_64_NORECOV on each. */
1126 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1127 if (m->p_type == PT_LOAD)
1129 int i;
1130 for (i = m->count - 1; i >= 0; --i)
1132 struct bfd_link_order *order = m->sections[i]->link_order_head;
1133 while (order)
1135 if (order->type == bfd_indirect_link_order)
1137 asection *is = order->u.indirect.section;
1138 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1139 if (flags & SHF_IA_64_NORECOV)
1141 m->p_flags |= PF_IA_64_NORECOV;
1142 goto found;
1145 order = order->next;
1148 found:;
1151 return true;
1155 /* According to the Tahoe assembler spec, all labels starting with a
1156 '.' are local. */
1158 static boolean
1159 elf64_ia64_is_local_label_name (abfd, name)
1160 bfd *abfd;
1161 const char *name;
1163 return name[0] == '.';
1166 /* Should we do dynamic things to this symbol? */
1168 static boolean
1169 elf64_ia64_dynamic_symbol_p (h, info)
1170 struct elf_link_hash_entry *h;
1171 struct bfd_link_info *info;
1173 if (h == NULL)
1174 return false;
1176 while (h->root.type == bfd_link_hash_indirect
1177 || h->root.type == bfd_link_hash_warning)
1178 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1180 if (h->dynindx == -1)
1181 return false;
1183 if (h->root.type == bfd_link_hash_undefweak
1184 || h->root.type == bfd_link_hash_defweak)
1185 return true;
1187 if ((info->shared && !info->symbolic)
1188 || ((h->elf_link_hash_flags
1189 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1190 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1191 return true;
1193 return false;
1196 static boolean
1197 elf64_ia64_local_hash_table_init (ht, abfd, new)
1198 struct elf64_ia64_local_hash_table *ht;
1199 bfd *abfd;
1200 new_hash_entry_func new;
1202 memset (ht, 0, sizeof(*ht));
1203 return bfd_hash_table_init (&ht->root, new);
1206 static struct bfd_hash_entry*
1207 elf64_ia64_new_loc_hash_entry (entry, table, string)
1208 struct bfd_hash_entry *entry;
1209 struct bfd_hash_table *table;
1210 const char *string;
1212 struct elf64_ia64_local_hash_entry *ret;
1213 ret = (struct elf64_ia64_local_hash_entry *) entry;
1215 /* Allocate the structure if it has not already been allocated by a
1216 subclass. */
1217 if (!ret)
1218 ret = bfd_hash_allocate (table, sizeof (*ret));
1220 if (!ret)
1221 return 0;
1223 /* Initialize our local data. All zeros, and definitely easier
1224 than setting a handful of bit fields. */
1225 memset (ret, 0, sizeof(*ret));
1227 /* Call the allocation method of the superclass. */
1228 ret = ((struct elf64_ia64_local_hash_entry *)
1229 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1231 return (struct bfd_hash_entry *) ret;
1234 static struct bfd_hash_entry*
1235 elf64_ia64_new_elf_hash_entry (entry, table, string)
1236 struct bfd_hash_entry *entry;
1237 struct bfd_hash_table *table;
1238 const char *string;
1240 struct elf64_ia64_link_hash_entry *ret;
1241 ret = (struct elf64_ia64_link_hash_entry *) entry;
1243 /* Allocate the structure if it has not already been allocated by a
1244 subclass. */
1245 if (!ret)
1246 ret = bfd_hash_allocate (table, sizeof (*ret));
1248 if (!ret)
1249 return 0;
1251 /* Initialize our local data. All zeros, and definitely easier
1252 than setting a handful of bit fields. */
1253 memset (ret, 0, sizeof(*ret));
1255 /* Call the allocation method of the superclass. */
1256 ret = ((struct elf64_ia64_link_hash_entry *)
1257 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1258 table, string));
1260 return (struct bfd_hash_entry *) ret;
1263 static void
1264 elf64_ia64_hash_copy_indirect (xdir, xind)
1265 struct elf_link_hash_entry *xdir, *xind;
1267 struct elf64_ia64_link_hash_entry *dir, *ind;
1269 dir = (struct elf64_ia64_link_hash_entry *)xdir;
1270 ind = (struct elf64_ia64_link_hash_entry *)xind;
1272 /* Copy down any references that we may have already seen to the
1273 symbol which just became indirect. */
1275 dir->root.elf_link_hash_flags |=
1276 (ind->root.elf_link_hash_flags
1277 & (ELF_LINK_HASH_REF_DYNAMIC
1278 | ELF_LINK_HASH_REF_REGULAR
1279 | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1281 /* Copy over the got and plt data. This would have been done
1282 by check_relocs. */
1284 if (dir->info == NULL)
1286 struct elf64_ia64_dyn_sym_info *dyn_i;
1288 dir->info = dyn_i = ind->info;
1289 ind->info = NULL;
1291 /* Fix up the dyn_sym_info pointers to the global symbol. */
1292 for (; dyn_i; dyn_i = dyn_i->next)
1293 dyn_i->h = &dir->root;
1295 BFD_ASSERT (ind->info == NULL);
1297 /* Copy over the dynindx. */
1299 if (dir->root.dynindx == -1)
1301 dir->root.dynindx = ind->root.dynindx;
1302 dir->root.dynstr_index = ind->root.dynstr_index;
1303 ind->root.dynindx = -1;
1304 ind->root.dynstr_index = 0;
1306 BFD_ASSERT (ind->root.dynindx == -1);
1309 static void
1310 elf64_ia64_hash_hide_symbol (info, xh)
1311 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1312 struct elf_link_hash_entry *xh;
1314 struct elf64_ia64_link_hash_entry *h;
1315 struct elf64_ia64_dyn_sym_info *dyn_i;
1317 h = (struct elf64_ia64_link_hash_entry *)xh;
1319 h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
1320 h->root.dynindx = -1;
1322 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1323 dyn_i->want_plt2 = 0;
1326 /* Create the derived linker hash table. The IA-64 ELF port uses this
1327 derived hash table to keep information specific to the IA-64 ElF
1328 linker (without using static variables). */
1330 static struct bfd_link_hash_table*
1331 elf64_ia64_hash_table_create (abfd)
1332 bfd *abfd;
1334 struct elf64_ia64_link_hash_table *ret;
1336 ret = bfd_alloc (abfd, sizeof (*ret));
1337 if (!ret)
1338 return 0;
1339 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1340 elf64_ia64_new_elf_hash_entry))
1342 bfd_release (abfd, ret);
1343 return 0;
1346 if (!elf64_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1347 elf64_ia64_new_loc_hash_entry))
1348 return 0;
1349 return &ret->root.root;
1352 /* Look up an entry in a Alpha ELF linker hash table. */
1354 static INLINE struct elf64_ia64_local_hash_entry *
1355 elf64_ia64_local_hash_lookup(table, string, create, copy)
1356 struct elf64_ia64_local_hash_table *table;
1357 const char *string;
1358 boolean create, copy;
1360 return ((struct elf64_ia64_local_hash_entry *)
1361 bfd_hash_lookup (&table->root, string, create, copy));
1364 /* Traverse both local and global hash tables. */
1366 struct elf64_ia64_dyn_sym_traverse_data
1368 boolean (*func) PARAMS ((struct elf64_ia64_dyn_sym_info *, PTR));
1369 PTR data;
1372 static boolean
1373 elf64_ia64_global_dyn_sym_thunk (xentry, xdata)
1374 struct bfd_hash_entry *xentry;
1375 PTR xdata;
1377 struct elf64_ia64_link_hash_entry *entry
1378 = (struct elf64_ia64_link_hash_entry *) xentry;
1379 struct elf64_ia64_dyn_sym_traverse_data *data
1380 = (struct elf64_ia64_dyn_sym_traverse_data *) xdata;
1381 struct elf64_ia64_dyn_sym_info *dyn_i;
1383 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1384 if (! (*data->func) (dyn_i, data->data))
1385 return false;
1386 return true;
1389 static boolean
1390 elf64_ia64_local_dyn_sym_thunk (xentry, xdata)
1391 struct bfd_hash_entry *xentry;
1392 PTR xdata;
1394 struct elf64_ia64_local_hash_entry *entry
1395 = (struct elf64_ia64_local_hash_entry *) xentry;
1396 struct elf64_ia64_dyn_sym_traverse_data *data
1397 = (struct elf64_ia64_dyn_sym_traverse_data *) xdata;
1398 struct elf64_ia64_dyn_sym_info *dyn_i;
1400 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1401 if (! (*data->func) (dyn_i, data->data))
1402 return false;
1403 return true;
1406 static void
1407 elf64_ia64_dyn_sym_traverse (ia64_info, func, data)
1408 struct elf64_ia64_link_hash_table *ia64_info;
1409 boolean (*func) PARAMS ((struct elf64_ia64_dyn_sym_info *, PTR));
1410 PTR data;
1412 struct elf64_ia64_dyn_sym_traverse_data xdata;
1414 xdata.func = func;
1415 xdata.data = data;
1417 elf_link_hash_traverse (&ia64_info->root,
1418 elf64_ia64_global_dyn_sym_thunk, &xdata);
1419 bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1420 elf64_ia64_local_dyn_sym_thunk, &xdata);
1423 static boolean
1424 elf64_ia64_create_dynamic_sections (abfd, info)
1425 bfd *abfd;
1426 struct bfd_link_info *info;
1428 struct elf64_ia64_link_hash_table *ia64_info;
1429 struct elf_link_hash_entry *h;
1430 asection *s;
1432 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1433 return false;
1435 ia64_info = elf64_ia64_hash_table (info);
1437 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1438 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1441 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1442 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1445 if (!get_pltoff (abfd, info, ia64_info))
1446 return false;
1448 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1449 if (s == NULL
1450 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1451 | SEC_HAS_CONTENTS
1452 | SEC_IN_MEMORY
1453 | SEC_LINKER_CREATED
1454 | SEC_READONLY))
1455 || !bfd_set_section_alignment (abfd, s, 3))
1456 return false;
1457 ia64_info->rel_pltoff_sec = s;
1459 s = bfd_make_section(abfd, ".rela.got");
1460 if (s == NULL
1461 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1462 | SEC_HAS_CONTENTS
1463 | SEC_IN_MEMORY
1464 | SEC_LINKER_CREATED
1465 | SEC_READONLY))
1466 || !bfd_set_section_alignment (abfd, s, 3))
1467 return false;
1468 ia64_info->rel_got_sec = s;
1470 return true;
1473 /* Find and/or create a descriptor for dynamic symbol info. This will
1474 vary based on global or local symbol, and the addend to the reloc. */
1476 static struct elf64_ia64_dyn_sym_info *
1477 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1478 struct elf64_ia64_link_hash_table *ia64_info;
1479 struct elf_link_hash_entry *h;
1480 bfd *abfd;
1481 const Elf_Internal_Rela *rel;
1482 boolean create;
1484 struct elf64_ia64_dyn_sym_info **pp;
1485 struct elf64_ia64_dyn_sym_info *dyn_i;
1486 bfd_vma addend = rel ? rel->r_addend : 0;
1488 if (h)
1489 pp = &((struct elf64_ia64_link_hash_entry *)h)->info;
1490 else
1492 struct elf64_ia64_local_hash_entry *loc_h;
1493 char *addr_name;
1494 size_t len;
1496 /* Construct a string for use in the elf64_ia64_local_hash_table.
1497 The name describes what was once anonymous memory. */
1499 len = sizeof(void*)*2 + 1 + sizeof(bfd_vma)*4 + 1 + 1;
1500 len += 10; /* %p slop */
1502 addr_name = alloca (len);
1503 sprintf (addr_name, "%p:%lx", abfd, ELF64_R_SYM (rel->r_info));
1505 /* Collect the canonical entry data for this address. */
1506 loc_h = elf64_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1507 addr_name, create, create);
1508 BFD_ASSERT (loc_h);
1510 pp = &loc_h->info;
1513 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1514 pp = &dyn_i->next;
1516 if (dyn_i == NULL && create)
1518 dyn_i = (struct elf64_ia64_dyn_sym_info *)
1519 bfd_zalloc (abfd, sizeof *dyn_i);
1520 *pp = dyn_i;
1521 dyn_i->addend = addend;
1524 return dyn_i;
1527 static asection *
1528 get_got (abfd, info, ia64_info)
1529 bfd *abfd;
1530 struct bfd_link_info *info;
1531 struct elf64_ia64_link_hash_table *ia64_info;
1533 asection *got, *srel;
1534 bfd *dynobj;
1536 got = ia64_info->got_sec;
1537 if (!got)
1539 flagword flags;
1541 dynobj = ia64_info->root.dynobj;
1542 if (!dynobj)
1543 ia64_info->root.dynobj = dynobj = abfd;
1544 if (!_bfd_elf_create_got_section (dynobj, info))
1545 return 0;
1547 got = bfd_get_section_by_name (dynobj, ".got");
1548 BFD_ASSERT (got);
1549 ia64_info->got_sec = got;
1551 flags = bfd_get_section_flags (abfd, got);
1552 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1555 return got;
1558 /* Create function descriptor section (.opd). This section is called .opd
1559 because it contains "official prodecure descriptors". The "official"
1560 refers to the fact that these descriptors are used when taking the address
1561 of a procedure, thus ensuring a unique address for each procedure. */
1563 static asection *
1564 get_fptr (abfd, info, ia64_info)
1565 bfd *abfd;
1566 struct bfd_link_info *info;
1567 struct elf64_ia64_link_hash_table *ia64_info;
1569 asection *fptr;
1570 bfd *dynobj;
1572 fptr = ia64_info->fptr_sec;
1573 if (!fptr)
1575 dynobj = ia64_info->root.dynobj;
1576 if (!dynobj)
1577 ia64_info->root.dynobj = dynobj = abfd;
1579 fptr = bfd_make_section (dynobj, ".opd");
1580 if (!fptr
1581 || !bfd_set_section_flags (dynobj, fptr,
1582 (SEC_ALLOC
1583 | SEC_LOAD
1584 | SEC_HAS_CONTENTS
1585 | SEC_IN_MEMORY
1586 | SEC_READONLY
1587 | SEC_LINKER_CREATED))
1588 || !bfd_set_section_alignment (abfd, fptr, 4))
1590 BFD_ASSERT (0);
1591 return NULL;
1594 ia64_info->fptr_sec = fptr;
1597 return fptr;
1600 static asection *
1601 get_pltoff (abfd, info, ia64_info)
1602 bfd *abfd;
1603 struct bfd_link_info *info;
1604 struct elf64_ia64_link_hash_table *ia64_info;
1606 asection *pltoff;
1607 bfd *dynobj;
1609 pltoff = ia64_info->pltoff_sec;
1610 if (!pltoff)
1612 dynobj = ia64_info->root.dynobj;
1613 if (!dynobj)
1614 ia64_info->root.dynobj = dynobj = abfd;
1616 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
1617 if (!pltoff
1618 || !bfd_set_section_flags (dynobj, pltoff,
1619 (SEC_ALLOC
1620 | SEC_LOAD
1621 | SEC_HAS_CONTENTS
1622 | SEC_IN_MEMORY
1623 | SEC_SMALL_DATA
1624 | SEC_LINKER_CREATED))
1625 || !bfd_set_section_alignment (abfd, pltoff, 4))
1627 BFD_ASSERT (0);
1628 return NULL;
1631 ia64_info->pltoff_sec = pltoff;
1634 return pltoff;
1637 static asection *
1638 get_reloc_section (abfd, ia64_info, sec, create)
1639 bfd *abfd;
1640 struct elf64_ia64_link_hash_table *ia64_info;
1641 asection *sec;
1642 boolean create;
1644 const char *srel_name;
1645 asection *srel;
1646 bfd *dynobj;
1648 srel_name = (bfd_elf_string_from_elf_section
1649 (abfd, elf_elfheader(abfd)->e_shstrndx,
1650 elf_section_data(sec)->rel_hdr.sh_name));
1651 if (srel_name == NULL)
1652 return NULL;
1654 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
1655 && strcmp (bfd_get_section_name (abfd, sec),
1656 srel_name+5) == 0)
1657 || (strncmp (srel_name, ".rel", 4) == 0
1658 && strcmp (bfd_get_section_name (abfd, sec),
1659 srel_name+4) == 0));
1661 dynobj = ia64_info->root.dynobj;
1662 if (!dynobj)
1663 ia64_info->root.dynobj = dynobj = abfd;
1665 srel = bfd_get_section_by_name (dynobj, srel_name);
1666 if (srel == NULL && create)
1668 srel = bfd_make_section (dynobj, srel_name);
1669 if (srel == NULL
1670 || !bfd_set_section_flags (dynobj, srel,
1671 (SEC_ALLOC
1672 | SEC_LOAD
1673 | SEC_HAS_CONTENTS
1674 | SEC_IN_MEMORY
1675 | SEC_LINKER_CREATED
1676 | SEC_READONLY))
1677 || !bfd_set_section_alignment (dynobj, srel, 3))
1678 return NULL;
1681 return srel;
1684 static boolean
1685 count_dyn_reloc (abfd, dyn_i, srel, type)
1686 bfd *abfd;
1687 struct elf64_ia64_dyn_sym_info *dyn_i;
1688 asection *srel;
1689 int type;
1691 struct elf64_ia64_dyn_reloc_entry *rent;
1693 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
1694 if (rent->srel == srel && rent->type == type)
1695 break;
1697 if (!rent)
1699 rent = (struct elf64_ia64_dyn_reloc_entry *)
1700 bfd_alloc (abfd, sizeof (*rent));
1701 if (!rent)
1702 return false;
1704 rent->next = dyn_i->reloc_entries;
1705 rent->srel = srel;
1706 rent->type = type;
1707 rent->count = 0;
1708 dyn_i->reloc_entries = rent;
1710 rent->count++;
1712 return true;
1715 static boolean
1716 elf64_ia64_check_relocs (abfd, info, sec, relocs)
1717 bfd *abfd;
1718 struct bfd_link_info *info;
1719 asection *sec;
1720 const Elf_Internal_Rela *relocs;
1722 struct elf64_ia64_link_hash_table *ia64_info;
1723 const Elf_Internal_Rela *relend;
1724 Elf_Internal_Shdr *symtab_hdr;
1725 const Elf_Internal_Rela *rel;
1726 asection *got, *fptr, *srel;
1728 if (info->relocateable)
1729 return true;
1731 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1732 ia64_info = elf64_ia64_hash_table (info);
1734 got = fptr = srel = NULL;
1736 relend = relocs + sec->reloc_count;
1737 for (rel = relocs; rel < relend; ++rel)
1739 enum {
1740 NEED_GOT = 1,
1741 NEED_FPTR = 2,
1742 NEED_PLTOFF = 4,
1743 NEED_MIN_PLT = 8,
1744 NEED_FULL_PLT = 16,
1745 NEED_DYNREL = 32,
1746 NEED_LTOFF_FPTR = 64,
1749 struct elf_link_hash_entry *h = NULL;
1750 unsigned long r_symndx = ELF64_R_SYM (rel->r_info);
1751 struct elf64_ia64_dyn_sym_info *dyn_i;
1752 int need_entry;
1753 boolean maybe_dynamic;
1754 int dynrel_type;
1756 if (r_symndx >= symtab_hdr->sh_info)
1758 /* We're dealing with a global symbol -- find its hash entry
1759 and mark it as being referenced. */
1760 long indx = r_symndx - symtab_hdr->sh_info;
1761 h = elf_sym_hashes (abfd)[indx];
1762 while (h->root.type == bfd_link_hash_indirect
1763 || h->root.type == bfd_link_hash_warning)
1764 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1766 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
1769 /* We can only get preliminary data on whether a symbol is
1770 locally or externally defined, as not all of the input files
1771 have yet been processed. Do something with what we know, as
1772 this may help reduce memory usage and processing time later. */
1773 maybe_dynamic = false;
1774 if (h && ((info->shared && ! info->symbolic)
1775 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
1776 || h->root.type == bfd_link_hash_defweak))
1777 maybe_dynamic = true;
1779 need_entry = 0;
1780 switch (ELF64_R_TYPE (rel->r_info))
1782 case R_IA64_TPREL22:
1783 case R_IA64_TPREL64MSB:
1784 case R_IA64_TPREL64LSB:
1785 case R_IA64_LTOFF_TP22:
1786 return false;
1788 case R_IA64_LTOFF_FPTR22:
1789 case R_IA64_LTOFF_FPTR64I:
1790 case R_IA64_LTOFF_FPTR64MSB:
1791 case R_IA64_LTOFF_FPTR64LSB:
1792 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
1793 break;
1795 case R_IA64_FPTR64I:
1796 case R_IA64_FPTR32MSB:
1797 case R_IA64_FPTR32LSB:
1798 case R_IA64_FPTR64MSB:
1799 case R_IA64_FPTR64LSB:
1800 if (info->shared || h)
1801 need_entry = NEED_FPTR | NEED_DYNREL;
1802 else
1803 need_entry = NEED_FPTR;
1804 dynrel_type = R_IA64_FPTR64LSB;
1805 break;
1807 case R_IA64_LTOFF22:
1808 case R_IA64_LTOFF22X:
1809 case R_IA64_LTOFF64I:
1810 need_entry = NEED_GOT;
1811 break;
1813 case R_IA64_PLTOFF22:
1814 case R_IA64_PLTOFF64I:
1815 case R_IA64_PLTOFF64MSB:
1816 case R_IA64_PLTOFF64LSB:
1817 need_entry = NEED_PLTOFF;
1818 if (h)
1820 if (maybe_dynamic)
1821 need_entry |= NEED_MIN_PLT;
1823 else
1825 (*info->callbacks->warning)
1826 (info, _("@pltoff reloc against local symbol"), 0,
1827 abfd, 0, 0);
1829 break;
1831 case R_IA64_PCREL21B:
1832 case R_IA64_PCREL60B:
1833 /* Depending on where this symbol is defined, we may or may not
1834 need a full plt entry. Only skip if we know we'll not need
1835 the entry -- static or symbolic, and the symbol definition
1836 has already been seen. */
1837 if (maybe_dynamic && rel->r_addend == 0)
1838 need_entry = NEED_FULL_PLT;
1839 break;
1841 case R_IA64_IMM14:
1842 case R_IA64_IMM22:
1843 case R_IA64_IMM64:
1844 case R_IA64_DIR32MSB:
1845 case R_IA64_DIR32LSB:
1846 case R_IA64_DIR64MSB:
1847 case R_IA64_DIR64LSB:
1848 /* Shared objects will always need at least a REL relocation. */
1849 if (info->shared || maybe_dynamic)
1850 need_entry = NEED_DYNREL;
1851 dynrel_type = R_IA64_DIR64LSB;
1852 break;
1854 case R_IA64_PCREL22:
1855 case R_IA64_PCREL64I:
1856 case R_IA64_PCREL32MSB:
1857 case R_IA64_PCREL32LSB:
1858 case R_IA64_PCREL64MSB:
1859 case R_IA64_PCREL64LSB:
1860 if (maybe_dynamic)
1861 need_entry = NEED_DYNREL;
1862 dynrel_type = R_IA64_PCREL64LSB;
1863 break;
1866 if (!need_entry)
1867 continue;
1869 if ((need_entry & NEED_FPTR) != 0
1870 && rel->r_addend)
1872 (*info->callbacks->warning)
1873 (info, _("non-zero addend in @fptr reloc"), 0,
1874 abfd, 0, 0);
1877 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
1879 /* Record whether or not this is a local symbol. */
1880 dyn_i->h = h;
1882 /* Create what's needed. */
1883 if (need_entry & NEED_GOT)
1885 if (!got)
1887 got = get_got (abfd, info, ia64_info);
1888 if (!got)
1889 return false;
1891 dyn_i->want_got = 1;
1893 if (need_entry & NEED_FPTR)
1895 if (!fptr)
1897 fptr = get_fptr (abfd, info, ia64_info);
1898 if (!fptr)
1899 return false;
1902 /* FPTRs for shared libraries are allocated by the dynamic
1903 linker. Make sure this local symbol will appear in the
1904 dynamic symbol table. */
1905 if (!h && info->shared)
1907 if (! (_bfd_elf64_link_record_local_dynamic_symbol
1908 (info, abfd, r_symndx)))
1909 return false;
1912 dyn_i->want_fptr = 1;
1914 if (need_entry & NEED_LTOFF_FPTR)
1915 dyn_i->want_ltoff_fptr = 1;
1916 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
1918 if (!ia64_info->root.dynobj)
1919 ia64_info->root.dynobj = abfd;
1920 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
1921 dyn_i->want_plt = 1;
1923 if (need_entry & NEED_FULL_PLT)
1924 dyn_i->want_plt2 = 1;
1925 if (need_entry & NEED_PLTOFF)
1926 dyn_i->want_pltoff = 1;
1927 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
1929 if (!srel)
1931 srel = get_reloc_section (abfd, ia64_info, sec, true);
1932 if (!srel)
1933 return false;
1935 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
1936 return false;
1940 return true;
1943 struct elf64_ia64_allocate_data
1945 struct bfd_link_info *info;
1946 bfd_size_type ofs;
1949 /* For cleanliness, and potentially faster dynamic loading, allocate
1950 external GOT entries first. */
1952 static boolean
1953 allocate_global_data_got (dyn_i, data)
1954 struct elf64_ia64_dyn_sym_info *dyn_i;
1955 PTR data;
1957 struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
1959 if (dyn_i->want_got
1960 && ! dyn_i->want_fptr
1961 && elf64_ia64_dynamic_symbol_p (dyn_i->h, x->info))
1963 dyn_i->got_offset = x->ofs;
1964 x->ofs += 8;
1966 return true;
1969 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
1971 static boolean
1972 allocate_global_fptr_got (dyn_i, data)
1973 struct elf64_ia64_dyn_sym_info *dyn_i;
1974 PTR data;
1976 struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
1978 if (dyn_i->want_got
1979 && dyn_i->want_fptr
1980 && elf64_ia64_dynamic_symbol_p (dyn_i->h, x->info))
1982 dyn_i->got_offset = x->ofs;
1983 x->ofs += 8;
1985 return true;
1988 /* Lastly, allocate all the GOT entries for local data. */
1990 static boolean
1991 allocate_local_got (dyn_i, data)
1992 struct elf64_ia64_dyn_sym_info *dyn_i;
1993 PTR data;
1995 struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
1997 if (dyn_i->want_got
1998 && ! elf64_ia64_dynamic_symbol_p (dyn_i->h, x->info))
2000 dyn_i->got_offset = x->ofs;
2001 x->ofs += 8;
2003 return true;
2006 /* Search for the index of a global symbol in it's defining object file. */
2008 static unsigned long
2009 global_sym_index (h)
2010 struct elf_link_hash_entry *h;
2012 struct elf_link_hash_entry **p;
2013 bfd *obj;
2015 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2016 || h->root.type == bfd_link_hash_defweak);
2018 obj = h->root.u.def.section->owner;
2019 for (p = elf_sym_hashes (obj); *p != h; ++p)
2020 continue;
2022 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2025 /* Allocate function descriptors. We can do these for every function
2026 in a main executable that is not exported. */
2028 static boolean
2029 allocate_fptr (dyn_i, data)
2030 struct elf64_ia64_dyn_sym_info *dyn_i;
2031 PTR data;
2033 struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
2035 if (dyn_i->want_fptr)
2037 struct elf_link_hash_entry *h = dyn_i->h;
2039 if (h)
2040 while (h->root.type == bfd_link_hash_indirect
2041 || h->root.type == bfd_link_hash_warning)
2042 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2044 if (x->info->shared)
2046 if (h && h->dynindx == -1)
2048 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2049 || (h->root.type == bfd_link_hash_defweak));
2051 if (!_bfd_elf64_link_record_local_dynamic_symbol
2052 (x->info, h->root.u.def.section->owner,
2053 global_sym_index (h)))
2054 return false;
2057 dyn_i->want_fptr = 0;
2059 else if (h == NULL || h->dynindx == -1)
2061 dyn_i->fptr_offset = x->ofs;
2062 x->ofs += 16;
2064 else
2065 dyn_i->want_fptr = 0;
2067 return true;
2070 /* Allocate all the minimal PLT entries. */
2072 static boolean
2073 allocate_plt_entries (dyn_i, data)
2074 struct elf64_ia64_dyn_sym_info *dyn_i;
2075 PTR data;
2077 struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
2079 if (dyn_i->want_plt)
2081 struct elf_link_hash_entry *h = dyn_i->h;
2083 if (h)
2084 while (h->root.type == bfd_link_hash_indirect
2085 || h->root.type == bfd_link_hash_warning)
2086 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2088 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2089 if (elf64_ia64_dynamic_symbol_p (h, x->info))
2091 bfd_size_type offset = x->ofs;
2092 if (offset == 0)
2093 offset = PLT_HEADER_SIZE;
2094 dyn_i->plt_offset = offset;
2095 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2097 dyn_i->want_pltoff = 1;
2099 else
2101 dyn_i->want_plt = 0;
2102 dyn_i->want_plt2 = 0;
2105 return true;
2108 /* Allocate all the full PLT entries. */
2110 static boolean
2111 allocate_plt2_entries (dyn_i, data)
2112 struct elf64_ia64_dyn_sym_info *dyn_i;
2113 PTR data;
2115 struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
2117 if (dyn_i->want_plt2)
2119 struct elf_link_hash_entry *h = dyn_i->h;
2120 bfd_size_type ofs = x->ofs;
2122 dyn_i->plt2_offset = ofs;
2123 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2125 while (h->root.type == bfd_link_hash_indirect
2126 || h->root.type == bfd_link_hash_warning)
2127 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2128 dyn_i->h->plt.offset = ofs;
2130 return true;
2133 /* Allocate all the PLTOFF entries requested by relocations and
2134 plt entries. We can't share space with allocated FPTR entries,
2135 because the latter are not necessarily addressable by the GP.
2136 ??? Relaxation might be able to determine that they are. */
2138 static boolean
2139 allocate_pltoff_entries (dyn_i, data)
2140 struct elf64_ia64_dyn_sym_info *dyn_i;
2141 PTR data;
2143 struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
2145 if (dyn_i->want_pltoff)
2147 dyn_i->pltoff_offset = x->ofs;
2148 x->ofs += 16;
2150 return true;
2153 /* Allocate dynamic relocations for those symbols that turned out
2154 to be dynamic. */
2156 static boolean
2157 allocate_dynrel_entries (dyn_i, data)
2158 struct elf64_ia64_dyn_sym_info *dyn_i;
2159 PTR data;
2161 struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
2162 struct elf64_ia64_link_hash_table *ia64_info;
2163 struct elf64_ia64_dyn_reloc_entry *rent;
2164 boolean dynamic_symbol, shared;
2166 ia64_info = elf64_ia64_hash_table (x->info);
2167 dynamic_symbol = elf64_ia64_dynamic_symbol_p (dyn_i->h, x->info);
2168 shared = x->info->shared;
2170 /* Take care of the normal data relocations. */
2172 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2174 switch (rent->type)
2176 case R_IA64_FPTR64LSB:
2177 /* Allocate one iff !want_fptr, which by this point will
2178 be true only if we're actually allocating one statically
2179 in the main executable. */
2180 if (dyn_i->want_fptr)
2181 continue;
2182 break;
2183 case R_IA64_PCREL64LSB:
2184 if (!dynamic_symbol)
2185 continue;
2186 break;
2187 case R_IA64_DIR64LSB:
2188 if (!dynamic_symbol && !shared)
2189 continue;
2190 break;
2192 rent->srel->_raw_size += sizeof (Elf64_External_Rela) * rent->count;
2195 /* Take care of the GOT and PLT relocations. */
2197 if (((dynamic_symbol || shared) && dyn_i->want_got)
2198 || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2199 ia64_info->rel_got_sec->_raw_size += sizeof (Elf64_External_Rela);
2201 if (dyn_i->want_pltoff)
2203 bfd_size_type t = 0;
2205 /* Dynamic symbols get one IPLT relocation. Local symbols in
2206 shared libraries get two REL relocations. Local symbols in
2207 main applications get nothing. */
2208 if (dynamic_symbol)
2209 t = sizeof (Elf64_External_Rela);
2210 else if (shared)
2211 t = 2 * sizeof (Elf64_External_Rela);
2213 ia64_info->rel_pltoff_sec->_raw_size += t;
2216 return true;
2219 static boolean
2220 elf64_ia64_adjust_dynamic_symbol (info, h)
2221 struct bfd_link_info *info;
2222 struct elf_link_hash_entry *h;
2224 /* ??? Undefined symbols with PLT entries should be re-defined
2225 to be the PLT entry. */
2227 /* If this is a weak symbol, and there is a real definition, the
2228 processor independent code will have arranged for us to see the
2229 real definition first, and we can just use the same value. */
2230 if (h->weakdef != NULL)
2232 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2233 || h->weakdef->root.type == bfd_link_hash_defweak);
2234 h->root.u.def.section = h->weakdef->root.u.def.section;
2235 h->root.u.def.value = h->weakdef->root.u.def.value;
2236 return true;
2239 /* If this is a reference to a symbol defined by a dynamic object which
2240 is not a function, we might allocate the symbol in our .dynbss section
2241 and allocate a COPY dynamic relocation.
2243 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2244 of hackery. */
2246 return true;
2249 static boolean
2250 elf64_ia64_size_dynamic_sections (output_bfd, info)
2251 bfd *output_bfd;
2252 struct bfd_link_info *info;
2254 struct elf64_ia64_allocate_data data;
2255 struct elf64_ia64_link_hash_table *ia64_info;
2256 asection *sec;
2257 bfd *dynobj;
2258 boolean reltext = false;
2259 boolean relplt = false;
2261 dynobj = elf_hash_table(info)->dynobj;
2262 ia64_info = elf64_ia64_hash_table (info);
2263 BFD_ASSERT(dynobj != NULL);
2264 data.info = info;
2266 /* Set the contents of the .interp section to the interpreter. */
2267 if (ia64_info->root.dynamic_sections_created
2268 && !info->shared)
2270 sec = bfd_get_section_by_name (dynobj, ".interp");
2271 BFD_ASSERT (sec != NULL);
2272 sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
2273 sec->_raw_size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
2276 /* DT_INIT and DT_FINI get function descriptors not raw code addresses.
2277 Force their symbols to have pltoff entries so we can use those. */
2278 if (ia64_info->root.dynamic_sections_created)
2280 struct elf_link_hash_entry *h;
2281 struct elf64_ia64_dyn_sym_info *dyn_i;
2283 if (info->init_function
2284 && (h = elf_link_hash_lookup (elf_hash_table (info),
2285 info->init_function, false,
2286 false, false))
2287 && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
2288 | ELF_LINK_HASH_DEF_REGULAR)) != 0)
2290 dyn_i = get_dyn_sym_info (ia64_info, h, output_bfd, NULL, true);
2291 dyn_i->want_pltoff = 1;
2294 if (info->fini_function
2295 && (h = elf_link_hash_lookup (elf_hash_table (info),
2296 info->fini_function, false,
2297 false, false))
2298 && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
2299 | ELF_LINK_HASH_DEF_REGULAR)) != 0)
2301 dyn_i = get_dyn_sym_info (ia64_info, h, output_bfd, NULL, true);
2302 dyn_i->want_pltoff = 1;
2306 /* Allocate the GOT entries. */
2308 if (ia64_info->got_sec)
2310 data.ofs = 0;
2311 elf64_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2312 elf64_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2313 elf64_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2314 ia64_info->got_sec->_raw_size = data.ofs;
2317 /* Allocate the FPTR entries. */
2319 if (ia64_info->fptr_sec)
2321 data.ofs = 0;
2322 elf64_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2323 ia64_info->fptr_sec->_raw_size = data.ofs;
2326 /* Now that we've seen all of the input files, we can decide which
2327 symbols need plt entries. Allocate the minimal PLT entries first.
2328 We do this even though dynamic_sections_created may be false, because
2329 this has the side-effect of clearing want_plt and want_plt2. */
2331 data.ofs = 0;
2332 elf64_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2334 ia64_info->minplt_entries = 0;
2335 if (data.ofs)
2337 ia64_info->minplt_entries
2338 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2341 /* Align the pointer for the plt2 entries. */
2342 data.ofs = (data.ofs + 31) & -32;
2344 elf64_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2345 if (data.ofs != 0)
2347 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2349 ia64_info->plt_sec->_raw_size = data.ofs;
2351 /* If we've got a .plt, we need some extra memory for the dynamic
2352 linker. We stuff these in .got.plt. */
2353 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2354 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2357 /* Allocate the PLTOFF entries. */
2359 if (ia64_info->pltoff_sec)
2361 data.ofs = 0;
2362 elf64_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2363 ia64_info->pltoff_sec->_raw_size = data.ofs;
2366 if (ia64_info->root.dynamic_sections_created)
2368 /* Allocate space for the dynamic relocations that turned out to be
2369 required. */
2371 elf64_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2374 /* We have now determined the sizes of the various dynamic sections.
2375 Allocate memory for them. */
2376 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2378 boolean strip;
2380 if (!(sec->flags & SEC_LINKER_CREATED))
2381 continue;
2383 /* If we don't need this section, strip it from the output file.
2384 There were several sections primarily related to dynamic
2385 linking that must be create before the linker maps input
2386 sections to output sections. The linker does that before
2387 bfd_elf_size_dynamic_sections is called, and it is that
2388 function which decides whether anything needs to go into
2389 these sections. */
2391 strip = (sec->_raw_size == 0);
2393 if (sec == ia64_info->got_sec)
2394 strip = false;
2395 else if (sec == ia64_info->rel_got_sec)
2397 if (strip)
2398 ia64_info->rel_got_sec = NULL;
2399 else
2400 /* We use the reloc_count field as a counter if we need to
2401 copy relocs into the output file. */
2402 sec->reloc_count = 0;
2404 else if (sec == ia64_info->fptr_sec)
2406 if (strip)
2407 ia64_info->fptr_sec = NULL;
2409 else if (sec == ia64_info->plt_sec)
2411 if (strip)
2412 ia64_info->plt_sec = NULL;
2414 else if (sec == ia64_info->pltoff_sec)
2416 if (strip)
2417 ia64_info->pltoff_sec = NULL;
2419 else if (sec == ia64_info->rel_pltoff_sec)
2421 if (strip)
2422 ia64_info->rel_pltoff_sec = NULL;
2423 else
2425 relplt = true;
2426 /* We use the reloc_count field as a counter if we need to
2427 copy relocs into the output file. */
2428 sec->reloc_count = 0;
2431 else
2433 const char *name;
2435 /* It's OK to base decisions on the section name, because none
2436 of the dynobj section names depend upon the input files. */
2437 name = bfd_get_section_name (dynobj, sec);
2439 if (strcmp (name, ".got.plt") == 0)
2440 strip = false;
2441 else if (strncmp (name, ".rel", 4) == 0)
2443 if (!strip)
2445 const char *outname;
2446 asection *target;
2448 /* If this relocation section applies to a read only
2449 section, then we probably need a DT_TEXTREL entry. */
2450 outname = bfd_get_section_name (output_bfd,
2451 sec->output_section);
2452 if (outname[4] == 'a')
2453 outname += 5;
2454 else
2455 outname += 4;
2457 target = bfd_get_section_by_name (output_bfd, outname);
2458 if (target != NULL
2459 && (target->flags & SEC_READONLY) != 0
2460 && (target->flags & SEC_ALLOC) != 0)
2461 reltext = true;
2463 /* We use the reloc_count field as a counter if we need to
2464 copy relocs into the output file. */
2465 sec->reloc_count = 0;
2468 else
2469 continue;
2472 if (strip)
2473 _bfd_strip_section_from_output (info, sec);
2474 else
2476 /* Allocate memory for the section contents. */
2477 sec->contents = (bfd_byte *) bfd_zalloc(dynobj, sec->_raw_size);
2478 if (sec->contents == NULL && sec->_raw_size != 0)
2479 return false;
2483 if (elf_hash_table (info)->dynamic_sections_created)
2485 /* Add some entries to the .dynamic section. We fill in the values
2486 later (in finish_dynamic_sections) but we must add the entries now
2487 so that we get the correct size for the .dynamic section. */
2489 if (!info->shared)
2491 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2492 by the debugger. */
2493 if (!bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
2494 return false;
2497 if (! bfd_elf64_add_dynamic_entry (info, DT_IA_64_PLT_RESERVE, 0))
2498 return false;
2499 if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0))
2500 return false;
2502 if (relplt)
2504 if (! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2505 || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2506 || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))
2507 return false;
2510 if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)
2511 || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)
2512 || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,
2513 sizeof(Elf64_External_Rela)))
2514 return false;
2516 if (reltext)
2518 if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
2519 return false;
2520 info->flags |= DF_TEXTREL;
2524 /* ??? Perhaps force __gp local. */
2526 return true;
2529 static bfd_reloc_status_type
2530 elf64_ia64_install_value (abfd, hit_addr, val, r_type)
2531 bfd *abfd;
2532 bfd_byte *hit_addr;
2533 bfd_vma val;
2534 unsigned int r_type;
2536 const struct ia64_operand *op;
2537 int bigendian = 0, shift = 0;
2538 bfd_vma t0, t1, insn, dword;
2539 enum ia64_opnd opnd;
2540 const char *err;
2541 size_t size = 8;
2543 opnd = IA64_OPND_NIL;
2544 switch (r_type)
2546 case R_IA64_NONE:
2547 case R_IA64_LDXMOV:
2548 return bfd_reloc_ok;
2550 /* Instruction relocations. */
2552 case R_IA64_IMM14: opnd = IA64_OPND_IMM14; break;
2554 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
2555 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
2556 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
2557 case R_IA64_PCREL21B:
2558 case R_IA64_PCREL21BI:
2559 opnd = IA64_OPND_TGT25c;
2560 break;
2562 case R_IA64_IMM22:
2563 case R_IA64_GPREL22:
2564 case R_IA64_LTOFF22:
2565 case R_IA64_LTOFF22X:
2566 case R_IA64_PLTOFF22:
2567 case R_IA64_PCREL22:
2568 case R_IA64_LTOFF_FPTR22:
2569 opnd = IA64_OPND_IMM22;
2570 break;
2572 case R_IA64_IMM64:
2573 case R_IA64_GPREL64I:
2574 case R_IA64_LTOFF64I:
2575 case R_IA64_PLTOFF64I:
2576 case R_IA64_PCREL64I:
2577 case R_IA64_FPTR64I:
2578 case R_IA64_LTOFF_FPTR64I:
2579 opnd = IA64_OPND_IMMU64;
2580 break;
2582 /* Data relocations. */
2584 case R_IA64_DIR32MSB:
2585 case R_IA64_GPREL32MSB:
2586 case R_IA64_FPTR32MSB:
2587 case R_IA64_PCREL32MSB:
2588 case R_IA64_SEGREL32MSB:
2589 case R_IA64_SECREL32MSB:
2590 case R_IA64_LTV32MSB:
2591 size = 4; bigendian = 1;
2592 break;
2594 case R_IA64_DIR32LSB:
2595 case R_IA64_GPREL32LSB:
2596 case R_IA64_FPTR32LSB:
2597 case R_IA64_PCREL32LSB:
2598 case R_IA64_SEGREL32LSB:
2599 case R_IA64_SECREL32LSB:
2600 case R_IA64_LTV32LSB:
2601 size = 4; bigendian = 0;
2602 break;
2604 case R_IA64_DIR64MSB:
2605 case R_IA64_GPREL64MSB:
2606 case R_IA64_PLTOFF64MSB:
2607 case R_IA64_FPTR64MSB:
2608 case R_IA64_PCREL64MSB:
2609 case R_IA64_LTOFF_FPTR64MSB:
2610 case R_IA64_SEGREL64MSB:
2611 case R_IA64_SECREL64MSB:
2612 case R_IA64_LTV64MSB:
2613 size = 8; bigendian = 1;
2614 break;
2616 case R_IA64_DIR64LSB:
2617 case R_IA64_GPREL64LSB:
2618 case R_IA64_PLTOFF64LSB:
2619 case R_IA64_FPTR64LSB:
2620 case R_IA64_PCREL64LSB:
2621 case R_IA64_LTOFF_FPTR64LSB:
2622 case R_IA64_SEGREL64LSB:
2623 case R_IA64_SECREL64LSB:
2624 case R_IA64_LTV64LSB:
2625 size = 8; bigendian = 0;
2626 break;
2628 /* Unsupported / Dynamic relocations. */
2630 case R_IA64_REL32MSB:
2631 case R_IA64_REL32LSB:
2632 case R_IA64_REL64MSB:
2633 case R_IA64_REL64LSB:
2635 case R_IA64_IPLTMSB:
2636 case R_IA64_IPLTLSB:
2637 case R_IA64_EPLTMSB:
2638 case R_IA64_EPLTLSB:
2639 case R_IA64_COPY:
2641 case R_IA64_SEGBASE:
2643 case R_IA64_TPREL22:
2644 case R_IA64_TPREL64MSB:
2645 case R_IA64_TPREL64LSB:
2646 case R_IA64_LTOFF_TP22:
2648 default:
2649 return bfd_reloc_notsupported;
2652 switch (opnd)
2654 case IA64_OPND_IMMU64:
2655 hit_addr -= (long) hit_addr & 0x3;
2656 t0 = bfd_get_64 (abfd, hit_addr);
2657 t1 = bfd_get_64 (abfd, hit_addr + 8);
2659 /* tmpl/s: bits 0.. 5 in t0
2660 slot 0: bits 5..45 in t0
2661 slot 1: bits 46..63 in t0, bits 0..22 in t1
2662 slot 2: bits 23..63 in t1 */
2664 /* First, clear the bits that form the 64 bit constant. */
2665 t0 &= ~(0x3ffffLL << 46);
2666 t1 &= ~(0x7fffffLL
2667 | (( (0x07fLL << 13) | (0x1ffLL << 27)
2668 | (0x01fLL << 22) | (0x001LL << 21)
2669 | (0x001LL << 36)) << 23));
2671 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
2672 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
2673 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
2674 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
2675 | (((val >> 16) & 0x01f) << 22) /* imm5c */
2676 | (((val >> 21) & 0x001) << 21) /* ic */
2677 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
2679 bfd_put_64 (abfd, t0, hit_addr);
2680 bfd_put_64 (abfd, t1, hit_addr + 8);
2681 break;
2683 case IA64_OPND_TGT64:
2684 hit_addr -= (long) hit_addr & 0x3;
2685 t0 = bfd_get_64 (abfd, hit_addr);
2686 t1 = bfd_get_64 (abfd, hit_addr + 8);
2688 /* tmpl/s: bits 0.. 5 in t0
2689 slot 0: bits 5..45 in t0
2690 slot 1: bits 46..63 in t0, bits 0..22 in t1
2691 slot 2: bits 23..63 in t1 */
2693 /* First, clear the bits that form the 64 bit constant. */
2694 t0 &= ~(0x3ffffLL << 46);
2695 t1 &= ~(0x7fffffLL
2696 | ((1LL << 36 | 0xfffffLL << 13) << 23));
2698 val >>= 4;
2699 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
2700 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
2701 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
2702 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
2704 bfd_put_64 (abfd, t0, hit_addr);
2705 bfd_put_64 (abfd, t1, hit_addr + 8);
2706 break;
2708 default:
2709 switch ((long) hit_addr & 0x3)
2711 case 0: shift = 5; break;
2712 case 1: shift = 14; hit_addr += 3; break;
2713 case 2: shift = 23; hit_addr += 6; break;
2714 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
2716 dword = bfd_get_64 (abfd, hit_addr);
2717 insn = (dword >> shift) & 0x1ffffffffffLL;
2719 op = elf64_ia64_operands + opnd;
2720 err = (*op->insert) (op, val, &insn);
2721 if (err)
2722 return bfd_reloc_overflow;
2724 dword &= ~(0x1ffffffffffLL << shift);
2725 dword |= (insn << shift);
2726 bfd_put_64 (abfd, dword, hit_addr);
2727 break;
2729 case IA64_OPND_NIL:
2730 /* A data relocation. */
2731 if (bigendian)
2732 if (size == 4)
2733 bfd_putb32 (val, hit_addr);
2734 else
2735 bfd_putb64 (val, hit_addr);
2736 else
2737 if (size == 4)
2738 bfd_putl32 (val, hit_addr);
2739 else
2740 bfd_putl64 (val, hit_addr);
2741 break;
2744 return bfd_reloc_ok;
2747 static void
2748 elf64_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
2749 dynindx, addend)
2750 bfd *abfd;
2751 struct bfd_link_info *info;
2752 asection *sec;
2753 asection *srel;
2754 bfd_vma offset;
2755 unsigned int type;
2756 long dynindx;
2757 bfd_vma addend;
2759 Elf_Internal_Rela outrel;
2761 outrel.r_offset = (sec->output_section->vma
2762 + sec->output_offset
2763 + offset);
2765 BFD_ASSERT (dynindx != -1);
2766 outrel.r_info = ELF64_R_INFO (dynindx, type);
2767 outrel.r_addend = addend;
2769 if (elf_section_data (sec)->stab_info != NULL)
2771 /* This may be NULL for linker-generated relocations, as it is
2772 inconvenient to pass all the bits around. And this shouldn't
2773 happen. */
2774 BFD_ASSERT (info != NULL);
2776 offset = (_bfd_stab_section_offset
2777 (abfd, &elf_hash_table (info)->stab_info, sec,
2778 &elf_section_data (sec)->stab_info, offset));
2779 if (offset == (bfd_vma) -1)
2781 /* Run for the hills. We shouldn't be outputting a relocation
2782 for this. So do what everyone else does and output a no-op. */
2783 outrel.r_info = ELF64_R_INFO (0, R_IA64_NONE);
2784 outrel.r_addend = 0;
2785 offset = 0;
2787 outrel.r_offset = offset;
2790 bfd_elf64_swap_reloca_out (abfd, &outrel,
2791 ((Elf64_External_Rela *) srel->contents
2792 + srel->reloc_count++));
2793 BFD_ASSERT (sizeof(Elf64_External_Rela) * srel->reloc_count
2794 <= srel->_cooked_size);
2797 /* Store an entry for target address TARGET_ADDR in the linkage table
2798 and return the gp-relative address of the linkage table entry. */
2800 static bfd_vma
2801 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
2802 bfd *abfd;
2803 struct bfd_link_info *info;
2804 struct elf64_ia64_dyn_sym_info *dyn_i;
2805 long dynindx;
2806 bfd_vma addend;
2807 bfd_vma value;
2808 unsigned int dyn_r_type;
2810 struct elf64_ia64_link_hash_table *ia64_info;
2811 asection *got_sec;
2813 ia64_info = elf64_ia64_hash_table (info);
2814 got_sec = ia64_info->got_sec;
2816 BFD_ASSERT ((dyn_i->got_offset & 7) == 0);
2818 if (! dyn_i->got_done)
2820 dyn_i->got_done = true;
2822 /* Store the target address in the linkage table entry. */
2823 bfd_put_64 (abfd, value, got_sec->contents + dyn_i->got_offset);
2825 /* Install a dynamic relocation if needed. */
2826 if (info->shared
2827 || elf64_ia64_dynamic_symbol_p (dyn_i->h, info)
2828 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
2830 if (dynindx == -1)
2832 dyn_r_type = R_IA64_REL64LSB;
2833 dynindx = 0;
2834 addend = value;
2837 if (bfd_big_endian (abfd))
2839 switch (dyn_r_type)
2841 case R_IA64_REL64LSB:
2842 dyn_r_type = R_IA64_REL64MSB;
2843 break;
2844 case R_IA64_DIR64LSB:
2845 dyn_r_type = R_IA64_DIR64MSB;
2846 break;
2847 case R_IA64_FPTR64LSB:
2848 dyn_r_type = R_IA64_FPTR64MSB;
2849 break;
2850 default:
2851 BFD_ASSERT (false);
2852 break;
2856 elf64_ia64_install_dyn_reloc (abfd, NULL, got_sec,
2857 ia64_info->rel_got_sec,
2858 dyn_i->got_offset, dyn_r_type,
2859 dynindx, addend);
2863 /* Return the address of the linkage table entry. */
2864 value = (got_sec->output_section->vma
2865 + got_sec->output_offset
2866 + dyn_i->got_offset);
2868 return value;
2871 /* Fill in a function descriptor consisting of the function's code
2872 address and its global pointer. Return the descriptor's address. */
2874 static bfd_vma
2875 set_fptr_entry (abfd, info, dyn_i, value)
2876 bfd *abfd;
2877 struct bfd_link_info *info;
2878 struct elf64_ia64_dyn_sym_info *dyn_i;
2879 bfd_vma value;
2881 struct elf64_ia64_link_hash_table *ia64_info;
2882 asection *fptr_sec;
2884 ia64_info = elf64_ia64_hash_table (info);
2885 fptr_sec = ia64_info->fptr_sec;
2887 if (!dyn_i->fptr_done)
2889 dyn_i->fptr_done = 1;
2891 /* Fill in the function descriptor. */
2892 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
2893 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
2894 fptr_sec->contents + dyn_i->fptr_offset + 8);
2897 /* Return the descriptor's address. */
2898 value = (fptr_sec->output_section->vma
2899 + fptr_sec->output_offset
2900 + dyn_i->fptr_offset);
2902 return value;
2905 /* Fill in a PLTOFF entry consisting of the function's code address
2906 and its global pointer. Return the descriptor's address. */
2908 static bfd_vma
2909 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
2910 bfd *abfd;
2911 struct bfd_link_info *info;
2912 struct elf64_ia64_dyn_sym_info *dyn_i;
2913 bfd_vma value;
2914 boolean is_plt;
2916 struct elf64_ia64_link_hash_table *ia64_info;
2917 asection *pltoff_sec;
2919 ia64_info = elf64_ia64_hash_table (info);
2920 pltoff_sec = ia64_info->pltoff_sec;
2922 /* Don't do anything if this symbol uses a real PLT entry. In
2923 that case, we'll fill this in during finish_dynamic_symbol. */
2924 if ((! dyn_i->want_plt || is_plt)
2925 && !dyn_i->pltoff_done)
2927 /* Fill in the function descriptor. */
2928 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
2929 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
2930 pltoff_sec->contents + dyn_i->pltoff_offset + 8);
2932 /* Install dynamic relocations if needed. */
2933 if (!is_plt && info->shared)
2935 unsigned int dyn_r_type;
2937 if (bfd_big_endian (abfd))
2938 dyn_r_type = R_IA64_REL64MSB;
2939 else
2940 dyn_r_type = R_IA64_REL64LSB;
2942 elf64_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
2943 ia64_info->rel_pltoff_sec,
2944 dyn_i->pltoff_offset,
2945 dyn_r_type, 0, 0);
2946 elf64_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
2947 ia64_info->rel_pltoff_sec,
2948 dyn_i->pltoff_offset + 8,
2949 dyn_r_type, 0, 0);
2952 dyn_i->pltoff_done = 1;
2955 /* Return the descriptor's address. */
2956 value = (pltoff_sec->output_section->vma
2957 + pltoff_sec->output_offset
2958 + dyn_i->pltoff_offset);
2960 return value;
2963 static boolean
2964 elf64_ia64_final_link (abfd, info)
2965 bfd *abfd;
2966 struct bfd_link_info *info;
2968 struct elf64_ia64_link_hash_table *ia64_info;
2969 ia64_info = elf64_ia64_hash_table (info);
2971 /* Make sure we've got ourselves a nice fat __gp value. */
2972 if (!info->relocateable)
2974 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
2975 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
2976 struct elf_link_hash_entry *gp;
2977 bfd_vma gp_val;
2978 asection *os;
2980 /* Find the min and max vma of all sections marked short. Also
2981 collect min and max vma of any type, for use in selecting a
2982 nice gp. */
2983 for (os = abfd->sections; os ; os = os->next)
2985 bfd_vma lo, hi;
2987 if ((os->flags & SEC_ALLOC) == 0)
2988 continue;
2990 lo = os->vma;
2991 hi = os->vma + os->_raw_size;
2992 if (hi < lo)
2993 hi = (bfd_vma) -1;
2995 if (min_vma > lo)
2996 min_vma = lo;
2997 if (max_vma < hi)
2998 max_vma = hi;
2999 if (os->flags & SEC_SMALL_DATA)
3001 if (min_short_vma > lo)
3002 min_short_vma = lo;
3003 if (max_short_vma < hi)
3004 max_short_vma = hi;
3008 /* See if the user wants to force a value. */
3009 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
3010 false, false);
3012 if (gp
3013 && (gp->root.type == bfd_link_hash_defined
3014 || gp->root.type == bfd_link_hash_defweak))
3016 asection *gp_sec = gp->root.u.def.section;
3017 gp_val = (gp->root.u.def.value
3018 + gp_sec->output_section->vma
3019 + gp_sec->output_offset);
3021 else
3023 /* Pick a sensible value. */
3025 asection *got_sec = ia64_info->got_sec;
3027 /* Start with just the address of the .got. */
3028 if (got_sec)
3029 gp_val = got_sec->output_section->vma;
3030 else if (max_short_vma != 0)
3031 gp_val = min_short_vma;
3032 else
3033 gp_val = min_vma;
3035 /* If it is possible to address the entire image, but we
3036 don't with the choice above, adjust. */
3037 if (max_vma - min_vma < 0x400000
3038 && max_vma - gp_val <= 0x200000
3039 && gp_val - min_vma > 0x200000)
3040 gp_val = min_vma + 0x200000;
3041 else if (max_short_vma != 0)
3043 /* If we don't cover all the short data, adjust. */
3044 if (max_short_vma - gp_val >= 0x200000)
3045 gp_val = min_short_vma + 0x200000;
3047 /* If we're addressing stuff past the end, adjust back. */
3048 if (gp_val > max_vma)
3049 gp_val = max_vma - 0x200000 + 8;
3053 /* Validate whether all SHF_IA_64_SHORT sections are within
3054 range of the chosen GP. */
3056 if (max_short_vma != 0)
3058 if (max_short_vma - min_short_vma >= 0x400000)
3060 (*_bfd_error_handler)
3061 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3062 bfd_get_filename (abfd),
3063 (unsigned long)(max_short_vma - min_short_vma));
3064 return false;
3066 else if ((gp_val > min_short_vma
3067 && gp_val - min_short_vma > 0x200000)
3068 || (gp_val < max_short_vma
3069 && max_short_vma - gp_val >= 0x200000))
3071 (*_bfd_error_handler)
3072 (_("%s: __gp does not cover short data segment"),
3073 bfd_get_filename (abfd));
3074 return false;
3078 _bfd_set_gp_value (abfd, gp_val);
3081 /* Tricky bits. DT_INIT and DT_FINI use a pltoff entry, which is
3082 normally initialized in finish_dynamic_sections. Except that
3083 we need all non-plt pltoff entries to be initialized before
3084 finish_dynamic_symbols. This because the array of relocations
3085 used for plt entries (aka DT_JMPREL) begins after all the
3086 non-plt pltoff relocations. If the order gets confused, we
3087 munge either the array or the array base. */
3088 if (ia64_info->root.dynamic_sections_created)
3090 struct elf_link_hash_entry *h;
3091 struct elf64_ia64_dyn_sym_info *dyn_i;
3092 bfd_vma addr;
3094 if (info->init_function
3095 && (h = elf_link_hash_lookup (elf_hash_table (info),
3096 info->init_function, false,
3097 false, false))
3098 && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
3099 | ELF_LINK_HASH_DEF_REGULAR)) != 0)
3101 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3102 addr = (h->root.u.def.section->output_section->vma
3103 + h->root.u.def.section->output_offset
3104 + h->root.u.def.value);
3105 (void) set_pltoff_entry (abfd, info, dyn_i, addr, false);
3108 if (info->fini_function
3109 && (h = elf_link_hash_lookup (elf_hash_table (info),
3110 info->fini_function, false,
3111 false, false))
3112 && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
3113 | ELF_LINK_HASH_DEF_REGULAR)) != 0)
3115 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3116 addr = (h->root.u.def.section->output_section->vma
3117 + h->root.u.def.section->output_offset
3118 + h->root.u.def.value);
3119 (void) set_pltoff_entry (abfd, info, dyn_i, addr, false);
3123 /* Invoke the regular ELF backend linker to do all the work. */
3124 return bfd_elf64_bfd_final_link (abfd, info);
3127 static boolean
3128 elf64_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3129 contents, relocs, local_syms, local_sections)
3130 bfd *output_bfd;
3131 struct bfd_link_info *info;
3132 bfd *input_bfd;
3133 asection *input_section;
3134 bfd_byte *contents;
3135 Elf_Internal_Rela *relocs;
3136 Elf_Internal_Sym *local_syms;
3137 asection **local_sections;
3139 struct elf64_ia64_link_hash_table *ia64_info;
3140 Elf_Internal_Shdr *symtab_hdr;
3141 Elf_Internal_Rela *rel;
3142 Elf_Internal_Rela *relend;
3143 asection *srel;
3144 boolean ret_val = true; /* for non-fatal errors */
3145 bfd_vma gp_val;
3147 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3148 ia64_info = elf64_ia64_hash_table (info);
3150 /* Infect various flags from the input section to the output section. */
3151 if (info->relocateable)
3153 bfd_vma flags;
3155 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3156 flags &= SHF_IA_64_NORECOV;
3158 elf_section_data(input_section->output_section)
3159 ->this_hdr.sh_flags |= flags;
3162 gp_val = _bfd_get_gp_value (output_bfd);
3163 srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3165 rel = relocs;
3166 relend = relocs + input_section->reloc_count;
3167 for (; rel < relend; ++rel)
3169 struct elf_link_hash_entry *h;
3170 struct elf64_ia64_dyn_sym_info *dyn_i;
3171 bfd_reloc_status_type r;
3172 reloc_howto_type *howto;
3173 unsigned long r_symndx;
3174 Elf_Internal_Sym *sym;
3175 unsigned int r_type;
3176 bfd_vma value;
3177 asection *sym_sec;
3178 bfd_byte *hit_addr;
3179 boolean dynamic_symbol_p;
3180 boolean undef_weak_ref;
3182 r_type = ELF64_R_TYPE (rel->r_info);
3183 if (r_type > R_IA64_MAX_RELOC_CODE)
3185 (*_bfd_error_handler)
3186 (_("%s: unknown relocation type %d"),
3187 bfd_get_filename (input_bfd), (int)r_type);
3188 bfd_set_error (bfd_error_bad_value);
3189 ret_val = false;
3190 continue;
3192 howto = lookup_howto (r_type);
3193 r_symndx = ELF64_R_SYM (rel->r_info);
3195 if (info->relocateable)
3197 /* This is a relocateable link. We don't have to change
3198 anything, unless the reloc is against a section symbol,
3199 in which case we have to adjust according to where the
3200 section symbol winds up in the output section. */
3201 if (r_symndx < symtab_hdr->sh_info)
3203 sym = local_syms + r_symndx;
3204 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3206 sym_sec = local_sections[r_symndx];
3207 rel->r_addend += sym_sec->output_offset;
3210 continue;
3213 /* This is a final link. */
3215 h = NULL;
3216 sym = NULL;
3217 sym_sec = NULL;
3218 undef_weak_ref = false;
3220 if (r_symndx < symtab_hdr->sh_info)
3222 /* Reloc against local symbol. */
3223 sym = local_syms + r_symndx;
3224 sym_sec = local_sections[r_symndx];
3225 value = (sym_sec->output_section->vma
3226 + sym_sec->output_offset
3227 + sym->st_value);
3229 else
3231 long indx;
3233 /* Reloc against global symbol. */
3234 indx = r_symndx - symtab_hdr->sh_info;
3235 h = elf_sym_hashes (input_bfd)[indx];
3236 while (h->root.type == bfd_link_hash_indirect
3237 || h->root.type == bfd_link_hash_warning)
3238 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3240 value = 0;
3241 if (h->root.type == bfd_link_hash_defined
3242 || h->root.type == bfd_link_hash_defweak)
3244 sym_sec = h->root.u.def.section;
3246 /* Detect the cases that sym_sec->output_section is
3247 expected to be NULL -- all cases in which the symbol
3248 is defined in another shared module. This includes
3249 PLT relocs for which we've created a PLT entry and
3250 other relocs for which we're prepared to create
3251 dynamic relocations. */
3252 /* ??? Just accept it NULL and continue. */
3254 if (sym_sec->output_section != NULL)
3256 value = (h->root.u.def.value
3257 + sym_sec->output_section->vma
3258 + sym_sec->output_offset);
3261 else if (h->root.type == bfd_link_hash_undefweak)
3262 undef_weak_ref = true;
3263 else if (info->shared && !info->symbolic
3264 && !info->no_undefined
3265 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3267 else
3269 if (! ((*info->callbacks->undefined_symbol)
3270 (info, h->root.root.string, input_bfd,
3271 input_section, rel->r_offset,
3272 (!info->shared || info->no_undefined
3273 || ELF_ST_VISIBILITY (h->other)))))
3274 return false;
3275 ret_val = false;
3276 continue;
3280 hit_addr = contents + rel->r_offset;
3281 value += rel->r_addend;
3282 dynamic_symbol_p = elf64_ia64_dynamic_symbol_p (h, info);
3284 switch (r_type)
3286 case R_IA64_NONE:
3287 case R_IA64_LDXMOV:
3288 continue;
3290 case R_IA64_IMM14:
3291 case R_IA64_IMM22:
3292 case R_IA64_IMM64:
3293 case R_IA64_DIR32MSB:
3294 case R_IA64_DIR32LSB:
3295 case R_IA64_DIR64MSB:
3296 case R_IA64_DIR64LSB:
3297 /* Install a dynamic relocation for this reloc. */
3298 if ((dynamic_symbol_p || info->shared)
3299 && (input_section->flags & SEC_ALLOC) != 0)
3301 unsigned int dyn_r_type;
3302 long dynindx;
3304 BFD_ASSERT (srel != NULL);
3306 /* If we don't need dynamic symbol lookup, find a
3307 matching RELATIVE relocation. */
3308 dyn_r_type = r_type;
3309 if (dynamic_symbol_p)
3310 dynindx = h->dynindx;
3311 else
3313 switch (r_type)
3315 case R_IA64_DIR32MSB:
3316 dyn_r_type = R_IA64_REL32MSB;
3317 break;
3318 case R_IA64_DIR32LSB:
3319 dyn_r_type = R_IA64_REL32LSB;
3320 break;
3321 case R_IA64_DIR64MSB:
3322 dyn_r_type = R_IA64_REL64MSB;
3323 break;
3324 case R_IA64_DIR64LSB:
3325 dyn_r_type = R_IA64_REL64LSB;
3326 break;
3328 default:
3329 /* We can't represent this without a dynamic symbol.
3330 Adjust the relocation to be against an output
3331 section symbol, which are always present in the
3332 dynamic symbol table. */
3333 /* ??? People shouldn't be doing non-pic code in
3334 shared libraries. Hork. */
3335 (*_bfd_error_handler)
3336 (_("%s: linking non-pic code in a shared library"),
3337 bfd_get_filename (input_bfd));
3338 ret_val = false;
3339 continue;
3341 dynindx = 0;
3344 elf64_ia64_install_dyn_reloc (output_bfd, info, input_section,
3345 srel, rel->r_offset, dyn_r_type,
3346 dynindx, rel->r_addend);
3348 /* FALLTHRU */
3350 case R_IA64_LTV32MSB:
3351 case R_IA64_LTV32LSB:
3352 case R_IA64_LTV64MSB:
3353 case R_IA64_LTV64LSB:
3354 r = elf64_ia64_install_value (output_bfd, hit_addr, value, r_type);
3355 break;
3357 case R_IA64_GPREL22:
3358 case R_IA64_GPREL64I:
3359 case R_IA64_GPREL32MSB:
3360 case R_IA64_GPREL32LSB:
3361 case R_IA64_GPREL64MSB:
3362 case R_IA64_GPREL64LSB:
3363 if (dynamic_symbol_p)
3365 (*_bfd_error_handler)
3366 (_("%s: @gprel relocation against dynamic symbol %s"),
3367 bfd_get_filename (input_bfd), h->root.root.string);
3368 ret_val = false;
3369 continue;
3371 value -= gp_val;
3372 r = elf64_ia64_install_value (output_bfd, hit_addr, value, r_type);
3373 break;
3375 case R_IA64_LTOFF22:
3376 case R_IA64_LTOFF22X:
3377 case R_IA64_LTOFF64I:
3378 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3379 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
3380 rel->r_addend, value, R_IA64_DIR64LSB);
3381 value -= gp_val;
3382 r = elf64_ia64_install_value (output_bfd, hit_addr, value, r_type);
3383 break;
3385 case R_IA64_PLTOFF22:
3386 case R_IA64_PLTOFF64I:
3387 case R_IA64_PLTOFF64MSB:
3388 case R_IA64_PLTOFF64LSB:
3389 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3390 value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
3391 value -= gp_val;
3392 r = elf64_ia64_install_value (output_bfd, hit_addr, value, r_type);
3393 break;
3395 case R_IA64_FPTR64I:
3396 case R_IA64_FPTR32MSB:
3397 case R_IA64_FPTR32LSB:
3398 case R_IA64_FPTR64MSB:
3399 case R_IA64_FPTR64LSB:
3400 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3401 if (dyn_i->want_fptr)
3403 if (!undef_weak_ref)
3404 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3406 else
3408 long dynindx;
3410 /* Otherwise, we expect the dynamic linker to create
3411 the entry. */
3413 if (h)
3415 if (h->dynindx != -1)
3416 dynindx = h->dynindx;
3417 else
3418 dynindx = (_bfd_elf_link_lookup_local_dynindx
3419 (info, h->root.u.def.section->owner,
3420 global_sym_index (h)));
3422 else
3424 dynindx = (_bfd_elf_link_lookup_local_dynindx
3425 (info, input_bfd, r_symndx));
3428 elf64_ia64_install_dyn_reloc (output_bfd, info, input_section,
3429 srel, rel->r_offset, r_type,
3430 dynindx, rel->r_addend);
3431 value = 0;
3434 r = elf64_ia64_install_value (output_bfd, hit_addr, value, r_type);
3435 break;
3437 case R_IA64_LTOFF_FPTR22:
3438 case R_IA64_LTOFF_FPTR64I:
3439 case R_IA64_LTOFF_FPTR64MSB:
3440 case R_IA64_LTOFF_FPTR64LSB:
3442 long dynindx;
3444 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3445 if (dyn_i->want_fptr)
3447 BFD_ASSERT (h == NULL || h->dynindx == -1)
3448 if (!undef_weak_ref)
3449 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3450 dynindx = -1;
3452 else
3454 /* Otherwise, we expect the dynamic linker to create
3455 the entry. */
3456 if (h)
3458 if (h->dynindx != -1)
3459 dynindx = h->dynindx;
3460 else
3461 dynindx = (_bfd_elf_link_lookup_local_dynindx
3462 (info, h->root.u.def.section->owner,
3463 global_sym_index (h)));
3465 else
3466 dynindx = (_bfd_elf_link_lookup_local_dynindx
3467 (info, input_bfd, r_symndx));
3468 value = 0;
3471 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
3472 rel->r_addend, value, R_IA64_FPTR64LSB);
3473 value -= gp_val;
3474 r = elf64_ia64_install_value (output_bfd, hit_addr, value, r_type);
3476 break;
3478 case R_IA64_PCREL32MSB:
3479 case R_IA64_PCREL32LSB:
3480 case R_IA64_PCREL64MSB:
3481 case R_IA64_PCREL64LSB:
3482 /* Install a dynamic relocation for this reloc. */
3483 if (dynamic_symbol_p)
3485 BFD_ASSERT (srel != NULL);
3487 elf64_ia64_install_dyn_reloc (output_bfd, info, input_section,
3488 srel, rel->r_offset, r_type,
3489 h->dynindx, rel->r_addend);
3491 goto finish_pcrel;
3493 case R_IA64_PCREL21BI:
3494 case R_IA64_PCREL21F:
3495 case R_IA64_PCREL21M:
3496 /* ??? These two are only used for speculation fixup code.
3497 They should never be dynamic. */
3498 if (dynamic_symbol_p)
3500 (*_bfd_error_handler)
3501 (_("%s: dynamic relocation against speculation fixup"),
3502 bfd_get_filename (input_bfd));
3503 ret_val = false;
3504 continue;
3506 if (undef_weak_ref)
3508 (*_bfd_error_handler)
3509 (_("%s: speculation fixup against undefined weak symbol"),
3510 bfd_get_filename (input_bfd));
3511 ret_val = false;
3512 continue;
3514 goto finish_pcrel;
3516 case R_IA64_PCREL21B:
3517 case R_IA64_PCREL60B:
3518 /* We should have created a PLT entry for any dynamic symbol. */
3519 dyn_i = NULL;
3520 if (h)
3521 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3523 if (dyn_i && dyn_i->want_plt2)
3525 /* Should have caught this earlier. */
3526 BFD_ASSERT (rel->r_addend == 0);
3528 value = (ia64_info->plt_sec->output_section->vma
3529 + ia64_info->plt_sec->output_offset
3530 + dyn_i->plt2_offset);
3532 else
3534 /* Since there's no PLT entry, Validate that this is
3535 locally defined. */
3536 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
3538 /* If the symbol is undef_weak, we shouldn't be trying
3539 to call it. There's every chance that we'd wind up
3540 with an out-of-range fixup here. Don't bother setting
3541 any value at all. */
3542 if (undef_weak_ref)
3543 continue;
3545 goto finish_pcrel;
3547 case R_IA64_PCREL22:
3548 case R_IA64_PCREL64I:
3549 finish_pcrel:
3550 /* Make pc-relative. */
3551 value -= (input_section->output_section->vma
3552 + input_section->output_offset
3553 + rel->r_offset) & ~ (bfd_vma) 0x3;
3554 r = elf64_ia64_install_value (output_bfd, hit_addr, value, r_type);
3555 break;
3557 case R_IA64_SEGREL32MSB:
3558 case R_IA64_SEGREL32LSB:
3559 case R_IA64_SEGREL64MSB:
3560 case R_IA64_SEGREL64LSB:
3562 struct elf_segment_map *m;
3563 Elf_Internal_Phdr *p;
3565 /* Find the segment that contains the output_section. */
3566 for (m = elf_tdata (output_bfd)->segment_map,
3567 p = elf_tdata (output_bfd)->phdr;
3568 m != NULL;
3569 m = m->next, p++)
3571 int i;
3572 for (i = m->count - 1; i >= 0; i--)
3573 if (m->sections[i] == sym_sec->output_section)
3574 break;
3575 if (i >= 0)
3576 break;
3579 if (m == NULL)
3581 /* If the input section was discarded from the output, then
3582 do nothing. */
3584 if (bfd_is_abs_section (sym_sec->output_section))
3585 r = bfd_reloc_ok;
3586 else
3587 r = bfd_reloc_notsupported;
3589 else
3591 /* The VMA of the segment is the vaddr of the associated
3592 program header. */
3593 if (value > p->p_vaddr)
3594 value -= p->p_vaddr;
3595 else
3596 value = 0;
3597 r = elf64_ia64_install_value (output_bfd, hit_addr, value,
3598 r_type);
3600 break;
3603 case R_IA64_SECREL32MSB:
3604 case R_IA64_SECREL32LSB:
3605 case R_IA64_SECREL64MSB:
3606 case R_IA64_SECREL64LSB:
3607 /* Make output-section relative. */
3608 if (value > input_section->output_section->vma)
3609 value -= input_section->output_section->vma;
3610 else
3611 value = 0;
3612 r = elf64_ia64_install_value (output_bfd, hit_addr, value, r_type);
3613 break;
3615 case R_IA64_SEGBASE:
3617 case R_IA64_REL32MSB:
3618 case R_IA64_REL32LSB:
3619 case R_IA64_REL64MSB:
3620 case R_IA64_REL64LSB:
3622 case R_IA64_IPLTMSB:
3623 case R_IA64_IPLTLSB:
3624 case R_IA64_EPLTMSB:
3625 case R_IA64_EPLTLSB:
3626 case R_IA64_COPY:
3628 case R_IA64_TPREL22:
3629 case R_IA64_TPREL64MSB:
3630 case R_IA64_TPREL64LSB:
3631 case R_IA64_LTOFF_TP22:
3632 default:
3633 r = bfd_reloc_notsupported;
3634 break;
3637 switch (r)
3639 case bfd_reloc_ok:
3640 break;
3642 case bfd_reloc_undefined:
3643 /* This can happen for global table relative relocs if
3644 __gp is undefined. This is a panic situation so we
3645 don't try to continue. */
3646 (*info->callbacks->undefined_symbol)
3647 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
3648 return false;
3650 case bfd_reloc_notsupported:
3652 const char *name;
3654 if (h)
3655 name = h->root.root.string;
3656 else
3658 name = bfd_elf_string_from_elf_section (input_bfd,
3659 symtab_hdr->sh_link,
3660 sym->st_name);
3661 if (name == NULL)
3662 return false;
3663 if (*name == '\0')
3664 name = bfd_section_name (input_bfd, input_section);
3666 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
3667 name, input_bfd,
3668 input_section, rel->r_offset))
3669 return false;
3670 ret_val = false;
3672 break;
3674 case bfd_reloc_dangerous:
3675 case bfd_reloc_outofrange:
3676 case bfd_reloc_overflow:
3677 default:
3679 const char *name;
3681 if (h)
3682 name = h->root.root.string;
3683 else
3685 name = bfd_elf_string_from_elf_section (input_bfd,
3686 symtab_hdr->sh_link,
3687 sym->st_name);
3688 if (name == NULL)
3689 return false;
3690 if (*name == '\0')
3691 name = bfd_section_name (input_bfd, input_section);
3693 if (!(*info->callbacks->reloc_overflow) (info, name,
3694 howto->name, 0,
3695 input_bfd,
3696 input_section,
3697 rel->r_offset))
3698 return false;
3699 ret_val = false;
3701 break;
3705 return ret_val;
3708 static boolean
3709 elf64_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
3710 bfd *output_bfd;
3711 struct bfd_link_info *info;
3712 struct elf_link_hash_entry *h;
3713 Elf_Internal_Sym *sym;
3715 struct elf64_ia64_link_hash_table *ia64_info;
3716 struct elf64_ia64_dyn_sym_info *dyn_i;
3718 ia64_info = elf64_ia64_hash_table (info);
3719 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3721 /* Fill in the PLT data, if required. */
3722 if (dyn_i && dyn_i->want_plt)
3724 Elf_Internal_Rela outrel;
3725 bfd_byte *loc;
3726 asection *plt_sec;
3727 bfd_vma plt_addr, pltoff_addr, gp_val, index;
3728 Elf64_External_Rela *rel;
3730 gp_val = _bfd_get_gp_value (output_bfd);
3732 /* Initialize the minimal PLT entry. */
3734 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3735 plt_sec = ia64_info->plt_sec;
3736 loc = plt_sec->contents + dyn_i->plt_offset;
3738 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
3739 elf64_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
3740 elf64_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
3741 R_IA64_PCREL21B);
3743 plt_addr = (plt_sec->output_section->vma
3744 + plt_sec->output_offset
3745 + dyn_i->plt_offset);
3746 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
3748 /* Initialize the FULL PLT entry, if needed. */
3749 if (dyn_i->want_plt2)
3751 loc = plt_sec->contents + dyn_i->plt2_offset;
3753 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
3754 elf64_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
3755 R_IA64_IMM22);
3757 /* Mark the symbol as undefined, rather than as defined in the
3758 plt section. Leave the value alone. */
3759 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
3760 first place. But perhaps elflink.h did some for us. */
3761 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
3762 sym->st_shndx = SHN_UNDEF;
3765 /* Create the dynamic relocation. */
3766 outrel.r_offset = pltoff_addr;
3767 if (bfd_little_endian (output_bfd))
3768 outrel.r_info = ELF64_R_INFO (h->dynindx, R_IA64_IPLTLSB);
3769 else
3770 outrel.r_info = ELF64_R_INFO (h->dynindx, R_IA64_IPLTMSB);
3771 outrel.r_addend = 0;
3773 /* This is fun. In the .IA_64.pltoff section, we've got entries
3774 that correspond both to real PLT entries, and those that
3775 happened to resolve to local symbols but need to be created
3776 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
3777 relocations for the real PLT should come at the end of the
3778 section, so that they can be indexed by plt entry at runtime.
3780 We emitted all of the relocations for the non-PLT @pltoff
3781 entries during relocate_section. So we can consider the
3782 existing sec->reloc_count to be the base of the array of
3783 PLT relocations. */
3785 rel = (Elf64_External_Rela *)ia64_info->rel_pltoff_sec->contents;
3786 rel += ia64_info->rel_pltoff_sec->reloc_count;
3788 bfd_elf64_swap_reloca_out (output_bfd, &outrel, rel + index);
3791 /* Mark some specially defined symbols as absolute. */
3792 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
3793 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
3794 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
3795 sym->st_shndx = SHN_ABS;
3797 return true;
3800 static boolean
3801 elf64_ia64_finish_dynamic_sections (abfd, info)
3802 bfd *abfd;
3803 struct bfd_link_info *info;
3805 struct elf64_ia64_link_hash_table *ia64_info;
3806 bfd *dynobj;
3808 ia64_info = elf64_ia64_hash_table (info);
3809 dynobj = ia64_info->root.dynobj;
3811 if (elf_hash_table (info)->dynamic_sections_created)
3813 Elf64_External_Dyn *dyncon, *dynconend;
3814 asection *sdyn, *sgotplt;
3815 bfd_vma gp_val;
3817 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3818 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
3819 BFD_ASSERT (sdyn != NULL);
3820 dyncon = (Elf64_External_Dyn *) sdyn->contents;
3821 dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
3823 gp_val = _bfd_get_gp_value (abfd);
3825 for (; dyncon < dynconend; dyncon++)
3827 Elf_Internal_Dyn dyn;
3828 const char *name;
3829 asection *s;
3831 bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
3833 switch (dyn.d_tag)
3835 case DT_PLTGOT:
3836 dyn.d_un.d_ptr = gp_val;
3837 break;
3839 case DT_PLTRELSZ:
3840 dyn.d_un.d_val = (ia64_info->minplt_entries
3841 * sizeof (Elf64_External_Rela));
3842 break;
3844 case DT_JMPREL:
3845 /* See the comment above in finish_dynamic_symbol. */
3846 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
3847 + ia64_info->rel_pltoff_sec->output_offset
3848 + (ia64_info->rel_pltoff_sec->reloc_count
3849 * sizeof (Elf64_External_Rela)));
3850 break;
3852 case DT_IA_64_PLT_RESERVE:
3853 dyn.d_un.d_ptr = (sgotplt->output_section->vma
3854 + sgotplt->output_offset);
3855 break;
3857 case DT_RELASZ:
3858 /* Do not have RELASZ include JMPREL. This makes things
3859 easier on ld.so. This is not what the rest of BFD set up. */
3860 dyn.d_un.d_val -= (ia64_info->minplt_entries
3861 * sizeof (Elf64_External_Rela));
3862 break;
3864 case DT_INIT:
3865 case DT_FINI:
3867 struct elf_link_hash_entry *h;
3868 struct elf64_ia64_dyn_sym_info *dyn_i;
3869 const char *which;
3871 if (dyn.d_tag == DT_INIT)
3872 which = info->init_function;
3873 else
3874 which = info->fini_function;
3876 h = elf_link_hash_lookup (elf_hash_table (info), which,
3877 false, false, false);
3878 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3879 dyn.d_un.d_ptr = set_pltoff_entry (abfd, info, dyn_i,
3880 dyn.d_un.d_ptr, 0);
3884 bfd_elf64_swap_dyn_out (abfd, &dyn, dyncon);
3887 /* Initialize the PLT0 entry */
3888 if (ia64_info->plt_sec)
3890 bfd_byte *loc = ia64_info->plt_sec->contents;
3891 bfd_vma pltres;
3893 memcpy (loc, plt_header, PLT_HEADER_SIZE);
3895 pltres = (sgotplt->output_section->vma
3896 + sgotplt->output_offset
3897 - gp_val);
3899 elf64_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
3903 return true;
3906 /* ELF file flag handling: */
3908 /* Function to keep IA-64 specific file flags. */
3909 static boolean
3910 elf64_ia64_set_private_flags (abfd, flags)
3911 bfd *abfd;
3912 flagword flags;
3914 BFD_ASSERT (!elf_flags_init (abfd)
3915 || elf_elfheader (abfd)->e_flags == flags);
3917 elf_elfheader (abfd)->e_flags = flags;
3918 elf_flags_init (abfd) = true;
3919 return true;
3922 /* Copy backend specific data from one object module to another */
3923 static boolean
3924 elf64_ia64_copy_private_bfd_data (ibfd, obfd)
3925 bfd *ibfd, *obfd;
3927 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3928 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3929 return true;
3931 BFD_ASSERT (!elf_flags_init (obfd)
3932 || (elf_elfheader (obfd)->e_flags
3933 == elf_elfheader (ibfd)->e_flags));
3935 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
3936 elf_flags_init (obfd) = true;
3937 return true;
3940 /* Merge backend specific data from an object file to the output
3941 object file when linking. */
3942 static boolean
3943 elf64_ia64_merge_private_bfd_data (ibfd, obfd)
3944 bfd *ibfd, *obfd;
3946 flagword out_flags;
3947 flagword in_flags;
3948 boolean ok = true;
3950 /* Don't even pretend to support mixed-format linking. */
3951 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3952 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3953 return false;
3955 in_flags = elf_elfheader (ibfd)->e_flags;
3956 out_flags = elf_elfheader (obfd)->e_flags;
3958 if (! elf_flags_init (obfd))
3960 elf_flags_init (obfd) = true;
3961 elf_elfheader (obfd)->e_flags = in_flags;
3963 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3964 && bfd_get_arch_info (obfd)->the_default)
3966 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
3967 bfd_get_mach (ibfd));
3970 return true;
3973 /* Check flag compatibility. */
3974 if (in_flags == out_flags)
3975 return true;
3977 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
3978 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
3979 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
3981 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
3983 (*_bfd_error_handler)
3984 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
3985 bfd_get_filename (ibfd));
3987 bfd_set_error (bfd_error_bad_value);
3988 ok = false;
3990 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
3992 (*_bfd_error_handler)
3993 (_("%s: linking big-endian files with little-endian files"),
3994 bfd_get_filename (ibfd));
3996 bfd_set_error (bfd_error_bad_value);
3997 ok = false;
3999 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4001 (*_bfd_error_handler)
4002 (_("%s: linking 64-bit files with 32-bit files"),
4003 bfd_get_filename (ibfd));
4005 bfd_set_error (bfd_error_bad_value);
4006 ok = false;
4008 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4010 (*_bfd_error_handler)
4011 (_("%s: linking constant-gp files with non-constant-gp files"),
4012 bfd_get_filename (ibfd));
4014 bfd_set_error (bfd_error_bad_value);
4015 ok = false;
4017 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4018 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4020 (*_bfd_error_handler)
4021 (_("%s: linking auto-pic files with non-auto-pic files"),
4022 bfd_get_filename (ibfd));
4024 bfd_set_error (bfd_error_bad_value);
4025 ok = false;
4028 return ok;
4031 static boolean
4032 elf64_ia64_print_private_bfd_data (abfd, ptr)
4033 bfd *abfd;
4034 PTR ptr;
4036 FILE *file = (FILE *) ptr;
4037 flagword flags = elf_elfheader (abfd)->e_flags;
4039 BFD_ASSERT (abfd != NULL && ptr != NULL);
4041 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4042 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4043 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4044 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4045 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4046 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4047 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4048 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4049 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4051 _bfd_elf_print_private_bfd_data (abfd, ptr);
4052 return true;
4055 #define TARGET_LITTLE_SYM bfd_elf64_ia64_little_vec
4056 #define TARGET_LITTLE_NAME "elf64-ia64-little"
4057 #define TARGET_BIG_SYM bfd_elf64_ia64_big_vec
4058 #define TARGET_BIG_NAME "elf64-ia64-big"
4059 #define ELF_ARCH bfd_arch_ia64
4060 #define ELF_MACHINE_CODE EM_IA_64
4061 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4062 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4063 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4065 #define elf_backend_section_from_shdr \
4066 elf64_ia64_section_from_shdr
4067 #define elf_backend_fake_sections \
4068 elf64_ia64_fake_sections
4069 #define elf_backend_add_symbol_hook \
4070 elf64_ia64_add_symbol_hook
4071 #define elf_backend_additional_program_headers \
4072 elf64_ia64_additional_program_headers
4073 #define elf_backend_modify_segment_map \
4074 elf64_ia64_modify_segment_map
4075 #define elf_info_to_howto \
4076 elf64_ia64_info_to_howto
4078 #define bfd_elf64_bfd_reloc_type_lookup \
4079 elf64_ia64_reloc_type_lookup
4080 #define bfd_elf64_bfd_is_local_label_name \
4081 elf64_ia64_is_local_label_name
4082 #define bfd_elf64_bfd_relax_section \
4083 elf64_ia64_relax_section
4085 /* Stuff for the BFD linker: */
4086 #define bfd_elf64_bfd_link_hash_table_create \
4087 elf64_ia64_hash_table_create
4088 #define elf_backend_create_dynamic_sections \
4089 elf64_ia64_create_dynamic_sections
4090 #define elf_backend_check_relocs \
4091 elf64_ia64_check_relocs
4092 #define elf_backend_adjust_dynamic_symbol \
4093 elf64_ia64_adjust_dynamic_symbol
4094 #define elf_backend_size_dynamic_sections \
4095 elf64_ia64_size_dynamic_sections
4096 #define elf_backend_relocate_section \
4097 elf64_ia64_relocate_section
4098 #define elf_backend_finish_dynamic_symbol \
4099 elf64_ia64_finish_dynamic_symbol
4100 #define elf_backend_finish_dynamic_sections \
4101 elf64_ia64_finish_dynamic_sections
4102 #define bfd_elf64_bfd_final_link \
4103 elf64_ia64_final_link
4105 #define bfd_elf64_bfd_copy_private_bfd_data \
4106 elf64_ia64_copy_private_bfd_data
4107 #define bfd_elf64_bfd_merge_private_bfd_data \
4108 elf64_ia64_merge_private_bfd_data
4109 #define bfd_elf64_bfd_set_private_flags \
4110 elf64_ia64_set_private_flags
4111 #define bfd_elf64_bfd_print_private_bfd_data \
4112 elf64_ia64_print_private_bfd_data
4114 #define elf_backend_plt_readonly 1
4115 #define elf_backend_want_plt_sym 0
4116 #define elf_backend_plt_alignment 5
4117 #define elf_backend_got_header_size 0
4118 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4119 #define elf_backend_want_got_plt 1
4120 #define elf_backend_may_use_rel_p 1
4121 #define elf_backend_may_use_rela_p 1
4122 #define elf_backend_default_use_rela_p 1
4123 #define elf_backend_want_dynbss 0
4124 #define elf_backend_copy_indirect_symbol elf64_ia64_hash_copy_indirect
4125 #define elf_backend_hide_symbol elf64_ia64_hash_hide_symbol
4127 #include "elf64-target.h"