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 */
142 struct elfNN_ia64_local_hash_table loc_hash_table
;
145 #define elfNN_ia64_hash_table(p) \
146 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
148 static bfd_reloc_status_type elfNN_ia64_reloc
149 PARAMS ((bfd
*abfd
, arelent
*reloc
, asymbol
*sym
, PTR data
,
150 asection
*input_section
, bfd
*output_bfd
, char **error_message
));
151 static reloc_howto_type
* lookup_howto
152 PARAMS ((unsigned int rtype
));
153 static reloc_howto_type
*elfNN_ia64_reloc_type_lookup
154 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type bfd_code
));
155 static void elfNN_ia64_info_to_howto
156 PARAMS ((bfd
*abfd
, arelent
*bfd_reloc
, ElfNN_Internal_Rela
*elf_reloc
));
157 static boolean elfNN_ia64_relax_section
158 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
160 static boolean is_unwind_section_name
161 PARAMS ((const char *));
162 static boolean elfNN_ia64_section_from_shdr
163 PARAMS ((bfd
*, ElfNN_Internal_Shdr
*, char *));
164 static boolean elfNN_ia64_section_flags
165 PARAMS ((flagword
*, ElfNN_Internal_Shdr
*));
166 static boolean elfNN_ia64_fake_sections
167 PARAMS ((bfd
*abfd
, ElfNN_Internal_Shdr
*hdr
, asection
*sec
));
168 static void elfNN_ia64_final_write_processing
169 PARAMS ((bfd
*abfd
, boolean linker
));
170 static boolean elfNN_ia64_add_symbol_hook
171 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
172 const char **namep
, flagword
*flagsp
, asection
**secp
,
174 static boolean elfNN_ia64_aix_vec
175 PARAMS ((const bfd_target
*vec
));
176 static boolean elfNN_ia64_aix_add_symbol_hook
177 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
178 const char **namep
, flagword
*flagsp
, asection
**secp
,
180 static boolean elfNN_ia64_aix_link_add_symbols
181 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
182 static int elfNN_ia64_additional_program_headers
183 PARAMS ((bfd
*abfd
));
184 static boolean elfNN_ia64_modify_segment_map
186 static boolean elfNN_ia64_is_local_label_name
187 PARAMS ((bfd
*abfd
, const char *name
));
188 static boolean elfNN_ia64_dynamic_symbol_p
189 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
));
190 static boolean elfNN_ia64_local_hash_table_init
191 PARAMS ((struct elfNN_ia64_local_hash_table
*ht
, bfd
*abfd
,
192 new_hash_entry_func
new));
193 static struct bfd_hash_entry
*elfNN_ia64_new_loc_hash_entry
194 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
195 const char *string
));
196 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
197 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
198 const char *string
));
199 static void elfNN_ia64_hash_copy_indirect
200 PARAMS ((struct elf_link_hash_entry
*, struct elf_link_hash_entry
*));
201 static void elfNN_ia64_hash_hide_symbol
202 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*));
203 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
204 PARAMS ((bfd
*abfd
));
205 static struct elfNN_ia64_local_hash_entry
*elfNN_ia64_local_hash_lookup
206 PARAMS ((struct elfNN_ia64_local_hash_table
*table
, const char *string
,
207 boolean create
, boolean copy
));
208 static boolean elfNN_ia64_global_dyn_sym_thunk
209 PARAMS ((struct bfd_hash_entry
*, PTR
));
210 static boolean elfNN_ia64_local_dyn_sym_thunk
211 PARAMS ((struct bfd_hash_entry
*, PTR
));
212 static void elfNN_ia64_dyn_sym_traverse
213 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
214 boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
216 static boolean elfNN_ia64_create_dynamic_sections
217 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
218 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
219 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
220 struct elf_link_hash_entry
*h
,
221 bfd
*abfd
, const Elf_Internal_Rela
*rel
, boolean create
));
222 static asection
*get_got
223 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
224 struct elfNN_ia64_link_hash_table
*ia64_info
));
225 static asection
*get_fptr
226 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
227 struct elfNN_ia64_link_hash_table
*ia64_info
));
228 static asection
*get_pltoff
229 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
230 struct elfNN_ia64_link_hash_table
*ia64_info
));
231 static asection
*get_reloc_section
232 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
233 asection
*sec
, boolean create
));
234 static boolean count_dyn_reloc
235 PARAMS ((bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
236 asection
*srel
, int type
));
237 static boolean elfNN_ia64_check_relocs
238 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
239 const Elf_Internal_Rela
*relocs
));
240 static boolean elfNN_ia64_adjust_dynamic_symbol
241 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
242 static unsigned long global_sym_index
243 PARAMS ((struct elf_link_hash_entry
*h
));
244 static boolean allocate_fptr
245 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
246 static boolean allocate_global_data_got
247 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
248 static boolean allocate_global_fptr_got
249 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
250 static boolean allocate_local_got
251 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
252 static boolean allocate_pltoff_entries
253 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
254 static boolean allocate_plt_entries
255 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
256 static boolean allocate_plt2_entries
257 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
258 static boolean allocate_dynrel_entries
259 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
260 static boolean elfNN_ia64_size_dynamic_sections
261 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
262 static bfd_reloc_status_type elfNN_ia64_install_value
263 PARAMS ((bfd
*abfd
, bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
264 static void elfNN_ia64_install_dyn_reloc
265 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
266 asection
*srel
, bfd_vma offset
, unsigned int type
,
267 long dynindx
, bfd_vma addend
));
268 static bfd_vma set_got_entry
269 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
270 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
271 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
272 static bfd_vma set_fptr_entry
273 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
274 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
276 static bfd_vma set_pltoff_entry
277 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
278 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
279 bfd_vma value
, boolean
));
280 static int elfNN_ia64_unwind_entry_compare
281 PARAMS ((const PTR
, const PTR
));
282 static boolean elfNN_ia64_final_link
283 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
284 static boolean elfNN_ia64_relocate_section
285 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
286 asection
*input_section
, bfd_byte
*contents
,
287 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
288 asection
**local_sections
));
289 static boolean elfNN_ia64_finish_dynamic_symbol
290 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
291 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
292 static boolean elfNN_ia64_finish_dynamic_sections
293 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
294 static boolean elfNN_ia64_set_private_flags
295 PARAMS ((bfd
*abfd
, flagword flags
));
296 static boolean elfNN_ia64_copy_private_bfd_data
297 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
298 static boolean elfNN_ia64_merge_private_bfd_data
299 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
300 static boolean elfNN_ia64_print_private_bfd_data
301 PARAMS ((bfd
*abfd
, PTR ptr
));
303 /* ia64-specific relocation */
305 /* Perform a relocation. Not much to do here as all the hard work is
306 done in elfNN_ia64_final_link_relocate. */
307 static bfd_reloc_status_type
308 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
309 output_bfd
, error_message
)
310 bfd
*abfd ATTRIBUTE_UNUSED
;
312 asymbol
*sym ATTRIBUTE_UNUSED
;
313 PTR data ATTRIBUTE_UNUSED
;
314 asection
*input_section
;
316 char **error_message
;
320 reloc
->address
+= input_section
->output_offset
;
323 *error_message
= "Unsupported call to elfNN_ia64_reloc";
324 return bfd_reloc_notsupported
;
327 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
328 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
329 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
331 /* This table has to be sorted according to increasing number of the
333 static reloc_howto_type ia64_howto_table
[] =
335 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, false, true),
337 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, false, true),
338 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, false, true),
339 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, false, true),
340 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, false, true),
341 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, false, true),
342 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, false, true),
343 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, false, true),
345 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, false, true),
346 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, false, true),
347 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, false, true),
348 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, false, true),
349 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, false, true),
350 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, false, true),
352 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, false, true),
353 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, false, true),
355 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, false, true),
356 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, false, true),
357 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, false, true),
358 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, false, true),
360 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, false, true),
361 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, false, true),
362 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, false, true),
363 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, false, true),
364 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, false, true),
366 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, true, true),
367 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, true, true),
368 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, true, true),
369 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, true, true),
370 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, true, true),
371 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, true, true),
372 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, true, true),
373 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, true, true),
375 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, false, true),
376 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, false, true),
377 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, false, true),
378 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, false, true),
379 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, false, true),
380 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, false, true),
382 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, false, true),
383 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, false, true),
384 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, false, true),
385 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, false, true),
387 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, false, true),
388 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, false, true),
389 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, false, true),
390 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, false, true),
392 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, false, true),
393 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, false, true),
394 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, false, true),
395 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, false, true),
397 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, false, true),
398 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, false, true),
399 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, false, true),
400 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, false, true),
402 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, true, true),
403 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, true, true),
404 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, true, true),
406 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, false, true),
407 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, false, true),
408 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, false, true),
409 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, false, true),
410 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, false, true),
412 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, false, false),
413 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, false, false),
414 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, false, false),
415 IA64_HOWTO (R_IA64_LTOFF_TP22
, "LTOFF_TP22", 0, false, false),
418 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
420 /* Given a BFD reloc type, return the matching HOWTO structure. */
422 static reloc_howto_type
*
426 static int inited
= 0;
433 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
434 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
435 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
438 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
439 i
= elf_code_to_howto_index
[rtype
];
440 if (i
>= NELEMS (ia64_howto_table
))
442 return ia64_howto_table
+ i
;
445 static reloc_howto_type
*
446 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
447 bfd
*abfd ATTRIBUTE_UNUSED
;
448 bfd_reloc_code_real_type bfd_code
;
454 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
456 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
457 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
458 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
460 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
461 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
462 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
463 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
465 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
466 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
467 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
468 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
469 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
470 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
472 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
473 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
475 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
476 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
477 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
478 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
479 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
480 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
481 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
482 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
483 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
485 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
486 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
487 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
488 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
489 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
490 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
491 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
492 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
493 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
494 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
495 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
497 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
498 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
499 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
500 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
501 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
502 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
504 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
505 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
506 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
507 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
509 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
510 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
511 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
512 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
514 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
515 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
516 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
517 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
519 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
520 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
521 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
522 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
524 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
525 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
526 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
527 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
528 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
530 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
531 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
532 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
533 case BFD_RELOC_IA64_LTOFF_TP22
: rtype
= R_IA64_LTOFF_TP22
; break;
537 return lookup_howto (rtype
);
540 /* Given a ELF reloc, return the matching HOWTO structure. */
543 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
544 bfd
*abfd ATTRIBUTE_UNUSED
;
546 ElfNN_Internal_Rela
*elf_reloc
;
548 bfd_reloc
->howto
= lookup_howto (ELFNN_R_TYPE (elf_reloc
->r_info
));
551 #define PLT_HEADER_SIZE (3 * 16)
552 #define PLT_MIN_ENTRY_SIZE (1 * 16)
553 #define PLT_FULL_ENTRY_SIZE (2 * 16)
554 #define PLT_RESERVED_WORDS 3
556 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
558 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
559 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
560 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
561 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
562 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
563 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
564 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
565 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
566 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
569 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
571 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
572 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
573 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
576 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
578 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
579 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
580 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
581 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
582 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
583 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
586 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
587 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
588 #define DYNAMIC_INTERPRETER(abfd) \
589 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
591 /* Select out of range branch fixup type. Note that Itanium does
592 not support brl, and so it gets emulated by the kernel. */
595 static const bfd_byte oor_brl
[16] =
597 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
599 0x00, 0x00, 0x00, 0xc0
602 static const bfd_byte oor_ip
[48] =
604 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
605 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
606 0x01, 0x00, 0x00, 0x60,
607 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
608 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
609 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
610 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
611 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
612 0x60, 0x00, 0x80, 0x00 /* br b6;; */
615 /* These functions do relaxation for IA-64 ELF.
617 This is primarily to support branches to targets out of range;
618 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
621 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
624 struct bfd_link_info
*link_info
;
629 struct one_fixup
*next
;
635 Elf_Internal_Shdr
*symtab_hdr
;
636 Elf_Internal_Rela
*internal_relocs
;
637 Elf_Internal_Rela
*free_relocs
= NULL
;
638 Elf_Internal_Rela
*irel
, *irelend
;
640 bfd_byte
*free_contents
= NULL
;
641 ElfNN_External_Sym
*extsyms
;
642 ElfNN_External_Sym
*free_extsyms
= NULL
;
643 struct elfNN_ia64_link_hash_table
*ia64_info
;
644 struct one_fixup
*fixups
= NULL
;
645 boolean changed_contents
= false;
646 boolean changed_relocs
= false;
648 /* Assume we're not going to change any sizes, and we'll only need
652 /* Nothing to do if there are no relocations. */
653 if ((sec
->flags
& SEC_RELOC
) == 0
654 || sec
->reloc_count
== 0)
657 /* If this is the first time we have been called for this section,
658 initialize the cooked size. */
659 if (sec
->_cooked_size
== 0)
660 sec
->_cooked_size
= sec
->_raw_size
;
662 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
664 /* Load the relocations for this section. */
665 internal_relocs
= (_bfd_elfNN_link_read_relocs
666 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
667 link_info
->keep_memory
));
668 if (internal_relocs
== NULL
)
671 if (! link_info
->keep_memory
)
672 free_relocs
= internal_relocs
;
674 ia64_info
= elfNN_ia64_hash_table (link_info
);
675 irelend
= internal_relocs
+ sec
->reloc_count
;
677 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
678 if (ELFNN_R_TYPE (irel
->r_info
) == (int) R_IA64_PCREL21B
)
681 /* No branch-type relocations. */
684 if (free_relocs
!= NULL
)
689 /* Get the section contents. */
690 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
691 contents
= elf_section_data (sec
)->this_hdr
.contents
;
694 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
695 if (contents
== NULL
)
697 free_contents
= contents
;
699 if (! bfd_get_section_contents (abfd
, sec
, contents
,
700 (file_ptr
) 0, sec
->_raw_size
))
704 /* Read this BFD's symbols. */
705 if (symtab_hdr
->contents
!= NULL
)
706 extsyms
= (ElfNN_External_Sym
*) symtab_hdr
->contents
;
709 extsyms
= (ElfNN_External_Sym
*) bfd_malloc (symtab_hdr
->sh_size
);
712 free_extsyms
= extsyms
;
713 if (bfd_seek (abfd
, symtab_hdr
->sh_offset
, SEEK_SET
) != 0
714 || (bfd_read (extsyms
, 1, symtab_hdr
->sh_size
, abfd
)
715 != symtab_hdr
->sh_size
))
719 for (; irel
< irelend
; irel
++)
721 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
722 Elf_Internal_Sym isym
;
726 if (ELFNN_R_TYPE (irel
->r_info
) != (int) R_IA64_PCREL21B
)
729 /* Get the value of the symbol referred to by the reloc. */
730 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
732 /* A local symbol. */
733 bfd_elfNN_swap_symbol_in (abfd
,
734 extsyms
+ ELFNN_R_SYM (irel
->r_info
),
736 if (isym
.st_shndx
== SHN_UNDEF
)
737 continue; /* We can't do anthing with undefined symbols. */
738 else if (isym
.st_shndx
== SHN_ABS
)
739 tsec
= bfd_abs_section_ptr
;
740 else if (isym
.st_shndx
== SHN_COMMON
)
741 tsec
= bfd_com_section_ptr
;
742 else if (isym
.st_shndx
> 0 && isym
.st_shndx
< SHN_LORESERVE
)
743 tsec
= bfd_section_from_elf_index (abfd
, isym
.st_shndx
);
745 continue; /* who knows. */
747 toff
= isym
.st_value
;
752 struct elf_link_hash_entry
*h
;
753 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
755 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
756 h
= elf_sym_hashes (abfd
)[indx
];
757 BFD_ASSERT (h
!= NULL
);
759 while (h
->root
.type
== bfd_link_hash_indirect
760 || h
->root
.type
== bfd_link_hash_warning
)
761 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
763 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, false);
765 /* For branches to dynamic symbols, we're interested instead
766 in a branch to the PLT entry. */
767 if (dyn_i
&& dyn_i
->want_plt2
)
769 tsec
= ia64_info
->plt_sec
;
770 toff
= dyn_i
->plt2_offset
;
774 /* We can't do anthing with undefined symbols. */
775 if (h
->root
.type
== bfd_link_hash_undefined
776 || h
->root
.type
== bfd_link_hash_undefweak
)
779 tsec
= h
->root
.u
.def
.section
;
780 toff
= h
->root
.u
.def
.value
;
784 symaddr
= (tsec
->output_section
->vma
785 + tsec
->output_offset
789 roff
= irel
->r_offset
;
790 reladdr
= (sec
->output_section
->vma
794 /* If the branch is in range, no need to do anything. */
795 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
796 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
799 /* If the branch and target are in the same section, you've
800 got one honking big section and we can't help you. You'll
801 get an error message later. */
805 /* Look for an existing fixup to this address. */
806 for (f
= fixups
; f
; f
= f
->next
)
807 if (f
->tsec
== tsec
&& f
->toff
== toff
)
812 /* Two alternatives: If it's a branch to a PLT entry, we can
813 make a copy of the FULL_PLT entry. Otherwise, we'll have
814 to use a `brl' insn to get where we're going. */
818 if (tsec
== ia64_info
->plt_sec
)
819 size
= sizeof (plt_full_entry
);
823 size
= sizeof (oor_brl
);
825 size
= sizeof (oor_ip
);
829 /* Resize the current section to make room for the new branch. */
830 trampoff
= (sec
->_cooked_size
+ 15) & -16;
831 contents
= (bfd_byte
*) bfd_realloc (contents
, trampoff
+ size
);
832 if (contents
== NULL
)
834 sec
->_cooked_size
= trampoff
+ size
;
836 if (tsec
== ia64_info
->plt_sec
)
838 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
840 /* Hijack the old relocation for use as the PLTOFF reloc. */
841 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
843 irel
->r_offset
= trampoff
;
848 memcpy (contents
+ trampoff
, oor_brl
, size
);
849 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
851 irel
->r_offset
= trampoff
+ 2;
853 memcpy (contents
+ trampoff
, oor_ip
, size
);
854 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
856 irel
->r_addend
-= 16;
857 irel
->r_offset
= trampoff
+ 2;
861 /* Record the fixup so we don't do it again this section. */
862 f
= (struct one_fixup
*) bfd_malloc (sizeof (*f
));
866 f
->trampoff
= trampoff
;
871 /* Nop out the reloc, since we're finalizing things here. */
872 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
875 /* Fix up the existing branch to hit the trampoline. Hope like
876 hell this doesn't overflow too. */
877 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
878 f
->trampoff
- (roff
& -4),
879 R_IA64_PCREL21B
) != bfd_reloc_ok
)
882 changed_contents
= true;
883 changed_relocs
= true;
886 /* Clean up and go home. */
889 struct one_fixup
*f
= fixups
;
890 fixups
= fixups
->next
;
895 elf_section_data (sec
)->relocs
= internal_relocs
;
896 else if (free_relocs
!= NULL
)
899 if (changed_contents
)
900 elf_section_data (sec
)->this_hdr
.contents
= contents
;
901 else if (free_contents
!= NULL
)
903 if (! link_info
->keep_memory
)
904 free (free_contents
);
907 /* Cache the section contents for elf_link_input_bfd. */
908 elf_section_data (sec
)->this_hdr
.contents
= contents
;
912 if (free_extsyms
!= NULL
)
914 if (! link_info
->keep_memory
)
918 /* Cache the symbols for elf_link_input_bfd. */
919 symtab_hdr
->contents
= extsyms
;
923 *again
= changed_contents
|| changed_relocs
;
927 if (free_relocs
!= NULL
)
929 if (free_contents
!= NULL
)
930 free (free_contents
);
931 if (free_extsyms
!= NULL
)
936 /* Return true if NAME is an unwind table section name. */
938 static inline boolean
939 is_unwind_section_name (name
)
942 size_t len1
, len2
, len3
;
944 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
945 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
946 len3
= sizeof (ELF_STRING_ia64_unwind_once
) - 1;
947 return ((strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
948 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0)
949 || strncmp (name
, ELF_STRING_ia64_unwind_once
, len3
) == 0);
952 /* Handle an IA-64 specific section when reading an object file. This
953 is called when elfcode.h finds a section with an unknown type. */
956 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
958 ElfNN_Internal_Shdr
*hdr
;
963 /* There ought to be a place to keep ELF backend specific flags, but
964 at the moment there isn't one. We just keep track of the
965 sections by their name, instead. Fortunately, the ABI gives
966 suggested names for all the MIPS specific sections, so we will
967 probably get away with this. */
968 switch (hdr
->sh_type
)
970 case SHT_IA_64_UNWIND
:
974 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
982 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
984 newsect
= hdr
->bfd_section
;
989 /* Convert IA-64 specific section flags to bfd internal section flags. */
991 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
995 elfNN_ia64_section_flags (flags
, hdr
)
997 ElfNN_Internal_Shdr
*hdr
;
999 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1000 *flags
|= SEC_SMALL_DATA
;
1005 /* Set the correct type for an IA-64 ELF section. We do this by the
1006 section name, which is a hack, but ought to work. */
1009 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1010 bfd
*abfd ATTRIBUTE_UNUSED
;
1011 ElfNN_Internal_Shdr
*hdr
;
1014 register const char *name
;
1016 name
= bfd_get_section_name (abfd
, sec
);
1018 if (is_unwind_section_name (name
))
1020 /* We don't have the sections numbered at this point, so sh_info
1021 is set later, in elfNN_ia64_final_write_processing. */
1022 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1023 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1025 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1026 hdr
->sh_type
= SHT_IA_64_EXT
;
1027 else if (strcmp (name
, ".reloc") == 0)
1029 * This is an ugly, but unfortunately necessary hack that is
1030 * needed when producing EFI binaries on IA-64. It tells
1031 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1032 * containing ELF relocation info. We need this hack in order to
1033 * be able to generate ELF binaries that can be translated into
1034 * EFI applications (which are essentially COFF objects). Those
1035 * files contain a COFF ".reloc" section inside an ELFNN object,
1036 * which would normally cause BFD to segfault because it would
1037 * attempt to interpret this section as containing relocation
1038 * entries for section "oc". With this hack enabled, ".reloc"
1039 * will be treated as a normal data section, which will avoid the
1040 * segfault. However, you won't be able to create an ELFNN binary
1041 * with a section named "oc" that needs relocations, but that's
1042 * the kind of ugly side-effects you get when detecting section
1043 * types based on their names... In practice, this limitation is
1046 hdr
->sh_type
= SHT_PROGBITS
;
1048 if (sec
->flags
& SEC_SMALL_DATA
)
1049 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1054 /* The final processing done just before writing out an IA-64 ELF
1058 elfNN_ia64_final_write_processing (abfd
, linker
)
1060 boolean linker ATTRIBUTE_UNUSED
;
1062 Elf_Internal_Shdr
*hdr
;
1064 asection
*text_sect
, *s
;
1067 for (s
= abfd
->sections
; s
; s
= s
->next
)
1069 hdr
= &elf_section_data (s
)->this_hdr
;
1070 switch (hdr
->sh_type
)
1072 case SHT_IA_64_UNWIND
:
1073 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1075 sname
= bfd_get_section_name (abfd
, s
);
1076 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1077 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1081 if (sname
[0] == '\0')
1082 /* .IA_64.unwind -> .text */
1083 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1085 /* .IA_64.unwindFOO -> FOO */
1086 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1089 && (len
= sizeof (ELF_STRING_ia64_unwind_once
) - 1,
1090 strncmp (sname
, ELF_STRING_ia64_unwind_once
, len
)) == 0)
1092 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1093 size_t len2
= sizeof (".gnu.linkonce.t.") - 1;
1094 char *once_name
= alloca (len2
+ strlen (sname
) - len
+ 1);
1096 memcpy (once_name
, ".gnu.linkonce.t.", len2
);
1097 strcpy (once_name
+ len2
, sname
+ len
);
1098 text_sect
= bfd_get_section_by_name (abfd
, once_name
);
1101 /* last resort: fall back on .text */
1102 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1106 /* The IA-64 processor-specific ABI requires setting
1107 sh_link to the unwind section, whereas HP-UX requires
1108 sh_info to do so. For maximum compatibility, we'll
1109 set both for now... */
1110 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1111 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1118 /* Hook called by the linker routine which adds symbols from an object
1119 file. We use it to put .comm items in .sbss, and not .bss. */
1122 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1124 struct bfd_link_info
*info
;
1125 const Elf_Internal_Sym
*sym
;
1126 const char **namep ATTRIBUTE_UNUSED
;
1127 flagword
*flagsp ATTRIBUTE_UNUSED
;
1131 if (sym
->st_shndx
== SHN_COMMON
1132 && !info
->relocateable
1133 && sym
->st_size
<= elf_gp_size (abfd
))
1135 /* Common symbols less than or equal to -G nn bytes are
1136 automatically put into .sbss. */
1138 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1142 scomm
= bfd_make_section (abfd
, ".scommon");
1144 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1146 | SEC_LINKER_CREATED
)))
1151 *valp
= sym
->st_size
;
1158 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1160 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1161 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1163 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1164 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1167 /* Hook called by the linker routine which adds symbols from an object
1168 file. We use it to handle OS-specific symbols. */
1171 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1173 struct bfd_link_info
*info
;
1174 const Elf_Internal_Sym
*sym
;
1180 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1182 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1183 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1184 no one else should use it b/c it is undocumented. */
1185 struct elf_link_hash_entry
*h
;
1187 h
= (struct elf_link_hash_entry
*) bfd_link_hash_lookup (info
->hash
, *namep
, false, false, false);
1190 struct elf_backend_data
*bed
;
1191 struct elfNN_ia64_link_hash_table
*ia64_info
;
1193 bed
= get_elf_backend_data (abfd
);
1194 ia64_info
= elfNN_ia64_hash_table (info
);
1196 if (!(_bfd_generic_link_add_one_symbol
1197 (info
, abfd
, *namep
, BSF_GLOBAL
,
1198 bfd_get_section_by_name (abfd
, ".bss"),
1199 bed
->got_symbol_offset
, (const char *) NULL
, false,
1200 bed
->collect
, (struct bfd_link_hash_entry
**) &h
)))
1203 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1204 h
->type
= STT_OBJECT
;
1206 if (! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1212 else if (sym
->st_shndx
== SHN_LOOS
)
1216 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1217 is only relevant when compiling code for extended system calls.
1218 Replace the "special" section with .text, if possible.
1219 Note that these symbols are always assumed to be in .text. */
1220 for (i
= 1; i
< elf_elfheader (abfd
)->e_shnum
; i
++)
1222 asection
* sec
= bfd_section_from_elf_index (abfd
, i
);
1224 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1232 *secp
= bfd_abs_section_ptr
;
1234 *valp
= sym
->st_size
;
1240 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1241 namep
, flagsp
, secp
, valp
);
1246 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1248 struct bfd_link_info
*info
;
1250 /* Make sure dynamic sections are always created. */
1251 if (! elf_hash_table (info
)->dynamic_sections_created
1252 && abfd
->xvec
== info
->hash
->creator
)
1254 if (! bfd_elfNN_link_create_dynamic_sections (abfd
, info
))
1258 /* Now do the standard call. */
1259 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1262 /* Return the number of additional phdrs we will need. */
1265 elfNN_ia64_additional_program_headers (abfd
)
1271 /* See if we need a PT_IA_64_ARCHEXT segment. */
1272 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1273 if (s
&& (s
->flags
& SEC_LOAD
))
1276 /* Count how many PT_IA_64_UNWIND segments we need. */
1277 for (s
= abfd
->sections
; s
; s
= s
->next
)
1278 if (is_unwind_section_name(s
->name
) && (s
->flags
& SEC_LOAD
))
1285 elfNN_ia64_modify_segment_map (abfd
)
1288 struct elf_segment_map
*m
, **pm
;
1289 Elf_Internal_Shdr
*hdr
;
1292 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1293 all PT_LOAD segments. */
1294 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1295 if (s
&& (s
->flags
& SEC_LOAD
))
1297 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1298 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1302 m
= (struct elf_segment_map
*) bfd_zalloc (abfd
, sizeof *m
);
1306 m
->p_type
= PT_IA_64_ARCHEXT
;
1310 /* We want to put it after the PHDR and INTERP segments. */
1311 pm
= &elf_tdata (abfd
)->segment_map
;
1313 && ((*pm
)->p_type
== PT_PHDR
1314 || (*pm
)->p_type
== PT_INTERP
))
1322 /* Install PT_IA_64_UNWIND segments, if needed. */
1323 for (s
= abfd
->sections
; s
; s
= s
->next
)
1325 hdr
= &elf_section_data (s
)->this_hdr
;
1326 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1329 if (s
&& (s
->flags
& SEC_LOAD
))
1331 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1332 if (m
->p_type
== PT_IA_64_UNWIND
&& m
->sections
[0] == s
)
1337 m
= (struct elf_segment_map
*) bfd_zalloc (abfd
, sizeof *m
);
1341 m
->p_type
= PT_IA_64_UNWIND
;
1346 /* We want to put it last. */
1347 pm
= &elf_tdata (abfd
)->segment_map
;
1355 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1356 the input sections for each output section in the segment and testing
1357 for SHF_IA_64_NORECOV on each. */
1358 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1359 if (m
->p_type
== PT_LOAD
)
1362 for (i
= m
->count
- 1; i
>= 0; --i
)
1364 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1367 if (order
->type
== bfd_indirect_link_order
)
1369 asection
*is
= order
->u
.indirect
.section
;
1370 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1371 if (flags
& SHF_IA_64_NORECOV
)
1373 m
->p_flags
|= PF_IA_64_NORECOV
;
1377 order
= order
->next
;
1386 /* According to the Tahoe assembler spec, all labels starting with a
1390 elfNN_ia64_is_local_label_name (abfd
, name
)
1391 bfd
*abfd ATTRIBUTE_UNUSED
;
1394 return name
[0] == '.';
1397 /* Should we do dynamic things to this symbol? */
1400 elfNN_ia64_dynamic_symbol_p (h
, info
)
1401 struct elf_link_hash_entry
*h
;
1402 struct bfd_link_info
*info
;
1407 while (h
->root
.type
== bfd_link_hash_indirect
1408 || h
->root
.type
== bfd_link_hash_warning
)
1409 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1411 if (h
->dynindx
== -1)
1413 switch (ELF_ST_VISIBILITY (h
->other
))
1420 if (h
->root
.type
== bfd_link_hash_undefweak
1421 || h
->root
.type
== bfd_link_hash_defweak
)
1424 if ((info
->shared
&& !info
->symbolic
)
1425 || ((h
->elf_link_hash_flags
1426 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1427 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1434 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1435 struct elfNN_ia64_local_hash_table
*ht
;
1436 bfd
*abfd ATTRIBUTE_UNUSED
;
1437 new_hash_entry_func
new;
1439 memset (ht
, 0, sizeof (*ht
));
1440 return bfd_hash_table_init (&ht
->root
, new);
1443 static struct bfd_hash_entry
*
1444 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1445 struct bfd_hash_entry
*entry
;
1446 struct bfd_hash_table
*table
;
1449 struct elfNN_ia64_local_hash_entry
*ret
;
1450 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1452 /* Allocate the structure if it has not already been allocated by a
1455 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1460 /* Initialize our local data. All zeros, and definitely easier
1461 than setting a handful of bit fields. */
1462 memset (ret
, 0, sizeof (*ret
));
1464 /* Call the allocation method of the superclass. */
1465 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1466 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1468 return (struct bfd_hash_entry
*) ret
;
1471 static struct bfd_hash_entry
*
1472 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1473 struct bfd_hash_entry
*entry
;
1474 struct bfd_hash_table
*table
;
1477 struct elfNN_ia64_link_hash_entry
*ret
;
1478 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1480 /* Allocate the structure if it has not already been allocated by a
1483 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1488 /* Initialize our local data. All zeros, and definitely easier
1489 than setting a handful of bit fields. */
1490 memset (ret
, 0, sizeof (*ret
));
1492 /* Call the allocation method of the superclass. */
1493 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1494 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1497 return (struct bfd_hash_entry
*) ret
;
1501 elfNN_ia64_hash_copy_indirect (xdir
, xind
)
1502 struct elf_link_hash_entry
*xdir
, *xind
;
1504 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1506 dir
= (struct elfNN_ia64_link_hash_entry
*)xdir
;
1507 ind
= (struct elfNN_ia64_link_hash_entry
*)xind
;
1509 /* Copy down any references that we may have already seen to the
1510 symbol which just became indirect. */
1512 dir
->root
.elf_link_hash_flags
|=
1513 (ind
->root
.elf_link_hash_flags
1514 & (ELF_LINK_HASH_REF_DYNAMIC
1515 | ELF_LINK_HASH_REF_REGULAR
1516 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1518 /* Copy over the got and plt data. This would have been done
1521 if (dir
->info
== NULL
)
1523 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1525 dir
->info
= dyn_i
= ind
->info
;
1528 /* Fix up the dyn_sym_info pointers to the global symbol. */
1529 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1530 dyn_i
->h
= &dir
->root
;
1532 BFD_ASSERT (ind
->info
== NULL
);
1534 /* Copy over the dynindx. */
1536 if (dir
->root
.dynindx
== -1)
1538 dir
->root
.dynindx
= ind
->root
.dynindx
;
1539 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1540 ind
->root
.dynindx
= -1;
1541 ind
->root
.dynstr_index
= 0;
1543 BFD_ASSERT (ind
->root
.dynindx
== -1);
1547 elfNN_ia64_hash_hide_symbol (info
, xh
)
1548 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1549 struct elf_link_hash_entry
*xh
;
1551 struct elfNN_ia64_link_hash_entry
*h
;
1552 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1554 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1556 h
->root
.elf_link_hash_flags
&= ~ELF_LINK_HASH_NEEDS_PLT
;
1557 if ((h
->root
.elf_link_hash_flags
& ELF_LINK_FORCED_LOCAL
) != 0)
1558 h
->root
.dynindx
= -1;
1560 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1561 dyn_i
->want_plt2
= 0;
1564 /* Create the derived linker hash table. The IA-64 ELF port uses this
1565 derived hash table to keep information specific to the IA-64 ElF
1566 linker (without using static variables). */
1568 static struct bfd_link_hash_table
*
1569 elfNN_ia64_hash_table_create (abfd
)
1572 struct elfNN_ia64_link_hash_table
*ret
;
1574 ret
= bfd_alloc (abfd
, sizeof (*ret
));
1577 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1578 elfNN_ia64_new_elf_hash_entry
))
1580 bfd_release (abfd
, ret
);
1584 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1585 elfNN_ia64_new_loc_hash_entry
))
1587 return &ret
->root
.root
;
1590 /* Look up an entry in a Alpha ELF linker hash table. */
1592 static INLINE
struct elfNN_ia64_local_hash_entry
*
1593 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1594 struct elfNN_ia64_local_hash_table
*table
;
1596 boolean create
, copy
;
1598 return ((struct elfNN_ia64_local_hash_entry
*)
1599 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1602 /* Traverse both local and global hash tables. */
1604 struct elfNN_ia64_dyn_sym_traverse_data
1606 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1611 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1612 struct bfd_hash_entry
*xentry
;
1615 struct elfNN_ia64_link_hash_entry
*entry
1616 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1617 struct elfNN_ia64_dyn_sym_traverse_data
*data
1618 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1619 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1621 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1622 if (! (*data
->func
) (dyn_i
, data
->data
))
1628 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1629 struct bfd_hash_entry
*xentry
;
1632 struct elfNN_ia64_local_hash_entry
*entry
1633 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1634 struct elfNN_ia64_dyn_sym_traverse_data
*data
1635 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1636 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1638 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1639 if (! (*data
->func
) (dyn_i
, data
->data
))
1645 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1646 struct elfNN_ia64_link_hash_table
*ia64_info
;
1647 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1650 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1655 elf_link_hash_traverse (&ia64_info
->root
,
1656 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1657 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1658 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1662 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1664 struct bfd_link_info
*info
;
1666 struct elfNN_ia64_link_hash_table
*ia64_info
;
1669 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1672 ia64_info
= elfNN_ia64_hash_table (info
);
1674 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1675 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1678 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1679 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1682 if (!get_pltoff (abfd
, info
, ia64_info
))
1685 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1687 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1690 | SEC_LINKER_CREATED
1692 || !bfd_set_section_alignment (abfd
, s
, 3))
1694 ia64_info
->rel_pltoff_sec
= s
;
1696 s
= bfd_make_section(abfd
, ".rela.got");
1698 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1701 | SEC_LINKER_CREATED
1703 || !bfd_set_section_alignment (abfd
, s
, 3))
1705 ia64_info
->rel_got_sec
= s
;
1710 /* Find and/or create a descriptor for dynamic symbol info. This will
1711 vary based on global or local symbol, and the addend to the reloc. */
1713 static struct elfNN_ia64_dyn_sym_info
*
1714 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1715 struct elfNN_ia64_link_hash_table
*ia64_info
;
1716 struct elf_link_hash_entry
*h
;
1718 const Elf_Internal_Rela
*rel
;
1721 struct elfNN_ia64_dyn_sym_info
**pp
;
1722 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1723 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1726 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1729 struct elfNN_ia64_local_hash_entry
*loc_h
;
1733 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1734 The name describes what was once anonymous memory. */
1736 len
= sizeof (void*)*2 + 1 + sizeof (bfd_vma
)*4 + 1 + 1;
1737 len
+= 10; /* %p slop */
1739 addr_name
= alloca (len
);
1740 sprintf (addr_name
, "%p:%lx",
1741 (void *) abfd
, (unsigned long) ELFNN_R_SYM (rel
->r_info
));
1743 /* Collect the canonical entry data for this address. */
1744 loc_h
= elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1745 addr_name
, create
, create
);
1751 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
1754 if (dyn_i
== NULL
&& create
)
1756 dyn_i
= (struct elfNN_ia64_dyn_sym_info
*)
1757 bfd_zalloc (abfd
, sizeof *dyn_i
);
1759 dyn_i
->addend
= addend
;
1766 get_got (abfd
, info
, ia64_info
)
1768 struct bfd_link_info
*info
;
1769 struct elfNN_ia64_link_hash_table
*ia64_info
;
1774 got
= ia64_info
->got_sec
;
1779 dynobj
= ia64_info
->root
.dynobj
;
1781 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1782 if (!_bfd_elf_create_got_section (dynobj
, info
))
1785 got
= bfd_get_section_by_name (dynobj
, ".got");
1787 ia64_info
->got_sec
= got
;
1789 flags
= bfd_get_section_flags (abfd
, got
);
1790 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
1796 /* Create function descriptor section (.opd). This section is called .opd
1797 because it contains "official prodecure descriptors". The "official"
1798 refers to the fact that these descriptors are used when taking the address
1799 of a procedure, thus ensuring a unique address for each procedure. */
1802 get_fptr (abfd
, info
, ia64_info
)
1804 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1805 struct elfNN_ia64_link_hash_table
*ia64_info
;
1810 fptr
= ia64_info
->fptr_sec
;
1813 dynobj
= ia64_info
->root
.dynobj
;
1815 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1817 fptr
= bfd_make_section (dynobj
, ".opd");
1819 || !bfd_set_section_flags (dynobj
, fptr
,
1825 | SEC_LINKER_CREATED
))
1826 || !bfd_set_section_alignment (abfd
, fptr
, 4))
1832 ia64_info
->fptr_sec
= fptr
;
1839 get_pltoff (abfd
, info
, ia64_info
)
1841 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1842 struct elfNN_ia64_link_hash_table
*ia64_info
;
1847 pltoff
= ia64_info
->pltoff_sec
;
1850 dynobj
= ia64_info
->root
.dynobj
;
1852 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1854 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
1856 || !bfd_set_section_flags (dynobj
, pltoff
,
1862 | SEC_LINKER_CREATED
))
1863 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
1869 ia64_info
->pltoff_sec
= pltoff
;
1876 get_reloc_section (abfd
, ia64_info
, sec
, create
)
1878 struct elfNN_ia64_link_hash_table
*ia64_info
;
1882 const char *srel_name
;
1886 srel_name
= (bfd_elf_string_from_elf_section
1887 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
1888 elf_section_data(sec
)->rel_hdr
.sh_name
));
1889 if (srel_name
== NULL
)
1892 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
1893 && strcmp (bfd_get_section_name (abfd
, sec
),
1895 || (strncmp (srel_name
, ".rel", 4) == 0
1896 && strcmp (bfd_get_section_name (abfd
, sec
),
1897 srel_name
+4) == 0));
1899 dynobj
= ia64_info
->root
.dynobj
;
1901 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1903 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
1904 if (srel
== NULL
&& create
)
1906 srel
= bfd_make_section (dynobj
, srel_name
);
1908 || !bfd_set_section_flags (dynobj
, srel
,
1913 | SEC_LINKER_CREATED
1915 || !bfd_set_section_alignment (dynobj
, srel
, 3))
1923 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
1925 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1929 struct elfNN_ia64_dyn_reloc_entry
*rent
;
1931 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
1932 if (rent
->srel
== srel
&& rent
->type
== type
)
1937 rent
= (struct elfNN_ia64_dyn_reloc_entry
*)
1938 bfd_alloc (abfd
, sizeof (*rent
));
1942 rent
->next
= dyn_i
->reloc_entries
;
1946 dyn_i
->reloc_entries
= rent
;
1954 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
1956 struct bfd_link_info
*info
;
1958 const Elf_Internal_Rela
*relocs
;
1960 struct elfNN_ia64_link_hash_table
*ia64_info
;
1961 const Elf_Internal_Rela
*relend
;
1962 Elf_Internal_Shdr
*symtab_hdr
;
1963 const Elf_Internal_Rela
*rel
;
1964 asection
*got
, *fptr
, *srel
;
1966 if (info
->relocateable
)
1969 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1970 ia64_info
= elfNN_ia64_hash_table (info
);
1972 got
= fptr
= srel
= NULL
;
1974 relend
= relocs
+ sec
->reloc_count
;
1975 for (rel
= relocs
; rel
< relend
; ++rel
)
1984 NEED_LTOFF_FPTR
= 64,
1987 struct elf_link_hash_entry
*h
= NULL
;
1988 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
1989 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1991 boolean maybe_dynamic
;
1992 int dynrel_type
= R_IA64_NONE
;
1994 if (r_symndx
>= symtab_hdr
->sh_info
)
1996 /* We're dealing with a global symbol -- find its hash entry
1997 and mark it as being referenced. */
1998 long indx
= r_symndx
- symtab_hdr
->sh_info
;
1999 h
= elf_sym_hashes (abfd
)[indx
];
2000 while (h
->root
.type
== bfd_link_hash_indirect
2001 || h
->root
.type
== bfd_link_hash_warning
)
2002 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2004 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
2007 /* We can only get preliminary data on whether a symbol is
2008 locally or externally defined, as not all of the input files
2009 have yet been processed. Do something with what we know, as
2010 this may help reduce memory usage and processing time later. */
2011 maybe_dynamic
= false;
2012 if (h
&& ((info
->shared
&& ! info
->symbolic
)
2013 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
2014 || h
->root
.type
== bfd_link_hash_defweak
2015 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2016 maybe_dynamic
= true;
2019 switch (ELFNN_R_TYPE (rel
->r_info
))
2021 case R_IA64_TPREL22
:
2022 case R_IA64_TPREL64MSB
:
2023 case R_IA64_TPREL64LSB
:
2024 case R_IA64_LTOFF_TP22
:
2027 case R_IA64_LTOFF_FPTR22
:
2028 case R_IA64_LTOFF_FPTR64I
:
2029 case R_IA64_LTOFF_FPTR32MSB
:
2030 case R_IA64_LTOFF_FPTR32LSB
:
2031 case R_IA64_LTOFF_FPTR64MSB
:
2032 case R_IA64_LTOFF_FPTR64LSB
:
2033 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2036 case R_IA64_FPTR64I
:
2037 case R_IA64_FPTR32MSB
:
2038 case R_IA64_FPTR32LSB
:
2039 case R_IA64_FPTR64MSB
:
2040 case R_IA64_FPTR64LSB
:
2041 if (info
->shared
|| h
|| elfNN_ia64_aix_vec (abfd
->xvec
))
2042 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2044 need_entry
= NEED_FPTR
;
2045 dynrel_type
= R_IA64_FPTR64LSB
;
2048 case R_IA64_LTOFF22
:
2049 case R_IA64_LTOFF22X
:
2050 case R_IA64_LTOFF64I
:
2051 need_entry
= NEED_GOT
;
2054 case R_IA64_PLTOFF22
:
2055 case R_IA64_PLTOFF64I
:
2056 case R_IA64_PLTOFF64MSB
:
2057 case R_IA64_PLTOFF64LSB
:
2058 need_entry
= NEED_PLTOFF
;
2062 need_entry
|= NEED_MIN_PLT
;
2066 (*info
->callbacks
->warning
)
2067 (info
, _("@pltoff reloc against local symbol"), 0,
2072 case R_IA64_PCREL21B
:
2073 case R_IA64_PCREL60B
:
2074 /* Depending on where this symbol is defined, we may or may not
2075 need a full plt entry. Only skip if we know we'll not need
2076 the entry -- static or symbolic, and the symbol definition
2077 has already been seen. */
2078 if (maybe_dynamic
&& rel
->r_addend
== 0)
2079 need_entry
= NEED_FULL_PLT
;
2085 case R_IA64_DIR32MSB
:
2086 case R_IA64_DIR32LSB
:
2087 case R_IA64_DIR64MSB
:
2088 case R_IA64_DIR64LSB
:
2089 /* Shared objects will always need at least a REL relocation. */
2090 if (info
->shared
|| maybe_dynamic
2091 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2092 && (!h
|| strcmp (h
->root
.root
.string
,
2093 "__GLOB_DATA_PTR") != 0)))
2094 need_entry
= NEED_DYNREL
;
2095 dynrel_type
= R_IA64_DIR64LSB
;
2098 case R_IA64_IPLTMSB
:
2099 case R_IA64_IPLTLSB
:
2100 /* Shared objects will always need at least a REL relocation. */
2101 if (info
->shared
|| maybe_dynamic
)
2102 need_entry
= NEED_DYNREL
;
2103 dynrel_type
= R_IA64_IPLTLSB
;
2106 case R_IA64_PCREL22
:
2107 case R_IA64_PCREL64I
:
2108 case R_IA64_PCREL32MSB
:
2109 case R_IA64_PCREL32LSB
:
2110 case R_IA64_PCREL64MSB
:
2111 case R_IA64_PCREL64LSB
:
2113 need_entry
= NEED_DYNREL
;
2114 dynrel_type
= R_IA64_PCREL64LSB
;
2121 if ((need_entry
& NEED_FPTR
) != 0
2124 (*info
->callbacks
->warning
)
2125 (info
, _("non-zero addend in @fptr reloc"), 0,
2129 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, true);
2131 /* Record whether or not this is a local symbol. */
2134 /* Create what's needed. */
2135 if (need_entry
& NEED_GOT
)
2139 got
= get_got (abfd
, info
, ia64_info
);
2143 dyn_i
->want_got
= 1;
2145 if (need_entry
& NEED_FPTR
)
2149 fptr
= get_fptr (abfd
, info
, ia64_info
);
2154 /* FPTRs for shared libraries are allocated by the dynamic
2155 linker. Make sure this local symbol will appear in the
2156 dynamic symbol table. */
2157 if (!h
&& (info
->shared
2158 /* AIX also needs one */
2159 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2161 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2162 (info
, abfd
, r_symndx
)))
2166 dyn_i
->want_fptr
= 1;
2168 if (need_entry
& NEED_LTOFF_FPTR
)
2169 dyn_i
->want_ltoff_fptr
= 1;
2170 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2172 if (!ia64_info
->root
.dynobj
)
2173 ia64_info
->root
.dynobj
= abfd
;
2174 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2175 dyn_i
->want_plt
= 1;
2177 if (need_entry
& NEED_FULL_PLT
)
2178 dyn_i
->want_plt2
= 1;
2179 if (need_entry
& NEED_PLTOFF
)
2180 dyn_i
->want_pltoff
= 1;
2181 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2185 srel
= get_reloc_section (abfd
, ia64_info
, sec
, true);
2189 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2197 struct elfNN_ia64_allocate_data
2199 struct bfd_link_info
*info
;
2203 /* For cleanliness, and potentially faster dynamic loading, allocate
2204 external GOT entries first. */
2207 allocate_global_data_got (dyn_i
, data
)
2208 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2211 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2214 && ! dyn_i
->want_fptr
2215 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2216 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2217 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2218 "__GLOB_DATA_PTR") != 0))))
2220 dyn_i
->got_offset
= x
->ofs
;
2226 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2229 allocate_global_fptr_got (dyn_i
, data
)
2230 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2233 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2237 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2238 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2240 dyn_i
->got_offset
= x
->ofs
;
2246 /* Lastly, allocate all the GOT entries for local data. */
2249 allocate_local_got (dyn_i
, data
)
2250 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2253 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2256 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2257 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2259 dyn_i
->got_offset
= x
->ofs
;
2265 /* Search for the index of a global symbol in it's defining object file. */
2267 static unsigned long
2268 global_sym_index (h
)
2269 struct elf_link_hash_entry
*h
;
2271 struct elf_link_hash_entry
**p
;
2274 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2275 || h
->root
.type
== bfd_link_hash_defweak
);
2277 obj
= h
->root
.u
.def
.section
->owner
;
2278 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2281 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2284 /* Allocate function descriptors. We can do these for every function
2285 in a main executable that is not exported. */
2288 allocate_fptr (dyn_i
, data
)
2289 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2292 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2294 if (dyn_i
->want_fptr
)
2296 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2299 while (h
->root
.type
== bfd_link_hash_indirect
2300 || h
->root
.type
== bfd_link_hash_warning
)
2301 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2304 /* AIX needs an FPTR in this case. */
2305 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2307 || h
->root
.type
== bfd_link_hash_defined
2308 || h
->root
.type
== bfd_link_hash_defweak
)))
2310 if (h
&& h
->dynindx
== -1)
2312 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2313 || (h
->root
.type
== bfd_link_hash_defweak
));
2315 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2316 (x
->info
, h
->root
.u
.def
.section
->owner
,
2317 global_sym_index (h
)))
2321 dyn_i
->want_fptr
= 0;
2323 else if (h
== NULL
|| h
->dynindx
== -1)
2325 dyn_i
->fptr_offset
= x
->ofs
;
2329 dyn_i
->want_fptr
= 0;
2334 /* Allocate all the minimal PLT entries. */
2337 allocate_plt_entries (dyn_i
, data
)
2338 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2341 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2343 if (dyn_i
->want_plt
)
2345 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2348 while (h
->root
.type
== bfd_link_hash_indirect
2349 || h
->root
.type
== bfd_link_hash_warning
)
2350 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2352 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2353 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2355 bfd_size_type offset
= x
->ofs
;
2357 offset
= PLT_HEADER_SIZE
;
2358 dyn_i
->plt_offset
= offset
;
2359 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2361 dyn_i
->want_pltoff
= 1;
2365 dyn_i
->want_plt
= 0;
2366 dyn_i
->want_plt2
= 0;
2372 /* Allocate all the full PLT entries. */
2375 allocate_plt2_entries (dyn_i
, data
)
2376 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2379 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2381 if (dyn_i
->want_plt2
)
2383 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2384 bfd_size_type ofs
= x
->ofs
;
2386 dyn_i
->plt2_offset
= ofs
;
2387 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2389 while (h
->root
.type
== bfd_link_hash_indirect
2390 || h
->root
.type
== bfd_link_hash_warning
)
2391 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2392 dyn_i
->h
->plt
.offset
= ofs
;
2397 /* Allocate all the PLTOFF entries requested by relocations and
2398 plt entries. We can't share space with allocated FPTR entries,
2399 because the latter are not necessarily addressable by the GP.
2400 ??? Relaxation might be able to determine that they are. */
2403 allocate_pltoff_entries (dyn_i
, data
)
2404 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2407 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2409 if (dyn_i
->want_pltoff
)
2411 dyn_i
->pltoff_offset
= x
->ofs
;
2417 /* Allocate dynamic relocations for those symbols that turned out
2421 allocate_dynrel_entries (dyn_i
, data
)
2422 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2425 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2426 struct elfNN_ia64_link_hash_table
*ia64_info
;
2427 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2428 boolean dynamic_symbol
, shared
;
2430 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2431 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2432 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2433 /* Don't allocate an entry for __GLOB_DATA_PTR */
2434 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2435 "__GLOB_DATA_PTR") != 0));
2436 shared
= x
->info
->shared
;
2438 /* Take care of the normal data relocations. */
2440 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2442 int count
= rent
->count
;
2446 case R_IA64_FPTR64LSB
:
2447 /* Allocate one iff !want_fptr, which by this point will
2448 be true only if we're actually allocating one statically
2449 in the main executable. */
2450 if (dyn_i
->want_fptr
)
2453 case R_IA64_PCREL64LSB
:
2454 if (!dynamic_symbol
)
2457 case R_IA64_DIR64LSB
:
2458 if (!dynamic_symbol
&& !shared
)
2461 case R_IA64_IPLTLSB
:
2462 if (!dynamic_symbol
&& !shared
)
2464 /* Use two REL relocations for IPLT relocations
2465 against local symbols. */
2466 if (!dynamic_symbol
)
2472 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2475 /* Take care of the GOT and PLT relocations. */
2477 if (((dynamic_symbol
|| shared
) && dyn_i
->want_got
)
2478 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2479 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2481 if (dyn_i
->want_pltoff
)
2483 bfd_size_type t
= 0;
2485 /* Dynamic symbols get one IPLT relocation. Local symbols in
2486 shared libraries get two REL relocations. Local symbols in
2487 main applications get nothing. */
2489 t
= sizeof (ElfNN_External_Rela
);
2491 t
= 2 * sizeof (ElfNN_External_Rela
);
2493 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2500 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2501 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2502 struct elf_link_hash_entry
*h
;
2504 /* ??? Undefined symbols with PLT entries should be re-defined
2505 to be the PLT entry. */
2507 /* If this is a weak symbol, and there is a real definition, the
2508 processor independent code will have arranged for us to see the
2509 real definition first, and we can just use the same value. */
2510 if (h
->weakdef
!= NULL
)
2512 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2513 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2514 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2515 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2519 /* If this is a reference to a symbol defined by a dynamic object which
2520 is not a function, we might allocate the symbol in our .dynbss section
2521 and allocate a COPY dynamic relocation.
2523 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2530 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2532 struct bfd_link_info
*info
;
2534 struct elfNN_ia64_allocate_data data
;
2535 struct elfNN_ia64_link_hash_table
*ia64_info
;
2538 boolean reltext
= false;
2539 boolean relplt
= false;
2541 dynobj
= elf_hash_table(info
)->dynobj
;
2542 ia64_info
= elfNN_ia64_hash_table (info
);
2543 BFD_ASSERT(dynobj
!= NULL
);
2546 /* Set the contents of the .interp section to the interpreter. */
2547 if (ia64_info
->root
.dynamic_sections_created
2550 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2551 BFD_ASSERT (sec
!= NULL
);
2552 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2553 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2556 /* Allocate the GOT entries. */
2558 if (ia64_info
->got_sec
)
2561 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2562 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2563 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2564 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2567 /* Allocate the FPTR entries. */
2569 if (ia64_info
->fptr_sec
)
2572 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2573 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2576 /* Now that we've seen all of the input files, we can decide which
2577 symbols need plt entries. Allocate the minimal PLT entries first.
2578 We do this even though dynamic_sections_created may be false, because
2579 this has the side-effect of clearing want_plt and want_plt2. */
2582 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2584 ia64_info
->minplt_entries
= 0;
2587 ia64_info
->minplt_entries
2588 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2591 /* Align the pointer for the plt2 entries. */
2592 data
.ofs
= (data
.ofs
+ 31) & -32;
2594 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2597 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2599 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2601 /* If we've got a .plt, we need some extra memory for the dynamic
2602 linker. We stuff these in .got.plt. */
2603 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2604 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2607 /* Allocate the PLTOFF entries. */
2609 if (ia64_info
->pltoff_sec
)
2612 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2613 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2616 if (ia64_info
->root
.dynamic_sections_created
)
2618 /* Allocate space for the dynamic relocations that turned out to be
2621 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2624 /* We have now determined the sizes of the various dynamic sections.
2625 Allocate memory for them. */
2626 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2630 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2633 /* If we don't need this section, strip it from the output file.
2634 There were several sections primarily related to dynamic
2635 linking that must be create before the linker maps input
2636 sections to output sections. The linker does that before
2637 bfd_elf_size_dynamic_sections is called, and it is that
2638 function which decides whether anything needs to go into
2641 strip
= (sec
->_raw_size
== 0);
2643 if (sec
== ia64_info
->got_sec
)
2645 else if (sec
== ia64_info
->rel_got_sec
)
2648 ia64_info
->rel_got_sec
= NULL
;
2650 /* We use the reloc_count field as a counter if we need to
2651 copy relocs into the output file. */
2652 sec
->reloc_count
= 0;
2654 else if (sec
== ia64_info
->fptr_sec
)
2657 ia64_info
->fptr_sec
= NULL
;
2659 else if (sec
== ia64_info
->plt_sec
)
2662 ia64_info
->plt_sec
= NULL
;
2664 else if (sec
== ia64_info
->pltoff_sec
)
2667 ia64_info
->pltoff_sec
= NULL
;
2669 else if (sec
== ia64_info
->rel_pltoff_sec
)
2672 ia64_info
->rel_pltoff_sec
= NULL
;
2676 /* We use the reloc_count field as a counter if we need to
2677 copy relocs into the output file. */
2678 sec
->reloc_count
= 0;
2685 /* It's OK to base decisions on the section name, because none
2686 of the dynobj section names depend upon the input files. */
2687 name
= bfd_get_section_name (dynobj
, sec
);
2689 if (strcmp (name
, ".got.plt") == 0)
2691 else if (strncmp (name
, ".rel", 4) == 0)
2695 const char *outname
;
2698 /* If this relocation section applies to a read only
2699 section, then we probably need a DT_TEXTREL entry. */
2700 outname
= bfd_get_section_name (output_bfd
,
2701 sec
->output_section
);
2702 if (outname
[4] == 'a')
2707 target
= bfd_get_section_by_name (output_bfd
, outname
);
2709 && (target
->flags
& SEC_READONLY
) != 0
2710 && (target
->flags
& SEC_ALLOC
) != 0)
2713 /* We use the reloc_count field as a counter if we need to
2714 copy relocs into the output file. */
2715 sec
->reloc_count
= 0;
2723 _bfd_strip_section_from_output (info
, sec
);
2726 /* Allocate memory for the section contents. */
2727 sec
->contents
= (bfd_byte
*) bfd_zalloc(dynobj
, sec
->_raw_size
);
2728 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
2733 if (elf_hash_table (info
)->dynamic_sections_created
)
2735 /* Add some entries to the .dynamic section. We fill in the values
2736 later (in finish_dynamic_sections) but we must add the entries now
2737 so that we get the correct size for the .dynamic section. */
2741 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2743 if (!bfd_elfNN_add_dynamic_entry (info
, DT_DEBUG
, 0))
2747 if (! bfd_elfNN_add_dynamic_entry (info
, DT_IA_64_PLT_RESERVE
, 0))
2749 if (! bfd_elfNN_add_dynamic_entry (info
, DT_PLTGOT
, 0))
2754 if (! bfd_elfNN_add_dynamic_entry (info
, DT_PLTRELSZ
, 0)
2755 || ! bfd_elfNN_add_dynamic_entry (info
, DT_PLTREL
, DT_RELA
)
2756 || ! bfd_elfNN_add_dynamic_entry (info
, DT_JMPREL
, 0))
2760 if (! bfd_elfNN_add_dynamic_entry (info
, DT_RELA
, 0)
2761 || ! bfd_elfNN_add_dynamic_entry (info
, DT_RELASZ
, 0)
2762 || ! bfd_elfNN_add_dynamic_entry (info
, DT_RELAENT
,
2763 sizeof (ElfNN_External_Rela
)))
2768 if (! bfd_elfNN_add_dynamic_entry (info
, DT_TEXTREL
, 0))
2770 info
->flags
|= DF_TEXTREL
;
2774 /* ??? Perhaps force __gp local. */
2779 static bfd_reloc_status_type
2780 elfNN_ia64_install_value (abfd
, hit_addr
, val
, r_type
)
2784 unsigned int r_type
;
2786 const struct ia64_operand
*op
;
2787 int bigendian
= 0, shift
= 0;
2788 bfd_vma t0
, t1
, insn
, dword
;
2789 enum ia64_opnd opnd
;
2793 opnd
= IA64_OPND_NIL
;
2798 return bfd_reloc_ok
;
2800 /* Instruction relocations. */
2802 case R_IA64_IMM14
: opnd
= IA64_OPND_IMM14
; break;
2804 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
2805 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
2806 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
2807 case R_IA64_PCREL21B
:
2808 case R_IA64_PCREL21BI
:
2809 opnd
= IA64_OPND_TGT25c
;
2813 case R_IA64_GPREL22
:
2814 case R_IA64_LTOFF22
:
2815 case R_IA64_LTOFF22X
:
2816 case R_IA64_PLTOFF22
:
2817 case R_IA64_PCREL22
:
2818 case R_IA64_LTOFF_FPTR22
:
2819 opnd
= IA64_OPND_IMM22
;
2823 case R_IA64_GPREL64I
:
2824 case R_IA64_LTOFF64I
:
2825 case R_IA64_PLTOFF64I
:
2826 case R_IA64_PCREL64I
:
2827 case R_IA64_FPTR64I
:
2828 case R_IA64_LTOFF_FPTR64I
:
2829 opnd
= IA64_OPND_IMMU64
;
2832 /* Data relocations. */
2834 case R_IA64_DIR32MSB
:
2835 case R_IA64_GPREL32MSB
:
2836 case R_IA64_FPTR32MSB
:
2837 case R_IA64_PCREL32MSB
:
2838 case R_IA64_LTOFF_FPTR32MSB
:
2839 case R_IA64_SEGREL32MSB
:
2840 case R_IA64_SECREL32MSB
:
2841 case R_IA64_LTV32MSB
:
2842 size
= 4; bigendian
= 1;
2845 case R_IA64_DIR32LSB
:
2846 case R_IA64_GPREL32LSB
:
2847 case R_IA64_FPTR32LSB
:
2848 case R_IA64_PCREL32LSB
:
2849 case R_IA64_LTOFF_FPTR32LSB
:
2850 case R_IA64_SEGREL32LSB
:
2851 case R_IA64_SECREL32LSB
:
2852 case R_IA64_LTV32LSB
:
2853 size
= 4; bigendian
= 0;
2856 case R_IA64_DIR64MSB
:
2857 case R_IA64_GPREL64MSB
:
2858 case R_IA64_PLTOFF64MSB
:
2859 case R_IA64_FPTR64MSB
:
2860 case R_IA64_PCREL64MSB
:
2861 case R_IA64_LTOFF_FPTR64MSB
:
2862 case R_IA64_SEGREL64MSB
:
2863 case R_IA64_SECREL64MSB
:
2864 case R_IA64_LTV64MSB
:
2865 size
= 8; bigendian
= 1;
2868 case R_IA64_DIR64LSB
:
2869 case R_IA64_GPREL64LSB
:
2870 case R_IA64_PLTOFF64LSB
:
2871 case R_IA64_FPTR64LSB
:
2872 case R_IA64_PCREL64LSB
:
2873 case R_IA64_LTOFF_FPTR64LSB
:
2874 case R_IA64_SEGREL64LSB
:
2875 case R_IA64_SECREL64LSB
:
2876 case R_IA64_LTV64LSB
:
2877 size
= 8; bigendian
= 0;
2880 /* Unsupported / Dynamic relocations. */
2882 return bfd_reloc_notsupported
;
2887 case IA64_OPND_IMMU64
:
2888 hit_addr
-= (long) hit_addr
& 0x3;
2889 t0
= bfd_get_64 (abfd
, hit_addr
);
2890 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2892 /* tmpl/s: bits 0.. 5 in t0
2893 slot 0: bits 5..45 in t0
2894 slot 1: bits 46..63 in t0, bits 0..22 in t1
2895 slot 2: bits 23..63 in t1 */
2897 /* First, clear the bits that form the 64 bit constant. */
2898 t0
&= ~(0x3ffffLL
<< 46);
2900 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
2901 | (0x01fLL
<< 22) | (0x001LL
<< 21)
2902 | (0x001LL
<< 36)) << 23));
2904 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
2905 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
2906 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
2907 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
2908 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
2909 | (((val
>> 21) & 0x001) << 21) /* ic */
2910 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
2912 bfd_put_64 (abfd
, t0
, hit_addr
);
2913 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2916 case IA64_OPND_TGT64
:
2917 hit_addr
-= (long) hit_addr
& 0x3;
2918 t0
= bfd_get_64 (abfd
, hit_addr
);
2919 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2921 /* tmpl/s: bits 0.. 5 in t0
2922 slot 0: bits 5..45 in t0
2923 slot 1: bits 46..63 in t0, bits 0..22 in t1
2924 slot 2: bits 23..63 in t1 */
2926 /* First, clear the bits that form the 64 bit constant. */
2927 t0
&= ~(0x3ffffLL
<< 46);
2929 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
2932 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
2933 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
2934 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
2935 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
2937 bfd_put_64 (abfd
, t0
, hit_addr
);
2938 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2942 switch ((long) hit_addr
& 0x3)
2944 case 0: shift
= 5; break;
2945 case 1: shift
= 14; hit_addr
+= 3; break;
2946 case 2: shift
= 23; hit_addr
+= 6; break;
2947 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
2949 dword
= bfd_get_64 (abfd
, hit_addr
);
2950 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
2952 op
= elf64_ia64_operands
+ opnd
;
2953 err
= (*op
->insert
) (op
, val
, &insn
);
2955 return bfd_reloc_overflow
;
2957 dword
&= ~(0x1ffffffffffLL
<< shift
);
2958 dword
|= (insn
<< shift
);
2959 bfd_put_64 (abfd
, dword
, hit_addr
);
2963 /* A data relocation. */
2966 bfd_putb32 (val
, hit_addr
);
2968 bfd_putb64 (val
, hit_addr
);
2971 bfd_putl32 (val
, hit_addr
);
2973 bfd_putl64 (val
, hit_addr
);
2977 return bfd_reloc_ok
;
2981 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
2984 struct bfd_link_info
*info
;
2992 Elf_Internal_Rela outrel
;
2994 outrel
.r_offset
= (sec
->output_section
->vma
2995 + sec
->output_offset
2998 BFD_ASSERT (dynindx
!= -1);
2999 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3000 outrel
.r_addend
= addend
;
3002 if (elf_section_data (sec
)->stab_info
!= NULL
)
3004 /* This may be NULL for linker-generated relocations, as it is
3005 inconvenient to pass all the bits around. And this shouldn't
3007 BFD_ASSERT (info
!= NULL
);
3009 offset
= (_bfd_stab_section_offset
3010 (abfd
, &elf_hash_table (info
)->stab_info
, sec
,
3011 &elf_section_data (sec
)->stab_info
, offset
));
3012 if (offset
== (bfd_vma
) -1)
3014 /* Run for the hills. We shouldn't be outputting a relocation
3015 for this. So do what everyone else does and output a no-op. */
3016 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3017 outrel
.r_addend
= 0;
3020 outrel
.r_offset
= offset
;
3023 bfd_elfNN_swap_reloca_out (abfd
, &outrel
,
3024 ((ElfNN_External_Rela
*) srel
->contents
3025 + srel
->reloc_count
++));
3026 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3027 <= srel
->_cooked_size
);
3030 /* Store an entry for target address TARGET_ADDR in the linkage table
3031 and return the gp-relative address of the linkage table entry. */
3034 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3036 struct bfd_link_info
*info
;
3037 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3041 unsigned int dyn_r_type
;
3043 struct elfNN_ia64_link_hash_table
*ia64_info
;
3046 ia64_info
= elfNN_ia64_hash_table (info
);
3047 got_sec
= ia64_info
->got_sec
;
3049 BFD_ASSERT ((dyn_i
->got_offset
& 7) == 0);
3051 if (! dyn_i
->got_done
)
3053 dyn_i
->got_done
= true;
3055 /* Store the target address in the linkage table entry. */
3056 bfd_put_64 (abfd
, value
, got_sec
->contents
+ dyn_i
->got_offset
);
3058 /* Install a dynamic relocation if needed. */
3060 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3061 || elfNN_ia64_aix_vec (abfd
->xvec
)
3062 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3066 dyn_r_type
= R_IA64_REL64LSB
;
3071 if (bfd_big_endian (abfd
))
3075 case R_IA64_REL64LSB
:
3076 dyn_r_type
= R_IA64_REL64MSB
;
3078 case R_IA64_DIR64LSB
:
3079 dyn_r_type
= R_IA64_DIR64MSB
;
3081 case R_IA64_FPTR64LSB
:
3082 dyn_r_type
= R_IA64_FPTR64MSB
;
3090 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3091 ia64_info
->rel_got_sec
,
3092 dyn_i
->got_offset
, dyn_r_type
,
3097 /* Return the address of the linkage table entry. */
3098 value
= (got_sec
->output_section
->vma
3099 + got_sec
->output_offset
3100 + dyn_i
->got_offset
);
3105 /* Fill in a function descriptor consisting of the function's code
3106 address and its global pointer. Return the descriptor's address. */
3109 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3111 struct bfd_link_info
*info
;
3112 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3115 struct elfNN_ia64_link_hash_table
*ia64_info
;
3118 ia64_info
= elfNN_ia64_hash_table (info
);
3119 fptr_sec
= ia64_info
->fptr_sec
;
3121 if (!dyn_i
->fptr_done
)
3123 dyn_i
->fptr_done
= 1;
3125 /* Fill in the function descriptor. */
3126 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3127 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3128 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3131 /* Return the descriptor's address. */
3132 value
= (fptr_sec
->output_section
->vma
3133 + fptr_sec
->output_offset
3134 + dyn_i
->fptr_offset
);
3139 /* Fill in a PLTOFF entry consisting of the function's code address
3140 and its global pointer. Return the descriptor's address. */
3143 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3145 struct bfd_link_info
*info
;
3146 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3150 struct elfNN_ia64_link_hash_table
*ia64_info
;
3151 asection
*pltoff_sec
;
3153 ia64_info
= elfNN_ia64_hash_table (info
);
3154 pltoff_sec
= ia64_info
->pltoff_sec
;
3156 /* Don't do anything if this symbol uses a real PLT entry. In
3157 that case, we'll fill this in during finish_dynamic_symbol. */
3158 if ((! dyn_i
->want_plt
|| is_plt
)
3159 && !dyn_i
->pltoff_done
)
3161 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3163 /* Fill in the function descriptor. */
3164 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3165 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3167 /* Install dynamic relocations if needed. */
3168 if (!is_plt
&& info
->shared
)
3170 unsigned int dyn_r_type
;
3172 if (bfd_big_endian (abfd
))
3173 dyn_r_type
= R_IA64_REL64MSB
;
3175 dyn_r_type
= R_IA64_REL64LSB
;
3177 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3178 ia64_info
->rel_pltoff_sec
,
3179 dyn_i
->pltoff_offset
,
3180 dyn_r_type
, 0, value
);
3181 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3182 ia64_info
->rel_pltoff_sec
,
3183 dyn_i
->pltoff_offset
+ 8,
3187 dyn_i
->pltoff_done
= 1;
3190 /* Return the descriptor's address. */
3191 value
= (pltoff_sec
->output_section
->vma
3192 + pltoff_sec
->output_offset
3193 + dyn_i
->pltoff_offset
);
3198 /* Called through qsort to sort the .IA_64.unwind section during a
3199 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3200 to the output bfd so we can do proper endianness frobbing. */
3202 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3205 elfNN_ia64_unwind_entry_compare (a
, b
)
3211 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3212 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3214 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3218 elfNN_ia64_final_link (abfd
, info
)
3220 struct bfd_link_info
*info
;
3222 struct elfNN_ia64_link_hash_table
*ia64_info
;
3223 asection
*unwind_output_sec
;
3225 ia64_info
= elfNN_ia64_hash_table (info
);
3227 /* Make sure we've got ourselves a nice fat __gp value. */
3228 if (!info
->relocateable
)
3230 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3231 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3232 struct elf_link_hash_entry
*gp
;
3236 /* Find the min and max vma of all sections marked short. Also
3237 collect min and max vma of any type, for use in selecting a
3239 for (os
= abfd
->sections
; os
; os
= os
->next
)
3243 if ((os
->flags
& SEC_ALLOC
) == 0)
3247 hi
= os
->vma
+ os
->_raw_size
;
3255 if (os
->flags
& SEC_SMALL_DATA
)
3257 if (min_short_vma
> lo
)
3259 if (max_short_vma
< hi
)
3264 /* See if the user wants to force a value. */
3265 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", false,
3269 && (gp
->root
.type
== bfd_link_hash_defined
3270 || gp
->root
.type
== bfd_link_hash_defweak
))
3272 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3273 gp_val
= (gp
->root
.u
.def
.value
3274 + gp_sec
->output_section
->vma
3275 + gp_sec
->output_offset
);
3279 /* Pick a sensible value. */
3281 asection
*got_sec
= ia64_info
->got_sec
;
3283 /* Start with just the address of the .got. */
3285 gp_val
= got_sec
->output_section
->vma
;
3286 else if (max_short_vma
!= 0)
3287 gp_val
= min_short_vma
;
3291 /* If it is possible to address the entire image, but we
3292 don't with the choice above, adjust. */
3293 if (max_vma
- min_vma
< 0x400000
3294 && max_vma
- gp_val
<= 0x200000
3295 && gp_val
- min_vma
> 0x200000)
3296 gp_val
= min_vma
+ 0x200000;
3297 else if (max_short_vma
!= 0)
3299 /* If we don't cover all the short data, adjust. */
3300 if (max_short_vma
- gp_val
>= 0x200000)
3301 gp_val
= min_short_vma
+ 0x200000;
3303 /* If we're addressing stuff past the end, adjust back. */
3304 if (gp_val
> max_vma
)
3305 gp_val
= max_vma
- 0x200000 + 8;
3309 /* Validate whether all SHF_IA_64_SHORT sections are within
3310 range of the chosen GP. */
3312 if (max_short_vma
!= 0)
3314 if (max_short_vma
- min_short_vma
>= 0x400000)
3316 (*_bfd_error_handler
)
3317 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3318 bfd_get_filename (abfd
),
3319 (unsigned long) (max_short_vma
- min_short_vma
));
3322 else if ((gp_val
> min_short_vma
3323 && gp_val
- min_short_vma
> 0x200000)
3324 || (gp_val
< max_short_vma
3325 && max_short_vma
- gp_val
>= 0x200000))
3327 (*_bfd_error_handler
)
3328 (_("%s: __gp does not cover short data segment"),
3329 bfd_get_filename (abfd
));
3334 _bfd_set_gp_value (abfd
, gp_val
);
3338 gp
->root
.type
= bfd_link_hash_defined
;
3339 gp
->root
.u
.def
.value
= gp_val
;
3340 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3344 /* If we're producing a final executable, we need to sort the contents
3345 of the .IA_64.unwind section. Force this section to be relocated
3346 into memory rather than written immediately to the output file. */
3347 unwind_output_sec
= NULL
;
3348 if (!info
->relocateable
)
3350 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3353 unwind_output_sec
= s
->output_section
;
3354 unwind_output_sec
->contents
3355 = bfd_malloc (unwind_output_sec
->_raw_size
);
3356 if (unwind_output_sec
->contents
== NULL
)
3361 /* Invoke the regular ELF backend linker to do all the work. */
3362 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3365 if (unwind_output_sec
)
3367 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3368 qsort (unwind_output_sec
->contents
, unwind_output_sec
->_raw_size
/ 24,
3369 24, elfNN_ia64_unwind_entry_compare
);
3371 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3372 unwind_output_sec
->contents
, 0,
3373 unwind_output_sec
->_raw_size
))
3381 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3382 contents
, relocs
, local_syms
, local_sections
)
3384 struct bfd_link_info
*info
;
3386 asection
*input_section
;
3388 Elf_Internal_Rela
*relocs
;
3389 Elf_Internal_Sym
*local_syms
;
3390 asection
**local_sections
;
3392 struct elfNN_ia64_link_hash_table
*ia64_info
;
3393 Elf_Internal_Shdr
*symtab_hdr
;
3394 Elf_Internal_Rela
*rel
;
3395 Elf_Internal_Rela
*relend
;
3397 boolean ret_val
= true; /* for non-fatal errors */
3400 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3401 ia64_info
= elfNN_ia64_hash_table (info
);
3403 /* Infect various flags from the input section to the output section. */
3404 if (info
->relocateable
)
3408 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3409 flags
&= SHF_IA_64_NORECOV
;
3411 elf_section_data(input_section
->output_section
)
3412 ->this_hdr
.sh_flags
|= flags
;
3415 gp_val
= _bfd_get_gp_value (output_bfd
);
3416 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, false);
3419 relend
= relocs
+ input_section
->reloc_count
;
3420 for (; rel
< relend
; ++rel
)
3422 struct elf_link_hash_entry
*h
;
3423 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3424 bfd_reloc_status_type r
;
3425 reloc_howto_type
*howto
;
3426 unsigned long r_symndx
;
3427 Elf_Internal_Sym
*sym
;
3428 unsigned int r_type
;
3432 boolean dynamic_symbol_p
;
3433 boolean undef_weak_ref
;
3435 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3436 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3438 (*_bfd_error_handler
)
3439 (_("%s: unknown relocation type %d"),
3440 bfd_get_filename (input_bfd
), (int)r_type
);
3441 bfd_set_error (bfd_error_bad_value
);
3445 howto
= lookup_howto (r_type
);
3446 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3448 if (info
->relocateable
)
3450 /* This is a relocateable link. We don't have to change
3451 anything, unless the reloc is against a section symbol,
3452 in which case we have to adjust according to where the
3453 section symbol winds up in the output section. */
3454 if (r_symndx
< symtab_hdr
->sh_info
)
3456 sym
= local_syms
+ r_symndx
;
3457 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
3459 sym_sec
= local_sections
[r_symndx
];
3460 rel
->r_addend
+= sym_sec
->output_offset
;
3466 /* This is a final link. */
3471 undef_weak_ref
= false;
3473 if (r_symndx
< symtab_hdr
->sh_info
)
3475 /* Reloc against local symbol. */
3476 sym
= local_syms
+ r_symndx
;
3477 sym_sec
= local_sections
[r_symndx
];
3478 value
= (sym_sec
->output_section
->vma
3479 + sym_sec
->output_offset
3486 /* Reloc against global symbol. */
3487 indx
= r_symndx
- symtab_hdr
->sh_info
;
3488 h
= elf_sym_hashes (input_bfd
)[indx
];
3489 while (h
->root
.type
== bfd_link_hash_indirect
3490 || h
->root
.type
== bfd_link_hash_warning
)
3491 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3494 if (h
->root
.type
== bfd_link_hash_defined
3495 || h
->root
.type
== bfd_link_hash_defweak
)
3497 sym_sec
= h
->root
.u
.def
.section
;
3499 /* Detect the cases that sym_sec->output_section is
3500 expected to be NULL -- all cases in which the symbol
3501 is defined in another shared module. This includes
3502 PLT relocs for which we've created a PLT entry and
3503 other relocs for which we're prepared to create
3504 dynamic relocations. */
3505 /* ??? Just accept it NULL and continue. */
3507 if (sym_sec
->output_section
!= NULL
)
3509 value
= (h
->root
.u
.def
.value
3510 + sym_sec
->output_section
->vma
3511 + sym_sec
->output_offset
);
3514 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3515 undef_weak_ref
= true;
3516 else if (info
->shared
&& !info
->symbolic
3517 && !info
->no_undefined
3518 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3522 if (! ((*info
->callbacks
->undefined_symbol
)
3523 (info
, h
->root
.root
.string
, input_bfd
,
3524 input_section
, rel
->r_offset
,
3525 (!info
->shared
|| info
->no_undefined
3526 || ELF_ST_VISIBILITY (h
->other
)))))
3533 hit_addr
= contents
+ rel
->r_offset
;
3534 value
+= rel
->r_addend
;
3535 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3546 case R_IA64_DIR32MSB
:
3547 case R_IA64_DIR32LSB
:
3548 case R_IA64_DIR64MSB
:
3549 case R_IA64_DIR64LSB
:
3550 /* Install a dynamic relocation for this reloc. */
3551 if ((dynamic_symbol_p
|| info
->shared
3552 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
3553 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3554 && (!h
|| strcmp (h
->root
.root
.string
,
3555 "__GLOB_DATA_PTR") != 0)))
3556 && (input_section
->flags
& SEC_ALLOC
) != 0)
3558 unsigned int dyn_r_type
;
3562 BFD_ASSERT (srel
!= NULL
);
3564 /* If we don't need dynamic symbol lookup, find a
3565 matching RELATIVE relocation. */
3566 dyn_r_type
= r_type
;
3567 if (dynamic_symbol_p
)
3569 dynindx
= h
->dynindx
;
3570 addend
= rel
->r_addend
;
3577 case R_IA64_DIR32MSB
:
3578 dyn_r_type
= R_IA64_REL32MSB
;
3580 case R_IA64_DIR32LSB
:
3581 dyn_r_type
= R_IA64_REL32LSB
;
3583 case R_IA64_DIR64MSB
:
3584 dyn_r_type
= R_IA64_REL64MSB
;
3586 case R_IA64_DIR64LSB
:
3587 dyn_r_type
= R_IA64_REL64LSB
;
3591 /* We can't represent this without a dynamic symbol.
3592 Adjust the relocation to be against an output
3593 section symbol, which are always present in the
3594 dynamic symbol table. */
3595 /* ??? People shouldn't be doing non-pic code in
3596 shared libraries. Hork. */
3597 (*_bfd_error_handler
)
3598 (_("%s: linking non-pic code in a shared library"),
3599 bfd_get_filename (input_bfd
));
3607 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
3608 rel
->r_addend
= value
;
3609 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3610 srel
, rel
->r_offset
, dyn_r_type
,
3615 case R_IA64_LTV32MSB
:
3616 case R_IA64_LTV32LSB
:
3617 case R_IA64_LTV64MSB
:
3618 case R_IA64_LTV64LSB
:
3619 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3622 case R_IA64_GPREL22
:
3623 case R_IA64_GPREL64I
:
3624 case R_IA64_GPREL32MSB
:
3625 case R_IA64_GPREL32LSB
:
3626 case R_IA64_GPREL64MSB
:
3627 case R_IA64_GPREL64LSB
:
3628 if (dynamic_symbol_p
)
3630 (*_bfd_error_handler
)
3631 (_("%s: @gprel relocation against dynamic symbol %s"),
3632 bfd_get_filename (input_bfd
), h
->root
.root
.string
);
3637 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3640 case R_IA64_LTOFF22
:
3641 case R_IA64_LTOFF22X
:
3642 case R_IA64_LTOFF64I
:
3643 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3644 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
3645 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
3647 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3650 case R_IA64_PLTOFF22
:
3651 case R_IA64_PLTOFF64I
:
3652 case R_IA64_PLTOFF64MSB
:
3653 case R_IA64_PLTOFF64LSB
:
3654 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3655 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, false);
3657 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3660 case R_IA64_FPTR64I
:
3661 case R_IA64_FPTR32MSB
:
3662 case R_IA64_FPTR32LSB
:
3663 case R_IA64_FPTR64MSB
:
3664 case R_IA64_FPTR64LSB
:
3665 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3666 if (dyn_i
->want_fptr
)
3668 if (!undef_weak_ref
)
3669 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3675 /* Otherwise, we expect the dynamic linker to create
3680 if (h
->dynindx
!= -1)
3681 dynindx
= h
->dynindx
;
3683 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3684 (info
, h
->root
.u
.def
.section
->owner
,
3685 global_sym_index (h
)));
3689 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3690 (info
, input_bfd
, r_symndx
));
3693 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3694 srel
, rel
->r_offset
, r_type
,
3695 dynindx
, rel
->r_addend
);
3699 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3702 case R_IA64_LTOFF_FPTR22
:
3703 case R_IA64_LTOFF_FPTR64I
:
3704 case R_IA64_LTOFF_FPTR32MSB
:
3705 case R_IA64_LTOFF_FPTR32LSB
:
3706 case R_IA64_LTOFF_FPTR64MSB
:
3707 case R_IA64_LTOFF_FPTR64LSB
:
3711 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3712 if (dyn_i
->want_fptr
)
3714 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
3715 if (!undef_weak_ref
)
3716 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3721 /* Otherwise, we expect the dynamic linker to create
3725 if (h
->dynindx
!= -1)
3726 dynindx
= h
->dynindx
;
3728 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3729 (info
, h
->root
.u
.def
.section
->owner
,
3730 global_sym_index (h
)));
3733 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3734 (info
, input_bfd
, r_symndx
));
3738 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
3739 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
3741 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3745 case R_IA64_PCREL32MSB
:
3746 case R_IA64_PCREL32LSB
:
3747 case R_IA64_PCREL64MSB
:
3748 case R_IA64_PCREL64LSB
:
3749 /* Install a dynamic relocation for this reloc. */
3750 if (dynamic_symbol_p
3751 || elfNN_ia64_aix_vec (info
->hash
->creator
))
3753 BFD_ASSERT (srel
!= NULL
);
3755 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3756 srel
, rel
->r_offset
, r_type
,
3757 h
->dynindx
, rel
->r_addend
);
3761 case R_IA64_PCREL21BI
:
3762 case R_IA64_PCREL21F
:
3763 case R_IA64_PCREL21M
:
3764 /* ??? These two are only used for speculation fixup code.
3765 They should never be dynamic. */
3766 if (dynamic_symbol_p
)
3768 (*_bfd_error_handler
)
3769 (_("%s: dynamic relocation against speculation fixup"),
3770 bfd_get_filename (input_bfd
));
3776 (*_bfd_error_handler
)
3777 (_("%s: speculation fixup against undefined weak symbol"),
3778 bfd_get_filename (input_bfd
));
3784 case R_IA64_PCREL21B
:
3785 case R_IA64_PCREL60B
:
3786 /* We should have created a PLT entry for any dynamic symbol. */
3789 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
3791 if (dyn_i
&& dyn_i
->want_plt2
)
3793 /* Should have caught this earlier. */
3794 BFD_ASSERT (rel
->r_addend
== 0);
3796 value
= (ia64_info
->plt_sec
->output_section
->vma
3797 + ia64_info
->plt_sec
->output_offset
3798 + dyn_i
->plt2_offset
);
3802 /* Since there's no PLT entry, Validate that this is
3804 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
3806 /* If the symbol is undef_weak, we shouldn't be trying
3807 to call it. There's every chance that we'd wind up
3808 with an out-of-range fixup here. Don't bother setting
3809 any value at all. */
3815 case R_IA64_PCREL22
:
3816 case R_IA64_PCREL64I
:
3818 /* Make pc-relative. */
3819 value
-= (input_section
->output_section
->vma
3820 + input_section
->output_offset
3821 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
3822 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3825 case R_IA64_SEGREL32MSB
:
3826 case R_IA64_SEGREL32LSB
:
3827 case R_IA64_SEGREL64MSB
:
3828 case R_IA64_SEGREL64LSB
:
3830 struct elf_segment_map
*m
;
3831 Elf_Internal_Phdr
*p
;
3833 /* Find the segment that contains the output_section. */
3834 for (m
= elf_tdata (output_bfd
)->segment_map
,
3835 p
= elf_tdata (output_bfd
)->phdr
;
3840 for (i
= m
->count
- 1; i
>= 0; i
--)
3841 if (m
->sections
[i
] == sym_sec
->output_section
)
3849 /* If the input section was discarded from the output, then
3852 if (bfd_is_abs_section (sym_sec
->output_section
))
3855 r
= bfd_reloc_notsupported
;
3859 /* The VMA of the segment is the vaddr of the associated
3861 if (value
> p
->p_vaddr
)
3862 value
-= p
->p_vaddr
;
3865 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
3871 case R_IA64_SECREL32MSB
:
3872 case R_IA64_SECREL32LSB
:
3873 case R_IA64_SECREL64MSB
:
3874 case R_IA64_SECREL64LSB
:
3875 /* Make output-section relative. */
3876 if (value
> input_section
->output_section
->vma
)
3877 value
-= input_section
->output_section
->vma
;
3880 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3883 case R_IA64_IPLTMSB
:
3884 case R_IA64_IPLTLSB
:
3885 /* Install a dynamic relocation for this reloc. */
3886 if ((dynamic_symbol_p
|| info
->shared
)
3887 && (input_section
->flags
& SEC_ALLOC
) != 0)
3889 BFD_ASSERT (srel
!= NULL
);
3891 /* If we don't need dynamic symbol lookup, install two
3892 RELATIVE relocations. */
3893 if (! dynamic_symbol_p
)
3895 unsigned int dyn_r_type
;
3897 if (r_type
== R_IA64_IPLTMSB
)
3898 dyn_r_type
= R_IA64_REL64MSB
;
3900 dyn_r_type
= R_IA64_REL64LSB
;
3902 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3904 srel
, rel
->r_offset
,
3905 dyn_r_type
, 0, value
);
3906 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3908 srel
, rel
->r_offset
+ 8,
3909 dyn_r_type
, 0, gp_val
);
3912 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3913 srel
, rel
->r_offset
, r_type
,
3914 h
->dynindx
, rel
->r_addend
);
3917 if (r_type
== R_IA64_IPLTMSB
)
3918 r_type
= R_IA64_DIR64MSB
;
3920 r_type
= R_IA64_DIR64LSB
;
3921 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3922 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
3927 r
= bfd_reloc_notsupported
;
3936 case bfd_reloc_undefined
:
3937 /* This can happen for global table relative relocs if
3938 __gp is undefined. This is a panic situation so we
3939 don't try to continue. */
3940 (*info
->callbacks
->undefined_symbol
)
3941 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
3944 case bfd_reloc_notsupported
:
3949 name
= h
->root
.root
.string
;
3952 name
= bfd_elf_string_from_elf_section (input_bfd
,
3953 symtab_hdr
->sh_link
,
3958 name
= bfd_section_name (input_bfd
, input_section
);
3960 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
3962 input_section
, rel
->r_offset
))
3968 case bfd_reloc_dangerous
:
3969 case bfd_reloc_outofrange
:
3970 case bfd_reloc_overflow
:
3976 name
= h
->root
.root
.string
;
3979 name
= bfd_elf_string_from_elf_section (input_bfd
,
3980 symtab_hdr
->sh_link
,
3985 name
= bfd_section_name (input_bfd
, input_section
);
3987 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
4003 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
4005 struct bfd_link_info
*info
;
4006 struct elf_link_hash_entry
*h
;
4007 Elf_Internal_Sym
*sym
;
4009 struct elfNN_ia64_link_hash_table
*ia64_info
;
4010 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4012 ia64_info
= elfNN_ia64_hash_table (info
);
4013 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
4015 /* Fill in the PLT data, if required. */
4016 if (dyn_i
&& dyn_i
->want_plt
)
4018 Elf_Internal_Rela outrel
;
4021 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
4022 ElfNN_External_Rela
*rel
;
4024 gp_val
= _bfd_get_gp_value (output_bfd
);
4026 /* Initialize the minimal PLT entry. */
4028 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4029 plt_sec
= ia64_info
->plt_sec
;
4030 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4032 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4033 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4034 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4037 plt_addr
= (plt_sec
->output_section
->vma
4038 + plt_sec
->output_offset
4039 + dyn_i
->plt_offset
);
4040 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, true);
4042 /* Initialize the FULL PLT entry, if needed. */
4043 if (dyn_i
->want_plt2
)
4045 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4047 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4048 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4051 /* Mark the symbol as undefined, rather than as defined in the
4052 plt section. Leave the value alone. */
4053 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4054 first place. But perhaps elflink.h did some for us. */
4055 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4056 sym
->st_shndx
= SHN_UNDEF
;
4059 /* Create the dynamic relocation. */
4060 outrel
.r_offset
= pltoff_addr
;
4061 if (bfd_little_endian (output_bfd
))
4062 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4064 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4065 outrel
.r_addend
= 0;
4067 /* This is fun. In the .IA_64.pltoff section, we've got entries
4068 that correspond both to real PLT entries, and those that
4069 happened to resolve to local symbols but need to be created
4070 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4071 relocations for the real PLT should come at the end of the
4072 section, so that they can be indexed by plt entry at runtime.
4074 We emitted all of the relocations for the non-PLT @pltoff
4075 entries during relocate_section. So we can consider the
4076 existing sec->reloc_count to be the base of the array of
4079 rel
= (ElfNN_External_Rela
*)ia64_info
->rel_pltoff_sec
->contents
;
4080 rel
+= ia64_info
->rel_pltoff_sec
->reloc_count
;
4082 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, rel
+ index
);
4085 /* Mark some specially defined symbols as absolute. */
4086 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4087 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4088 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4089 sym
->st_shndx
= SHN_ABS
;
4095 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4097 struct bfd_link_info
*info
;
4099 struct elfNN_ia64_link_hash_table
*ia64_info
;
4102 ia64_info
= elfNN_ia64_hash_table (info
);
4103 dynobj
= ia64_info
->root
.dynobj
;
4105 if (elf_hash_table (info
)->dynamic_sections_created
)
4107 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4108 asection
*sdyn
, *sgotplt
;
4111 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4112 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4113 BFD_ASSERT (sdyn
!= NULL
);
4114 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4115 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4117 gp_val
= _bfd_get_gp_value (abfd
);
4119 for (; dyncon
< dynconend
; dyncon
++)
4121 Elf_Internal_Dyn dyn
;
4123 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4128 dyn
.d_un
.d_ptr
= gp_val
;
4132 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4133 * sizeof (ElfNN_External_Rela
));
4137 /* See the comment above in finish_dynamic_symbol. */
4138 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4139 + ia64_info
->rel_pltoff_sec
->output_offset
4140 + (ia64_info
->rel_pltoff_sec
->reloc_count
4141 * sizeof (ElfNN_External_Rela
)));
4144 case DT_IA_64_PLT_RESERVE
:
4145 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4146 + sgotplt
->output_offset
);
4150 /* Do not have RELASZ include JMPREL. This makes things
4151 easier on ld.so. This is not what the rest of BFD set up. */
4152 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4153 * sizeof (ElfNN_External_Rela
));
4157 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4160 /* Initialize the PLT0 entry */
4161 if (ia64_info
->plt_sec
)
4163 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4166 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4168 pltres
= (sgotplt
->output_section
->vma
4169 + sgotplt
->output_offset
4172 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4179 /* ELF file flag handling: */
4181 /* Function to keep IA-64 specific file flags. */
4183 elfNN_ia64_set_private_flags (abfd
, flags
)
4187 BFD_ASSERT (!elf_flags_init (abfd
)
4188 || elf_elfheader (abfd
)->e_flags
== flags
);
4190 elf_elfheader (abfd
)->e_flags
= flags
;
4191 elf_flags_init (abfd
) = true;
4195 /* Copy backend specific data from one object module to another */
4197 elfNN_ia64_copy_private_bfd_data (ibfd
, obfd
)
4200 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4201 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4204 BFD_ASSERT (!elf_flags_init (obfd
)
4205 || (elf_elfheader (obfd
)->e_flags
4206 == elf_elfheader (ibfd
)->e_flags
));
4208 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
4209 elf_flags_init (obfd
) = true;
4213 /* Merge backend specific data from an object file to the output
4214 object file when linking. */
4216 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4223 /* Don't even pretend to support mixed-format linking. */
4224 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4225 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4228 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4229 out_flags
= elf_elfheader (obfd
)->e_flags
;
4231 if (! elf_flags_init (obfd
))
4233 elf_flags_init (obfd
) = true;
4234 elf_elfheader (obfd
)->e_flags
= in_flags
;
4236 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4237 && bfd_get_arch_info (obfd
)->the_default
)
4239 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4240 bfd_get_mach (ibfd
));
4246 /* Check flag compatibility. */
4247 if (in_flags
== out_flags
)
4250 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4251 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4252 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4254 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4256 (*_bfd_error_handler
)
4257 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4258 bfd_get_filename (ibfd
));
4260 bfd_set_error (bfd_error_bad_value
);
4263 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4265 (*_bfd_error_handler
)
4266 (_("%s: linking big-endian files with little-endian files"),
4267 bfd_get_filename (ibfd
));
4269 bfd_set_error (bfd_error_bad_value
);
4272 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4274 (*_bfd_error_handler
)
4275 (_("%s: linking 64-bit files with 32-bit files"),
4276 bfd_get_filename (ibfd
));
4278 bfd_set_error (bfd_error_bad_value
);
4281 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4283 (*_bfd_error_handler
)
4284 (_("%s: linking constant-gp files with non-constant-gp files"),
4285 bfd_get_filename (ibfd
));
4287 bfd_set_error (bfd_error_bad_value
);
4290 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4291 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4293 (*_bfd_error_handler
)
4294 (_("%s: linking auto-pic files with non-auto-pic files"),
4295 bfd_get_filename (ibfd
));
4297 bfd_set_error (bfd_error_bad_value
);
4305 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4309 FILE *file
= (FILE *) ptr
;
4310 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4312 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4314 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4315 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4316 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4317 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4318 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4319 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4320 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4321 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4322 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4324 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4328 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4329 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4330 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4331 #define TARGET_BIG_NAME "elfNN-ia64-big"
4332 #define ELF_ARCH bfd_arch_ia64
4333 #define ELF_MACHINE_CODE EM_IA_64
4334 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4335 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4336 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4338 #define elf_backend_section_from_shdr \
4339 elfNN_ia64_section_from_shdr
4340 #define elf_backend_section_flags \
4341 elfNN_ia64_section_flags
4342 #define elf_backend_fake_sections \
4343 elfNN_ia64_fake_sections
4344 #define elf_backend_final_write_processing \
4345 elfNN_ia64_final_write_processing
4346 #define elf_backend_add_symbol_hook \
4347 elfNN_ia64_add_symbol_hook
4348 #define elf_backend_additional_program_headers \
4349 elfNN_ia64_additional_program_headers
4350 #define elf_backend_modify_segment_map \
4351 elfNN_ia64_modify_segment_map
4352 #define elf_info_to_howto \
4353 elfNN_ia64_info_to_howto
4355 #define bfd_elfNN_bfd_reloc_type_lookup \
4356 elfNN_ia64_reloc_type_lookup
4357 #define bfd_elfNN_bfd_is_local_label_name \
4358 elfNN_ia64_is_local_label_name
4359 #define bfd_elfNN_bfd_relax_section \
4360 elfNN_ia64_relax_section
4362 /* Stuff for the BFD linker: */
4363 #define bfd_elfNN_bfd_link_hash_table_create \
4364 elfNN_ia64_hash_table_create
4365 #define elf_backend_create_dynamic_sections \
4366 elfNN_ia64_create_dynamic_sections
4367 #define elf_backend_check_relocs \
4368 elfNN_ia64_check_relocs
4369 #define elf_backend_adjust_dynamic_symbol \
4370 elfNN_ia64_adjust_dynamic_symbol
4371 #define elf_backend_size_dynamic_sections \
4372 elfNN_ia64_size_dynamic_sections
4373 #define elf_backend_relocate_section \
4374 elfNN_ia64_relocate_section
4375 #define elf_backend_finish_dynamic_symbol \
4376 elfNN_ia64_finish_dynamic_symbol
4377 #define elf_backend_finish_dynamic_sections \
4378 elfNN_ia64_finish_dynamic_sections
4379 #define bfd_elfNN_bfd_final_link \
4380 elfNN_ia64_final_link
4382 #define bfd_elfNN_bfd_copy_private_bfd_data \
4383 elfNN_ia64_copy_private_bfd_data
4384 #define bfd_elfNN_bfd_merge_private_bfd_data \
4385 elfNN_ia64_merge_private_bfd_data
4386 #define bfd_elfNN_bfd_set_private_flags \
4387 elfNN_ia64_set_private_flags
4388 #define bfd_elfNN_bfd_print_private_bfd_data \
4389 elfNN_ia64_print_private_bfd_data
4391 #define elf_backend_plt_readonly 1
4392 #define elf_backend_want_plt_sym 0
4393 #define elf_backend_plt_alignment 5
4394 #define elf_backend_got_header_size 0
4395 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4396 #define elf_backend_want_got_plt 1
4397 #define elf_backend_may_use_rel_p 1
4398 #define elf_backend_may_use_rela_p 1
4399 #define elf_backend_default_use_rela_p 1
4400 #define elf_backend_want_dynbss 0
4401 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4402 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4404 #include "elfNN-target.h"
4406 /* AIX-specific vectors. */
4408 #undef TARGET_LITTLE_SYM
4409 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4410 #undef TARGET_LITTLE_NAME
4411 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4412 #undef TARGET_BIG_SYM
4413 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4414 #undef TARGET_BIG_NAME
4415 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4417 #undef elf_backend_add_symbol_hook
4418 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4420 #undef bfd_elfNN_bfd_link_add_symbols
4421 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4423 #define elfNN_bed elfNN_ia64_aix_bed
4425 #include "elfNN-target.h"