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