2001-01-23 H.J. Lu <hjl@gnu.org>
[binutils.git] / bfd / elfxx-ia64.c
blob6751e4acc1da3d161cbfce045dd80bd361a351b7
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));
277 /* ia64-specific relocation */
279 /* Perform a relocation. Not much to do here as all the hard work is
280 done in elfNN_ia64_final_link_relocate. */
281 static bfd_reloc_status_type
282 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
283 output_bfd, error_message)
284 bfd *abfd ATTRIBUTE_UNUSED;
285 arelent *reloc;
286 asymbol *sym ATTRIBUTE_UNUSED;
287 PTR data ATTRIBUTE_UNUSED;
288 asection *input_section;
289 bfd *output_bfd;
290 char **error_message;
292 if (output_bfd)
294 reloc->address += input_section->output_offset;
295 return bfd_reloc_ok;
297 *error_message = "Unsupported call to elfNN_ia64_reloc";
298 return bfd_reloc_notsupported;
301 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
302 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
303 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
305 /* This table has to be sorted according to increasing number of the
306 TYPE field. */
307 static reloc_howto_type ia64_howto_table[] =
309 IA64_HOWTO (R_IA64_NONE, "NONE", 0, false, true),
311 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, false, true),
312 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, false, true),
313 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, false, true),
314 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, false, true),
315 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, false, true),
316 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, false, true),
317 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, false, true),
319 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, false, true),
320 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, false, true),
321 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, false, true),
322 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, false, true),
323 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, false, true),
324 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, false, true),
326 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, false, true),
327 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, false, true),
329 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, false, true),
330 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, false, true),
331 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, false, true),
332 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, false, true),
334 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, false, true),
335 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, false, true),
336 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, false, true),
337 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, false, true),
338 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, false, true),
340 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, true, true),
341 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, true, true),
342 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, true, true),
343 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, true, true),
344 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, true, true),
345 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, true, true),
346 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, true, true),
347 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, true, true),
349 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true),
350 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true),
351 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
352 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
354 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
355 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
356 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
357 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, false, true),
359 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, false, true),
360 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, false, true),
361 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, false, true),
362 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, false, true),
364 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, false, true),
365 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, false, true),
366 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, false, true),
367 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, false, true),
369 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, false, true),
370 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, false, true),
371 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, false, true),
372 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, false, true),
374 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, true, true),
375 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, true, true),
376 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, true, true),
378 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, false, true),
379 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, false, true),
380 IA64_HOWTO (R_IA64_COPY, "COPY", 4, false, true),
381 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, false, true),
382 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, false, true),
384 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, false, false),
385 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 8, false, false),
386 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 8, false, false),
387 IA64_HOWTO (R_IA64_LTOFF_TP22, "LTOFF_TP22", 0, false, false),
390 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
392 /* Given a BFD reloc type, return the matching HOWTO structure. */
394 static reloc_howto_type*
395 lookup_howto (rtype)
396 unsigned int rtype;
398 static int inited = 0;
399 int i;
401 if (!inited)
403 inited = 1;
405 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
406 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
407 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
410 BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
411 i = elf_code_to_howto_index[rtype];
412 if (i >= NELEMS (ia64_howto_table))
413 return 0;
414 return ia64_howto_table + i;
417 static reloc_howto_type*
418 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
419 bfd *abfd ATTRIBUTE_UNUSED;
420 bfd_reloc_code_real_type bfd_code;
422 unsigned int rtype;
424 switch (bfd_code)
426 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
428 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
429 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
430 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
432 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
433 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
434 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
435 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
437 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
438 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
439 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
440 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
441 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
442 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
444 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
445 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
447 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
448 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
449 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
450 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
451 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
452 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
453 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
454 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
455 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
457 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
458 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
459 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
460 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
461 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
462 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
463 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
464 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
465 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
466 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
467 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
469 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
470 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
471 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
472 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
474 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
475 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
476 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
477 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
479 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
480 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
481 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
482 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
484 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
485 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
486 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
487 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
489 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
490 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
491 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
492 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
494 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
495 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
496 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
497 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
498 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
500 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
501 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
502 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
503 case BFD_RELOC_IA64_LTOFF_TP22: rtype = R_IA64_LTOFF_TP22; break;
505 default: return 0;
507 return lookup_howto (rtype);
510 /* Given a ELF reloc, return the matching HOWTO structure. */
512 static void
513 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
514 bfd *abfd ATTRIBUTE_UNUSED;
515 arelent *bfd_reloc;
516 ElfNN_Internal_Rela *elf_reloc;
518 bfd_reloc->howto = lookup_howto (ELFNN_R_TYPE (elf_reloc->r_info));
521 #define PLT_HEADER_SIZE (3 * 16)
522 #define PLT_MIN_ENTRY_SIZE (1 * 16)
523 #define PLT_FULL_ENTRY_SIZE (2 * 16)
524 #define PLT_RESERVED_WORDS 3
526 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
528 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
529 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
530 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
531 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
532 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
533 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
534 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
535 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
536 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
539 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
541 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
542 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
543 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
546 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
548 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
549 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
550 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
551 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
552 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
553 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
556 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
558 /* Select out of range branch fixup type. Note that Itanium does
559 not support brl, and so it gets emulated by the kernel. */
560 #undef USE_BRL
562 static const bfd_byte oor_brl[16] =
564 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
566 0x00, 0x00, 0x00, 0xc0
569 static const bfd_byte oor_ip[48] =
571 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
572 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
573 0x01, 0x00, 0x00, 0x60,
574 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
575 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
576 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
577 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
578 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
579 0x60, 0x00, 0x80, 0x00 /* br b6;; */
582 /* These functions do relaxation for IA-64 ELF.
584 This is primarily to support branches to targets out of range;
585 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
587 static boolean
588 elfNN_ia64_relax_section (abfd, sec, link_info, again)
589 bfd *abfd;
590 asection *sec;
591 struct bfd_link_info *link_info;
592 boolean *again;
594 struct one_fixup
596 struct one_fixup *next;
597 asection *tsec;
598 bfd_vma toff;
599 bfd_vma trampoff;
602 Elf_Internal_Shdr *symtab_hdr;
603 Elf_Internal_Rela *internal_relocs;
604 Elf_Internal_Rela *free_relocs = NULL;
605 Elf_Internal_Rela *irel, *irelend;
606 bfd_byte *contents;
607 bfd_byte *free_contents = NULL;
608 ElfNN_External_Sym *extsyms;
609 ElfNN_External_Sym *free_extsyms = NULL;
610 struct elfNN_ia64_link_hash_table *ia64_info;
611 struct one_fixup *fixups = NULL;
612 boolean changed_contents = false;
613 boolean changed_relocs = false;
615 /* Assume we're not going to change any sizes, and we'll only need
616 one pass. */
617 *again = false;
619 /* Nothing to do if there are no relocations. */
620 if ((sec->flags & SEC_RELOC) == 0
621 || sec->reloc_count == 0)
622 return true;
624 /* If this is the first time we have been called for this section,
625 initialize the cooked size. */
626 if (sec->_cooked_size == 0)
627 sec->_cooked_size = sec->_raw_size;
629 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
631 /* Load the relocations for this section. */
632 internal_relocs = (_bfd_elfNN_link_read_relocs
633 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
634 link_info->keep_memory));
635 if (internal_relocs == NULL)
636 goto error_return;
638 if (! link_info->keep_memory)
639 free_relocs = internal_relocs;
641 ia64_info = elfNN_ia64_hash_table (link_info);
642 irelend = internal_relocs + sec->reloc_count;
644 for (irel = internal_relocs; irel < irelend; irel++)
645 if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
646 break;
648 /* No branch-type relocations. */
649 if (irel == irelend)
651 if (free_relocs != NULL)
652 free (free_relocs);
653 return true;
656 /* Get the section contents. */
657 if (elf_section_data (sec)->this_hdr.contents != NULL)
658 contents = elf_section_data (sec)->this_hdr.contents;
659 else
661 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
662 if (contents == NULL)
663 goto error_return;
664 free_contents = contents;
666 if (! bfd_get_section_contents (abfd, sec, contents,
667 (file_ptr) 0, sec->_raw_size))
668 goto error_return;
671 /* Read this BFD's symbols. */
672 if (symtab_hdr->contents != NULL)
673 extsyms = (ElfNN_External_Sym *) symtab_hdr->contents;
674 else
676 extsyms = (ElfNN_External_Sym *) bfd_malloc (symtab_hdr->sh_size);
677 if (extsyms == NULL)
678 goto error_return;
679 free_extsyms = extsyms;
680 if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
681 || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
682 != symtab_hdr->sh_size))
683 goto error_return;
686 for (; irel < irelend; irel++)
688 bfd_vma symaddr, reladdr, trampoff, toff, roff;
689 Elf_Internal_Sym isym;
690 asection *tsec;
691 struct one_fixup *f;
693 if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
694 continue;
696 /* Get the value of the symbol referred to by the reloc. */
697 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
699 /* A local symbol. */
700 bfd_elfNN_swap_symbol_in (abfd,
701 extsyms + ELFNN_R_SYM (irel->r_info),
702 &isym);
703 if (isym.st_shndx == SHN_UNDEF)
704 continue; /* We can't do anthing with undefined symbols. */
705 else if (isym.st_shndx == SHN_ABS)
706 tsec = bfd_abs_section_ptr;
707 else if (isym.st_shndx == SHN_COMMON)
708 tsec = bfd_com_section_ptr;
709 else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
710 tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
711 else
712 continue; /* who knows. */
714 toff = isym.st_value;
716 else
718 unsigned long indx;
719 struct elf_link_hash_entry *h;
720 struct elfNN_ia64_dyn_sym_info *dyn_i;
722 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
723 h = elf_sym_hashes (abfd)[indx];
724 BFD_ASSERT (h != NULL);
726 while (h->root.type == bfd_link_hash_indirect
727 || h->root.type == bfd_link_hash_warning)
728 h = (struct elf_link_hash_entry *) h->root.u.i.link;
730 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
732 /* For branches to dynamic symbols, we're interested instead
733 in a branch to the PLT entry. */
734 if (dyn_i && dyn_i->want_plt2)
736 tsec = ia64_info->plt_sec;
737 toff = dyn_i->plt2_offset;
739 else
741 /* We can't do anthing with undefined symbols. */
742 if (h->root.type == bfd_link_hash_undefined
743 || h->root.type == bfd_link_hash_undefweak)
744 continue;
746 tsec = h->root.u.def.section;
747 toff = h->root.u.def.value;
751 symaddr = (tsec->output_section->vma
752 + tsec->output_offset
753 + toff
754 + irel->r_addend);
756 roff = irel->r_offset;
757 reladdr = (sec->output_section->vma
758 + sec->output_offset
759 + roff) & -4;
761 /* If the branch is in range, no need to do anything. */
762 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
763 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
764 continue;
766 /* If the branch and target are in the same section, you've
767 got one honking big section and we can't help you. You'll
768 get an error message later. */
769 if (tsec == sec)
770 continue;
772 /* Look for an existing fixup to this address. */
773 for (f = fixups; f ; f = f->next)
774 if (f->tsec == tsec && f->toff == toff)
775 break;
777 if (f == NULL)
779 /* Two alternatives: If it's a branch to a PLT entry, we can
780 make a copy of the FULL_PLT entry. Otherwise, we'll have
781 to use a `brl' insn to get where we're going. */
783 int size;
785 if (tsec == ia64_info->plt_sec)
786 size = sizeof (plt_full_entry);
787 else
789 #ifdef USE_BRL
790 size = sizeof (oor_brl);
791 #else
792 size = sizeof (oor_ip);
793 #endif
796 /* Resize the current section to make room for the new branch. */
797 trampoff = (sec->_cooked_size + 15) & -16;
798 contents = (bfd_byte *) bfd_realloc (contents, trampoff + size);
799 if (contents == NULL)
800 goto error_return;
801 sec->_cooked_size = trampoff + size;
803 if (tsec == ia64_info->plt_sec)
805 memcpy (contents + trampoff, plt_full_entry, size);
807 /* Hijack the old relocation for use as the PLTOFF reloc. */
808 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
809 R_IA64_PLTOFF22);
810 irel->r_offset = trampoff;
812 else
814 #ifdef USE_BRL
815 memcpy (contents + trampoff, oor_brl, size);
816 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
817 R_IA64_PCREL60B);
818 irel->r_offset = trampoff + 2;
819 #else
820 memcpy (contents + trampoff, oor_ip, size);
821 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
822 R_IA64_PCREL64I);
823 irel->r_addend -= 16;
824 irel->r_offset = trampoff + 2;
825 #endif
828 /* Record the fixup so we don't do it again this section. */
829 f = (struct one_fixup *) bfd_malloc (sizeof (*f));
830 f->next = fixups;
831 f->tsec = tsec;
832 f->toff = toff;
833 f->trampoff = trampoff;
834 fixups = f;
836 else
838 /* Nop out the reloc, since we're finalizing things here. */
839 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
842 /* Fix up the existing branch to hit the trampoline. Hope like
843 hell this doesn't overflow too. */
844 if (elfNN_ia64_install_value (abfd, contents + roff,
845 f->trampoff - (roff & -4),
846 R_IA64_PCREL21B) != bfd_reloc_ok)
847 goto error_return;
849 changed_contents = true;
850 changed_relocs = true;
853 /* Clean up and go home. */
854 while (fixups)
856 struct one_fixup *f = fixups;
857 fixups = fixups->next;
858 free (f);
861 if (changed_relocs)
862 elf_section_data (sec)->relocs = internal_relocs;
863 else if (free_relocs != NULL)
864 free (free_relocs);
866 if (changed_contents)
867 elf_section_data (sec)->this_hdr.contents = contents;
868 else if (free_contents != NULL)
870 if (! link_info->keep_memory)
871 free (free_contents);
872 else
874 /* Cache the section contents for elf_link_input_bfd. */
875 elf_section_data (sec)->this_hdr.contents = contents;
879 if (free_extsyms != NULL)
881 if (! link_info->keep_memory)
882 free (free_extsyms);
883 else
885 /* Cache the symbols for elf_link_input_bfd. */
886 symtab_hdr->contents = extsyms;
890 *again = changed_contents || changed_relocs;
891 return true;
893 error_return:
894 if (free_relocs != NULL)
895 free (free_relocs);
896 if (free_contents != NULL)
897 free (free_contents);
898 if (free_extsyms != NULL)
899 free (free_extsyms);
900 return false;
903 /* Handle an IA-64 specific section when reading an object file. This
904 is called when elfcode.h finds a section with an unknown type. */
906 static boolean
907 elfNN_ia64_section_from_shdr (abfd, hdr, name)
908 bfd *abfd;
909 ElfNN_Internal_Shdr *hdr;
910 char *name;
912 asection *newsect;
914 /* There ought to be a place to keep ELF backend specific flags, but
915 at the moment there isn't one. We just keep track of the
916 sections by their name, instead. Fortunately, the ABI gives
917 suggested names for all the MIPS specific sections, so we will
918 probably get away with this. */
919 switch (hdr->sh_type)
921 case SHT_IA_64_UNWIND:
922 if (strcmp (name, ELF_STRING_ia64_unwind) != 0)
923 return false;
924 break;
926 case SHT_IA_64_EXT:
927 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
928 return false;
929 break;
931 default:
932 return false;
935 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
936 return false;
937 newsect = hdr->bfd_section;
939 return true;
942 /* Convert IA-64 specific section flags to bfd internal section flags. */
944 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
945 flag. */
947 static boolean
948 elfNN_ia64_section_flags (flags, hdr)
949 flagword *flags;
950 ElfNN_Internal_Shdr *hdr;
952 if (hdr->sh_flags & SHF_IA_64_SHORT)
953 *flags |= SEC_SMALL_DATA;
955 return true;
958 /* Set the correct type for an IA-64 ELF section. We do this by the
959 section name, which is a hack, but ought to work. */
961 static boolean
962 elfNN_ia64_fake_sections (abfd, hdr, sec)
963 bfd *abfd ATTRIBUTE_UNUSED;
964 ElfNN_Internal_Shdr *hdr;
965 asection *sec;
967 register const char *name;
969 name = bfd_get_section_name (abfd, sec);
971 if (strcmp (name, ELF_STRING_ia64_unwind) == 0)
972 hdr->sh_type = SHT_IA_64_UNWIND;
973 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
974 hdr->sh_type = SHT_IA_64_EXT;
975 else if (strcmp (name, ".reloc") == 0)
977 * This is an ugly, but unfortunately necessary hack that is
978 * needed when producing EFI binaries on IA-64. It tells
979 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
980 * containing ELF relocation info. We need this hack in order to
981 * be able to generate ELF binaries that can be translated into
982 * EFI applications (which are essentially COFF objects). Those
983 * files contain a COFF ".reloc" section inside an ELFNN object,
984 * which would normally cause BFD to segfault because it would
985 * attempt to interpret this section as containing relocation
986 * entries for section "oc". With this hack enabled, ".reloc"
987 * will be treated as a normal data section, which will avoid the
988 * segfault. However, you won't be able to create an ELFNN binary
989 * with a section named "oc" that needs relocations, but that's
990 * the kind of ugly side-effects you get when detecting section
991 * types based on their names... In practice, this limitation is
992 * unlikely to bite.
994 hdr->sh_type = SHT_PROGBITS;
996 if (sec->flags & SEC_SMALL_DATA)
997 hdr->sh_flags |= SHF_IA_64_SHORT;
999 return true;
1002 /* Hook called by the linker routine which adds symbols from an object
1003 file. We use it to put .comm items in .sbss, and not .bss. */
1005 static boolean
1006 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1007 bfd *abfd;
1008 struct bfd_link_info *info;
1009 const Elf_Internal_Sym *sym;
1010 const char **namep ATTRIBUTE_UNUSED;
1011 flagword *flagsp ATTRIBUTE_UNUSED;
1012 asection **secp;
1013 bfd_vma *valp;
1015 if (sym->st_shndx == SHN_COMMON
1016 && !info->relocateable
1017 && sym->st_size <= (unsigned) bfd_get_gp_size (abfd))
1019 /* Common symbols less than or equal to -G nn bytes are
1020 automatically put into .sbss. */
1022 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1024 if (scomm == NULL)
1026 scomm = bfd_make_section (abfd, ".scommon");
1027 if (scomm == NULL
1028 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1029 | SEC_IS_COMMON
1030 | SEC_LINKER_CREATED)))
1031 return false;
1034 *secp = scomm;
1035 *valp = sym->st_size;
1038 return true;
1041 /* Return the number of additional phdrs we will need. */
1043 static int
1044 elfNN_ia64_additional_program_headers (abfd)
1045 bfd *abfd;
1047 asection *s;
1048 int ret = 0;
1050 /* See if we need a PT_IA_64_ARCHEXT segment. */
1051 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1052 if (s && (s->flags & SEC_LOAD))
1053 ++ret;
1055 /* See if we need a PT_IA_64_UNWIND segment. */
1056 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
1057 if (s && (s->flags & SEC_LOAD))
1058 ++ret;
1060 return ret;
1063 static boolean
1064 elfNN_ia64_modify_segment_map (abfd)
1065 bfd *abfd;
1067 struct elf_segment_map *m, **pm;
1068 asection *s;
1070 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1071 all PT_LOAD segments. */
1072 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1073 if (s && (s->flags & SEC_LOAD))
1075 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1076 if (m->p_type == PT_IA_64_ARCHEXT)
1077 break;
1078 if (m == NULL)
1080 m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1081 if (m == NULL)
1082 return false;
1084 m->p_type = PT_IA_64_ARCHEXT;
1085 m->count = 1;
1086 m->sections[0] = s;
1088 /* We want to put it after the PHDR and INTERP segments. */
1089 pm = &elf_tdata (abfd)->segment_map;
1090 while (*pm != NULL
1091 && ((*pm)->p_type == PT_PHDR
1092 || (*pm)->p_type == PT_INTERP))
1093 pm = &(*pm)->next;
1095 m->next = *pm;
1096 *pm = m;
1100 /* Install the PT_IA_64_UNWIND segment, if needed. */
1101 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
1102 if (s && (s->flags & SEC_LOAD))
1104 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1105 if (m->p_type == PT_IA_64_UNWIND)
1106 break;
1107 if (m == NULL)
1109 m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1110 if (m == NULL)
1111 return false;
1113 m->p_type = PT_IA_64_UNWIND;
1114 m->count = 1;
1115 m->sections[0] = s;
1116 m->next = NULL;
1118 /* We want to put it last. */
1119 pm = &elf_tdata (abfd)->segment_map;
1120 while (*pm != NULL)
1121 pm = &(*pm)->next;
1122 *pm = m;
1126 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1127 the input sections for each output section in the segment and testing
1128 for SHF_IA_64_NORECOV on each. */
1129 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1130 if (m->p_type == PT_LOAD)
1132 int i;
1133 for (i = m->count - 1; i >= 0; --i)
1135 struct bfd_link_order *order = m->sections[i]->link_order_head;
1136 while (order)
1138 if (order->type == bfd_indirect_link_order)
1140 asection *is = order->u.indirect.section;
1141 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1142 if (flags & SHF_IA_64_NORECOV)
1144 m->p_flags |= PF_IA_64_NORECOV;
1145 goto found;
1148 order = order->next;
1151 found:;
1154 return true;
1157 /* According to the Tahoe assembler spec, all labels starting with a
1158 '.' are local. */
1160 static boolean
1161 elfNN_ia64_is_local_label_name (abfd, name)
1162 bfd *abfd ATTRIBUTE_UNUSED;
1163 const char *name;
1165 return name[0] == '.';
1168 /* Should we do dynamic things to this symbol? */
1170 static boolean
1171 elfNN_ia64_dynamic_symbol_p (h, info)
1172 struct elf_link_hash_entry *h;
1173 struct bfd_link_info *info;
1175 if (h == NULL)
1176 return false;
1178 while (h->root.type == bfd_link_hash_indirect
1179 || h->root.type == bfd_link_hash_warning)
1180 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1182 if (h->dynindx == -1)
1183 return false;
1184 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
1185 return false;
1187 if (h->root.type == bfd_link_hash_undefweak
1188 || h->root.type == bfd_link_hash_defweak)
1189 return true;
1191 if ((info->shared && !info->symbolic)
1192 || ((h->elf_link_hash_flags
1193 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1194 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1195 return true;
1197 return false;
1200 static boolean
1201 elfNN_ia64_local_hash_table_init (ht, abfd, new)
1202 struct elfNN_ia64_local_hash_table *ht;
1203 bfd *abfd ATTRIBUTE_UNUSED;
1204 new_hash_entry_func new;
1206 memset (ht, 0, sizeof (*ht));
1207 return bfd_hash_table_init (&ht->root, new);
1210 static struct bfd_hash_entry*
1211 elfNN_ia64_new_loc_hash_entry (entry, table, string)
1212 struct bfd_hash_entry *entry;
1213 struct bfd_hash_table *table;
1214 const char *string;
1216 struct elfNN_ia64_local_hash_entry *ret;
1217 ret = (struct elfNN_ia64_local_hash_entry *) entry;
1219 /* Allocate the structure if it has not already been allocated by a
1220 subclass. */
1221 if (!ret)
1222 ret = bfd_hash_allocate (table, sizeof (*ret));
1224 if (!ret)
1225 return 0;
1227 /* Initialize our local data. All zeros, and definitely easier
1228 than setting a handful of bit fields. */
1229 memset (ret, 0, sizeof (*ret));
1231 /* Call the allocation method of the superclass. */
1232 ret = ((struct elfNN_ia64_local_hash_entry *)
1233 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1235 return (struct bfd_hash_entry *) ret;
1238 static struct bfd_hash_entry*
1239 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1240 struct bfd_hash_entry *entry;
1241 struct bfd_hash_table *table;
1242 const char *string;
1244 struct elfNN_ia64_link_hash_entry *ret;
1245 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1247 /* Allocate the structure if it has not already been allocated by a
1248 subclass. */
1249 if (!ret)
1250 ret = bfd_hash_allocate (table, sizeof (*ret));
1252 if (!ret)
1253 return 0;
1255 /* Initialize our local data. All zeros, and definitely easier
1256 than setting a handful of bit fields. */
1257 memset (ret, 0, sizeof (*ret));
1259 /* Call the allocation method of the superclass. */
1260 ret = ((struct elfNN_ia64_link_hash_entry *)
1261 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1262 table, string));
1264 return (struct bfd_hash_entry *) ret;
1267 static void
1268 elfNN_ia64_hash_copy_indirect (xdir, xind)
1269 struct elf_link_hash_entry *xdir, *xind;
1271 struct elfNN_ia64_link_hash_entry *dir, *ind;
1273 dir = (struct elfNN_ia64_link_hash_entry *)xdir;
1274 ind = (struct elfNN_ia64_link_hash_entry *)xind;
1276 /* Copy down any references that we may have already seen to the
1277 symbol which just became indirect. */
1279 dir->root.elf_link_hash_flags |=
1280 (ind->root.elf_link_hash_flags
1281 & (ELF_LINK_HASH_REF_DYNAMIC
1282 | ELF_LINK_HASH_REF_REGULAR
1283 | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1285 /* Copy over the got and plt data. This would have been done
1286 by check_relocs. */
1288 if (dir->info == NULL)
1290 struct elfNN_ia64_dyn_sym_info *dyn_i;
1292 dir->info = dyn_i = ind->info;
1293 ind->info = NULL;
1295 /* Fix up the dyn_sym_info pointers to the global symbol. */
1296 for (; dyn_i; dyn_i = dyn_i->next)
1297 dyn_i->h = &dir->root;
1299 BFD_ASSERT (ind->info == NULL);
1301 /* Copy over the dynindx. */
1303 if (dir->root.dynindx == -1)
1305 dir->root.dynindx = ind->root.dynindx;
1306 dir->root.dynstr_index = ind->root.dynstr_index;
1307 ind->root.dynindx = -1;
1308 ind->root.dynstr_index = 0;
1310 BFD_ASSERT (ind->root.dynindx == -1);
1313 static void
1314 elfNN_ia64_hash_hide_symbol (info, xh)
1315 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1316 struct elf_link_hash_entry *xh;
1318 struct elfNN_ia64_link_hash_entry *h;
1319 struct elfNN_ia64_dyn_sym_info *dyn_i;
1321 h = (struct elfNN_ia64_link_hash_entry *)xh;
1323 h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
1324 h->root.dynindx = -1;
1326 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1327 dyn_i->want_plt2 = 0;
1330 /* Create the derived linker hash table. The IA-64 ELF port uses this
1331 derived hash table to keep information specific to the IA-64 ElF
1332 linker (without using static variables). */
1334 static struct bfd_link_hash_table*
1335 elfNN_ia64_hash_table_create (abfd)
1336 bfd *abfd;
1338 struct elfNN_ia64_link_hash_table *ret;
1340 ret = bfd_alloc (abfd, sizeof (*ret));
1341 if (!ret)
1342 return 0;
1343 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1344 elfNN_ia64_new_elf_hash_entry))
1346 bfd_release (abfd, ret);
1347 return 0;
1350 if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1351 elfNN_ia64_new_loc_hash_entry))
1352 return 0;
1353 return &ret->root.root;
1356 /* Look up an entry in a Alpha ELF linker hash table. */
1358 static INLINE struct elfNN_ia64_local_hash_entry *
1359 elfNN_ia64_local_hash_lookup(table, string, create, copy)
1360 struct elfNN_ia64_local_hash_table *table;
1361 const char *string;
1362 boolean create, copy;
1364 return ((struct elfNN_ia64_local_hash_entry *)
1365 bfd_hash_lookup (&table->root, string, create, copy));
1368 /* Traverse both local and global hash tables. */
1370 struct elfNN_ia64_dyn_sym_traverse_data
1372 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1373 PTR data;
1376 static boolean
1377 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1378 struct bfd_hash_entry *xentry;
1379 PTR xdata;
1381 struct elfNN_ia64_link_hash_entry *entry
1382 = (struct elfNN_ia64_link_hash_entry *) xentry;
1383 struct elfNN_ia64_dyn_sym_traverse_data *data
1384 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1385 struct elfNN_ia64_dyn_sym_info *dyn_i;
1387 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1388 if (! (*data->func) (dyn_i, data->data))
1389 return false;
1390 return true;
1393 static boolean
1394 elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1395 struct bfd_hash_entry *xentry;
1396 PTR xdata;
1398 struct elfNN_ia64_local_hash_entry *entry
1399 = (struct elfNN_ia64_local_hash_entry *) xentry;
1400 struct elfNN_ia64_dyn_sym_traverse_data *data
1401 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1402 struct elfNN_ia64_dyn_sym_info *dyn_i;
1404 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1405 if (! (*data->func) (dyn_i, data->data))
1406 return false;
1407 return true;
1410 static void
1411 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1412 struct elfNN_ia64_link_hash_table *ia64_info;
1413 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1414 PTR data;
1416 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1418 xdata.func = func;
1419 xdata.data = data;
1421 elf_link_hash_traverse (&ia64_info->root,
1422 elfNN_ia64_global_dyn_sym_thunk, &xdata);
1423 bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1424 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1427 static boolean
1428 elfNN_ia64_create_dynamic_sections (abfd, info)
1429 bfd *abfd;
1430 struct bfd_link_info *info;
1432 struct elfNN_ia64_link_hash_table *ia64_info;
1433 asection *s;
1435 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1436 return false;
1438 ia64_info = elfNN_ia64_hash_table (info);
1440 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1441 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1444 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1445 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1448 if (!get_pltoff (abfd, info, ia64_info))
1449 return false;
1451 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1452 if (s == NULL
1453 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1454 | SEC_HAS_CONTENTS
1455 | SEC_IN_MEMORY
1456 | SEC_LINKER_CREATED
1457 | SEC_READONLY))
1458 || !bfd_set_section_alignment (abfd, s, 3))
1459 return false;
1460 ia64_info->rel_pltoff_sec = s;
1462 s = bfd_make_section(abfd, ".rela.got");
1463 if (s == NULL
1464 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1465 | SEC_HAS_CONTENTS
1466 | SEC_IN_MEMORY
1467 | SEC_LINKER_CREATED
1468 | SEC_READONLY))
1469 || !bfd_set_section_alignment (abfd, s, 3))
1470 return false;
1471 ia64_info->rel_got_sec = s;
1473 return true;
1476 /* Find and/or create a descriptor for dynamic symbol info. This will
1477 vary based on global or local symbol, and the addend to the reloc. */
1479 static struct elfNN_ia64_dyn_sym_info *
1480 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1481 struct elfNN_ia64_link_hash_table *ia64_info;
1482 struct elf_link_hash_entry *h;
1483 bfd *abfd;
1484 const Elf_Internal_Rela *rel;
1485 boolean create;
1487 struct elfNN_ia64_dyn_sym_info **pp;
1488 struct elfNN_ia64_dyn_sym_info *dyn_i;
1489 bfd_vma addend = rel ? rel->r_addend : 0;
1491 if (h)
1492 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1493 else
1495 struct elfNN_ia64_local_hash_entry *loc_h;
1496 char *addr_name;
1497 size_t len;
1499 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1500 The name describes what was once anonymous memory. */
1502 len = sizeof (void*)*2 + 1 + sizeof (bfd_vma)*4 + 1 + 1;
1503 len += 10; /* %p slop */
1505 addr_name = alloca (len);
1506 sprintf (addr_name, "%p:%lx", (void *) abfd, ELFNN_R_SYM (rel->r_info));
1508 /* Collect the canonical entry data for this address. */
1509 loc_h = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1510 addr_name, create, create);
1511 BFD_ASSERT (loc_h);
1513 pp = &loc_h->info;
1516 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1517 pp = &dyn_i->next;
1519 if (dyn_i == NULL && create)
1521 dyn_i = (struct elfNN_ia64_dyn_sym_info *)
1522 bfd_zalloc (abfd, sizeof *dyn_i);
1523 *pp = dyn_i;
1524 dyn_i->addend = addend;
1527 return dyn_i;
1530 static asection *
1531 get_got (abfd, info, ia64_info)
1532 bfd *abfd;
1533 struct bfd_link_info *info;
1534 struct elfNN_ia64_link_hash_table *ia64_info;
1536 asection *got;
1537 bfd *dynobj;
1539 got = ia64_info->got_sec;
1540 if (!got)
1542 flagword flags;
1544 dynobj = ia64_info->root.dynobj;
1545 if (!dynobj)
1546 ia64_info->root.dynobj = dynobj = abfd;
1547 if (!_bfd_elf_create_got_section (dynobj, info))
1548 return 0;
1550 got = bfd_get_section_by_name (dynobj, ".got");
1551 BFD_ASSERT (got);
1552 ia64_info->got_sec = got;
1554 flags = bfd_get_section_flags (abfd, got);
1555 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1558 return got;
1561 /* Create function descriptor section (.opd). This section is called .opd
1562 because it contains "official prodecure descriptors". The "official"
1563 refers to the fact that these descriptors are used when taking the address
1564 of a procedure, thus ensuring a unique address for each procedure. */
1566 static asection *
1567 get_fptr (abfd, info, ia64_info)
1568 bfd *abfd;
1569 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1570 struct elfNN_ia64_link_hash_table *ia64_info;
1572 asection *fptr;
1573 bfd *dynobj;
1575 fptr = ia64_info->fptr_sec;
1576 if (!fptr)
1578 dynobj = ia64_info->root.dynobj;
1579 if (!dynobj)
1580 ia64_info->root.dynobj = dynobj = abfd;
1582 fptr = bfd_make_section (dynobj, ".opd");
1583 if (!fptr
1584 || !bfd_set_section_flags (dynobj, fptr,
1585 (SEC_ALLOC
1586 | SEC_LOAD
1587 | SEC_HAS_CONTENTS
1588 | SEC_IN_MEMORY
1589 | SEC_READONLY
1590 | SEC_LINKER_CREATED))
1591 || !bfd_set_section_alignment (abfd, fptr, 4))
1593 BFD_ASSERT (0);
1594 return NULL;
1597 ia64_info->fptr_sec = fptr;
1600 return fptr;
1603 static asection *
1604 get_pltoff (abfd, info, ia64_info)
1605 bfd *abfd;
1606 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1607 struct elfNN_ia64_link_hash_table *ia64_info;
1609 asection *pltoff;
1610 bfd *dynobj;
1612 pltoff = ia64_info->pltoff_sec;
1613 if (!pltoff)
1615 dynobj = ia64_info->root.dynobj;
1616 if (!dynobj)
1617 ia64_info->root.dynobj = dynobj = abfd;
1619 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
1620 if (!pltoff
1621 || !bfd_set_section_flags (dynobj, pltoff,
1622 (SEC_ALLOC
1623 | SEC_LOAD
1624 | SEC_HAS_CONTENTS
1625 | SEC_IN_MEMORY
1626 | SEC_SMALL_DATA
1627 | SEC_LINKER_CREATED))
1628 || !bfd_set_section_alignment (abfd, pltoff, 4))
1630 BFD_ASSERT (0);
1631 return NULL;
1634 ia64_info->pltoff_sec = pltoff;
1637 return pltoff;
1640 static asection *
1641 get_reloc_section (abfd, ia64_info, sec, create)
1642 bfd *abfd;
1643 struct elfNN_ia64_link_hash_table *ia64_info;
1644 asection *sec;
1645 boolean create;
1647 const char *srel_name;
1648 asection *srel;
1649 bfd *dynobj;
1651 srel_name = (bfd_elf_string_from_elf_section
1652 (abfd, elf_elfheader(abfd)->e_shstrndx,
1653 elf_section_data(sec)->rel_hdr.sh_name));
1654 if (srel_name == NULL)
1655 return NULL;
1657 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
1658 && strcmp (bfd_get_section_name (abfd, sec),
1659 srel_name+5) == 0)
1660 || (strncmp (srel_name, ".rel", 4) == 0
1661 && strcmp (bfd_get_section_name (abfd, sec),
1662 srel_name+4) == 0));
1664 dynobj = ia64_info->root.dynobj;
1665 if (!dynobj)
1666 ia64_info->root.dynobj = dynobj = abfd;
1668 srel = bfd_get_section_by_name (dynobj, srel_name);
1669 if (srel == NULL && create)
1671 srel = bfd_make_section (dynobj, srel_name);
1672 if (srel == NULL
1673 || !bfd_set_section_flags (dynobj, srel,
1674 (SEC_ALLOC
1675 | SEC_LOAD
1676 | SEC_HAS_CONTENTS
1677 | SEC_IN_MEMORY
1678 | SEC_LINKER_CREATED
1679 | SEC_READONLY))
1680 || !bfd_set_section_alignment (dynobj, srel, 3))
1681 return NULL;
1684 return srel;
1687 static boolean
1688 count_dyn_reloc (abfd, dyn_i, srel, type)
1689 bfd *abfd;
1690 struct elfNN_ia64_dyn_sym_info *dyn_i;
1691 asection *srel;
1692 int type;
1694 struct elfNN_ia64_dyn_reloc_entry *rent;
1696 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
1697 if (rent->srel == srel && rent->type == type)
1698 break;
1700 if (!rent)
1702 rent = (struct elfNN_ia64_dyn_reloc_entry *)
1703 bfd_alloc (abfd, sizeof (*rent));
1704 if (!rent)
1705 return false;
1707 rent->next = dyn_i->reloc_entries;
1708 rent->srel = srel;
1709 rent->type = type;
1710 rent->count = 0;
1711 dyn_i->reloc_entries = rent;
1713 rent->count++;
1715 return true;
1718 static boolean
1719 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
1720 bfd *abfd;
1721 struct bfd_link_info *info;
1722 asection *sec;
1723 const Elf_Internal_Rela *relocs;
1725 struct elfNN_ia64_link_hash_table *ia64_info;
1726 const Elf_Internal_Rela *relend;
1727 Elf_Internal_Shdr *symtab_hdr;
1728 const Elf_Internal_Rela *rel;
1729 asection *got, *fptr, *srel;
1731 if (info->relocateable)
1732 return true;
1734 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1735 ia64_info = elfNN_ia64_hash_table (info);
1737 got = fptr = srel = NULL;
1739 relend = relocs + sec->reloc_count;
1740 for (rel = relocs; rel < relend; ++rel)
1742 enum {
1743 NEED_GOT = 1,
1744 NEED_FPTR = 2,
1745 NEED_PLTOFF = 4,
1746 NEED_MIN_PLT = 8,
1747 NEED_FULL_PLT = 16,
1748 NEED_DYNREL = 32,
1749 NEED_LTOFF_FPTR = 64,
1752 struct elf_link_hash_entry *h = NULL;
1753 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
1754 struct elfNN_ia64_dyn_sym_info *dyn_i;
1755 int need_entry;
1756 boolean maybe_dynamic;
1757 int dynrel_type = R_IA64_NONE;
1759 if (r_symndx >= symtab_hdr->sh_info)
1761 /* We're dealing with a global symbol -- find its hash entry
1762 and mark it as being referenced. */
1763 long indx = r_symndx - symtab_hdr->sh_info;
1764 h = elf_sym_hashes (abfd)[indx];
1765 while (h->root.type == bfd_link_hash_indirect
1766 || h->root.type == bfd_link_hash_warning)
1767 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1769 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
1772 /* We can only get preliminary data on whether a symbol is
1773 locally or externally defined, as not all of the input files
1774 have yet been processed. Do something with what we know, as
1775 this may help reduce memory usage and processing time later. */
1776 maybe_dynamic = false;
1777 if (h && ((info->shared && ! info->symbolic)
1778 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
1779 || h->root.type == bfd_link_hash_defweak))
1780 maybe_dynamic = true;
1782 need_entry = 0;
1783 switch (ELFNN_R_TYPE (rel->r_info))
1785 case R_IA64_TPREL22:
1786 case R_IA64_TPREL64MSB:
1787 case R_IA64_TPREL64LSB:
1788 case R_IA64_LTOFF_TP22:
1789 return false;
1791 case R_IA64_LTOFF_FPTR22:
1792 case R_IA64_LTOFF_FPTR64I:
1793 case R_IA64_LTOFF_FPTR64MSB:
1794 case R_IA64_LTOFF_FPTR64LSB:
1795 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
1796 break;
1798 case R_IA64_FPTR64I:
1799 case R_IA64_FPTR32MSB:
1800 case R_IA64_FPTR32LSB:
1801 case R_IA64_FPTR64MSB:
1802 case R_IA64_FPTR64LSB:
1803 if (info->shared || h)
1804 need_entry = NEED_FPTR | NEED_DYNREL;
1805 else
1806 need_entry = NEED_FPTR;
1807 dynrel_type = R_IA64_FPTR64LSB;
1808 break;
1810 case R_IA64_LTOFF22:
1811 case R_IA64_LTOFF22X:
1812 case R_IA64_LTOFF64I:
1813 need_entry = NEED_GOT;
1814 break;
1816 case R_IA64_PLTOFF22:
1817 case R_IA64_PLTOFF64I:
1818 case R_IA64_PLTOFF64MSB:
1819 case R_IA64_PLTOFF64LSB:
1820 need_entry = NEED_PLTOFF;
1821 if (h)
1823 if (maybe_dynamic)
1824 need_entry |= NEED_MIN_PLT;
1826 else
1828 (*info->callbacks->warning)
1829 (info, _("@pltoff reloc against local symbol"), 0,
1830 abfd, 0, 0);
1832 break;
1834 case R_IA64_PCREL21B:
1835 case R_IA64_PCREL60B:
1836 /* Depending on where this symbol is defined, we may or may not
1837 need a full plt entry. Only skip if we know we'll not need
1838 the entry -- static or symbolic, and the symbol definition
1839 has already been seen. */
1840 if (maybe_dynamic && rel->r_addend == 0)
1841 need_entry = NEED_FULL_PLT;
1842 break;
1844 case R_IA64_IMM14:
1845 case R_IA64_IMM22:
1846 case R_IA64_IMM64:
1847 case R_IA64_DIR32MSB:
1848 case R_IA64_DIR32LSB:
1849 case R_IA64_DIR64MSB:
1850 case R_IA64_DIR64LSB:
1851 /* Shared objects will always need at least a REL relocation. */
1852 if (info->shared || maybe_dynamic)
1853 need_entry = NEED_DYNREL;
1854 dynrel_type = R_IA64_DIR64LSB;
1855 break;
1857 case R_IA64_IPLTMSB:
1858 case R_IA64_IPLTLSB:
1859 /* Shared objects will always need at least a REL relocation. */
1860 if (info->shared || maybe_dynamic)
1861 need_entry = NEED_DYNREL;
1862 dynrel_type = R_IA64_IPLTLSB;
1863 break;
1865 case R_IA64_PCREL22:
1866 case R_IA64_PCREL64I:
1867 case R_IA64_PCREL32MSB:
1868 case R_IA64_PCREL32LSB:
1869 case R_IA64_PCREL64MSB:
1870 case R_IA64_PCREL64LSB:
1871 if (maybe_dynamic)
1872 need_entry = NEED_DYNREL;
1873 dynrel_type = R_IA64_PCREL64LSB;
1874 break;
1877 if (!need_entry)
1878 continue;
1880 if ((need_entry & NEED_FPTR) != 0
1881 && rel->r_addend)
1883 (*info->callbacks->warning)
1884 (info, _("non-zero addend in @fptr reloc"), 0,
1885 abfd, 0, 0);
1888 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
1890 /* Record whether or not this is a local symbol. */
1891 dyn_i->h = h;
1893 /* Create what's needed. */
1894 if (need_entry & NEED_GOT)
1896 if (!got)
1898 got = get_got (abfd, info, ia64_info);
1899 if (!got)
1900 return false;
1902 dyn_i->want_got = 1;
1904 if (need_entry & NEED_FPTR)
1906 if (!fptr)
1908 fptr = get_fptr (abfd, info, ia64_info);
1909 if (!fptr)
1910 return false;
1913 /* FPTRs for shared libraries are allocated by the dynamic
1914 linker. Make sure this local symbol will appear in the
1915 dynamic symbol table. */
1916 if (!h && info->shared)
1918 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
1919 (info, abfd, r_symndx)))
1920 return false;
1923 dyn_i->want_fptr = 1;
1925 if (need_entry & NEED_LTOFF_FPTR)
1926 dyn_i->want_ltoff_fptr = 1;
1927 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
1929 if (!ia64_info->root.dynobj)
1930 ia64_info->root.dynobj = abfd;
1931 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
1932 dyn_i->want_plt = 1;
1934 if (need_entry & NEED_FULL_PLT)
1935 dyn_i->want_plt2 = 1;
1936 if (need_entry & NEED_PLTOFF)
1937 dyn_i->want_pltoff = 1;
1938 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
1940 if (!srel)
1942 srel = get_reloc_section (abfd, ia64_info, sec, true);
1943 if (!srel)
1944 return false;
1946 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
1947 return false;
1951 return true;
1954 struct elfNN_ia64_allocate_data
1956 struct bfd_link_info *info;
1957 bfd_size_type ofs;
1960 /* For cleanliness, and potentially faster dynamic loading, allocate
1961 external GOT entries first. */
1963 static boolean
1964 allocate_global_data_got (dyn_i, data)
1965 struct elfNN_ia64_dyn_sym_info *dyn_i;
1966 PTR data;
1968 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
1970 if (dyn_i->want_got
1971 && ! dyn_i->want_fptr
1972 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
1974 dyn_i->got_offset = x->ofs;
1975 x->ofs += 8;
1977 return true;
1980 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
1982 static boolean
1983 allocate_global_fptr_got (dyn_i, data)
1984 struct elfNN_ia64_dyn_sym_info *dyn_i;
1985 PTR data;
1987 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
1989 if (dyn_i->want_got
1990 && dyn_i->want_fptr
1991 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
1993 dyn_i->got_offset = x->ofs;
1994 x->ofs += 8;
1996 return true;
1999 /* Lastly, allocate all the GOT entries for local data. */
2001 static boolean
2002 allocate_local_got (dyn_i, data)
2003 struct elfNN_ia64_dyn_sym_info *dyn_i;
2004 PTR data;
2006 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2008 if (dyn_i->want_got
2009 && ! elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
2011 dyn_i->got_offset = x->ofs;
2012 x->ofs += 8;
2014 return true;
2017 /* Search for the index of a global symbol in it's defining object file. */
2019 static unsigned long
2020 global_sym_index (h)
2021 struct elf_link_hash_entry *h;
2023 struct elf_link_hash_entry **p;
2024 bfd *obj;
2026 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2027 || h->root.type == bfd_link_hash_defweak);
2029 obj = h->root.u.def.section->owner;
2030 for (p = elf_sym_hashes (obj); *p != h; ++p)
2031 continue;
2033 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2036 /* Allocate function descriptors. We can do these for every function
2037 in a main executable that is not exported. */
2039 static boolean
2040 allocate_fptr (dyn_i, data)
2041 struct elfNN_ia64_dyn_sym_info *dyn_i;
2042 PTR data;
2044 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2046 if (dyn_i->want_fptr)
2048 struct elf_link_hash_entry *h = dyn_i->h;
2050 if (h)
2051 while (h->root.type == bfd_link_hash_indirect
2052 || h->root.type == bfd_link_hash_warning)
2053 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2055 if (x->info->shared)
2057 if (h && h->dynindx == -1)
2059 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2060 || (h->root.type == bfd_link_hash_defweak));
2062 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2063 (x->info, h->root.u.def.section->owner,
2064 global_sym_index (h)))
2065 return false;
2068 dyn_i->want_fptr = 0;
2070 else if (h == NULL || h->dynindx == -1)
2072 dyn_i->fptr_offset = x->ofs;
2073 x->ofs += 16;
2075 else
2076 dyn_i->want_fptr = 0;
2078 return true;
2081 /* Allocate all the minimal PLT entries. */
2083 static boolean
2084 allocate_plt_entries (dyn_i, data)
2085 struct elfNN_ia64_dyn_sym_info *dyn_i;
2086 PTR data;
2088 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2090 if (dyn_i->want_plt)
2092 struct elf_link_hash_entry *h = dyn_i->h;
2094 if (h)
2095 while (h->root.type == bfd_link_hash_indirect
2096 || h->root.type == bfd_link_hash_warning)
2097 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2099 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2100 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2102 bfd_size_type offset = x->ofs;
2103 if (offset == 0)
2104 offset = PLT_HEADER_SIZE;
2105 dyn_i->plt_offset = offset;
2106 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2108 dyn_i->want_pltoff = 1;
2110 else
2112 dyn_i->want_plt = 0;
2113 dyn_i->want_plt2 = 0;
2116 return true;
2119 /* Allocate all the full PLT entries. */
2121 static boolean
2122 allocate_plt2_entries (dyn_i, data)
2123 struct elfNN_ia64_dyn_sym_info *dyn_i;
2124 PTR data;
2126 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2128 if (dyn_i->want_plt2)
2130 struct elf_link_hash_entry *h = dyn_i->h;
2131 bfd_size_type ofs = x->ofs;
2133 dyn_i->plt2_offset = ofs;
2134 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2136 while (h->root.type == bfd_link_hash_indirect
2137 || h->root.type == bfd_link_hash_warning)
2138 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2139 dyn_i->h->plt.offset = ofs;
2141 return true;
2144 /* Allocate all the PLTOFF entries requested by relocations and
2145 plt entries. We can't share space with allocated FPTR entries,
2146 because the latter are not necessarily addressable by the GP.
2147 ??? Relaxation might be able to determine that they are. */
2149 static boolean
2150 allocate_pltoff_entries (dyn_i, data)
2151 struct elfNN_ia64_dyn_sym_info *dyn_i;
2152 PTR data;
2154 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2156 if (dyn_i->want_pltoff)
2158 dyn_i->pltoff_offset = x->ofs;
2159 x->ofs += 16;
2161 return true;
2164 /* Allocate dynamic relocations for those symbols that turned out
2165 to be dynamic. */
2167 static boolean
2168 allocate_dynrel_entries (dyn_i, data)
2169 struct elfNN_ia64_dyn_sym_info *dyn_i;
2170 PTR data;
2172 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2173 struct elfNN_ia64_link_hash_table *ia64_info;
2174 struct elfNN_ia64_dyn_reloc_entry *rent;
2175 boolean dynamic_symbol, shared;
2177 ia64_info = elfNN_ia64_hash_table (x->info);
2178 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info);
2179 shared = x->info->shared;
2181 /* Take care of the normal data relocations. */
2183 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2185 int count = rent->count;
2187 switch (rent->type)
2189 case R_IA64_FPTR64LSB:
2190 /* Allocate one iff !want_fptr, which by this point will
2191 be true only if we're actually allocating one statically
2192 in the main executable. */
2193 if (dyn_i->want_fptr)
2194 continue;
2195 break;
2196 case R_IA64_PCREL64LSB:
2197 if (!dynamic_symbol)
2198 continue;
2199 break;
2200 case R_IA64_DIR64LSB:
2201 if (!dynamic_symbol && !shared)
2202 continue;
2203 break;
2204 case R_IA64_IPLTLSB:
2205 if (!dynamic_symbol && !shared)
2206 continue;
2207 /* Use two REL relocations for IPLT relocations
2208 against local symbols. */
2209 if (!dynamic_symbol)
2210 count *= 2;
2211 break;
2212 default:
2213 abort ();
2215 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2218 /* Take care of the GOT and PLT relocations. */
2220 if (((dynamic_symbol || shared) && dyn_i->want_got)
2221 || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2222 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2224 if (dyn_i->want_pltoff)
2226 bfd_size_type t = 0;
2228 /* Dynamic symbols get one IPLT relocation. Local symbols in
2229 shared libraries get two REL relocations. Local symbols in
2230 main applications get nothing. */
2231 if (dynamic_symbol)
2232 t = sizeof (ElfNN_External_Rela);
2233 else if (shared)
2234 t = 2 * sizeof (ElfNN_External_Rela);
2236 ia64_info->rel_pltoff_sec->_raw_size += t;
2239 return true;
2242 static boolean
2243 elfNN_ia64_adjust_dynamic_symbol (info, h)
2244 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2245 struct elf_link_hash_entry *h;
2247 /* ??? Undefined symbols with PLT entries should be re-defined
2248 to be the PLT entry. */
2250 /* If this is a weak symbol, and there is a real definition, the
2251 processor independent code will have arranged for us to see the
2252 real definition first, and we can just use the same value. */
2253 if (h->weakdef != NULL)
2255 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2256 || h->weakdef->root.type == bfd_link_hash_defweak);
2257 h->root.u.def.section = h->weakdef->root.u.def.section;
2258 h->root.u.def.value = h->weakdef->root.u.def.value;
2259 return true;
2262 /* If this is a reference to a symbol defined by a dynamic object which
2263 is not a function, we might allocate the symbol in our .dynbss section
2264 and allocate a COPY dynamic relocation.
2266 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2267 of hackery. */
2269 return true;
2272 static boolean
2273 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2274 bfd *output_bfd;
2275 struct bfd_link_info *info;
2277 struct elfNN_ia64_allocate_data data;
2278 struct elfNN_ia64_link_hash_table *ia64_info;
2279 asection *sec;
2280 bfd *dynobj;
2281 boolean reltext = false;
2282 boolean relplt = false;
2284 dynobj = elf_hash_table(info)->dynobj;
2285 ia64_info = elfNN_ia64_hash_table (info);
2286 BFD_ASSERT(dynobj != NULL);
2287 data.info = info;
2289 /* Set the contents of the .interp section to the interpreter. */
2290 if (ia64_info->root.dynamic_sections_created
2291 && !info->shared)
2293 sec = bfd_get_section_by_name (dynobj, ".interp");
2294 BFD_ASSERT (sec != NULL);
2295 sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
2296 sec->_raw_size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
2299 /* Allocate the GOT entries. */
2301 if (ia64_info->got_sec)
2303 data.ofs = 0;
2304 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2305 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2306 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2307 ia64_info->got_sec->_raw_size = data.ofs;
2310 /* Allocate the FPTR entries. */
2312 if (ia64_info->fptr_sec)
2314 data.ofs = 0;
2315 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2316 ia64_info->fptr_sec->_raw_size = data.ofs;
2319 /* Now that we've seen all of the input files, we can decide which
2320 symbols need plt entries. Allocate the minimal PLT entries first.
2321 We do this even though dynamic_sections_created may be false, because
2322 this has the side-effect of clearing want_plt and want_plt2. */
2324 data.ofs = 0;
2325 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2327 ia64_info->minplt_entries = 0;
2328 if (data.ofs)
2330 ia64_info->minplt_entries
2331 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2334 /* Align the pointer for the plt2 entries. */
2335 data.ofs = (data.ofs + 31) & -32;
2337 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2338 if (data.ofs != 0)
2340 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2342 ia64_info->plt_sec->_raw_size = data.ofs;
2344 /* If we've got a .plt, we need some extra memory for the dynamic
2345 linker. We stuff these in .got.plt. */
2346 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2347 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2350 /* Allocate the PLTOFF entries. */
2352 if (ia64_info->pltoff_sec)
2354 data.ofs = 0;
2355 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2356 ia64_info->pltoff_sec->_raw_size = data.ofs;
2359 if (ia64_info->root.dynamic_sections_created)
2361 /* Allocate space for the dynamic relocations that turned out to be
2362 required. */
2364 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2367 /* We have now determined the sizes of the various dynamic sections.
2368 Allocate memory for them. */
2369 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2371 boolean strip;
2373 if (!(sec->flags & SEC_LINKER_CREATED))
2374 continue;
2376 /* If we don't need this section, strip it from the output file.
2377 There were several sections primarily related to dynamic
2378 linking that must be create before the linker maps input
2379 sections to output sections. The linker does that before
2380 bfd_elf_size_dynamic_sections is called, and it is that
2381 function which decides whether anything needs to go into
2382 these sections. */
2384 strip = (sec->_raw_size == 0);
2386 if (sec == ia64_info->got_sec)
2387 strip = false;
2388 else if (sec == ia64_info->rel_got_sec)
2390 if (strip)
2391 ia64_info->rel_got_sec = NULL;
2392 else
2393 /* We use the reloc_count field as a counter if we need to
2394 copy relocs into the output file. */
2395 sec->reloc_count = 0;
2397 else if (sec == ia64_info->fptr_sec)
2399 if (strip)
2400 ia64_info->fptr_sec = NULL;
2402 else if (sec == ia64_info->plt_sec)
2404 if (strip)
2405 ia64_info->plt_sec = NULL;
2407 else if (sec == ia64_info->pltoff_sec)
2409 if (strip)
2410 ia64_info->pltoff_sec = NULL;
2412 else if (sec == ia64_info->rel_pltoff_sec)
2414 if (strip)
2415 ia64_info->rel_pltoff_sec = NULL;
2416 else
2418 relplt = true;
2419 /* We use the reloc_count field as a counter if we need to
2420 copy relocs into the output file. */
2421 sec->reloc_count = 0;
2424 else
2426 const char *name;
2428 /* It's OK to base decisions on the section name, because none
2429 of the dynobj section names depend upon the input files. */
2430 name = bfd_get_section_name (dynobj, sec);
2432 if (strcmp (name, ".got.plt") == 0)
2433 strip = false;
2434 else if (strncmp (name, ".rel", 4) == 0)
2436 if (!strip)
2438 const char *outname;
2439 asection *target;
2441 /* If this relocation section applies to a read only
2442 section, then we probably need a DT_TEXTREL entry. */
2443 outname = bfd_get_section_name (output_bfd,
2444 sec->output_section);
2445 if (outname[4] == 'a')
2446 outname += 5;
2447 else
2448 outname += 4;
2450 target = bfd_get_section_by_name (output_bfd, outname);
2451 if (target != NULL
2452 && (target->flags & SEC_READONLY) != 0
2453 && (target->flags & SEC_ALLOC) != 0)
2454 reltext = true;
2456 /* We use the reloc_count field as a counter if we need to
2457 copy relocs into the output file. */
2458 sec->reloc_count = 0;
2461 else
2462 continue;
2465 if (strip)
2466 _bfd_strip_section_from_output (info, sec);
2467 else
2469 /* Allocate memory for the section contents. */
2470 sec->contents = (bfd_byte *) bfd_zalloc(dynobj, sec->_raw_size);
2471 if (sec->contents == NULL && sec->_raw_size != 0)
2472 return false;
2476 if (elf_hash_table (info)->dynamic_sections_created)
2478 /* Add some entries to the .dynamic section. We fill in the values
2479 later (in finish_dynamic_sections) but we must add the entries now
2480 so that we get the correct size for the .dynamic section. */
2482 if (!info->shared)
2484 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2485 by the debugger. */
2486 if (!bfd_elfNN_add_dynamic_entry (info, DT_DEBUG, 0))
2487 return false;
2490 if (! bfd_elfNN_add_dynamic_entry (info, DT_IA_64_PLT_RESERVE, 0))
2491 return false;
2492 if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTGOT, 0))
2493 return false;
2495 if (relplt)
2497 if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2498 || ! bfd_elfNN_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2499 || ! bfd_elfNN_add_dynamic_entry (info, DT_JMPREL, 0))
2500 return false;
2503 if (! bfd_elfNN_add_dynamic_entry (info, DT_RELA, 0)
2504 || ! bfd_elfNN_add_dynamic_entry (info, DT_RELASZ, 0)
2505 || ! bfd_elfNN_add_dynamic_entry (info, DT_RELAENT,
2506 sizeof (ElfNN_External_Rela)))
2507 return false;
2509 if (reltext)
2511 if (! bfd_elfNN_add_dynamic_entry (info, DT_TEXTREL, 0))
2512 return false;
2513 info->flags |= DF_TEXTREL;
2517 /* ??? Perhaps force __gp local. */
2519 return true;
2522 static bfd_reloc_status_type
2523 elfNN_ia64_install_value (abfd, hit_addr, val, r_type)
2524 bfd *abfd;
2525 bfd_byte *hit_addr;
2526 bfd_vma val;
2527 unsigned int r_type;
2529 const struct ia64_operand *op;
2530 int bigendian = 0, shift = 0;
2531 bfd_vma t0, t1, insn, dword;
2532 enum ia64_opnd opnd;
2533 const char *err;
2534 size_t size = 8;
2536 opnd = IA64_OPND_NIL;
2537 switch (r_type)
2539 case R_IA64_NONE:
2540 case R_IA64_LDXMOV:
2541 return bfd_reloc_ok;
2543 /* Instruction relocations. */
2545 case R_IA64_IMM14: opnd = IA64_OPND_IMM14; break;
2547 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
2548 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
2549 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
2550 case R_IA64_PCREL21B:
2551 case R_IA64_PCREL21BI:
2552 opnd = IA64_OPND_TGT25c;
2553 break;
2555 case R_IA64_IMM22:
2556 case R_IA64_GPREL22:
2557 case R_IA64_LTOFF22:
2558 case R_IA64_LTOFF22X:
2559 case R_IA64_PLTOFF22:
2560 case R_IA64_PCREL22:
2561 case R_IA64_LTOFF_FPTR22:
2562 opnd = IA64_OPND_IMM22;
2563 break;
2565 case R_IA64_IMM64:
2566 case R_IA64_GPREL64I:
2567 case R_IA64_LTOFF64I:
2568 case R_IA64_PLTOFF64I:
2569 case R_IA64_PCREL64I:
2570 case R_IA64_FPTR64I:
2571 case R_IA64_LTOFF_FPTR64I:
2572 opnd = IA64_OPND_IMMU64;
2573 break;
2575 /* Data relocations. */
2577 case R_IA64_DIR32MSB:
2578 case R_IA64_GPREL32MSB:
2579 case R_IA64_FPTR32MSB:
2580 case R_IA64_PCREL32MSB:
2581 case R_IA64_SEGREL32MSB:
2582 case R_IA64_SECREL32MSB:
2583 case R_IA64_LTV32MSB:
2584 size = 4; bigendian = 1;
2585 break;
2587 case R_IA64_DIR32LSB:
2588 case R_IA64_GPREL32LSB:
2589 case R_IA64_FPTR32LSB:
2590 case R_IA64_PCREL32LSB:
2591 case R_IA64_SEGREL32LSB:
2592 case R_IA64_SECREL32LSB:
2593 case R_IA64_LTV32LSB:
2594 size = 4; bigendian = 0;
2595 break;
2597 case R_IA64_DIR64MSB:
2598 case R_IA64_GPREL64MSB:
2599 case R_IA64_PLTOFF64MSB:
2600 case R_IA64_FPTR64MSB:
2601 case R_IA64_PCREL64MSB:
2602 case R_IA64_LTOFF_FPTR64MSB:
2603 case R_IA64_SEGREL64MSB:
2604 case R_IA64_SECREL64MSB:
2605 case R_IA64_LTV64MSB:
2606 size = 8; bigendian = 1;
2607 break;
2609 case R_IA64_DIR64LSB:
2610 case R_IA64_GPREL64LSB:
2611 case R_IA64_PLTOFF64LSB:
2612 case R_IA64_FPTR64LSB:
2613 case R_IA64_PCREL64LSB:
2614 case R_IA64_LTOFF_FPTR64LSB:
2615 case R_IA64_SEGREL64LSB:
2616 case R_IA64_SECREL64LSB:
2617 case R_IA64_LTV64LSB:
2618 size = 8; bigendian = 0;
2619 break;
2621 /* Unsupported / Dynamic relocations. */
2622 default:
2623 return bfd_reloc_notsupported;
2626 switch (opnd)
2628 case IA64_OPND_IMMU64:
2629 hit_addr -= (long) hit_addr & 0x3;
2630 t0 = bfd_get_64 (abfd, hit_addr);
2631 t1 = bfd_get_64 (abfd, hit_addr + 8);
2633 /* tmpl/s: bits 0.. 5 in t0
2634 slot 0: bits 5..45 in t0
2635 slot 1: bits 46..63 in t0, bits 0..22 in t1
2636 slot 2: bits 23..63 in t1 */
2638 /* First, clear the bits that form the 64 bit constant. */
2639 t0 &= ~(0x3ffffLL << 46);
2640 t1 &= ~(0x7fffffLL
2641 | (( (0x07fLL << 13) | (0x1ffLL << 27)
2642 | (0x01fLL << 22) | (0x001LL << 21)
2643 | (0x001LL << 36)) << 23));
2645 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
2646 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
2647 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
2648 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
2649 | (((val >> 16) & 0x01f) << 22) /* imm5c */
2650 | (((val >> 21) & 0x001) << 21) /* ic */
2651 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
2653 bfd_put_64 (abfd, t0, hit_addr);
2654 bfd_put_64 (abfd, t1, hit_addr + 8);
2655 break;
2657 case IA64_OPND_TGT64:
2658 hit_addr -= (long) hit_addr & 0x3;
2659 t0 = bfd_get_64 (abfd, hit_addr);
2660 t1 = bfd_get_64 (abfd, hit_addr + 8);
2662 /* tmpl/s: bits 0.. 5 in t0
2663 slot 0: bits 5..45 in t0
2664 slot 1: bits 46..63 in t0, bits 0..22 in t1
2665 slot 2: bits 23..63 in t1 */
2667 /* First, clear the bits that form the 64 bit constant. */
2668 t0 &= ~(0x3ffffLL << 46);
2669 t1 &= ~(0x7fffffLL
2670 | ((1LL << 36 | 0xfffffLL << 13) << 23));
2672 val >>= 4;
2673 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
2674 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
2675 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
2676 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
2678 bfd_put_64 (abfd, t0, hit_addr);
2679 bfd_put_64 (abfd, t1, hit_addr + 8);
2680 break;
2682 default:
2683 switch ((long) hit_addr & 0x3)
2685 case 0: shift = 5; break;
2686 case 1: shift = 14; hit_addr += 3; break;
2687 case 2: shift = 23; hit_addr += 6; break;
2688 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
2690 dword = bfd_get_64 (abfd, hit_addr);
2691 insn = (dword >> shift) & 0x1ffffffffffLL;
2693 op = elf64_ia64_operands + opnd;
2694 err = (*op->insert) (op, val, &insn);
2695 if (err)
2696 return bfd_reloc_overflow;
2698 dword &= ~(0x1ffffffffffLL << shift);
2699 dword |= (insn << shift);
2700 bfd_put_64 (abfd, dword, hit_addr);
2701 break;
2703 case IA64_OPND_NIL:
2704 /* A data relocation. */
2705 if (bigendian)
2706 if (size == 4)
2707 bfd_putb32 (val, hit_addr);
2708 else
2709 bfd_putb64 (val, hit_addr);
2710 else
2711 if (size == 4)
2712 bfd_putl32 (val, hit_addr);
2713 else
2714 bfd_putl64 (val, hit_addr);
2715 break;
2718 return bfd_reloc_ok;
2721 static void
2722 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
2723 dynindx, addend)
2724 bfd *abfd;
2725 struct bfd_link_info *info;
2726 asection *sec;
2727 asection *srel;
2728 bfd_vma offset;
2729 unsigned int type;
2730 long dynindx;
2731 bfd_vma addend;
2733 Elf_Internal_Rela outrel;
2735 outrel.r_offset = (sec->output_section->vma
2736 + sec->output_offset
2737 + offset);
2739 BFD_ASSERT (dynindx != -1);
2740 outrel.r_info = ELFNN_R_INFO (dynindx, type);
2741 outrel.r_addend = addend;
2743 if (elf_section_data (sec)->stab_info != NULL)
2745 /* This may be NULL for linker-generated relocations, as it is
2746 inconvenient to pass all the bits around. And this shouldn't
2747 happen. */
2748 BFD_ASSERT (info != NULL);
2750 offset = (_bfd_stab_section_offset
2751 (abfd, &elf_hash_table (info)->stab_info, sec,
2752 &elf_section_data (sec)->stab_info, offset));
2753 if (offset == (bfd_vma) -1)
2755 /* Run for the hills. We shouldn't be outputting a relocation
2756 for this. So do what everyone else does and output a no-op. */
2757 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
2758 outrel.r_addend = 0;
2759 offset = 0;
2761 outrel.r_offset = offset;
2764 bfd_elfNN_swap_reloca_out (abfd, &outrel,
2765 ((ElfNN_External_Rela *) srel->contents
2766 + srel->reloc_count++));
2767 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
2768 <= srel->_cooked_size);
2771 /* Store an entry for target address TARGET_ADDR in the linkage table
2772 and return the gp-relative address of the linkage table entry. */
2774 static bfd_vma
2775 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
2776 bfd *abfd;
2777 struct bfd_link_info *info;
2778 struct elfNN_ia64_dyn_sym_info *dyn_i;
2779 long dynindx;
2780 bfd_vma addend;
2781 bfd_vma value;
2782 unsigned int dyn_r_type;
2784 struct elfNN_ia64_link_hash_table *ia64_info;
2785 asection *got_sec;
2787 ia64_info = elfNN_ia64_hash_table (info);
2788 got_sec = ia64_info->got_sec;
2790 BFD_ASSERT ((dyn_i->got_offset & 7) == 0);
2792 if (! dyn_i->got_done)
2794 dyn_i->got_done = true;
2796 /* Store the target address in the linkage table entry. */
2797 bfd_put_64 (abfd, value, got_sec->contents + dyn_i->got_offset);
2799 /* Install a dynamic relocation if needed. */
2800 if (info->shared
2801 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
2802 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
2804 if (dynindx == -1)
2806 dyn_r_type = R_IA64_REL64LSB;
2807 dynindx = 0;
2808 addend = value;
2811 if (bfd_big_endian (abfd))
2813 switch (dyn_r_type)
2815 case R_IA64_REL64LSB:
2816 dyn_r_type = R_IA64_REL64MSB;
2817 break;
2818 case R_IA64_DIR64LSB:
2819 dyn_r_type = R_IA64_DIR64MSB;
2820 break;
2821 case R_IA64_FPTR64LSB:
2822 dyn_r_type = R_IA64_FPTR64MSB;
2823 break;
2824 default:
2825 BFD_ASSERT (false);
2826 break;
2830 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
2831 ia64_info->rel_got_sec,
2832 dyn_i->got_offset, dyn_r_type,
2833 dynindx, addend);
2837 /* Return the address of the linkage table entry. */
2838 value = (got_sec->output_section->vma
2839 + got_sec->output_offset
2840 + dyn_i->got_offset);
2842 return value;
2845 /* Fill in a function descriptor consisting of the function's code
2846 address and its global pointer. Return the descriptor's address. */
2848 static bfd_vma
2849 set_fptr_entry (abfd, info, dyn_i, value)
2850 bfd *abfd;
2851 struct bfd_link_info *info;
2852 struct elfNN_ia64_dyn_sym_info *dyn_i;
2853 bfd_vma value;
2855 struct elfNN_ia64_link_hash_table *ia64_info;
2856 asection *fptr_sec;
2858 ia64_info = elfNN_ia64_hash_table (info);
2859 fptr_sec = ia64_info->fptr_sec;
2861 if (!dyn_i->fptr_done)
2863 dyn_i->fptr_done = 1;
2865 /* Fill in the function descriptor. */
2866 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
2867 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
2868 fptr_sec->contents + dyn_i->fptr_offset + 8);
2871 /* Return the descriptor's address. */
2872 value = (fptr_sec->output_section->vma
2873 + fptr_sec->output_offset
2874 + dyn_i->fptr_offset);
2876 return value;
2879 /* Fill in a PLTOFF entry consisting of the function's code address
2880 and its global pointer. Return the descriptor's address. */
2882 static bfd_vma
2883 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
2884 bfd *abfd;
2885 struct bfd_link_info *info;
2886 struct elfNN_ia64_dyn_sym_info *dyn_i;
2887 bfd_vma value;
2888 boolean is_plt;
2890 struct elfNN_ia64_link_hash_table *ia64_info;
2891 asection *pltoff_sec;
2893 ia64_info = elfNN_ia64_hash_table (info);
2894 pltoff_sec = ia64_info->pltoff_sec;
2896 /* Don't do anything if this symbol uses a real PLT entry. In
2897 that case, we'll fill this in during finish_dynamic_symbol. */
2898 if ((! dyn_i->want_plt || is_plt)
2899 && !dyn_i->pltoff_done)
2901 bfd_vma gp = _bfd_get_gp_value (abfd);
2903 /* Fill in the function descriptor. */
2904 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
2905 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
2907 /* Install dynamic relocations if needed. */
2908 if (!is_plt && info->shared)
2910 unsigned int dyn_r_type;
2912 if (bfd_big_endian (abfd))
2913 dyn_r_type = R_IA64_REL64MSB;
2914 else
2915 dyn_r_type = R_IA64_REL64LSB;
2917 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
2918 ia64_info->rel_pltoff_sec,
2919 dyn_i->pltoff_offset,
2920 dyn_r_type, 0, value);
2921 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
2922 ia64_info->rel_pltoff_sec,
2923 dyn_i->pltoff_offset + 8,
2924 dyn_r_type, 0, gp);
2927 dyn_i->pltoff_done = 1;
2930 /* Return the descriptor's address. */
2931 value = (pltoff_sec->output_section->vma
2932 + pltoff_sec->output_offset
2933 + dyn_i->pltoff_offset);
2935 return value;
2938 /* Called through qsort to sort the .IA_64.unwind section during a
2939 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
2940 to the output bfd so we can do proper endianness frobbing. */
2942 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
2944 static int
2945 elfNN_ia64_unwind_entry_compare (a, b)
2946 PTR a;
2947 PTR b;
2949 bfd_vma av, bv;
2951 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
2952 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
2954 return (av < bv ? -1 : av > bv ? 1 : 0);
2957 static boolean
2958 elfNN_ia64_final_link (abfd, info)
2959 bfd *abfd;
2960 struct bfd_link_info *info;
2962 struct elfNN_ia64_link_hash_table *ia64_info;
2963 asection *unwind_output_sec;
2965 ia64_info = elfNN_ia64_hash_table (info);
2967 /* Make sure we've got ourselves a nice fat __gp value. */
2968 if (!info->relocateable)
2970 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
2971 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
2972 struct elf_link_hash_entry *gp;
2973 bfd_vma gp_val;
2974 asection *os;
2976 /* Find the min and max vma of all sections marked short. Also
2977 collect min and max vma of any type, for use in selecting a
2978 nice gp. */
2979 for (os = abfd->sections; os ; os = os->next)
2981 bfd_vma lo, hi;
2983 if ((os->flags & SEC_ALLOC) == 0)
2984 continue;
2986 lo = os->vma;
2987 hi = os->vma + os->_raw_size;
2988 if (hi < lo)
2989 hi = (bfd_vma) -1;
2991 if (min_vma > lo)
2992 min_vma = lo;
2993 if (max_vma < hi)
2994 max_vma = hi;
2995 if (os->flags & SEC_SMALL_DATA)
2997 if (min_short_vma > lo)
2998 min_short_vma = lo;
2999 if (max_short_vma < hi)
3000 max_short_vma = hi;
3004 /* See if the user wants to force a value. */
3005 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
3006 false, false);
3008 if (gp
3009 && (gp->root.type == bfd_link_hash_defined
3010 || gp->root.type == bfd_link_hash_defweak))
3012 asection *gp_sec = gp->root.u.def.section;
3013 gp_val = (gp->root.u.def.value
3014 + gp_sec->output_section->vma
3015 + gp_sec->output_offset);
3017 else
3019 /* Pick a sensible value. */
3021 asection *got_sec = ia64_info->got_sec;
3023 /* Start with just the address of the .got. */
3024 if (got_sec)
3025 gp_val = got_sec->output_section->vma;
3026 else if (max_short_vma != 0)
3027 gp_val = min_short_vma;
3028 else
3029 gp_val = min_vma;
3031 /* If it is possible to address the entire image, but we
3032 don't with the choice above, adjust. */
3033 if (max_vma - min_vma < 0x400000
3034 && max_vma - gp_val <= 0x200000
3035 && gp_val - min_vma > 0x200000)
3036 gp_val = min_vma + 0x200000;
3037 else if (max_short_vma != 0)
3039 /* If we don't cover all the short data, adjust. */
3040 if (max_short_vma - gp_val >= 0x200000)
3041 gp_val = min_short_vma + 0x200000;
3043 /* If we're addressing stuff past the end, adjust back. */
3044 if (gp_val > max_vma)
3045 gp_val = max_vma - 0x200000 + 8;
3049 /* Validate whether all SHF_IA_64_SHORT sections are within
3050 range of the chosen GP. */
3052 if (max_short_vma != 0)
3054 if (max_short_vma - min_short_vma >= 0x400000)
3056 (*_bfd_error_handler)
3057 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3058 bfd_get_filename (abfd),
3059 (unsigned long) (max_short_vma - min_short_vma));
3060 return false;
3062 else if ((gp_val > min_short_vma
3063 && gp_val - min_short_vma > 0x200000)
3064 || (gp_val < max_short_vma
3065 && max_short_vma - gp_val >= 0x200000))
3067 (*_bfd_error_handler)
3068 (_("%s: __gp does not cover short data segment"),
3069 bfd_get_filename (abfd));
3070 return false;
3074 _bfd_set_gp_value (abfd, gp_val);
3077 /* If we're producing a final executable, we need to sort the contents
3078 of the .IA_64.unwind section. Force this section to be relocated
3079 into memory rather than written immediately to the output file. */
3080 unwind_output_sec = NULL;
3081 if (!info->relocateable)
3083 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3084 if (s)
3086 unwind_output_sec = s->output_section;
3087 unwind_output_sec->contents
3088 = bfd_malloc (unwind_output_sec->_raw_size);
3089 if (unwind_output_sec->contents == NULL)
3090 return false;
3094 /* Invoke the regular ELF backend linker to do all the work. */
3095 if (!bfd_elfNN_bfd_final_link (abfd, info))
3096 return false;
3098 if (unwind_output_sec)
3100 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3101 qsort (unwind_output_sec->contents, unwind_output_sec->_raw_size / 24,
3102 24, elfNN_ia64_unwind_entry_compare);
3104 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3105 unwind_output_sec->contents, 0,
3106 unwind_output_sec->_raw_size))
3107 return false;
3110 return true;
3113 static boolean
3114 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3115 contents, relocs, local_syms, local_sections)
3116 bfd *output_bfd;
3117 struct bfd_link_info *info;
3118 bfd *input_bfd;
3119 asection *input_section;
3120 bfd_byte *contents;
3121 Elf_Internal_Rela *relocs;
3122 Elf_Internal_Sym *local_syms;
3123 asection **local_sections;
3125 struct elfNN_ia64_link_hash_table *ia64_info;
3126 Elf_Internal_Shdr *symtab_hdr;
3127 Elf_Internal_Rela *rel;
3128 Elf_Internal_Rela *relend;
3129 asection *srel;
3130 boolean ret_val = true; /* for non-fatal errors */
3131 bfd_vma gp_val;
3133 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3134 ia64_info = elfNN_ia64_hash_table (info);
3136 /* Infect various flags from the input section to the output section. */
3137 if (info->relocateable)
3139 bfd_vma flags;
3141 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3142 flags &= SHF_IA_64_NORECOV;
3144 elf_section_data(input_section->output_section)
3145 ->this_hdr.sh_flags |= flags;
3148 gp_val = _bfd_get_gp_value (output_bfd);
3149 srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3151 rel = relocs;
3152 relend = relocs + input_section->reloc_count;
3153 for (; rel < relend; ++rel)
3155 struct elf_link_hash_entry *h;
3156 struct elfNN_ia64_dyn_sym_info *dyn_i;
3157 bfd_reloc_status_type r;
3158 reloc_howto_type *howto;
3159 unsigned long r_symndx;
3160 Elf_Internal_Sym *sym;
3161 unsigned int r_type;
3162 bfd_vma value;
3163 asection *sym_sec;
3164 bfd_byte *hit_addr;
3165 boolean dynamic_symbol_p;
3166 boolean undef_weak_ref;
3168 r_type = ELFNN_R_TYPE (rel->r_info);
3169 if (r_type > R_IA64_MAX_RELOC_CODE)
3171 (*_bfd_error_handler)
3172 (_("%s: unknown relocation type %d"),
3173 bfd_get_filename (input_bfd), (int)r_type);
3174 bfd_set_error (bfd_error_bad_value);
3175 ret_val = false;
3176 continue;
3178 howto = lookup_howto (r_type);
3179 r_symndx = ELFNN_R_SYM (rel->r_info);
3181 if (info->relocateable)
3183 /* This is a relocateable link. We don't have to change
3184 anything, unless the reloc is against a section symbol,
3185 in which case we have to adjust according to where the
3186 section symbol winds up in the output section. */
3187 if (r_symndx < symtab_hdr->sh_info)
3189 sym = local_syms + r_symndx;
3190 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3192 sym_sec = local_sections[r_symndx];
3193 rel->r_addend += sym_sec->output_offset;
3196 continue;
3199 /* This is a final link. */
3201 h = NULL;
3202 sym = NULL;
3203 sym_sec = NULL;
3204 undef_weak_ref = false;
3206 if (r_symndx < symtab_hdr->sh_info)
3208 /* Reloc against local symbol. */
3209 sym = local_syms + r_symndx;
3210 sym_sec = local_sections[r_symndx];
3211 value = (sym_sec->output_section->vma
3212 + sym_sec->output_offset
3213 + sym->st_value);
3215 else
3217 long indx;
3219 /* Reloc against global symbol. */
3220 indx = r_symndx - symtab_hdr->sh_info;
3221 h = elf_sym_hashes (input_bfd)[indx];
3222 while (h->root.type == bfd_link_hash_indirect
3223 || h->root.type == bfd_link_hash_warning)
3224 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3226 value = 0;
3227 if (h->root.type == bfd_link_hash_defined
3228 || h->root.type == bfd_link_hash_defweak)
3230 sym_sec = h->root.u.def.section;
3232 /* Detect the cases that sym_sec->output_section is
3233 expected to be NULL -- all cases in which the symbol
3234 is defined in another shared module. This includes
3235 PLT relocs for which we've created a PLT entry and
3236 other relocs for which we're prepared to create
3237 dynamic relocations. */
3238 /* ??? Just accept it NULL and continue. */
3240 if (sym_sec->output_section != NULL)
3242 value = (h->root.u.def.value
3243 + sym_sec->output_section->vma
3244 + sym_sec->output_offset);
3247 else if (h->root.type == bfd_link_hash_undefweak)
3248 undef_weak_ref = true;
3249 else if (info->shared && !info->symbolic
3250 && !info->no_undefined
3251 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3253 else
3255 if (! ((*info->callbacks->undefined_symbol)
3256 (info, h->root.root.string, input_bfd,
3257 input_section, rel->r_offset,
3258 (!info->shared || info->no_undefined
3259 || ELF_ST_VISIBILITY (h->other)))))
3260 return false;
3261 ret_val = false;
3262 continue;
3266 hit_addr = contents + rel->r_offset;
3267 value += rel->r_addend;
3268 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3270 switch (r_type)
3272 case R_IA64_NONE:
3273 case R_IA64_LDXMOV:
3274 continue;
3276 case R_IA64_IMM14:
3277 case R_IA64_IMM22:
3278 case R_IA64_IMM64:
3279 case R_IA64_DIR32MSB:
3280 case R_IA64_DIR32LSB:
3281 case R_IA64_DIR64MSB:
3282 case R_IA64_DIR64LSB:
3283 /* Install a dynamic relocation for this reloc. */
3284 if ((dynamic_symbol_p || info->shared)
3285 && (input_section->flags & SEC_ALLOC) != 0)
3287 unsigned int dyn_r_type;
3288 long dynindx;
3289 bfd_vma addend;
3291 BFD_ASSERT (srel != NULL);
3293 /* If we don't need dynamic symbol lookup, find a
3294 matching RELATIVE relocation. */
3295 dyn_r_type = r_type;
3296 if (dynamic_symbol_p)
3298 dynindx = h->dynindx;
3299 addend = rel->r_addend;
3300 value = 0;
3302 else
3304 switch (r_type)
3306 case R_IA64_DIR32MSB:
3307 dyn_r_type = R_IA64_REL32MSB;
3308 break;
3309 case R_IA64_DIR32LSB:
3310 dyn_r_type = R_IA64_REL32LSB;
3311 break;
3312 case R_IA64_DIR64MSB:
3313 dyn_r_type = R_IA64_REL64MSB;
3314 break;
3315 case R_IA64_DIR64LSB:
3316 dyn_r_type = R_IA64_REL64LSB;
3317 break;
3319 default:
3320 /* We can't represent this without a dynamic symbol.
3321 Adjust the relocation to be against an output
3322 section symbol, which are always present in the
3323 dynamic symbol table. */
3324 /* ??? People shouldn't be doing non-pic code in
3325 shared libraries. Hork. */
3326 (*_bfd_error_handler)
3327 (_("%s: linking non-pic code in a shared library"),
3328 bfd_get_filename (input_bfd));
3329 ret_val = false;
3330 continue;
3332 dynindx = 0;
3333 addend = value;
3336 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3337 srel, rel->r_offset, dyn_r_type,
3338 dynindx, addend);
3340 /* FALLTHRU */
3342 case R_IA64_LTV32MSB:
3343 case R_IA64_LTV32LSB:
3344 case R_IA64_LTV64MSB:
3345 case R_IA64_LTV64LSB:
3346 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3347 break;
3349 case R_IA64_GPREL22:
3350 case R_IA64_GPREL64I:
3351 case R_IA64_GPREL32MSB:
3352 case R_IA64_GPREL32LSB:
3353 case R_IA64_GPREL64MSB:
3354 case R_IA64_GPREL64LSB:
3355 if (dynamic_symbol_p)
3357 (*_bfd_error_handler)
3358 (_("%s: @gprel relocation against dynamic symbol %s"),
3359 bfd_get_filename (input_bfd), h->root.root.string);
3360 ret_val = false;
3361 continue;
3363 value -= gp_val;
3364 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3365 break;
3367 case R_IA64_LTOFF22:
3368 case R_IA64_LTOFF22X:
3369 case R_IA64_LTOFF64I:
3370 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3371 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
3372 rel->r_addend, value, R_IA64_DIR64LSB);
3373 value -= gp_val;
3374 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3375 break;
3377 case R_IA64_PLTOFF22:
3378 case R_IA64_PLTOFF64I:
3379 case R_IA64_PLTOFF64MSB:
3380 case R_IA64_PLTOFF64LSB:
3381 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3382 value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
3383 value -= gp_val;
3384 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3385 break;
3387 case R_IA64_FPTR64I:
3388 case R_IA64_FPTR32MSB:
3389 case R_IA64_FPTR32LSB:
3390 case R_IA64_FPTR64MSB:
3391 case R_IA64_FPTR64LSB:
3392 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3393 if (dyn_i->want_fptr)
3395 if (!undef_weak_ref)
3396 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3398 else
3400 long dynindx;
3402 /* Otherwise, we expect the dynamic linker to create
3403 the entry. */
3405 if (h)
3407 if (h->dynindx != -1)
3408 dynindx = h->dynindx;
3409 else
3410 dynindx = (_bfd_elf_link_lookup_local_dynindx
3411 (info, h->root.u.def.section->owner,
3412 global_sym_index (h)));
3414 else
3416 dynindx = (_bfd_elf_link_lookup_local_dynindx
3417 (info, input_bfd, r_symndx));
3420 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3421 srel, rel->r_offset, r_type,
3422 dynindx, rel->r_addend);
3423 value = 0;
3426 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3427 break;
3429 case R_IA64_LTOFF_FPTR22:
3430 case R_IA64_LTOFF_FPTR64I:
3431 case R_IA64_LTOFF_FPTR64MSB:
3432 case R_IA64_LTOFF_FPTR64LSB:
3434 long dynindx;
3436 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3437 if (dyn_i->want_fptr)
3439 BFD_ASSERT (h == NULL || h->dynindx == -1)
3440 if (!undef_weak_ref)
3441 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3442 dynindx = -1;
3444 else
3446 /* Otherwise, we expect the dynamic linker to create
3447 the entry. */
3448 if (h)
3450 if (h->dynindx != -1)
3451 dynindx = h->dynindx;
3452 else
3453 dynindx = (_bfd_elf_link_lookup_local_dynindx
3454 (info, h->root.u.def.section->owner,
3455 global_sym_index (h)));
3457 else
3458 dynindx = (_bfd_elf_link_lookup_local_dynindx
3459 (info, input_bfd, r_symndx));
3460 value = 0;
3463 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
3464 rel->r_addend, value, R_IA64_FPTR64LSB);
3465 value -= gp_val;
3466 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3468 break;
3470 case R_IA64_PCREL32MSB:
3471 case R_IA64_PCREL32LSB:
3472 case R_IA64_PCREL64MSB:
3473 case R_IA64_PCREL64LSB:
3474 /* Install a dynamic relocation for this reloc. */
3475 if (dynamic_symbol_p)
3477 BFD_ASSERT (srel != NULL);
3479 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3480 srel, rel->r_offset, r_type,
3481 h->dynindx, rel->r_addend);
3483 goto finish_pcrel;
3485 case R_IA64_PCREL21BI:
3486 case R_IA64_PCREL21F:
3487 case R_IA64_PCREL21M:
3488 /* ??? These two are only used for speculation fixup code.
3489 They should never be dynamic. */
3490 if (dynamic_symbol_p)
3492 (*_bfd_error_handler)
3493 (_("%s: dynamic relocation against speculation fixup"),
3494 bfd_get_filename (input_bfd));
3495 ret_val = false;
3496 continue;
3498 if (undef_weak_ref)
3500 (*_bfd_error_handler)
3501 (_("%s: speculation fixup against undefined weak symbol"),
3502 bfd_get_filename (input_bfd));
3503 ret_val = false;
3504 continue;
3506 goto finish_pcrel;
3508 case R_IA64_PCREL21B:
3509 case R_IA64_PCREL60B:
3510 /* We should have created a PLT entry for any dynamic symbol. */
3511 dyn_i = NULL;
3512 if (h)
3513 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3515 if (dyn_i && dyn_i->want_plt2)
3517 /* Should have caught this earlier. */
3518 BFD_ASSERT (rel->r_addend == 0);
3520 value = (ia64_info->plt_sec->output_section->vma
3521 + ia64_info->plt_sec->output_offset
3522 + dyn_i->plt2_offset);
3524 else
3526 /* Since there's no PLT entry, Validate that this is
3527 locally defined. */
3528 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
3530 /* If the symbol is undef_weak, we shouldn't be trying
3531 to call it. There's every chance that we'd wind up
3532 with an out-of-range fixup here. Don't bother setting
3533 any value at all. */
3534 if (undef_weak_ref)
3535 continue;
3537 goto finish_pcrel;
3539 case R_IA64_PCREL22:
3540 case R_IA64_PCREL64I:
3541 finish_pcrel:
3542 /* Make pc-relative. */
3543 value -= (input_section->output_section->vma
3544 + input_section->output_offset
3545 + rel->r_offset) & ~ (bfd_vma) 0x3;
3546 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3547 break;
3549 case R_IA64_SEGREL32MSB:
3550 case R_IA64_SEGREL32LSB:
3551 case R_IA64_SEGREL64MSB:
3552 case R_IA64_SEGREL64LSB:
3554 struct elf_segment_map *m;
3555 Elf_Internal_Phdr *p;
3557 /* Find the segment that contains the output_section. */
3558 for (m = elf_tdata (output_bfd)->segment_map,
3559 p = elf_tdata (output_bfd)->phdr;
3560 m != NULL;
3561 m = m->next, p++)
3563 int i;
3564 for (i = m->count - 1; i >= 0; i--)
3565 if (m->sections[i] == sym_sec->output_section)
3566 break;
3567 if (i >= 0)
3568 break;
3571 if (m == NULL)
3573 /* If the input section was discarded from the output, then
3574 do nothing. */
3576 if (bfd_is_abs_section (sym_sec->output_section))
3577 r = bfd_reloc_ok;
3578 else
3579 r = bfd_reloc_notsupported;
3581 else
3583 /* The VMA of the segment is the vaddr of the associated
3584 program header. */
3585 if (value > p->p_vaddr)
3586 value -= p->p_vaddr;
3587 else
3588 value = 0;
3589 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
3590 r_type);
3592 break;
3595 case R_IA64_SECREL32MSB:
3596 case R_IA64_SECREL32LSB:
3597 case R_IA64_SECREL64MSB:
3598 case R_IA64_SECREL64LSB:
3599 /* Make output-section relative. */
3600 if (value > input_section->output_section->vma)
3601 value -= input_section->output_section->vma;
3602 else
3603 value = 0;
3604 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3605 break;
3607 case R_IA64_IPLTMSB:
3608 case R_IA64_IPLTLSB:
3609 /* Install a dynamic relocation for this reloc. */
3610 if ((dynamic_symbol_p || info->shared)
3611 && (input_section->flags & SEC_ALLOC) != 0)
3613 BFD_ASSERT (srel != NULL);
3615 /* If we don't need dynamic symbol lookup, install two
3616 RELATIVE relocations. */
3617 if (! dynamic_symbol_p)
3619 unsigned int dyn_r_type;
3621 if (r_type == R_IA64_IPLTMSB)
3622 dyn_r_type = R_IA64_REL64MSB;
3623 else
3624 dyn_r_type = R_IA64_REL64LSB;
3626 elfNN_ia64_install_dyn_reloc (output_bfd, info,
3627 input_section,
3628 srel, rel->r_offset,
3629 dyn_r_type, 0, value);
3630 elfNN_ia64_install_dyn_reloc (output_bfd, info,
3631 input_section,
3632 srel, rel->r_offset + 8,
3633 dyn_r_type, 0, gp_val);
3635 else
3636 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3637 srel, rel->r_offset, r_type,
3638 h->dynindx, rel->r_addend);
3641 if (r_type == R_IA64_IPLTMSB)
3642 r_type = R_IA64_DIR64MSB;
3643 else
3644 r_type = R_IA64_DIR64LSB;
3645 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3646 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
3647 r_type);
3648 break;
3650 default:
3651 r = bfd_reloc_notsupported;
3652 break;
3655 switch (r)
3657 case bfd_reloc_ok:
3658 break;
3660 case bfd_reloc_undefined:
3661 /* This can happen for global table relative relocs if
3662 __gp is undefined. This is a panic situation so we
3663 don't try to continue. */
3664 (*info->callbacks->undefined_symbol)
3665 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
3666 return false;
3668 case bfd_reloc_notsupported:
3670 const char *name;
3672 if (h)
3673 name = h->root.root.string;
3674 else
3676 name = bfd_elf_string_from_elf_section (input_bfd,
3677 symtab_hdr->sh_link,
3678 sym->st_name);
3679 if (name == NULL)
3680 return false;
3681 if (*name == '\0')
3682 name = bfd_section_name (input_bfd, input_section);
3684 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
3685 name, input_bfd,
3686 input_section, rel->r_offset))
3687 return false;
3688 ret_val = false;
3690 break;
3692 case bfd_reloc_dangerous:
3693 case bfd_reloc_outofrange:
3694 case bfd_reloc_overflow:
3695 default:
3697 const char *name;
3699 if (h)
3700 name = h->root.root.string;
3701 else
3703 name = bfd_elf_string_from_elf_section (input_bfd,
3704 symtab_hdr->sh_link,
3705 sym->st_name);
3706 if (name == NULL)
3707 return false;
3708 if (*name == '\0')
3709 name = bfd_section_name (input_bfd, input_section);
3711 if (!(*info->callbacks->reloc_overflow) (info, name,
3712 howto->name, 0,
3713 input_bfd,
3714 input_section,
3715 rel->r_offset))
3716 return false;
3717 ret_val = false;
3719 break;
3723 return ret_val;
3726 static boolean
3727 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
3728 bfd *output_bfd;
3729 struct bfd_link_info *info;
3730 struct elf_link_hash_entry *h;
3731 Elf_Internal_Sym *sym;
3733 struct elfNN_ia64_link_hash_table *ia64_info;
3734 struct elfNN_ia64_dyn_sym_info *dyn_i;
3736 ia64_info = elfNN_ia64_hash_table (info);
3737 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3739 /* Fill in the PLT data, if required. */
3740 if (dyn_i && dyn_i->want_plt)
3742 Elf_Internal_Rela outrel;
3743 bfd_byte *loc;
3744 asection *plt_sec;
3745 bfd_vma plt_addr, pltoff_addr, gp_val, index;
3746 ElfNN_External_Rela *rel;
3748 gp_val = _bfd_get_gp_value (output_bfd);
3750 /* Initialize the minimal PLT entry. */
3752 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3753 plt_sec = ia64_info->plt_sec;
3754 loc = plt_sec->contents + dyn_i->plt_offset;
3756 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
3757 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
3758 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
3759 R_IA64_PCREL21B);
3761 plt_addr = (plt_sec->output_section->vma
3762 + plt_sec->output_offset
3763 + dyn_i->plt_offset);
3764 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
3766 /* Initialize the FULL PLT entry, if needed. */
3767 if (dyn_i->want_plt2)
3769 loc = plt_sec->contents + dyn_i->plt2_offset;
3771 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
3772 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
3773 R_IA64_IMM22);
3775 /* Mark the symbol as undefined, rather than as defined in the
3776 plt section. Leave the value alone. */
3777 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
3778 first place. But perhaps elflink.h did some for us. */
3779 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
3780 sym->st_shndx = SHN_UNDEF;
3783 /* Create the dynamic relocation. */
3784 outrel.r_offset = pltoff_addr;
3785 if (bfd_little_endian (output_bfd))
3786 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
3787 else
3788 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
3789 outrel.r_addend = 0;
3791 /* This is fun. In the .IA_64.pltoff section, we've got entries
3792 that correspond both to real PLT entries, and those that
3793 happened to resolve to local symbols but need to be created
3794 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
3795 relocations for the real PLT should come at the end of the
3796 section, so that they can be indexed by plt entry at runtime.
3798 We emitted all of the relocations for the non-PLT @pltoff
3799 entries during relocate_section. So we can consider the
3800 existing sec->reloc_count to be the base of the array of
3801 PLT relocations. */
3803 rel = (ElfNN_External_Rela *)ia64_info->rel_pltoff_sec->contents;
3804 rel += ia64_info->rel_pltoff_sec->reloc_count;
3806 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, rel + index);
3809 /* Mark some specially defined symbols as absolute. */
3810 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
3811 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
3812 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
3813 sym->st_shndx = SHN_ABS;
3815 return true;
3818 static boolean
3819 elfNN_ia64_finish_dynamic_sections (abfd, info)
3820 bfd *abfd;
3821 struct bfd_link_info *info;
3823 struct elfNN_ia64_link_hash_table *ia64_info;
3824 bfd *dynobj;
3826 ia64_info = elfNN_ia64_hash_table (info);
3827 dynobj = ia64_info->root.dynobj;
3829 if (elf_hash_table (info)->dynamic_sections_created)
3831 ElfNN_External_Dyn *dyncon, *dynconend;
3832 asection *sdyn, *sgotplt;
3833 bfd_vma gp_val;
3835 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3836 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
3837 BFD_ASSERT (sdyn != NULL);
3838 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
3839 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
3841 gp_val = _bfd_get_gp_value (abfd);
3843 for (; dyncon < dynconend; dyncon++)
3845 Elf_Internal_Dyn dyn;
3847 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
3849 switch (dyn.d_tag)
3851 case DT_PLTGOT:
3852 dyn.d_un.d_ptr = gp_val;
3853 break;
3855 case DT_PLTRELSZ:
3856 dyn.d_un.d_val = (ia64_info->minplt_entries
3857 * sizeof (ElfNN_External_Rela));
3858 break;
3860 case DT_JMPREL:
3861 /* See the comment above in finish_dynamic_symbol. */
3862 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
3863 + ia64_info->rel_pltoff_sec->output_offset
3864 + (ia64_info->rel_pltoff_sec->reloc_count
3865 * sizeof (ElfNN_External_Rela)));
3866 break;
3868 case DT_IA_64_PLT_RESERVE:
3869 dyn.d_un.d_ptr = (sgotplt->output_section->vma
3870 + sgotplt->output_offset);
3871 break;
3873 case DT_RELASZ:
3874 /* Do not have RELASZ include JMPREL. This makes things
3875 easier on ld.so. This is not what the rest of BFD set up. */
3876 dyn.d_un.d_val -= (ia64_info->minplt_entries
3877 * sizeof (ElfNN_External_Rela));
3878 break;
3881 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
3884 /* Initialize the PLT0 entry */
3885 if (ia64_info->plt_sec)
3887 bfd_byte *loc = ia64_info->plt_sec->contents;
3888 bfd_vma pltres;
3890 memcpy (loc, plt_header, PLT_HEADER_SIZE);
3892 pltres = (sgotplt->output_section->vma
3893 + sgotplt->output_offset
3894 - gp_val);
3896 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
3900 return true;
3903 /* ELF file flag handling: */
3905 /* Function to keep IA-64 specific file flags. */
3906 static boolean
3907 elfNN_ia64_set_private_flags (abfd, flags)
3908 bfd *abfd;
3909 flagword flags;
3911 BFD_ASSERT (!elf_flags_init (abfd)
3912 || elf_elfheader (abfd)->e_flags == flags);
3914 elf_elfheader (abfd)->e_flags = flags;
3915 elf_flags_init (abfd) = true;
3916 return true;
3919 /* Copy backend specific data from one object module to another */
3920 static boolean
3921 elfNN_ia64_copy_private_bfd_data (ibfd, obfd)
3922 bfd *ibfd, *obfd;
3924 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3925 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3926 return true;
3928 BFD_ASSERT (!elf_flags_init (obfd)
3929 || (elf_elfheader (obfd)->e_flags
3930 == elf_elfheader (ibfd)->e_flags));
3932 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
3933 elf_flags_init (obfd) = true;
3934 return true;
3937 /* Merge backend specific data from an object file to the output
3938 object file when linking. */
3939 static boolean
3940 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
3941 bfd *ibfd, *obfd;
3943 flagword out_flags;
3944 flagword in_flags;
3945 boolean ok = true;
3947 /* Don't even pretend to support mixed-format linking. */
3948 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3949 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3950 return false;
3952 in_flags = elf_elfheader (ibfd)->e_flags;
3953 out_flags = elf_elfheader (obfd)->e_flags;
3955 if (! elf_flags_init (obfd))
3957 elf_flags_init (obfd) = true;
3958 elf_elfheader (obfd)->e_flags = in_flags;
3960 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3961 && bfd_get_arch_info (obfd)->the_default)
3963 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
3964 bfd_get_mach (ibfd));
3967 return true;
3970 /* Check flag compatibility. */
3971 if (in_flags == out_flags)
3972 return true;
3974 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
3975 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
3976 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
3978 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
3980 (*_bfd_error_handler)
3981 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
3982 bfd_get_filename (ibfd));
3984 bfd_set_error (bfd_error_bad_value);
3985 ok = false;
3987 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
3989 (*_bfd_error_handler)
3990 (_("%s: linking big-endian files with little-endian files"),
3991 bfd_get_filename (ibfd));
3993 bfd_set_error (bfd_error_bad_value);
3994 ok = false;
3996 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
3998 (*_bfd_error_handler)
3999 (_("%s: linking 64-bit files with 32-bit files"),
4000 bfd_get_filename (ibfd));
4002 bfd_set_error (bfd_error_bad_value);
4003 ok = false;
4005 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4007 (*_bfd_error_handler)
4008 (_("%s: linking constant-gp files with non-constant-gp files"),
4009 bfd_get_filename (ibfd));
4011 bfd_set_error (bfd_error_bad_value);
4012 ok = false;
4014 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4015 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4017 (*_bfd_error_handler)
4018 (_("%s: linking auto-pic files with non-auto-pic files"),
4019 bfd_get_filename (ibfd));
4021 bfd_set_error (bfd_error_bad_value);
4022 ok = false;
4025 return ok;
4028 static boolean
4029 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4030 bfd *abfd;
4031 PTR ptr;
4033 FILE *file = (FILE *) ptr;
4034 flagword flags = elf_elfheader (abfd)->e_flags;
4036 BFD_ASSERT (abfd != NULL && ptr != NULL);
4038 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4039 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4040 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4041 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4042 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4043 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4044 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4045 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4046 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4048 _bfd_elf_print_private_bfd_data (abfd, ptr);
4049 return true;
4052 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4053 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4054 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4055 #define TARGET_BIG_NAME "elfNN-ia64-big"
4056 #define ELF_ARCH bfd_arch_ia64
4057 #define ELF_MACHINE_CODE EM_IA_64
4058 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4059 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4060 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4062 #define elf_backend_section_from_shdr \
4063 elfNN_ia64_section_from_shdr
4064 #define elf_backend_section_flags \
4065 elfNN_ia64_section_flags
4066 #define elf_backend_fake_sections \
4067 elfNN_ia64_fake_sections
4068 #define elf_backend_add_symbol_hook \
4069 elfNN_ia64_add_symbol_hook
4070 #define elf_backend_additional_program_headers \
4071 elfNN_ia64_additional_program_headers
4072 #define elf_backend_modify_segment_map \
4073 elfNN_ia64_modify_segment_map
4074 #define elf_info_to_howto \
4075 elfNN_ia64_info_to_howto
4077 #define bfd_elfNN_bfd_reloc_type_lookup \
4078 elfNN_ia64_reloc_type_lookup
4079 #define bfd_elfNN_bfd_is_local_label_name \
4080 elfNN_ia64_is_local_label_name
4081 #define bfd_elfNN_bfd_relax_section \
4082 elfNN_ia64_relax_section
4084 /* Stuff for the BFD linker: */
4085 #define bfd_elfNN_bfd_link_hash_table_create \
4086 elfNN_ia64_hash_table_create
4087 #define elf_backend_create_dynamic_sections \
4088 elfNN_ia64_create_dynamic_sections
4089 #define elf_backend_check_relocs \
4090 elfNN_ia64_check_relocs
4091 #define elf_backend_adjust_dynamic_symbol \
4092 elfNN_ia64_adjust_dynamic_symbol
4093 #define elf_backend_size_dynamic_sections \
4094 elfNN_ia64_size_dynamic_sections
4095 #define elf_backend_relocate_section \
4096 elfNN_ia64_relocate_section
4097 #define elf_backend_finish_dynamic_symbol \
4098 elfNN_ia64_finish_dynamic_symbol
4099 #define elf_backend_finish_dynamic_sections \
4100 elfNN_ia64_finish_dynamic_sections
4101 #define bfd_elfNN_bfd_final_link \
4102 elfNN_ia64_final_link
4104 #define bfd_elfNN_bfd_copy_private_bfd_data \
4105 elfNN_ia64_copy_private_bfd_data
4106 #define bfd_elfNN_bfd_merge_private_bfd_data \
4107 elfNN_ia64_merge_private_bfd_data
4108 #define bfd_elfNN_bfd_set_private_flags \
4109 elfNN_ia64_set_private_flags
4110 #define bfd_elfNN_bfd_print_private_bfd_data \
4111 elfNN_ia64_print_private_bfd_data
4113 #define elf_backend_plt_readonly 1
4114 #define elf_backend_want_plt_sym 0
4115 #define elf_backend_plt_alignment 5
4116 #define elf_backend_got_header_size 0
4117 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4118 #define elf_backend_want_got_plt 1
4119 #define elf_backend_may_use_rel_p 1
4120 #define elf_backend_may_use_rela_p 1
4121 #define elf_backend_default_use_rela_p 1
4122 #define elf_backend_want_dynbss 0
4123 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4124 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4126 #include "elfNN-target.h"