1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #include "opcode/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. */
74 /* Next addend in the list. */
75 struct elfNN_ia64_dyn_sym_info
*next
;
79 bfd_vma pltoff_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
;
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 */
141 unsigned reltext
: 1; /* are there relocs against readonly sections? */
143 struct elfNN_ia64_local_hash_table loc_hash_table
;
146 #define elfNN_ia64_hash_table(p) \
147 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
149 static bfd_reloc_status_type elfNN_ia64_reloc
150 PARAMS ((bfd
*abfd
, arelent
*reloc
, asymbol
*sym
, PTR data
,
151 asection
*input_section
, bfd
*output_bfd
, char **error_message
));
152 static reloc_howto_type
* lookup_howto
153 PARAMS ((unsigned int rtype
));
154 static reloc_howto_type
*elfNN_ia64_reloc_type_lookup
155 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type bfd_code
));
156 static void elfNN_ia64_info_to_howto
157 PARAMS ((bfd
*abfd
, arelent
*bfd_reloc
, ElfNN_Internal_Rela
*elf_reloc
));
158 static boolean elfNN_ia64_relax_section
159 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
161 static boolean is_unwind_section_name
162 PARAMS ((const char *));
163 static boolean elfNN_ia64_section_from_shdr
164 PARAMS ((bfd
*, ElfNN_Internal_Shdr
*, char *));
165 static boolean elfNN_ia64_section_flags
166 PARAMS ((flagword
*, ElfNN_Internal_Shdr
*));
167 static boolean elfNN_ia64_fake_sections
168 PARAMS ((bfd
*abfd
, ElfNN_Internal_Shdr
*hdr
, asection
*sec
));
169 static void elfNN_ia64_final_write_processing
170 PARAMS ((bfd
*abfd
, boolean linker
));
171 static boolean elfNN_ia64_add_symbol_hook
172 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
173 const char **namep
, flagword
*flagsp
, asection
**secp
,
175 static boolean elfNN_ia64_aix_vec
176 PARAMS ((const bfd_target
*vec
));
177 static boolean elfNN_ia64_aix_add_symbol_hook
178 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
179 const char **namep
, flagword
*flagsp
, asection
**secp
,
181 static boolean elfNN_ia64_aix_link_add_symbols
182 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
183 static int elfNN_ia64_additional_program_headers
184 PARAMS ((bfd
*abfd
));
185 static boolean elfNN_ia64_modify_segment_map
187 static boolean elfNN_ia64_is_local_label_name
188 PARAMS ((bfd
*abfd
, const char *name
));
189 static boolean elfNN_ia64_dynamic_symbol_p
190 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
));
191 static boolean elfNN_ia64_local_hash_table_init
192 PARAMS ((struct elfNN_ia64_local_hash_table
*ht
, bfd
*abfd
,
193 new_hash_entry_func
new));
194 static struct bfd_hash_entry
*elfNN_ia64_new_loc_hash_entry
195 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
196 const char *string
));
197 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
198 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
199 const char *string
));
200 static void elfNN_ia64_hash_copy_indirect
201 PARAMS ((struct elf_link_hash_entry
*, struct elf_link_hash_entry
*));
202 static void elfNN_ia64_hash_hide_symbol
203 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*));
204 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
205 PARAMS ((bfd
*abfd
));
206 static struct elfNN_ia64_local_hash_entry
*elfNN_ia64_local_hash_lookup
207 PARAMS ((struct elfNN_ia64_local_hash_table
*table
, const char *string
,
208 boolean create
, boolean copy
));
209 static boolean elfNN_ia64_global_dyn_sym_thunk
210 PARAMS ((struct bfd_hash_entry
*, PTR
));
211 static boolean elfNN_ia64_local_dyn_sym_thunk
212 PARAMS ((struct bfd_hash_entry
*, PTR
));
213 static void elfNN_ia64_dyn_sym_traverse
214 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
215 boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
217 static boolean elfNN_ia64_create_dynamic_sections
218 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
219 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
220 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
221 struct elf_link_hash_entry
*h
,
222 bfd
*abfd
, const Elf_Internal_Rela
*rel
, boolean create
));
223 static asection
*get_got
224 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
225 struct elfNN_ia64_link_hash_table
*ia64_info
));
226 static asection
*get_fptr
227 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
228 struct elfNN_ia64_link_hash_table
*ia64_info
));
229 static asection
*get_pltoff
230 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
231 struct elfNN_ia64_link_hash_table
*ia64_info
));
232 static asection
*get_reloc_section
233 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
234 asection
*sec
, boolean create
));
235 static boolean count_dyn_reloc
236 PARAMS ((bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
237 asection
*srel
, int type
));
238 static boolean elfNN_ia64_check_relocs
239 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
240 const Elf_Internal_Rela
*relocs
));
241 static boolean elfNN_ia64_adjust_dynamic_symbol
242 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
243 static unsigned long global_sym_index
244 PARAMS ((struct elf_link_hash_entry
*h
));
245 static boolean allocate_fptr
246 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
247 static boolean allocate_global_data_got
248 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
249 static boolean allocate_global_fptr_got
250 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
251 static boolean allocate_local_got
252 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
253 static boolean allocate_pltoff_entries
254 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
255 static boolean allocate_plt_entries
256 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
257 static boolean allocate_plt2_entries
258 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
259 static boolean allocate_dynrel_entries
260 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
261 static boolean elfNN_ia64_size_dynamic_sections
262 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
263 static bfd_reloc_status_type elfNN_ia64_install_value
264 PARAMS ((bfd
*abfd
, bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
265 static void elfNN_ia64_install_dyn_reloc
266 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
267 asection
*srel
, bfd_vma offset
, unsigned int type
,
268 long dynindx
, bfd_vma addend
));
269 static bfd_vma set_got_entry
270 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
271 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
272 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
273 static bfd_vma set_fptr_entry
274 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
275 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
277 static bfd_vma set_pltoff_entry
278 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
279 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
280 bfd_vma value
, boolean
));
281 static int elfNN_ia64_unwind_entry_compare
282 PARAMS ((const PTR
, const PTR
));
283 static boolean elfNN_ia64_final_link
284 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
285 static boolean elfNN_ia64_relocate_section
286 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
287 asection
*input_section
, bfd_byte
*contents
,
288 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
289 asection
**local_sections
));
290 static boolean elfNN_ia64_finish_dynamic_symbol
291 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
292 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
293 static boolean elfNN_ia64_finish_dynamic_sections
294 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
295 static boolean elfNN_ia64_set_private_flags
296 PARAMS ((bfd
*abfd
, flagword flags
));
297 static boolean elfNN_ia64_copy_private_bfd_data
298 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
299 static boolean elfNN_ia64_merge_private_bfd_data
300 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
301 static boolean elfNN_ia64_print_private_bfd_data
302 PARAMS ((bfd
*abfd
, PTR ptr
));
303 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
306 /* ia64-specific relocation */
308 /* Perform a relocation. Not much to do here as all the hard work is
309 done in elfNN_ia64_final_link_relocate. */
310 static bfd_reloc_status_type
311 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
312 output_bfd
, error_message
)
313 bfd
*abfd ATTRIBUTE_UNUSED
;
315 asymbol
*sym ATTRIBUTE_UNUSED
;
316 PTR data ATTRIBUTE_UNUSED
;
317 asection
*input_section
;
319 char **error_message
;
323 reloc
->address
+= input_section
->output_offset
;
326 *error_message
= "Unsupported call to elfNN_ia64_reloc";
327 return bfd_reloc_notsupported
;
330 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
331 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
332 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
334 /* This table has to be sorted according to increasing number of the
336 static reloc_howto_type ia64_howto_table
[] =
338 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, false, true),
340 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, false, true),
341 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, false, true),
342 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, false, true),
343 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, false, true),
344 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, false, true),
345 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, false, true),
346 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, false, true),
348 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, false, true),
349 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, false, true),
350 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, false, true),
351 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, false, true),
352 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, false, true),
353 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, false, true),
355 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, false, true),
356 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, false, true),
358 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, false, true),
359 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, false, true),
360 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, false, true),
361 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, false, true),
363 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, false, true),
364 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, false, true),
365 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, false, true),
366 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, false, true),
367 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, false, true),
369 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, true, true),
370 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, true, true),
371 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, true, true),
372 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, true, true),
373 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, true, true),
374 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, true, true),
375 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, true, true),
376 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, true, true),
378 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, false, true),
379 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, false, true),
380 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, false, true),
381 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, false, true),
382 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, false, true),
383 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, false, true),
385 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, false, true),
386 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, false, true),
387 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, false, true),
388 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, false, true),
390 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, false, true),
391 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, false, true),
392 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, false, true),
393 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, false, true),
395 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, false, true),
396 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, false, true),
397 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, false, true),
398 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, false, true),
400 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, false, true),
401 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, false, true),
402 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, false, true),
403 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, false, true),
405 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, true, true),
406 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, true, true),
407 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, true, true),
409 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, false, true),
410 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, false, true),
411 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, false, true),
412 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, false, true),
413 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, false, true),
415 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, false, false),
416 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, false, false),
417 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, false, false),
418 IA64_HOWTO (R_IA64_LTOFF_TP22
, "LTOFF_TP22", 0, false, false),
421 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
423 /* Given a BFD reloc type, return the matching HOWTO structure. */
425 static reloc_howto_type
*
429 static int inited
= 0;
436 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
437 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
438 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
441 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
442 i
= elf_code_to_howto_index
[rtype
];
443 if (i
>= NELEMS (ia64_howto_table
))
445 return ia64_howto_table
+ i
;
448 static reloc_howto_type
*
449 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
450 bfd
*abfd ATTRIBUTE_UNUSED
;
451 bfd_reloc_code_real_type bfd_code
;
457 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
459 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
460 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
461 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
463 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
464 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
465 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
466 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
468 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
469 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
470 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
471 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
472 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
473 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
475 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
476 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
478 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
479 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
480 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
481 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
482 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
483 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
484 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
485 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
486 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
488 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
489 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
490 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
491 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
492 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
493 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
494 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
495 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
496 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
497 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
498 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
500 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
501 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
502 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
503 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
504 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
505 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
507 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
508 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
509 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
510 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
512 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
513 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
514 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
515 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
517 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
518 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
519 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
520 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
522 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
523 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
524 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
525 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
527 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
528 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
529 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
530 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
531 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
533 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
534 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
535 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
536 case BFD_RELOC_IA64_LTOFF_TP22
: rtype
= R_IA64_LTOFF_TP22
; break;
540 return lookup_howto (rtype
);
543 /* Given a ELF reloc, return the matching HOWTO structure. */
546 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
547 bfd
*abfd ATTRIBUTE_UNUSED
;
549 ElfNN_Internal_Rela
*elf_reloc
;
551 bfd_reloc
->howto
= lookup_howto (ELFNN_R_TYPE (elf_reloc
->r_info
));
554 #define PLT_HEADER_SIZE (3 * 16)
555 #define PLT_MIN_ENTRY_SIZE (1 * 16)
556 #define PLT_FULL_ENTRY_SIZE (2 * 16)
557 #define PLT_RESERVED_WORDS 3
559 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
561 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
562 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
563 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
564 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
565 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
566 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
567 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
568 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
569 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
572 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
574 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
575 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
576 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
579 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
581 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
582 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
583 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
584 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
585 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
586 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
589 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
590 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
591 #define DYNAMIC_INTERPRETER(abfd) \
592 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
594 /* Select out of range branch fixup type. Note that Itanium does
595 not support brl, and so it gets emulated by the kernel. */
598 static const bfd_byte oor_brl
[16] =
600 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
602 0x00, 0x00, 0x00, 0xc0
605 static const bfd_byte oor_ip
[48] =
607 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
608 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
609 0x01, 0x00, 0x00, 0x60,
610 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
611 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
612 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
613 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
614 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
615 0x60, 0x00, 0x80, 0x00 /* br b6;; */
618 /* These functions do relaxation for IA-64 ELF.
620 This is primarily to support branches to targets out of range;
621 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
624 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
627 struct bfd_link_info
*link_info
;
632 struct one_fixup
*next
;
638 Elf_Internal_Shdr
*symtab_hdr
;
639 Elf_Internal_Rela
*internal_relocs
;
640 Elf_Internal_Rela
*free_relocs
= NULL
;
641 Elf_Internal_Rela
*irel
, *irelend
;
643 bfd_byte
*free_contents
= NULL
;
644 ElfNN_External_Sym
*extsyms
;
645 ElfNN_External_Sym
*free_extsyms
= NULL
;
646 struct elfNN_ia64_link_hash_table
*ia64_info
;
647 struct one_fixup
*fixups
= NULL
;
648 boolean changed_contents
= false;
649 boolean changed_relocs
= false;
651 /* Assume we're not going to change any sizes, and we'll only need
655 /* Nothing to do if there are no relocations. */
656 if ((sec
->flags
& SEC_RELOC
) == 0
657 || sec
->reloc_count
== 0)
660 /* If this is the first time we have been called for this section,
661 initialize the cooked size. */
662 if (sec
->_cooked_size
== 0)
663 sec
->_cooked_size
= sec
->_raw_size
;
665 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
667 /* Load the relocations for this section. */
668 internal_relocs
= (_bfd_elfNN_link_read_relocs
669 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
670 link_info
->keep_memory
));
671 if (internal_relocs
== NULL
)
674 if (! link_info
->keep_memory
)
675 free_relocs
= internal_relocs
;
677 ia64_info
= elfNN_ia64_hash_table (link_info
);
678 irelend
= internal_relocs
+ sec
->reloc_count
;
680 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
681 if (ELFNN_R_TYPE (irel
->r_info
) == (int) R_IA64_PCREL21B
)
684 /* No branch-type relocations. */
687 if (free_relocs
!= NULL
)
692 /* Get the section contents. */
693 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
694 contents
= elf_section_data (sec
)->this_hdr
.contents
;
697 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
698 if (contents
== NULL
)
700 free_contents
= contents
;
702 if (! bfd_get_section_contents (abfd
, sec
, contents
,
703 (file_ptr
) 0, sec
->_raw_size
))
707 /* Read this BFD's symbols. */
708 if (symtab_hdr
->contents
!= NULL
)
709 extsyms
= (ElfNN_External_Sym
*) symtab_hdr
->contents
;
712 extsyms
= (ElfNN_External_Sym
*) bfd_malloc (symtab_hdr
->sh_size
);
715 free_extsyms
= extsyms
;
716 if (bfd_seek (abfd
, symtab_hdr
->sh_offset
, SEEK_SET
) != 0
717 || (bfd_read (extsyms
, 1, symtab_hdr
->sh_size
, abfd
)
718 != symtab_hdr
->sh_size
))
722 for (; irel
< irelend
; irel
++)
724 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
725 Elf_Internal_Sym isym
;
729 if (ELFNN_R_TYPE (irel
->r_info
) != (int) R_IA64_PCREL21B
)
732 /* Get the value of the symbol referred to by the reloc. */
733 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
735 /* A local symbol. */
736 bfd_elfNN_swap_symbol_in (abfd
,
737 extsyms
+ ELFNN_R_SYM (irel
->r_info
),
739 if (isym
.st_shndx
== SHN_UNDEF
)
740 continue; /* We can't do anthing with undefined symbols. */
741 else if (isym
.st_shndx
== SHN_ABS
)
742 tsec
= bfd_abs_section_ptr
;
743 else if (isym
.st_shndx
== SHN_COMMON
)
744 tsec
= bfd_com_section_ptr
;
745 else if (isym
.st_shndx
> 0 && isym
.st_shndx
< SHN_LORESERVE
)
746 tsec
= bfd_section_from_elf_index (abfd
, isym
.st_shndx
);
748 continue; /* who knows. */
750 toff
= isym
.st_value
;
755 struct elf_link_hash_entry
*h
;
756 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
758 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
759 h
= elf_sym_hashes (abfd
)[indx
];
760 BFD_ASSERT (h
!= NULL
);
762 while (h
->root
.type
== bfd_link_hash_indirect
763 || h
->root
.type
== bfd_link_hash_warning
)
764 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
766 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, false);
768 /* For branches to dynamic symbols, we're interested instead
769 in a branch to the PLT entry. */
770 if (dyn_i
&& dyn_i
->want_plt2
)
772 tsec
= ia64_info
->plt_sec
;
773 toff
= dyn_i
->plt2_offset
;
777 /* We can't do anthing with undefined symbols. */
778 if (h
->root
.type
== bfd_link_hash_undefined
779 || h
->root
.type
== bfd_link_hash_undefweak
)
782 tsec
= h
->root
.u
.def
.section
;
783 toff
= h
->root
.u
.def
.value
;
787 symaddr
= (tsec
->output_section
->vma
788 + tsec
->output_offset
792 roff
= irel
->r_offset
;
793 reladdr
= (sec
->output_section
->vma
797 /* If the branch is in range, no need to do anything. */
798 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
799 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
802 /* If the branch and target are in the same section, you've
803 got one honking big section and we can't help you. You'll
804 get an error message later. */
808 /* Look for an existing fixup to this address. */
809 for (f
= fixups
; f
; f
= f
->next
)
810 if (f
->tsec
== tsec
&& f
->toff
== toff
)
815 /* Two alternatives: If it's a branch to a PLT entry, we can
816 make a copy of the FULL_PLT entry. Otherwise, we'll have
817 to use a `brl' insn to get where we're going. */
821 if (tsec
== ia64_info
->plt_sec
)
822 size
= sizeof (plt_full_entry
);
826 size
= sizeof (oor_brl
);
828 size
= sizeof (oor_ip
);
832 /* Resize the current section to make room for the new branch. */
833 trampoff
= (sec
->_cooked_size
+ 15) & -16;
834 contents
= (bfd_byte
*) bfd_realloc (contents
, trampoff
+ size
);
835 if (contents
== NULL
)
837 sec
->_cooked_size
= trampoff
+ size
;
839 if (tsec
== ia64_info
->plt_sec
)
841 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
843 /* Hijack the old relocation for use as the PLTOFF reloc. */
844 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
846 irel
->r_offset
= trampoff
;
851 memcpy (contents
+ trampoff
, oor_brl
, size
);
852 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
854 irel
->r_offset
= trampoff
+ 2;
856 memcpy (contents
+ trampoff
, oor_ip
, size
);
857 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
859 irel
->r_addend
-= 16;
860 irel
->r_offset
= trampoff
+ 2;
864 /* Record the fixup so we don't do it again this section. */
865 f
= (struct one_fixup
*) bfd_malloc (sizeof (*f
));
869 f
->trampoff
= trampoff
;
874 /* Nop out the reloc, since we're finalizing things here. */
875 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
878 /* Fix up the existing branch to hit the trampoline. Hope like
879 hell this doesn't overflow too. */
880 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
881 f
->trampoff
- (roff
& -4),
882 R_IA64_PCREL21B
) != bfd_reloc_ok
)
885 changed_contents
= true;
886 changed_relocs
= true;
889 /* Clean up and go home. */
892 struct one_fixup
*f
= fixups
;
893 fixups
= fixups
->next
;
898 elf_section_data (sec
)->relocs
= internal_relocs
;
899 else if (free_relocs
!= NULL
)
902 if (changed_contents
)
903 elf_section_data (sec
)->this_hdr
.contents
= contents
;
904 else if (free_contents
!= NULL
)
906 if (! link_info
->keep_memory
)
907 free (free_contents
);
910 /* Cache the section contents for elf_link_input_bfd. */
911 elf_section_data (sec
)->this_hdr
.contents
= contents
;
915 if (free_extsyms
!= NULL
)
917 if (! link_info
->keep_memory
)
921 /* Cache the symbols for elf_link_input_bfd. */
922 symtab_hdr
->contents
= extsyms
;
926 *again
= changed_contents
|| changed_relocs
;
930 if (free_relocs
!= NULL
)
932 if (free_contents
!= NULL
)
933 free (free_contents
);
934 if (free_extsyms
!= NULL
)
939 /* Return true if NAME is an unwind table section name. */
941 static inline boolean
942 is_unwind_section_name (name
)
945 size_t len1
, len2
, len3
;
947 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
948 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
949 len3
= sizeof (ELF_STRING_ia64_unwind_once
) - 1;
950 return ((strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
951 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0)
952 || strncmp (name
, ELF_STRING_ia64_unwind_once
, len3
) == 0);
955 /* Handle an IA-64 specific section when reading an object file. This
956 is called when elfcode.h finds a section with an unknown type. */
959 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
961 ElfNN_Internal_Shdr
*hdr
;
966 /* There ought to be a place to keep ELF backend specific flags, but
967 at the moment there isn't one. We just keep track of the
968 sections by their name, instead. Fortunately, the ABI gives
969 suggested names for all the MIPS specific sections, so we will
970 probably get away with this. */
971 switch (hdr
->sh_type
)
973 case SHT_IA_64_UNWIND
:
977 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
985 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
987 newsect
= hdr
->bfd_section
;
992 /* Convert IA-64 specific section flags to bfd internal section flags. */
994 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
998 elfNN_ia64_section_flags (flags
, hdr
)
1000 ElfNN_Internal_Shdr
*hdr
;
1002 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1003 *flags
|= SEC_SMALL_DATA
;
1008 /* Set the correct type for an IA-64 ELF section. We do this by the
1009 section name, which is a hack, but ought to work. */
1012 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1013 bfd
*abfd ATTRIBUTE_UNUSED
;
1014 ElfNN_Internal_Shdr
*hdr
;
1017 register const char *name
;
1019 name
= bfd_get_section_name (abfd
, sec
);
1021 if (is_unwind_section_name (name
))
1023 /* We don't have the sections numbered at this point, so sh_info
1024 is set later, in elfNN_ia64_final_write_processing. */
1025 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1026 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1028 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1029 hdr
->sh_type
= SHT_IA_64_EXT
;
1030 else if (strcmp (name
, ".reloc") == 0)
1032 * This is an ugly, but unfortunately necessary hack that is
1033 * needed when producing EFI binaries on IA-64. It tells
1034 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1035 * containing ELF relocation info. We need this hack in order to
1036 * be able to generate ELF binaries that can be translated into
1037 * EFI applications (which are essentially COFF objects). Those
1038 * files contain a COFF ".reloc" section inside an ELFNN object,
1039 * which would normally cause BFD to segfault because it would
1040 * attempt to interpret this section as containing relocation
1041 * entries for section "oc". With this hack enabled, ".reloc"
1042 * will be treated as a normal data section, which will avoid the
1043 * segfault. However, you won't be able to create an ELFNN binary
1044 * with a section named "oc" that needs relocations, but that's
1045 * the kind of ugly side-effects you get when detecting section
1046 * types based on their names... In practice, this limitation is
1049 hdr
->sh_type
= SHT_PROGBITS
;
1051 if (sec
->flags
& SEC_SMALL_DATA
)
1052 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1057 /* The final processing done just before writing out an IA-64 ELF
1061 elfNN_ia64_final_write_processing (abfd
, linker
)
1063 boolean linker ATTRIBUTE_UNUSED
;
1065 Elf_Internal_Shdr
*hdr
;
1067 asection
*text_sect
, *s
;
1070 for (s
= abfd
->sections
; s
; s
= s
->next
)
1072 hdr
= &elf_section_data (s
)->this_hdr
;
1073 switch (hdr
->sh_type
)
1075 case SHT_IA_64_UNWIND
:
1076 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1078 sname
= bfd_get_section_name (abfd
, s
);
1079 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1080 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1084 if (sname
[0] == '\0')
1085 /* .IA_64.unwind -> .text */
1086 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1088 /* .IA_64.unwindFOO -> FOO */
1089 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1092 && (len
= sizeof (ELF_STRING_ia64_unwind_once
) - 1,
1093 strncmp (sname
, ELF_STRING_ia64_unwind_once
, len
)) == 0)
1095 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1096 size_t len2
= sizeof (".gnu.linkonce.t.") - 1;
1097 char *once_name
= alloca (len2
+ strlen (sname
) - len
+ 1);
1099 memcpy (once_name
, ".gnu.linkonce.t.", len2
);
1100 strcpy (once_name
+ len2
, sname
+ len
);
1101 text_sect
= bfd_get_section_by_name (abfd
, once_name
);
1104 /* last resort: fall back on .text */
1105 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1109 /* The IA-64 processor-specific ABI requires setting
1110 sh_link to the unwind section, whereas HP-UX requires
1111 sh_info to do so. For maximum compatibility, we'll
1112 set both for now... */
1113 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1114 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1121 /* Hook called by the linker routine which adds symbols from an object
1122 file. We use it to put .comm items in .sbss, and not .bss. */
1125 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1127 struct bfd_link_info
*info
;
1128 const Elf_Internal_Sym
*sym
;
1129 const char **namep ATTRIBUTE_UNUSED
;
1130 flagword
*flagsp ATTRIBUTE_UNUSED
;
1134 if (sym
->st_shndx
== SHN_COMMON
1135 && !info
->relocateable
1136 && sym
->st_size
<= elf_gp_size (abfd
))
1138 /* Common symbols less than or equal to -G nn bytes are
1139 automatically put into .sbss. */
1141 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1145 scomm
= bfd_make_section (abfd
, ".scommon");
1147 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1149 | SEC_LINKER_CREATED
)))
1154 *valp
= sym
->st_size
;
1161 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1163 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1164 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1166 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1167 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1170 /* Hook called by the linker routine which adds symbols from an object
1171 file. We use it to handle OS-specific symbols. */
1174 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1176 struct bfd_link_info
*info
;
1177 const Elf_Internal_Sym
*sym
;
1183 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1185 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1186 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1187 no one else should use it b/c it is undocumented. */
1188 struct elf_link_hash_entry
*h
;
1190 h
= (struct elf_link_hash_entry
*) bfd_link_hash_lookup (info
->hash
, *namep
, false, false, false);
1193 struct elf_backend_data
*bed
;
1194 struct elfNN_ia64_link_hash_table
*ia64_info
;
1196 bed
= get_elf_backend_data (abfd
);
1197 ia64_info
= elfNN_ia64_hash_table (info
);
1199 if (!(_bfd_generic_link_add_one_symbol
1200 (info
, abfd
, *namep
, BSF_GLOBAL
,
1201 bfd_get_section_by_name (abfd
, ".bss"),
1202 bed
->got_symbol_offset
, (const char *) NULL
, false,
1203 bed
->collect
, (struct bfd_link_hash_entry
**) &h
)))
1206 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1207 h
->type
= STT_OBJECT
;
1209 if (! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1215 else if (sym
->st_shndx
== SHN_LOOS
)
1219 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1220 is only relevant when compiling code for extended system calls.
1221 Replace the "special" section with .text, if possible.
1222 Note that these symbols are always assumed to be in .text. */
1223 for (i
= 1; i
< elf_elfheader (abfd
)->e_shnum
; i
++)
1225 asection
* sec
= bfd_section_from_elf_index (abfd
, i
);
1227 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1235 *secp
= bfd_abs_section_ptr
;
1237 *valp
= sym
->st_size
;
1243 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1244 namep
, flagsp
, secp
, valp
);
1249 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1251 struct bfd_link_info
*info
;
1253 /* Make sure dynamic sections are always created. */
1254 if (! elf_hash_table (info
)->dynamic_sections_created
1255 && abfd
->xvec
== info
->hash
->creator
)
1257 if (! bfd_elfNN_link_create_dynamic_sections (abfd
, info
))
1261 /* Now do the standard call. */
1262 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1265 /* Return the number of additional phdrs we will need. */
1268 elfNN_ia64_additional_program_headers (abfd
)
1274 /* See if we need a PT_IA_64_ARCHEXT segment. */
1275 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1276 if (s
&& (s
->flags
& SEC_LOAD
))
1279 /* Count how many PT_IA_64_UNWIND segments we need. */
1280 for (s
= abfd
->sections
; s
; s
= s
->next
)
1281 if (is_unwind_section_name(s
->name
) && (s
->flags
& SEC_LOAD
))
1288 elfNN_ia64_modify_segment_map (abfd
)
1291 struct elf_segment_map
*m
, **pm
;
1292 Elf_Internal_Shdr
*hdr
;
1295 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1296 all PT_LOAD segments. */
1297 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1298 if (s
&& (s
->flags
& SEC_LOAD
))
1300 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1301 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1305 m
= (struct elf_segment_map
*) bfd_zalloc (abfd
, sizeof *m
);
1309 m
->p_type
= PT_IA_64_ARCHEXT
;
1313 /* We want to put it after the PHDR and INTERP segments. */
1314 pm
= &elf_tdata (abfd
)->segment_map
;
1316 && ((*pm
)->p_type
== PT_PHDR
1317 || (*pm
)->p_type
== PT_INTERP
))
1325 /* Install PT_IA_64_UNWIND segments, if needed. */
1326 for (s
= abfd
->sections
; s
; s
= s
->next
)
1328 hdr
= &elf_section_data (s
)->this_hdr
;
1329 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1332 if (s
&& (s
->flags
& SEC_LOAD
))
1334 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1335 if (m
->p_type
== PT_IA_64_UNWIND
&& m
->sections
[0] == s
)
1340 m
= (struct elf_segment_map
*) bfd_zalloc (abfd
, sizeof *m
);
1344 m
->p_type
= PT_IA_64_UNWIND
;
1349 /* We want to put it last. */
1350 pm
= &elf_tdata (abfd
)->segment_map
;
1358 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1359 the input sections for each output section in the segment and testing
1360 for SHF_IA_64_NORECOV on each. */
1361 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1362 if (m
->p_type
== PT_LOAD
)
1365 for (i
= m
->count
- 1; i
>= 0; --i
)
1367 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1370 if (order
->type
== bfd_indirect_link_order
)
1372 asection
*is
= order
->u
.indirect
.section
;
1373 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1374 if (flags
& SHF_IA_64_NORECOV
)
1376 m
->p_flags
|= PF_IA_64_NORECOV
;
1380 order
= order
->next
;
1389 /* According to the Tahoe assembler spec, all labels starting with a
1393 elfNN_ia64_is_local_label_name (abfd
, name
)
1394 bfd
*abfd ATTRIBUTE_UNUSED
;
1397 return name
[0] == '.';
1400 /* Should we do dynamic things to this symbol? */
1403 elfNN_ia64_dynamic_symbol_p (h
, info
)
1404 struct elf_link_hash_entry
*h
;
1405 struct bfd_link_info
*info
;
1410 while (h
->root
.type
== bfd_link_hash_indirect
1411 || h
->root
.type
== bfd_link_hash_warning
)
1412 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1414 if (h
->dynindx
== -1)
1416 switch (ELF_ST_VISIBILITY (h
->other
))
1423 if (h
->root
.type
== bfd_link_hash_undefweak
1424 || h
->root
.type
== bfd_link_hash_defweak
)
1427 if ((info
->shared
&& !info
->symbolic
)
1428 || ((h
->elf_link_hash_flags
1429 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1430 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1437 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1438 struct elfNN_ia64_local_hash_table
*ht
;
1439 bfd
*abfd ATTRIBUTE_UNUSED
;
1440 new_hash_entry_func
new;
1442 memset (ht
, 0, sizeof (*ht
));
1443 return bfd_hash_table_init (&ht
->root
, new);
1446 static struct bfd_hash_entry
*
1447 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1448 struct bfd_hash_entry
*entry
;
1449 struct bfd_hash_table
*table
;
1452 struct elfNN_ia64_local_hash_entry
*ret
;
1453 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1455 /* Allocate the structure if it has not already been allocated by a
1458 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1463 /* Initialize our local data. All zeros, and definitely easier
1464 than setting a handful of bit fields. */
1465 memset (ret
, 0, sizeof (*ret
));
1467 /* Call the allocation method of the superclass. */
1468 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1469 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1471 return (struct bfd_hash_entry
*) ret
;
1474 static struct bfd_hash_entry
*
1475 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1476 struct bfd_hash_entry
*entry
;
1477 struct bfd_hash_table
*table
;
1480 struct elfNN_ia64_link_hash_entry
*ret
;
1481 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1483 /* Allocate the structure if it has not already been allocated by a
1486 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1491 /* Initialize our local data. All zeros, and definitely easier
1492 than setting a handful of bit fields. */
1493 memset (ret
, 0, sizeof (*ret
));
1495 /* Call the allocation method of the superclass. */
1496 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1497 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1500 return (struct bfd_hash_entry
*) ret
;
1504 elfNN_ia64_hash_copy_indirect (xdir
, xind
)
1505 struct elf_link_hash_entry
*xdir
, *xind
;
1507 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1509 dir
= (struct elfNN_ia64_link_hash_entry
*)xdir
;
1510 ind
= (struct elfNN_ia64_link_hash_entry
*)xind
;
1512 /* Copy down any references that we may have already seen to the
1513 symbol which just became indirect. */
1515 dir
->root
.elf_link_hash_flags
|=
1516 (ind
->root
.elf_link_hash_flags
1517 & (ELF_LINK_HASH_REF_DYNAMIC
1518 | ELF_LINK_HASH_REF_REGULAR
1519 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1521 /* Copy over the got and plt data. This would have been done
1524 if (dir
->info
== NULL
)
1526 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1528 dir
->info
= dyn_i
= ind
->info
;
1531 /* Fix up the dyn_sym_info pointers to the global symbol. */
1532 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1533 dyn_i
->h
= &dir
->root
;
1535 BFD_ASSERT (ind
->info
== NULL
);
1537 /* Copy over the dynindx. */
1539 if (dir
->root
.dynindx
== -1)
1541 dir
->root
.dynindx
= ind
->root
.dynindx
;
1542 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1543 ind
->root
.dynindx
= -1;
1544 ind
->root
.dynstr_index
= 0;
1546 BFD_ASSERT (ind
->root
.dynindx
== -1);
1550 elfNN_ia64_hash_hide_symbol (info
, xh
)
1551 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1552 struct elf_link_hash_entry
*xh
;
1554 struct elfNN_ia64_link_hash_entry
*h
;
1555 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1557 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1559 h
->root
.elf_link_hash_flags
&= ~ELF_LINK_HASH_NEEDS_PLT
;
1560 if ((h
->root
.elf_link_hash_flags
& ELF_LINK_FORCED_LOCAL
) != 0)
1561 h
->root
.dynindx
= -1;
1563 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1564 dyn_i
->want_plt2
= 0;
1567 /* Create the derived linker hash table. The IA-64 ELF port uses this
1568 derived hash table to keep information specific to the IA-64 ElF
1569 linker (without using static variables). */
1571 static struct bfd_link_hash_table
*
1572 elfNN_ia64_hash_table_create (abfd
)
1575 struct elfNN_ia64_link_hash_table
*ret
;
1577 ret
= bfd_zalloc (abfd
, sizeof (*ret
));
1580 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1581 elfNN_ia64_new_elf_hash_entry
))
1583 bfd_release (abfd
, ret
);
1587 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1588 elfNN_ia64_new_loc_hash_entry
))
1590 return &ret
->root
.root
;
1593 /* Look up an entry in a Alpha ELF linker hash table. */
1595 static INLINE
struct elfNN_ia64_local_hash_entry
*
1596 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1597 struct elfNN_ia64_local_hash_table
*table
;
1599 boolean create
, copy
;
1601 return ((struct elfNN_ia64_local_hash_entry
*)
1602 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1605 /* Traverse both local and global hash tables. */
1607 struct elfNN_ia64_dyn_sym_traverse_data
1609 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1614 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1615 struct bfd_hash_entry
*xentry
;
1618 struct elfNN_ia64_link_hash_entry
*entry
1619 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1620 struct elfNN_ia64_dyn_sym_traverse_data
*data
1621 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1622 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1624 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1625 if (! (*data
->func
) (dyn_i
, data
->data
))
1631 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1632 struct bfd_hash_entry
*xentry
;
1635 struct elfNN_ia64_local_hash_entry
*entry
1636 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1637 struct elfNN_ia64_dyn_sym_traverse_data
*data
1638 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1639 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1641 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1642 if (! (*data
->func
) (dyn_i
, data
->data
))
1648 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1649 struct elfNN_ia64_link_hash_table
*ia64_info
;
1650 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1653 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1658 elf_link_hash_traverse (&ia64_info
->root
,
1659 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1660 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1661 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1665 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1667 struct bfd_link_info
*info
;
1669 struct elfNN_ia64_link_hash_table
*ia64_info
;
1672 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1675 ia64_info
= elfNN_ia64_hash_table (info
);
1677 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1678 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1681 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1682 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1685 if (!get_pltoff (abfd
, info
, ia64_info
))
1688 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1690 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1693 | SEC_LINKER_CREATED
1695 || !bfd_set_section_alignment (abfd
, s
, 3))
1697 ia64_info
->rel_pltoff_sec
= s
;
1699 s
= bfd_make_section(abfd
, ".rela.got");
1701 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1704 | SEC_LINKER_CREATED
1706 || !bfd_set_section_alignment (abfd
, s
, 3))
1708 ia64_info
->rel_got_sec
= s
;
1713 /* Find and/or create a descriptor for dynamic symbol info. This will
1714 vary based on global or local symbol, and the addend to the reloc. */
1716 static struct elfNN_ia64_dyn_sym_info
*
1717 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1718 struct elfNN_ia64_link_hash_table
*ia64_info
;
1719 struct elf_link_hash_entry
*h
;
1721 const Elf_Internal_Rela
*rel
;
1724 struct elfNN_ia64_dyn_sym_info
**pp
;
1725 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1726 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1729 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1732 struct elfNN_ia64_local_hash_entry
*loc_h
;
1736 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1737 The name describes what was once anonymous memory. */
1739 len
= sizeof (void*)*2 + 1 + sizeof (bfd_vma
)*4 + 1 + 1;
1740 len
+= 10; /* %p slop */
1742 addr_name
= alloca (len
);
1743 sprintf (addr_name
, "%p:%lx",
1744 (void *) abfd
, (unsigned long) ELFNN_R_SYM (rel
->r_info
));
1746 /* Collect the canonical entry data for this address. */
1747 loc_h
= elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1748 addr_name
, create
, create
);
1754 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
1757 if (dyn_i
== NULL
&& create
)
1759 dyn_i
= (struct elfNN_ia64_dyn_sym_info
*)
1760 bfd_zalloc (abfd
, sizeof *dyn_i
);
1762 dyn_i
->addend
= addend
;
1769 get_got (abfd
, info
, ia64_info
)
1771 struct bfd_link_info
*info
;
1772 struct elfNN_ia64_link_hash_table
*ia64_info
;
1777 got
= ia64_info
->got_sec
;
1782 dynobj
= ia64_info
->root
.dynobj
;
1784 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1785 if (!_bfd_elf_create_got_section (dynobj
, info
))
1788 got
= bfd_get_section_by_name (dynobj
, ".got");
1790 ia64_info
->got_sec
= got
;
1792 flags
= bfd_get_section_flags (abfd
, got
);
1793 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
1799 /* Create function descriptor section (.opd). This section is called .opd
1800 because it contains "official prodecure descriptors". The "official"
1801 refers to the fact that these descriptors are used when taking the address
1802 of a procedure, thus ensuring a unique address for each procedure. */
1805 get_fptr (abfd
, info
, ia64_info
)
1807 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1808 struct elfNN_ia64_link_hash_table
*ia64_info
;
1813 fptr
= ia64_info
->fptr_sec
;
1816 dynobj
= ia64_info
->root
.dynobj
;
1818 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1820 fptr
= bfd_make_section (dynobj
, ".opd");
1822 || !bfd_set_section_flags (dynobj
, fptr
,
1828 | SEC_LINKER_CREATED
))
1829 || !bfd_set_section_alignment (abfd
, fptr
, 4))
1835 ia64_info
->fptr_sec
= fptr
;
1842 get_pltoff (abfd
, info
, ia64_info
)
1844 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1845 struct elfNN_ia64_link_hash_table
*ia64_info
;
1850 pltoff
= ia64_info
->pltoff_sec
;
1853 dynobj
= ia64_info
->root
.dynobj
;
1855 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1857 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
1859 || !bfd_set_section_flags (dynobj
, pltoff
,
1865 | SEC_LINKER_CREATED
))
1866 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
1872 ia64_info
->pltoff_sec
= pltoff
;
1879 get_reloc_section (abfd
, ia64_info
, sec
, create
)
1881 struct elfNN_ia64_link_hash_table
*ia64_info
;
1885 const char *srel_name
;
1889 srel_name
= (bfd_elf_string_from_elf_section
1890 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
1891 elf_section_data(sec
)->rel_hdr
.sh_name
));
1892 if (srel_name
== NULL
)
1895 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
1896 && strcmp (bfd_get_section_name (abfd
, sec
),
1898 || (strncmp (srel_name
, ".rel", 4) == 0
1899 && strcmp (bfd_get_section_name (abfd
, sec
),
1900 srel_name
+4) == 0));
1902 dynobj
= ia64_info
->root
.dynobj
;
1904 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1906 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
1907 if (srel
== NULL
&& create
)
1909 srel
= bfd_make_section (dynobj
, srel_name
);
1911 || !bfd_set_section_flags (dynobj
, srel
,
1916 | SEC_LINKER_CREATED
1918 || !bfd_set_section_alignment (dynobj
, srel
, 3))
1922 if (sec
->flags
& SEC_READONLY
)
1923 ia64_info
->reltext
= 1;
1929 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
1931 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1935 struct elfNN_ia64_dyn_reloc_entry
*rent
;
1937 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
1938 if (rent
->srel
== srel
&& rent
->type
== type
)
1943 rent
= (struct elfNN_ia64_dyn_reloc_entry
*)
1944 bfd_alloc (abfd
, sizeof (*rent
));
1948 rent
->next
= dyn_i
->reloc_entries
;
1952 dyn_i
->reloc_entries
= rent
;
1960 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
1962 struct bfd_link_info
*info
;
1964 const Elf_Internal_Rela
*relocs
;
1966 struct elfNN_ia64_link_hash_table
*ia64_info
;
1967 const Elf_Internal_Rela
*relend
;
1968 Elf_Internal_Shdr
*symtab_hdr
;
1969 const Elf_Internal_Rela
*rel
;
1970 asection
*got
, *fptr
, *srel
;
1972 if (info
->relocateable
)
1975 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1976 ia64_info
= elfNN_ia64_hash_table (info
);
1978 got
= fptr
= srel
= NULL
;
1980 relend
= relocs
+ sec
->reloc_count
;
1981 for (rel
= relocs
; rel
< relend
; ++rel
)
1990 NEED_LTOFF_FPTR
= 64,
1993 struct elf_link_hash_entry
*h
= NULL
;
1994 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
1995 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1997 boolean maybe_dynamic
;
1998 int dynrel_type
= R_IA64_NONE
;
2000 if (r_symndx
>= symtab_hdr
->sh_info
)
2002 /* We're dealing with a global symbol -- find its hash entry
2003 and mark it as being referenced. */
2004 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2005 h
= elf_sym_hashes (abfd
)[indx
];
2006 while (h
->root
.type
== bfd_link_hash_indirect
2007 || h
->root
.type
== bfd_link_hash_warning
)
2008 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2010 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
2013 /* We can only get preliminary data on whether a symbol is
2014 locally or externally defined, as not all of the input files
2015 have yet been processed. Do something with what we know, as
2016 this may help reduce memory usage and processing time later. */
2017 maybe_dynamic
= false;
2018 if (h
&& ((info
->shared
&& ! info
->symbolic
)
2019 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
2020 || h
->root
.type
== bfd_link_hash_defweak
2021 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2022 maybe_dynamic
= true;
2025 switch (ELFNN_R_TYPE (rel
->r_info
))
2027 case R_IA64_TPREL22
:
2028 case R_IA64_TPREL64MSB
:
2029 case R_IA64_TPREL64LSB
:
2030 case R_IA64_LTOFF_TP22
:
2033 case R_IA64_LTOFF_FPTR22
:
2034 case R_IA64_LTOFF_FPTR64I
:
2035 case R_IA64_LTOFF_FPTR32MSB
:
2036 case R_IA64_LTOFF_FPTR32LSB
:
2037 case R_IA64_LTOFF_FPTR64MSB
:
2038 case R_IA64_LTOFF_FPTR64LSB
:
2039 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2042 case R_IA64_FPTR64I
:
2043 case R_IA64_FPTR32MSB
:
2044 case R_IA64_FPTR32LSB
:
2045 case R_IA64_FPTR64MSB
:
2046 case R_IA64_FPTR64LSB
:
2047 if (info
->shared
|| h
|| elfNN_ia64_aix_vec (abfd
->xvec
))
2048 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2050 need_entry
= NEED_FPTR
;
2051 dynrel_type
= R_IA64_FPTR64LSB
;
2054 case R_IA64_LTOFF22
:
2055 case R_IA64_LTOFF22X
:
2056 case R_IA64_LTOFF64I
:
2057 need_entry
= NEED_GOT
;
2060 case R_IA64_PLTOFF22
:
2061 case R_IA64_PLTOFF64I
:
2062 case R_IA64_PLTOFF64MSB
:
2063 case R_IA64_PLTOFF64LSB
:
2064 need_entry
= NEED_PLTOFF
;
2068 need_entry
|= NEED_MIN_PLT
;
2072 (*info
->callbacks
->warning
)
2073 (info
, _("@pltoff reloc against local symbol"), 0,
2078 case R_IA64_PCREL21B
:
2079 case R_IA64_PCREL60B
:
2080 /* Depending on where this symbol is defined, we may or may not
2081 need a full plt entry. Only skip if we know we'll not need
2082 the entry -- static or symbolic, and the symbol definition
2083 has already been seen. */
2084 if (maybe_dynamic
&& rel
->r_addend
== 0)
2085 need_entry
= NEED_FULL_PLT
;
2091 case R_IA64_DIR32MSB
:
2092 case R_IA64_DIR32LSB
:
2093 case R_IA64_DIR64MSB
:
2094 case R_IA64_DIR64LSB
:
2095 /* Shared objects will always need at least a REL relocation. */
2096 if (info
->shared
|| maybe_dynamic
2097 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2098 && (!h
|| strcmp (h
->root
.root
.string
,
2099 "__GLOB_DATA_PTR") != 0)))
2100 need_entry
= NEED_DYNREL
;
2101 dynrel_type
= R_IA64_DIR64LSB
;
2104 case R_IA64_IPLTMSB
:
2105 case R_IA64_IPLTLSB
:
2106 /* Shared objects will always need at least a REL relocation. */
2107 if (info
->shared
|| maybe_dynamic
)
2108 need_entry
= NEED_DYNREL
;
2109 dynrel_type
= R_IA64_IPLTLSB
;
2112 case R_IA64_PCREL22
:
2113 case R_IA64_PCREL64I
:
2114 case R_IA64_PCREL32MSB
:
2115 case R_IA64_PCREL32LSB
:
2116 case R_IA64_PCREL64MSB
:
2117 case R_IA64_PCREL64LSB
:
2119 need_entry
= NEED_DYNREL
;
2120 dynrel_type
= R_IA64_PCREL64LSB
;
2127 if ((need_entry
& NEED_FPTR
) != 0
2130 (*info
->callbacks
->warning
)
2131 (info
, _("non-zero addend in @fptr reloc"), 0,
2135 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, true);
2137 /* Record whether or not this is a local symbol. */
2140 /* Create what's needed. */
2141 if (need_entry
& NEED_GOT
)
2145 got
= get_got (abfd
, info
, ia64_info
);
2149 dyn_i
->want_got
= 1;
2151 if (need_entry
& NEED_FPTR
)
2155 fptr
= get_fptr (abfd
, info
, ia64_info
);
2160 /* FPTRs for shared libraries are allocated by the dynamic
2161 linker. Make sure this local symbol will appear in the
2162 dynamic symbol table. */
2163 if (!h
&& (info
->shared
2164 /* AIX also needs one */
2165 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2167 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2168 (info
, abfd
, r_symndx
)))
2172 dyn_i
->want_fptr
= 1;
2174 if (need_entry
& NEED_LTOFF_FPTR
)
2175 dyn_i
->want_ltoff_fptr
= 1;
2176 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2178 if (!ia64_info
->root
.dynobj
)
2179 ia64_info
->root
.dynobj
= abfd
;
2180 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2181 dyn_i
->want_plt
= 1;
2183 if (need_entry
& NEED_FULL_PLT
)
2184 dyn_i
->want_plt2
= 1;
2185 if (need_entry
& NEED_PLTOFF
)
2186 dyn_i
->want_pltoff
= 1;
2187 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2191 srel
= get_reloc_section (abfd
, ia64_info
, sec
, true);
2195 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2203 struct elfNN_ia64_allocate_data
2205 struct bfd_link_info
*info
;
2209 /* For cleanliness, and potentially faster dynamic loading, allocate
2210 external GOT entries first. */
2213 allocate_global_data_got (dyn_i
, data
)
2214 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2217 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2220 && ! dyn_i
->want_fptr
2221 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2222 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2223 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2224 "__GLOB_DATA_PTR") != 0))))
2226 dyn_i
->got_offset
= x
->ofs
;
2232 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2235 allocate_global_fptr_got (dyn_i
, data
)
2236 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2239 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2243 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2244 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2246 dyn_i
->got_offset
= x
->ofs
;
2252 /* Lastly, allocate all the GOT entries for local data. */
2255 allocate_local_got (dyn_i
, data
)
2256 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2259 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2262 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2263 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2265 dyn_i
->got_offset
= x
->ofs
;
2271 /* Search for the index of a global symbol in it's defining object file. */
2273 static unsigned long
2274 global_sym_index (h
)
2275 struct elf_link_hash_entry
*h
;
2277 struct elf_link_hash_entry
**p
;
2280 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2281 || h
->root
.type
== bfd_link_hash_defweak
);
2283 obj
= h
->root
.u
.def
.section
->owner
;
2284 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2287 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2290 /* Allocate function descriptors. We can do these for every function
2291 in a main executable that is not exported. */
2294 allocate_fptr (dyn_i
, data
)
2295 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2298 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2300 if (dyn_i
->want_fptr
)
2302 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2305 while (h
->root
.type
== bfd_link_hash_indirect
2306 || h
->root
.type
== bfd_link_hash_warning
)
2307 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2310 /* AIX needs an FPTR in this case. */
2311 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2313 || h
->root
.type
== bfd_link_hash_defined
2314 || h
->root
.type
== bfd_link_hash_defweak
)))
2316 if (h
&& h
->dynindx
== -1)
2318 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2319 || (h
->root
.type
== bfd_link_hash_defweak
));
2321 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2322 (x
->info
, h
->root
.u
.def
.section
->owner
,
2323 global_sym_index (h
)))
2327 dyn_i
->want_fptr
= 0;
2329 else if (h
== NULL
|| h
->dynindx
== -1)
2331 dyn_i
->fptr_offset
= x
->ofs
;
2335 dyn_i
->want_fptr
= 0;
2340 /* Allocate all the minimal PLT entries. */
2343 allocate_plt_entries (dyn_i
, data
)
2344 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2347 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2349 if (dyn_i
->want_plt
)
2351 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2354 while (h
->root
.type
== bfd_link_hash_indirect
2355 || h
->root
.type
== bfd_link_hash_warning
)
2356 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2358 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2359 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2361 bfd_size_type offset
= x
->ofs
;
2363 offset
= PLT_HEADER_SIZE
;
2364 dyn_i
->plt_offset
= offset
;
2365 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2367 dyn_i
->want_pltoff
= 1;
2371 dyn_i
->want_plt
= 0;
2372 dyn_i
->want_plt2
= 0;
2378 /* Allocate all the full PLT entries. */
2381 allocate_plt2_entries (dyn_i
, data
)
2382 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2385 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2387 if (dyn_i
->want_plt2
)
2389 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2390 bfd_size_type ofs
= x
->ofs
;
2392 dyn_i
->plt2_offset
= ofs
;
2393 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2395 while (h
->root
.type
== bfd_link_hash_indirect
2396 || h
->root
.type
== bfd_link_hash_warning
)
2397 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2398 dyn_i
->h
->plt
.offset
= ofs
;
2403 /* Allocate all the PLTOFF entries requested by relocations and
2404 plt entries. We can't share space with allocated FPTR entries,
2405 because the latter are not necessarily addressable by the GP.
2406 ??? Relaxation might be able to determine that they are. */
2409 allocate_pltoff_entries (dyn_i
, data
)
2410 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2413 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2415 if (dyn_i
->want_pltoff
)
2417 dyn_i
->pltoff_offset
= x
->ofs
;
2423 /* Allocate dynamic relocations for those symbols that turned out
2427 allocate_dynrel_entries (dyn_i
, data
)
2428 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2431 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2432 struct elfNN_ia64_link_hash_table
*ia64_info
;
2433 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2434 boolean dynamic_symbol
, shared
;
2436 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2437 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2438 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2439 /* Don't allocate an entry for __GLOB_DATA_PTR */
2440 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2441 "__GLOB_DATA_PTR") != 0));
2442 shared
= x
->info
->shared
;
2444 /* Take care of the normal data relocations. */
2446 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2448 int count
= rent
->count
;
2452 case R_IA64_FPTR64LSB
:
2453 /* Allocate one iff !want_fptr, which by this point will
2454 be true only if we're actually allocating one statically
2455 in the main executable. */
2456 if (dyn_i
->want_fptr
)
2459 case R_IA64_PCREL64LSB
:
2460 if (!dynamic_symbol
)
2463 case R_IA64_DIR64LSB
:
2464 if (!dynamic_symbol
&& !shared
)
2467 case R_IA64_IPLTLSB
:
2468 if (!dynamic_symbol
&& !shared
)
2470 /* Use two REL relocations for IPLT relocations
2471 against local symbols. */
2472 if (!dynamic_symbol
)
2478 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2481 /* Take care of the GOT and PLT relocations. */
2483 if (((dynamic_symbol
|| shared
) && dyn_i
->want_got
)
2484 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2485 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2487 if (dyn_i
->want_pltoff
)
2489 bfd_size_type t
= 0;
2491 /* Dynamic symbols get one IPLT relocation. Local symbols in
2492 shared libraries get two REL relocations. Local symbols in
2493 main applications get nothing. */
2495 t
= sizeof (ElfNN_External_Rela
);
2497 t
= 2 * sizeof (ElfNN_External_Rela
);
2499 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2506 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2507 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2508 struct elf_link_hash_entry
*h
;
2510 /* ??? Undefined symbols with PLT entries should be re-defined
2511 to be the PLT entry. */
2513 /* If this is a weak symbol, and there is a real definition, the
2514 processor independent code will have arranged for us to see the
2515 real definition first, and we can just use the same value. */
2516 if (h
->weakdef
!= NULL
)
2518 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2519 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2520 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2521 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2525 /* If this is a reference to a symbol defined by a dynamic object which
2526 is not a function, we might allocate the symbol in our .dynbss section
2527 and allocate a COPY dynamic relocation.
2529 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2536 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2538 struct bfd_link_info
*info
;
2540 struct elfNN_ia64_allocate_data data
;
2541 struct elfNN_ia64_link_hash_table
*ia64_info
;
2544 boolean relplt
= false;
2546 dynobj
= elf_hash_table(info
)->dynobj
;
2547 ia64_info
= elfNN_ia64_hash_table (info
);
2548 BFD_ASSERT(dynobj
!= NULL
);
2551 /* Set the contents of the .interp section to the interpreter. */
2552 if (ia64_info
->root
.dynamic_sections_created
2555 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2556 BFD_ASSERT (sec
!= NULL
);
2557 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2558 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2561 /* Allocate the GOT entries. */
2563 if (ia64_info
->got_sec
)
2566 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2567 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2568 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2569 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2572 /* Allocate the FPTR entries. */
2574 if (ia64_info
->fptr_sec
)
2577 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2578 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2581 /* Now that we've seen all of the input files, we can decide which
2582 symbols need plt entries. Allocate the minimal PLT entries first.
2583 We do this even though dynamic_sections_created may be false, because
2584 this has the side-effect of clearing want_plt and want_plt2. */
2587 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2589 ia64_info
->minplt_entries
= 0;
2592 ia64_info
->minplt_entries
2593 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2596 /* Align the pointer for the plt2 entries. */
2597 data
.ofs
= (data
.ofs
+ 31) & -32;
2599 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2602 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2604 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2606 /* If we've got a .plt, we need some extra memory for the dynamic
2607 linker. We stuff these in .got.plt. */
2608 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2609 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2612 /* Allocate the PLTOFF entries. */
2614 if (ia64_info
->pltoff_sec
)
2617 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2618 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2621 if (ia64_info
->root
.dynamic_sections_created
)
2623 /* Allocate space for the dynamic relocations that turned out to be
2626 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2629 /* We have now determined the sizes of the various dynamic sections.
2630 Allocate memory for them. */
2631 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2635 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2638 /* If we don't need this section, strip it from the output file.
2639 There were several sections primarily related to dynamic
2640 linking that must be create before the linker maps input
2641 sections to output sections. The linker does that before
2642 bfd_elf_size_dynamic_sections is called, and it is that
2643 function which decides whether anything needs to go into
2646 strip
= (sec
->_raw_size
== 0);
2648 if (sec
== ia64_info
->got_sec
)
2650 else if (sec
== ia64_info
->rel_got_sec
)
2653 ia64_info
->rel_got_sec
= NULL
;
2655 /* We use the reloc_count field as a counter if we need to
2656 copy relocs into the output file. */
2657 sec
->reloc_count
= 0;
2659 else if (sec
== ia64_info
->fptr_sec
)
2662 ia64_info
->fptr_sec
= NULL
;
2664 else if (sec
== ia64_info
->plt_sec
)
2667 ia64_info
->plt_sec
= NULL
;
2669 else if (sec
== ia64_info
->pltoff_sec
)
2672 ia64_info
->pltoff_sec
= NULL
;
2674 else if (sec
== ia64_info
->rel_pltoff_sec
)
2677 ia64_info
->rel_pltoff_sec
= NULL
;
2681 /* We use the reloc_count field as a counter if we need to
2682 copy relocs into the output file. */
2683 sec
->reloc_count
= 0;
2690 /* It's OK to base decisions on the section name, because none
2691 of the dynobj section names depend upon the input files. */
2692 name
= bfd_get_section_name (dynobj
, sec
);
2694 if (strcmp (name
, ".got.plt") == 0)
2696 else if (strncmp (name
, ".rel", 4) == 0)
2700 /* We use the reloc_count field as a counter if we need to
2701 copy relocs into the output file. */
2702 sec
->reloc_count
= 0;
2710 _bfd_strip_section_from_output (info
, sec
);
2713 /* Allocate memory for the section contents. */
2714 sec
->contents
= (bfd_byte
*) bfd_zalloc(dynobj
, sec
->_raw_size
);
2715 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
2720 if (elf_hash_table (info
)->dynamic_sections_created
)
2722 /* Add some entries to the .dynamic section. We fill in the values
2723 later (in finish_dynamic_sections) but we must add the entries now
2724 so that we get the correct size for the .dynamic section. */
2728 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2730 if (!bfd_elfNN_add_dynamic_entry (info
, DT_DEBUG
, 0))
2734 if (! bfd_elfNN_add_dynamic_entry (info
, DT_IA_64_PLT_RESERVE
, 0))
2736 if (! bfd_elfNN_add_dynamic_entry (info
, DT_PLTGOT
, 0))
2741 if (! bfd_elfNN_add_dynamic_entry (info
, DT_PLTRELSZ
, 0)
2742 || ! bfd_elfNN_add_dynamic_entry (info
, DT_PLTREL
, DT_RELA
)
2743 || ! bfd_elfNN_add_dynamic_entry (info
, DT_JMPREL
, 0))
2747 if (! bfd_elfNN_add_dynamic_entry (info
, DT_RELA
, 0)
2748 || ! bfd_elfNN_add_dynamic_entry (info
, DT_RELASZ
, 0)
2749 || ! bfd_elfNN_add_dynamic_entry (info
, DT_RELAENT
,
2750 sizeof (ElfNN_External_Rela
)))
2753 if (ia64_info
->reltext
)
2755 if (! bfd_elfNN_add_dynamic_entry (info
, DT_TEXTREL
, 0))
2757 info
->flags
|= DF_TEXTREL
;
2761 /* ??? Perhaps force __gp local. */
2766 static bfd_reloc_status_type
2767 elfNN_ia64_install_value (abfd
, hit_addr
, val
, r_type
)
2771 unsigned int r_type
;
2773 const struct ia64_operand
*op
;
2774 int bigendian
= 0, shift
= 0;
2775 bfd_vma t0
, t1
, insn
, dword
;
2776 enum ia64_opnd opnd
;
2780 opnd
= IA64_OPND_NIL
;
2785 return bfd_reloc_ok
;
2787 /* Instruction relocations. */
2789 case R_IA64_IMM14
: opnd
= IA64_OPND_IMM14
; break;
2791 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
2792 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
2793 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
2794 case R_IA64_PCREL21B
:
2795 case R_IA64_PCREL21BI
:
2796 opnd
= IA64_OPND_TGT25c
;
2800 case R_IA64_GPREL22
:
2801 case R_IA64_LTOFF22
:
2802 case R_IA64_LTOFF22X
:
2803 case R_IA64_PLTOFF22
:
2804 case R_IA64_PCREL22
:
2805 case R_IA64_LTOFF_FPTR22
:
2806 opnd
= IA64_OPND_IMM22
;
2810 case R_IA64_GPREL64I
:
2811 case R_IA64_LTOFF64I
:
2812 case R_IA64_PLTOFF64I
:
2813 case R_IA64_PCREL64I
:
2814 case R_IA64_FPTR64I
:
2815 case R_IA64_LTOFF_FPTR64I
:
2816 opnd
= IA64_OPND_IMMU64
;
2819 /* Data relocations. */
2821 case R_IA64_DIR32MSB
:
2822 case R_IA64_GPREL32MSB
:
2823 case R_IA64_FPTR32MSB
:
2824 case R_IA64_PCREL32MSB
:
2825 case R_IA64_LTOFF_FPTR32MSB
:
2826 case R_IA64_SEGREL32MSB
:
2827 case R_IA64_SECREL32MSB
:
2828 case R_IA64_LTV32MSB
:
2829 size
= 4; bigendian
= 1;
2832 case R_IA64_DIR32LSB
:
2833 case R_IA64_GPREL32LSB
:
2834 case R_IA64_FPTR32LSB
:
2835 case R_IA64_PCREL32LSB
:
2836 case R_IA64_LTOFF_FPTR32LSB
:
2837 case R_IA64_SEGREL32LSB
:
2838 case R_IA64_SECREL32LSB
:
2839 case R_IA64_LTV32LSB
:
2840 size
= 4; bigendian
= 0;
2843 case R_IA64_DIR64MSB
:
2844 case R_IA64_GPREL64MSB
:
2845 case R_IA64_PLTOFF64MSB
:
2846 case R_IA64_FPTR64MSB
:
2847 case R_IA64_PCREL64MSB
:
2848 case R_IA64_LTOFF_FPTR64MSB
:
2849 case R_IA64_SEGREL64MSB
:
2850 case R_IA64_SECREL64MSB
:
2851 case R_IA64_LTV64MSB
:
2852 size
= 8; bigendian
= 1;
2855 case R_IA64_DIR64LSB
:
2856 case R_IA64_GPREL64LSB
:
2857 case R_IA64_PLTOFF64LSB
:
2858 case R_IA64_FPTR64LSB
:
2859 case R_IA64_PCREL64LSB
:
2860 case R_IA64_LTOFF_FPTR64LSB
:
2861 case R_IA64_SEGREL64LSB
:
2862 case R_IA64_SECREL64LSB
:
2863 case R_IA64_LTV64LSB
:
2864 size
= 8; bigendian
= 0;
2867 /* Unsupported / Dynamic relocations. */
2869 return bfd_reloc_notsupported
;
2874 case IA64_OPND_IMMU64
:
2875 hit_addr
-= (long) hit_addr
& 0x3;
2876 t0
= bfd_get_64 (abfd
, hit_addr
);
2877 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2879 /* tmpl/s: bits 0.. 5 in t0
2880 slot 0: bits 5..45 in t0
2881 slot 1: bits 46..63 in t0, bits 0..22 in t1
2882 slot 2: bits 23..63 in t1 */
2884 /* First, clear the bits that form the 64 bit constant. */
2885 t0
&= ~(0x3ffffLL
<< 46);
2887 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
2888 | (0x01fLL
<< 22) | (0x001LL
<< 21)
2889 | (0x001LL
<< 36)) << 23));
2891 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
2892 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
2893 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
2894 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
2895 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
2896 | (((val
>> 21) & 0x001) << 21) /* ic */
2897 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
2899 bfd_put_64 (abfd
, t0
, hit_addr
);
2900 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2903 case IA64_OPND_TGT64
:
2904 hit_addr
-= (long) hit_addr
& 0x3;
2905 t0
= bfd_get_64 (abfd
, hit_addr
);
2906 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2908 /* tmpl/s: bits 0.. 5 in t0
2909 slot 0: bits 5..45 in t0
2910 slot 1: bits 46..63 in t0, bits 0..22 in t1
2911 slot 2: bits 23..63 in t1 */
2913 /* First, clear the bits that form the 64 bit constant. */
2914 t0
&= ~(0x3ffffLL
<< 46);
2916 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
2919 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
2920 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
2921 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
2922 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
2924 bfd_put_64 (abfd
, t0
, hit_addr
);
2925 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2929 switch ((long) hit_addr
& 0x3)
2931 case 0: shift
= 5; break;
2932 case 1: shift
= 14; hit_addr
+= 3; break;
2933 case 2: shift
= 23; hit_addr
+= 6; break;
2934 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
2936 dword
= bfd_get_64 (abfd
, hit_addr
);
2937 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
2939 op
= elf64_ia64_operands
+ opnd
;
2940 err
= (*op
->insert
) (op
, val
, &insn
);
2942 return bfd_reloc_overflow
;
2944 dword
&= ~(0x1ffffffffffLL
<< shift
);
2945 dword
|= (insn
<< shift
);
2946 bfd_put_64 (abfd
, dword
, hit_addr
);
2950 /* A data relocation. */
2953 bfd_putb32 (val
, hit_addr
);
2955 bfd_putb64 (val
, hit_addr
);
2958 bfd_putl32 (val
, hit_addr
);
2960 bfd_putl64 (val
, hit_addr
);
2964 return bfd_reloc_ok
;
2968 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
2971 struct bfd_link_info
*info
;
2979 Elf_Internal_Rela outrel
;
2981 outrel
.r_offset
= (sec
->output_section
->vma
2982 + sec
->output_offset
2985 BFD_ASSERT (dynindx
!= -1);
2986 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
2987 outrel
.r_addend
= addend
;
2989 if (elf_section_data (sec
)->stab_info
!= NULL
)
2991 /* This may be NULL for linker-generated relocations, as it is
2992 inconvenient to pass all the bits around. And this shouldn't
2994 BFD_ASSERT (info
!= NULL
);
2996 offset
= (_bfd_stab_section_offset
2997 (abfd
, &elf_hash_table (info
)->stab_info
, sec
,
2998 &elf_section_data (sec
)->stab_info
, offset
));
2999 if (offset
== (bfd_vma
) -1)
3001 /* Run for the hills. We shouldn't be outputting a relocation
3002 for this. So do what everyone else does and output a no-op. */
3003 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3004 outrel
.r_addend
= 0;
3007 outrel
.r_offset
= offset
;
3010 bfd_elfNN_swap_reloca_out (abfd
, &outrel
,
3011 ((ElfNN_External_Rela
*) srel
->contents
3012 + srel
->reloc_count
++));
3013 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3014 <= srel
->_cooked_size
);
3017 /* Store an entry for target address TARGET_ADDR in the linkage table
3018 and return the gp-relative address of the linkage table entry. */
3021 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3023 struct bfd_link_info
*info
;
3024 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3028 unsigned int dyn_r_type
;
3030 struct elfNN_ia64_link_hash_table
*ia64_info
;
3033 ia64_info
= elfNN_ia64_hash_table (info
);
3034 got_sec
= ia64_info
->got_sec
;
3036 BFD_ASSERT ((dyn_i
->got_offset
& 7) == 0);
3038 if (! dyn_i
->got_done
)
3040 dyn_i
->got_done
= true;
3042 /* Store the target address in the linkage table entry. */
3043 bfd_put_64 (abfd
, value
, got_sec
->contents
+ dyn_i
->got_offset
);
3045 /* Install a dynamic relocation if needed. */
3047 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3048 || elfNN_ia64_aix_vec (abfd
->xvec
)
3049 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3053 dyn_r_type
= R_IA64_REL64LSB
;
3058 if (bfd_big_endian (abfd
))
3062 case R_IA64_REL64LSB
:
3063 dyn_r_type
= R_IA64_REL64MSB
;
3065 case R_IA64_DIR64LSB
:
3066 dyn_r_type
= R_IA64_DIR64MSB
;
3068 case R_IA64_FPTR64LSB
:
3069 dyn_r_type
= R_IA64_FPTR64MSB
;
3077 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3078 ia64_info
->rel_got_sec
,
3079 dyn_i
->got_offset
, dyn_r_type
,
3084 /* Return the address of the linkage table entry. */
3085 value
= (got_sec
->output_section
->vma
3086 + got_sec
->output_offset
3087 + dyn_i
->got_offset
);
3092 /* Fill in a function descriptor consisting of the function's code
3093 address and its global pointer. Return the descriptor's address. */
3096 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3098 struct bfd_link_info
*info
;
3099 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3102 struct elfNN_ia64_link_hash_table
*ia64_info
;
3105 ia64_info
= elfNN_ia64_hash_table (info
);
3106 fptr_sec
= ia64_info
->fptr_sec
;
3108 if (!dyn_i
->fptr_done
)
3110 dyn_i
->fptr_done
= 1;
3112 /* Fill in the function descriptor. */
3113 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3114 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3115 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3118 /* Return the descriptor's address. */
3119 value
= (fptr_sec
->output_section
->vma
3120 + fptr_sec
->output_offset
3121 + dyn_i
->fptr_offset
);
3126 /* Fill in a PLTOFF entry consisting of the function's code address
3127 and its global pointer. Return the descriptor's address. */
3130 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3132 struct bfd_link_info
*info
;
3133 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3137 struct elfNN_ia64_link_hash_table
*ia64_info
;
3138 asection
*pltoff_sec
;
3140 ia64_info
= elfNN_ia64_hash_table (info
);
3141 pltoff_sec
= ia64_info
->pltoff_sec
;
3143 /* Don't do anything if this symbol uses a real PLT entry. In
3144 that case, we'll fill this in during finish_dynamic_symbol. */
3145 if ((! dyn_i
->want_plt
|| is_plt
)
3146 && !dyn_i
->pltoff_done
)
3148 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3150 /* Fill in the function descriptor. */
3151 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3152 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3154 /* Install dynamic relocations if needed. */
3155 if (!is_plt
&& info
->shared
)
3157 unsigned int dyn_r_type
;
3159 if (bfd_big_endian (abfd
))
3160 dyn_r_type
= R_IA64_REL64MSB
;
3162 dyn_r_type
= R_IA64_REL64LSB
;
3164 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3165 ia64_info
->rel_pltoff_sec
,
3166 dyn_i
->pltoff_offset
,
3167 dyn_r_type
, 0, value
);
3168 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3169 ia64_info
->rel_pltoff_sec
,
3170 dyn_i
->pltoff_offset
+ 8,
3174 dyn_i
->pltoff_done
= 1;
3177 /* Return the descriptor's address. */
3178 value
= (pltoff_sec
->output_section
->vma
3179 + pltoff_sec
->output_offset
3180 + dyn_i
->pltoff_offset
);
3185 /* Called through qsort to sort the .IA_64.unwind section during a
3186 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3187 to the output bfd so we can do proper endianness frobbing. */
3189 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3192 elfNN_ia64_unwind_entry_compare (a
, b
)
3198 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3199 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3201 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3205 elfNN_ia64_final_link (abfd
, info
)
3207 struct bfd_link_info
*info
;
3209 struct elfNN_ia64_link_hash_table
*ia64_info
;
3210 asection
*unwind_output_sec
;
3212 ia64_info
= elfNN_ia64_hash_table (info
);
3214 /* Make sure we've got ourselves a nice fat __gp value. */
3215 if (!info
->relocateable
)
3217 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3218 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3219 struct elf_link_hash_entry
*gp
;
3223 /* Find the min and max vma of all sections marked short. Also
3224 collect min and max vma of any type, for use in selecting a
3226 for (os
= abfd
->sections
; os
; os
= os
->next
)
3230 if ((os
->flags
& SEC_ALLOC
) == 0)
3234 hi
= os
->vma
+ os
->_raw_size
;
3242 if (os
->flags
& SEC_SMALL_DATA
)
3244 if (min_short_vma
> lo
)
3246 if (max_short_vma
< hi
)
3251 /* See if the user wants to force a value. */
3252 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", false,
3256 && (gp
->root
.type
== bfd_link_hash_defined
3257 || gp
->root
.type
== bfd_link_hash_defweak
))
3259 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3260 gp_val
= (gp
->root
.u
.def
.value
3261 + gp_sec
->output_section
->vma
3262 + gp_sec
->output_offset
);
3266 /* Pick a sensible value. */
3268 asection
*got_sec
= ia64_info
->got_sec
;
3270 /* Start with just the address of the .got. */
3272 gp_val
= got_sec
->output_section
->vma
;
3273 else if (max_short_vma
!= 0)
3274 gp_val
= min_short_vma
;
3278 /* If it is possible to address the entire image, but we
3279 don't with the choice above, adjust. */
3280 if (max_vma
- min_vma
< 0x400000
3281 && max_vma
- gp_val
<= 0x200000
3282 && gp_val
- min_vma
> 0x200000)
3283 gp_val
= min_vma
+ 0x200000;
3284 else if (max_short_vma
!= 0)
3286 /* If we don't cover all the short data, adjust. */
3287 if (max_short_vma
- gp_val
>= 0x200000)
3288 gp_val
= min_short_vma
+ 0x200000;
3290 /* If we're addressing stuff past the end, adjust back. */
3291 if (gp_val
> max_vma
)
3292 gp_val
= max_vma
- 0x200000 + 8;
3296 /* Validate whether all SHF_IA_64_SHORT sections are within
3297 range of the chosen GP. */
3299 if (max_short_vma
!= 0)
3301 if (max_short_vma
- min_short_vma
>= 0x400000)
3303 (*_bfd_error_handler
)
3304 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3305 bfd_get_filename (abfd
),
3306 (unsigned long) (max_short_vma
- min_short_vma
));
3309 else if ((gp_val
> min_short_vma
3310 && gp_val
- min_short_vma
> 0x200000)
3311 || (gp_val
< max_short_vma
3312 && max_short_vma
- gp_val
>= 0x200000))
3314 (*_bfd_error_handler
)
3315 (_("%s: __gp does not cover short data segment"),
3316 bfd_get_filename (abfd
));
3321 _bfd_set_gp_value (abfd
, gp_val
);
3325 gp
->root
.type
= bfd_link_hash_defined
;
3326 gp
->root
.u
.def
.value
= gp_val
;
3327 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3331 /* If we're producing a final executable, we need to sort the contents
3332 of the .IA_64.unwind section. Force this section to be relocated
3333 into memory rather than written immediately to the output file. */
3334 unwind_output_sec
= NULL
;
3335 if (!info
->relocateable
)
3337 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3340 unwind_output_sec
= s
->output_section
;
3341 unwind_output_sec
->contents
3342 = bfd_malloc (unwind_output_sec
->_raw_size
);
3343 if (unwind_output_sec
->contents
== NULL
)
3348 /* Invoke the regular ELF backend linker to do all the work. */
3349 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3352 if (unwind_output_sec
)
3354 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3355 qsort (unwind_output_sec
->contents
, unwind_output_sec
->_raw_size
/ 24,
3356 24, elfNN_ia64_unwind_entry_compare
);
3358 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3359 unwind_output_sec
->contents
, 0,
3360 unwind_output_sec
->_raw_size
))
3368 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3369 contents
, relocs
, local_syms
, local_sections
)
3371 struct bfd_link_info
*info
;
3373 asection
*input_section
;
3375 Elf_Internal_Rela
*relocs
;
3376 Elf_Internal_Sym
*local_syms
;
3377 asection
**local_sections
;
3379 struct elfNN_ia64_link_hash_table
*ia64_info
;
3380 Elf_Internal_Shdr
*symtab_hdr
;
3381 Elf_Internal_Rela
*rel
;
3382 Elf_Internal_Rela
*relend
;
3384 boolean ret_val
= true; /* for non-fatal errors */
3387 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3388 ia64_info
= elfNN_ia64_hash_table (info
);
3390 /* Infect various flags from the input section to the output section. */
3391 if (info
->relocateable
)
3395 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3396 flags
&= SHF_IA_64_NORECOV
;
3398 elf_section_data(input_section
->output_section
)
3399 ->this_hdr
.sh_flags
|= flags
;
3402 gp_val
= _bfd_get_gp_value (output_bfd
);
3403 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, false);
3406 relend
= relocs
+ input_section
->reloc_count
;
3407 for (; rel
< relend
; ++rel
)
3409 struct elf_link_hash_entry
*h
;
3410 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3411 bfd_reloc_status_type r
;
3412 reloc_howto_type
*howto
;
3413 unsigned long r_symndx
;
3414 Elf_Internal_Sym
*sym
;
3415 unsigned int r_type
;
3419 boolean dynamic_symbol_p
;
3420 boolean undef_weak_ref
;
3422 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3423 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3425 (*_bfd_error_handler
)
3426 (_("%s: unknown relocation type %d"),
3427 bfd_get_filename (input_bfd
), (int)r_type
);
3428 bfd_set_error (bfd_error_bad_value
);
3432 howto
= lookup_howto (r_type
);
3433 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3435 if (info
->relocateable
)
3437 /* This is a relocateable link. We don't have to change
3438 anything, unless the reloc is against a section symbol,
3439 in which case we have to adjust according to where the
3440 section symbol winds up in the output section. */
3441 if (r_symndx
< symtab_hdr
->sh_info
)
3443 sym
= local_syms
+ r_symndx
;
3444 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
3446 sym_sec
= local_sections
[r_symndx
];
3447 rel
->r_addend
+= sym_sec
->output_offset
;
3453 /* This is a final link. */
3458 undef_weak_ref
= false;
3460 if (r_symndx
< symtab_hdr
->sh_info
)
3462 /* Reloc against local symbol. */
3463 sym
= local_syms
+ r_symndx
;
3464 sym_sec
= local_sections
[r_symndx
];
3465 value
= (sym_sec
->output_section
->vma
3466 + sym_sec
->output_offset
3473 /* Reloc against global symbol. */
3474 indx
= r_symndx
- symtab_hdr
->sh_info
;
3475 h
= elf_sym_hashes (input_bfd
)[indx
];
3476 while (h
->root
.type
== bfd_link_hash_indirect
3477 || h
->root
.type
== bfd_link_hash_warning
)
3478 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3481 if (h
->root
.type
== bfd_link_hash_defined
3482 || h
->root
.type
== bfd_link_hash_defweak
)
3484 sym_sec
= h
->root
.u
.def
.section
;
3486 /* Detect the cases that sym_sec->output_section is
3487 expected to be NULL -- all cases in which the symbol
3488 is defined in another shared module. This includes
3489 PLT relocs for which we've created a PLT entry and
3490 other relocs for which we're prepared to create
3491 dynamic relocations. */
3492 /* ??? Just accept it NULL and continue. */
3494 if (sym_sec
->output_section
!= NULL
)
3496 value
= (h
->root
.u
.def
.value
3497 + sym_sec
->output_section
->vma
3498 + sym_sec
->output_offset
);
3501 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3502 undef_weak_ref
= true;
3503 else if (info
->shared
&& !info
->symbolic
3504 && !info
->no_undefined
3505 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3509 if (! ((*info
->callbacks
->undefined_symbol
)
3510 (info
, h
->root
.root
.string
, input_bfd
,
3511 input_section
, rel
->r_offset
,
3512 (!info
->shared
|| info
->no_undefined
3513 || ELF_ST_VISIBILITY (h
->other
)))))
3520 hit_addr
= contents
+ rel
->r_offset
;
3521 value
+= rel
->r_addend
;
3522 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3533 case R_IA64_DIR32MSB
:
3534 case R_IA64_DIR32LSB
:
3535 case R_IA64_DIR64MSB
:
3536 case R_IA64_DIR64LSB
:
3537 /* Install a dynamic relocation for this reloc. */
3538 if ((dynamic_symbol_p
|| info
->shared
3539 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
3540 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3541 && (!h
|| strcmp (h
->root
.root
.string
,
3542 "__GLOB_DATA_PTR") != 0)))
3543 && (input_section
->flags
& SEC_ALLOC
) != 0)
3545 unsigned int dyn_r_type
;
3549 BFD_ASSERT (srel
!= NULL
);
3551 /* If we don't need dynamic symbol lookup, find a
3552 matching RELATIVE relocation. */
3553 dyn_r_type
= r_type
;
3554 if (dynamic_symbol_p
)
3556 dynindx
= h
->dynindx
;
3557 addend
= rel
->r_addend
;
3564 case R_IA64_DIR32MSB
:
3565 dyn_r_type
= R_IA64_REL32MSB
;
3567 case R_IA64_DIR32LSB
:
3568 dyn_r_type
= R_IA64_REL32LSB
;
3570 case R_IA64_DIR64MSB
:
3571 dyn_r_type
= R_IA64_REL64MSB
;
3573 case R_IA64_DIR64LSB
:
3574 dyn_r_type
= R_IA64_REL64LSB
;
3578 /* We can't represent this without a dynamic symbol.
3579 Adjust the relocation to be against an output
3580 section symbol, which are always present in the
3581 dynamic symbol table. */
3582 /* ??? People shouldn't be doing non-pic code in
3583 shared libraries. Hork. */
3584 (*_bfd_error_handler
)
3585 (_("%s: linking non-pic code in a shared library"),
3586 bfd_get_filename (input_bfd
));
3594 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
3595 rel
->r_addend
= value
;
3596 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3597 srel
, rel
->r_offset
, dyn_r_type
,
3602 case R_IA64_LTV32MSB
:
3603 case R_IA64_LTV32LSB
:
3604 case R_IA64_LTV64MSB
:
3605 case R_IA64_LTV64LSB
:
3606 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3609 case R_IA64_GPREL22
:
3610 case R_IA64_GPREL64I
:
3611 case R_IA64_GPREL32MSB
:
3612 case R_IA64_GPREL32LSB
:
3613 case R_IA64_GPREL64MSB
:
3614 case R_IA64_GPREL64LSB
:
3615 if (dynamic_symbol_p
)
3617 (*_bfd_error_handler
)
3618 (_("%s: @gprel relocation against dynamic symbol %s"),
3619 bfd_get_filename (input_bfd
), h
->root
.root
.string
);
3624 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3627 case R_IA64_LTOFF22
:
3628 case R_IA64_LTOFF22X
:
3629 case R_IA64_LTOFF64I
:
3630 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3631 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
3632 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
3634 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3637 case R_IA64_PLTOFF22
:
3638 case R_IA64_PLTOFF64I
:
3639 case R_IA64_PLTOFF64MSB
:
3640 case R_IA64_PLTOFF64LSB
:
3641 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3642 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, false);
3644 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3647 case R_IA64_FPTR64I
:
3648 case R_IA64_FPTR32MSB
:
3649 case R_IA64_FPTR32LSB
:
3650 case R_IA64_FPTR64MSB
:
3651 case R_IA64_FPTR64LSB
:
3652 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3653 if (dyn_i
->want_fptr
)
3655 if (!undef_weak_ref
)
3656 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3662 /* Otherwise, we expect the dynamic linker to create
3667 if (h
->dynindx
!= -1)
3668 dynindx
= h
->dynindx
;
3670 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3671 (info
, h
->root
.u
.def
.section
->owner
,
3672 global_sym_index (h
)));
3676 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3677 (info
, input_bfd
, r_symndx
));
3680 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3681 srel
, rel
->r_offset
, r_type
,
3682 dynindx
, rel
->r_addend
);
3686 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3689 case R_IA64_LTOFF_FPTR22
:
3690 case R_IA64_LTOFF_FPTR64I
:
3691 case R_IA64_LTOFF_FPTR32MSB
:
3692 case R_IA64_LTOFF_FPTR32LSB
:
3693 case R_IA64_LTOFF_FPTR64MSB
:
3694 case R_IA64_LTOFF_FPTR64LSB
:
3698 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3699 if (dyn_i
->want_fptr
)
3701 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
3702 if (!undef_weak_ref
)
3703 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3708 /* Otherwise, we expect the dynamic linker to create
3712 if (h
->dynindx
!= -1)
3713 dynindx
= h
->dynindx
;
3715 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3716 (info
, h
->root
.u
.def
.section
->owner
,
3717 global_sym_index (h
)));
3720 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3721 (info
, input_bfd
, r_symndx
));
3725 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
3726 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
3728 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3732 case R_IA64_PCREL32MSB
:
3733 case R_IA64_PCREL32LSB
:
3734 case R_IA64_PCREL64MSB
:
3735 case R_IA64_PCREL64LSB
:
3736 /* Install a dynamic relocation for this reloc. */
3737 if (dynamic_symbol_p
3738 || elfNN_ia64_aix_vec (info
->hash
->creator
))
3740 BFD_ASSERT (srel
!= NULL
);
3742 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3743 srel
, rel
->r_offset
, r_type
,
3744 h
->dynindx
, rel
->r_addend
);
3748 case R_IA64_PCREL21BI
:
3749 case R_IA64_PCREL21F
:
3750 case R_IA64_PCREL21M
:
3751 /* ??? These two are only used for speculation fixup code.
3752 They should never be dynamic. */
3753 if (dynamic_symbol_p
)
3755 (*_bfd_error_handler
)
3756 (_("%s: dynamic relocation against speculation fixup"),
3757 bfd_get_filename (input_bfd
));
3763 (*_bfd_error_handler
)
3764 (_("%s: speculation fixup against undefined weak symbol"),
3765 bfd_get_filename (input_bfd
));
3771 case R_IA64_PCREL21B
:
3772 case R_IA64_PCREL60B
:
3773 /* We should have created a PLT entry for any dynamic symbol. */
3776 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
3778 if (dyn_i
&& dyn_i
->want_plt2
)
3780 /* Should have caught this earlier. */
3781 BFD_ASSERT (rel
->r_addend
== 0);
3783 value
= (ia64_info
->plt_sec
->output_section
->vma
3784 + ia64_info
->plt_sec
->output_offset
3785 + dyn_i
->plt2_offset
);
3789 /* Since there's no PLT entry, Validate that this is
3791 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
3793 /* If the symbol is undef_weak, we shouldn't be trying
3794 to call it. There's every chance that we'd wind up
3795 with an out-of-range fixup here. Don't bother setting
3796 any value at all. */
3802 case R_IA64_PCREL22
:
3803 case R_IA64_PCREL64I
:
3805 /* Make pc-relative. */
3806 value
-= (input_section
->output_section
->vma
3807 + input_section
->output_offset
3808 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
3809 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3812 case R_IA64_SEGREL32MSB
:
3813 case R_IA64_SEGREL32LSB
:
3814 case R_IA64_SEGREL64MSB
:
3815 case R_IA64_SEGREL64LSB
:
3817 struct elf_segment_map
*m
;
3818 Elf_Internal_Phdr
*p
;
3820 /* Find the segment that contains the output_section. */
3821 for (m
= elf_tdata (output_bfd
)->segment_map
,
3822 p
= elf_tdata (output_bfd
)->phdr
;
3827 for (i
= m
->count
- 1; i
>= 0; i
--)
3828 if (m
->sections
[i
] == sym_sec
->output_section
)
3836 /* If the input section was discarded from the output, then
3839 if (bfd_is_abs_section (sym_sec
->output_section
))
3842 r
= bfd_reloc_notsupported
;
3846 /* The VMA of the segment is the vaddr of the associated
3848 if (value
> p
->p_vaddr
)
3849 value
-= p
->p_vaddr
;
3852 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
3858 case R_IA64_SECREL32MSB
:
3859 case R_IA64_SECREL32LSB
:
3860 case R_IA64_SECREL64MSB
:
3861 case R_IA64_SECREL64LSB
:
3862 /* Make output-section relative. */
3863 if (value
> input_section
->output_section
->vma
)
3864 value
-= input_section
->output_section
->vma
;
3867 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3870 case R_IA64_IPLTMSB
:
3871 case R_IA64_IPLTLSB
:
3872 /* Install a dynamic relocation for this reloc. */
3873 if ((dynamic_symbol_p
|| info
->shared
)
3874 && (input_section
->flags
& SEC_ALLOC
) != 0)
3876 BFD_ASSERT (srel
!= NULL
);
3878 /* If we don't need dynamic symbol lookup, install two
3879 RELATIVE relocations. */
3880 if (! dynamic_symbol_p
)
3882 unsigned int dyn_r_type
;
3884 if (r_type
== R_IA64_IPLTMSB
)
3885 dyn_r_type
= R_IA64_REL64MSB
;
3887 dyn_r_type
= R_IA64_REL64LSB
;
3889 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3891 srel
, rel
->r_offset
,
3892 dyn_r_type
, 0, value
);
3893 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3895 srel
, rel
->r_offset
+ 8,
3896 dyn_r_type
, 0, gp_val
);
3899 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3900 srel
, rel
->r_offset
, r_type
,
3901 h
->dynindx
, rel
->r_addend
);
3904 if (r_type
== R_IA64_IPLTMSB
)
3905 r_type
= R_IA64_DIR64MSB
;
3907 r_type
= R_IA64_DIR64LSB
;
3908 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3909 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
3914 r
= bfd_reloc_notsupported
;
3923 case bfd_reloc_undefined
:
3924 /* This can happen for global table relative relocs if
3925 __gp is undefined. This is a panic situation so we
3926 don't try to continue. */
3927 (*info
->callbacks
->undefined_symbol
)
3928 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
3931 case bfd_reloc_notsupported
:
3936 name
= h
->root
.root
.string
;
3939 name
= bfd_elf_string_from_elf_section (input_bfd
,
3940 symtab_hdr
->sh_link
,
3945 name
= bfd_section_name (input_bfd
, input_section
);
3947 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
3949 input_section
, rel
->r_offset
))
3955 case bfd_reloc_dangerous
:
3956 case bfd_reloc_outofrange
:
3957 case bfd_reloc_overflow
:
3963 name
= h
->root
.root
.string
;
3966 name
= bfd_elf_string_from_elf_section (input_bfd
,
3967 symtab_hdr
->sh_link
,
3972 name
= bfd_section_name (input_bfd
, input_section
);
3974 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
3990 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
3992 struct bfd_link_info
*info
;
3993 struct elf_link_hash_entry
*h
;
3994 Elf_Internal_Sym
*sym
;
3996 struct elfNN_ia64_link_hash_table
*ia64_info
;
3997 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3999 ia64_info
= elfNN_ia64_hash_table (info
);
4000 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
4002 /* Fill in the PLT data, if required. */
4003 if (dyn_i
&& dyn_i
->want_plt
)
4005 Elf_Internal_Rela outrel
;
4008 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
4009 ElfNN_External_Rela
*rel
;
4011 gp_val
= _bfd_get_gp_value (output_bfd
);
4013 /* Initialize the minimal PLT entry. */
4015 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4016 plt_sec
= ia64_info
->plt_sec
;
4017 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4019 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4020 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4021 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4024 plt_addr
= (plt_sec
->output_section
->vma
4025 + plt_sec
->output_offset
4026 + dyn_i
->plt_offset
);
4027 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, true);
4029 /* Initialize the FULL PLT entry, if needed. */
4030 if (dyn_i
->want_plt2
)
4032 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4034 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4035 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4038 /* Mark the symbol as undefined, rather than as defined in the
4039 plt section. Leave the value alone. */
4040 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4041 first place. But perhaps elflink.h did some for us. */
4042 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4043 sym
->st_shndx
= SHN_UNDEF
;
4046 /* Create the dynamic relocation. */
4047 outrel
.r_offset
= pltoff_addr
;
4048 if (bfd_little_endian (output_bfd
))
4049 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4051 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4052 outrel
.r_addend
= 0;
4054 /* This is fun. In the .IA_64.pltoff section, we've got entries
4055 that correspond both to real PLT entries, and those that
4056 happened to resolve to local symbols but need to be created
4057 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4058 relocations for the real PLT should come at the end of the
4059 section, so that they can be indexed by plt entry at runtime.
4061 We emitted all of the relocations for the non-PLT @pltoff
4062 entries during relocate_section. So we can consider the
4063 existing sec->reloc_count to be the base of the array of
4066 rel
= (ElfNN_External_Rela
*)ia64_info
->rel_pltoff_sec
->contents
;
4067 rel
+= ia64_info
->rel_pltoff_sec
->reloc_count
;
4069 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, rel
+ index
);
4072 /* Mark some specially defined symbols as absolute. */
4073 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4074 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4075 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4076 sym
->st_shndx
= SHN_ABS
;
4082 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4084 struct bfd_link_info
*info
;
4086 struct elfNN_ia64_link_hash_table
*ia64_info
;
4089 ia64_info
= elfNN_ia64_hash_table (info
);
4090 dynobj
= ia64_info
->root
.dynobj
;
4092 if (elf_hash_table (info
)->dynamic_sections_created
)
4094 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4095 asection
*sdyn
, *sgotplt
;
4098 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4099 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4100 BFD_ASSERT (sdyn
!= NULL
);
4101 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4102 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4104 gp_val
= _bfd_get_gp_value (abfd
);
4106 for (; dyncon
< dynconend
; dyncon
++)
4108 Elf_Internal_Dyn dyn
;
4110 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4115 dyn
.d_un
.d_ptr
= gp_val
;
4119 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4120 * sizeof (ElfNN_External_Rela
));
4124 /* See the comment above in finish_dynamic_symbol. */
4125 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4126 + ia64_info
->rel_pltoff_sec
->output_offset
4127 + (ia64_info
->rel_pltoff_sec
->reloc_count
4128 * sizeof (ElfNN_External_Rela
)));
4131 case DT_IA_64_PLT_RESERVE
:
4132 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4133 + sgotplt
->output_offset
);
4137 /* Do not have RELASZ include JMPREL. This makes things
4138 easier on ld.so. This is not what the rest of BFD set up. */
4139 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4140 * sizeof (ElfNN_External_Rela
));
4144 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4147 /* Initialize the PLT0 entry */
4148 if (ia64_info
->plt_sec
)
4150 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4153 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4155 pltres
= (sgotplt
->output_section
->vma
4156 + sgotplt
->output_offset
4159 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4166 /* ELF file flag handling: */
4168 /* Function to keep IA-64 specific file flags. */
4170 elfNN_ia64_set_private_flags (abfd
, flags
)
4174 BFD_ASSERT (!elf_flags_init (abfd
)
4175 || elf_elfheader (abfd
)->e_flags
== flags
);
4177 elf_elfheader (abfd
)->e_flags
= flags
;
4178 elf_flags_init (abfd
) = true;
4182 /* Copy backend specific data from one object module to another */
4184 elfNN_ia64_copy_private_bfd_data (ibfd
, obfd
)
4187 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4188 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4191 BFD_ASSERT (!elf_flags_init (obfd
)
4192 || (elf_elfheader (obfd
)->e_flags
4193 == elf_elfheader (ibfd
)->e_flags
));
4195 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
4196 elf_flags_init (obfd
) = true;
4200 /* Merge backend specific data from an object file to the output
4201 object file when linking. */
4203 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4210 /* Don't even pretend to support mixed-format linking. */
4211 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4212 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4215 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4216 out_flags
= elf_elfheader (obfd
)->e_flags
;
4218 if (! elf_flags_init (obfd
))
4220 elf_flags_init (obfd
) = true;
4221 elf_elfheader (obfd
)->e_flags
= in_flags
;
4223 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4224 && bfd_get_arch_info (obfd
)->the_default
)
4226 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4227 bfd_get_mach (ibfd
));
4233 /* Check flag compatibility. */
4234 if (in_flags
== out_flags
)
4237 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4238 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4239 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4241 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4243 (*_bfd_error_handler
)
4244 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4245 bfd_get_filename (ibfd
));
4247 bfd_set_error (bfd_error_bad_value
);
4250 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4252 (*_bfd_error_handler
)
4253 (_("%s: linking big-endian files with little-endian files"),
4254 bfd_get_filename (ibfd
));
4256 bfd_set_error (bfd_error_bad_value
);
4259 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4261 (*_bfd_error_handler
)
4262 (_("%s: linking 64-bit files with 32-bit files"),
4263 bfd_get_filename (ibfd
));
4265 bfd_set_error (bfd_error_bad_value
);
4268 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4270 (*_bfd_error_handler
)
4271 (_("%s: linking constant-gp files with non-constant-gp files"),
4272 bfd_get_filename (ibfd
));
4274 bfd_set_error (bfd_error_bad_value
);
4277 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4278 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4280 (*_bfd_error_handler
)
4281 (_("%s: linking auto-pic files with non-auto-pic files"),
4282 bfd_get_filename (ibfd
));
4284 bfd_set_error (bfd_error_bad_value
);
4292 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4296 FILE *file
= (FILE *) ptr
;
4297 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4299 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4301 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4302 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4303 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4304 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4305 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4306 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4307 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4308 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4309 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4311 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4315 static enum elf_reloc_type_class
4316 elfNN_ia64_reloc_type_class (type
)
4321 case R_IA64_REL32MSB
:
4322 case R_IA64_REL32LSB
:
4323 case R_IA64_REL64MSB
:
4324 case R_IA64_REL64LSB
:
4325 return reloc_class_relative
;
4326 case R_IA64_IPLTMSB
:
4327 case R_IA64_IPLTLSB
:
4328 return reloc_class_plt
;
4330 return reloc_class_copy
;
4332 return reloc_class_normal
;
4336 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4337 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4338 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4339 #define TARGET_BIG_NAME "elfNN-ia64-big"
4340 #define ELF_ARCH bfd_arch_ia64
4341 #define ELF_MACHINE_CODE EM_IA_64
4342 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4343 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4344 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4346 #define elf_backend_section_from_shdr \
4347 elfNN_ia64_section_from_shdr
4348 #define elf_backend_section_flags \
4349 elfNN_ia64_section_flags
4350 #define elf_backend_fake_sections \
4351 elfNN_ia64_fake_sections
4352 #define elf_backend_final_write_processing \
4353 elfNN_ia64_final_write_processing
4354 #define elf_backend_add_symbol_hook \
4355 elfNN_ia64_add_symbol_hook
4356 #define elf_backend_additional_program_headers \
4357 elfNN_ia64_additional_program_headers
4358 #define elf_backend_modify_segment_map \
4359 elfNN_ia64_modify_segment_map
4360 #define elf_info_to_howto \
4361 elfNN_ia64_info_to_howto
4363 #define bfd_elfNN_bfd_reloc_type_lookup \
4364 elfNN_ia64_reloc_type_lookup
4365 #define bfd_elfNN_bfd_is_local_label_name \
4366 elfNN_ia64_is_local_label_name
4367 #define bfd_elfNN_bfd_relax_section \
4368 elfNN_ia64_relax_section
4370 /* Stuff for the BFD linker: */
4371 #define bfd_elfNN_bfd_link_hash_table_create \
4372 elfNN_ia64_hash_table_create
4373 #define elf_backend_create_dynamic_sections \
4374 elfNN_ia64_create_dynamic_sections
4375 #define elf_backend_check_relocs \
4376 elfNN_ia64_check_relocs
4377 #define elf_backend_adjust_dynamic_symbol \
4378 elfNN_ia64_adjust_dynamic_symbol
4379 #define elf_backend_size_dynamic_sections \
4380 elfNN_ia64_size_dynamic_sections
4381 #define elf_backend_relocate_section \
4382 elfNN_ia64_relocate_section
4383 #define elf_backend_finish_dynamic_symbol \
4384 elfNN_ia64_finish_dynamic_symbol
4385 #define elf_backend_finish_dynamic_sections \
4386 elfNN_ia64_finish_dynamic_sections
4387 #define bfd_elfNN_bfd_final_link \
4388 elfNN_ia64_final_link
4390 #define bfd_elfNN_bfd_copy_private_bfd_data \
4391 elfNN_ia64_copy_private_bfd_data
4392 #define bfd_elfNN_bfd_merge_private_bfd_data \
4393 elfNN_ia64_merge_private_bfd_data
4394 #define bfd_elfNN_bfd_set_private_flags \
4395 elfNN_ia64_set_private_flags
4396 #define bfd_elfNN_bfd_print_private_bfd_data \
4397 elfNN_ia64_print_private_bfd_data
4399 #define elf_backend_plt_readonly 1
4400 #define elf_backend_want_plt_sym 0
4401 #define elf_backend_plt_alignment 5
4402 #define elf_backend_got_header_size 0
4403 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4404 #define elf_backend_want_got_plt 1
4405 #define elf_backend_may_use_rel_p 1
4406 #define elf_backend_may_use_rela_p 1
4407 #define elf_backend_default_use_rela_p 1
4408 #define elf_backend_want_dynbss 0
4409 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4410 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4411 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4413 #include "elfNN-target.h"
4415 /* AIX-specific vectors. */
4417 #undef TARGET_LITTLE_SYM
4418 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4419 #undef TARGET_LITTLE_NAME
4420 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4421 #undef TARGET_BIG_SYM
4422 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4423 #undef TARGET_BIG_NAME
4424 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4426 #undef elf_backend_add_symbol_hook
4427 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4429 #undef bfd_elfNN_bfd_link_add_symbols
4430 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4432 #define elfNN_bed elfNN_ia64_aix_bed
4434 #include "elfNN-target.h"