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_fake_sections
165 PARAMS ((bfd
*abfd
, ElfNN_Internal_Shdr
*hdr
, asection
*sec
));
166 static void elfNN_ia64_final_write_processing
167 PARAMS ((bfd
*abfd
, boolean linker
));
168 static boolean elfNN_ia64_add_symbol_hook
169 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
170 const char **namep
, flagword
*flagsp
, asection
**secp
,
172 static boolean elfNN_ia64_aix_vec
173 PARAMS ((const bfd_target
*vec
));
174 static boolean elfNN_ia64_aix_add_symbol_hook
175 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
176 const char **namep
, flagword
*flagsp
, asection
**secp
,
178 static boolean elfNN_ia64_aix_link_add_symbols
179 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
180 static int elfNN_ia64_additional_program_headers
181 PARAMS ((bfd
*abfd
));
182 static boolean elfNN_ia64_is_local_label_name
183 PARAMS ((bfd
*abfd
, const char *name
));
184 static boolean elfNN_ia64_dynamic_symbol_p
185 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
));
186 static boolean elfNN_ia64_local_hash_table_init
187 PARAMS ((struct elfNN_ia64_local_hash_table
*ht
, bfd
*abfd
,
188 new_hash_entry_func
new));
189 static struct bfd_hash_entry
*elfNN_ia64_new_loc_hash_entry
190 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
191 const char *string
));
192 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
193 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
194 const char *string
));
195 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
196 PARAMS ((bfd
*abfd
));
197 static struct elfNN_ia64_local_hash_entry
*elfNN_ia64_local_hash_lookup
198 PARAMS ((struct elfNN_ia64_local_hash_table
*table
, const char *string
,
199 boolean create
, boolean copy
));
200 static void elfNN_ia64_dyn_sym_traverse
201 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
202 boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
204 static boolean elfNN_ia64_create_dynamic_sections
205 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
206 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
207 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
208 struct elf_link_hash_entry
*h
,
209 bfd
*abfd
, const Elf_Internal_Rela
*rel
, boolean create
));
210 static asection
*get_got
211 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
212 struct elfNN_ia64_link_hash_table
*ia64_info
));
213 static asection
*get_fptr
214 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
215 struct elfNN_ia64_link_hash_table
*ia64_info
));
216 static asection
*get_pltoff
217 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
218 struct elfNN_ia64_link_hash_table
*ia64_info
));
219 static asection
*get_reloc_section
220 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
221 asection
*sec
, boolean create
));
222 static boolean count_dyn_reloc
223 PARAMS ((bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
224 asection
*srel
, int type
));
225 static boolean elfNN_ia64_check_relocs
226 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
227 const Elf_Internal_Rela
*relocs
));
228 static boolean elfNN_ia64_adjust_dynamic_symbol
229 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
230 static unsigned long global_sym_index
231 PARAMS ((struct elf_link_hash_entry
*h
));
232 static boolean allocate_fptr
233 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
234 static boolean allocate_global_data_got
235 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
236 static boolean allocate_global_fptr_got
237 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
238 static boolean allocate_local_got
239 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
240 static boolean allocate_pltoff_entries
241 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
242 static boolean allocate_plt_entries
243 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
244 static boolean allocate_plt2_entries
245 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
246 static boolean allocate_dynrel_entries
247 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
248 static boolean elfNN_ia64_size_dynamic_sections
249 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
250 static bfd_reloc_status_type elfNN_ia64_install_value
251 PARAMS ((bfd
*abfd
, bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
252 static void elfNN_ia64_install_dyn_reloc
253 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
254 asection
*srel
, bfd_vma offset
, unsigned int type
,
255 long dynindx
, bfd_vma addend
));
256 static bfd_vma set_got_entry
257 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
258 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
259 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
260 static bfd_vma set_fptr_entry
261 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
262 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
264 static bfd_vma set_pltoff_entry
265 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
266 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
267 bfd_vma value
, boolean
));
268 static boolean elfNN_ia64_final_link
269 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
270 static boolean elfNN_ia64_relocate_section
271 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
272 asection
*input_section
, bfd_byte
*contents
,
273 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
274 asection
**local_sections
));
275 static boolean elfNN_ia64_finish_dynamic_symbol
276 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
277 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
278 static boolean elfNN_ia64_finish_dynamic_sections
279 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
280 static boolean elfNN_ia64_set_private_flags
281 PARAMS ((bfd
*abfd
, flagword flags
));
282 static boolean elfNN_ia64_copy_private_bfd_data
283 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
284 static boolean elfNN_ia64_merge_private_bfd_data
285 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
286 static boolean elfNN_ia64_print_private_bfd_data
287 PARAMS ((bfd
*abfd
, PTR ptr
));
289 /* ia64-specific relocation */
291 /* Perform a relocation. Not much to do here as all the hard work is
292 done in elfNN_ia64_final_link_relocate. */
293 static bfd_reloc_status_type
294 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
295 output_bfd
, error_message
)
296 bfd
*abfd ATTRIBUTE_UNUSED
;
298 asymbol
*sym ATTRIBUTE_UNUSED
;
299 PTR data ATTRIBUTE_UNUSED
;
300 asection
*input_section
;
302 char **error_message
;
306 reloc
->address
+= input_section
->output_offset
;
309 *error_message
= "Unsupported call to elfNN_ia64_reloc";
310 return bfd_reloc_notsupported
;
313 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
314 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
315 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
317 /* This table has to be sorted according to increasing number of the
319 static reloc_howto_type ia64_howto_table
[] =
321 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, false, true),
323 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, false, true),
324 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, false, true),
325 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, false, true),
326 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, false, true),
327 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, false, true),
328 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, false, true),
329 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, false, true),
331 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, false, true),
332 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, false, true),
333 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, false, true),
334 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, false, true),
335 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, false, true),
336 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, false, true),
338 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, false, true),
339 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, false, true),
341 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, false, true),
342 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, false, true),
343 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, false, true),
344 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, false, true),
346 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, false, true),
347 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, false, true),
348 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, false, true),
349 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, false, true),
350 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, false, true),
352 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, true, true),
353 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, true, true),
354 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, true, true),
355 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, true, true),
356 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, true, true),
357 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, true, true),
358 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, true, true),
359 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, true, true),
361 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, false, true),
362 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, false, true),
363 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, false, true),
364 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, false, true),
366 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, false, true),
367 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, false, true),
368 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, false, true),
369 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, false, true),
371 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, false, true),
372 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, false, true),
373 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, false, true),
374 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, false, true),
376 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, false, true),
377 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, false, true),
378 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, false, true),
379 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, false, true),
381 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, false, true),
382 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, false, true),
383 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, false, true),
384 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, false, true),
386 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, true, true),
387 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, true, true),
388 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, true, true),
390 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, false, true),
391 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, false, true),
392 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, false, true),
393 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, false, true),
394 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, false, true),
396 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, false, false),
397 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, false, false),
398 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, false, false),
399 IA64_HOWTO (R_IA64_LTOFF_TP22
, "LTOFF_TP22", 0, false, false),
402 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
404 /* Given a BFD reloc type, return the matching HOWTO structure. */
406 static reloc_howto_type
*
410 static int inited
= 0;
417 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
418 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
419 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
422 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
423 i
= elf_code_to_howto_index
[rtype
];
424 if (i
>= NELEMS (ia64_howto_table
))
426 return ia64_howto_table
+ i
;
429 static reloc_howto_type
*
430 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
431 bfd
*abfd ATTRIBUTE_UNUSED
;
432 bfd_reloc_code_real_type bfd_code
;
438 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
440 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
441 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
442 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
444 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
445 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
446 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
447 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
449 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
450 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
451 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
452 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
453 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
454 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
456 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
457 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
459 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
460 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
461 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
462 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
463 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
464 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
465 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
466 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
467 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
469 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
470 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
471 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
472 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
473 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
474 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
475 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
476 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
477 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
478 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
479 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
481 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
482 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
483 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
484 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
486 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
487 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
488 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
489 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
491 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
492 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
493 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
494 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
496 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
497 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
498 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
499 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
501 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
502 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
503 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
504 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
506 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
507 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
508 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
509 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
510 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
512 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
513 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
514 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
515 case BFD_RELOC_IA64_LTOFF_TP22
: rtype
= R_IA64_LTOFF_TP22
; break;
519 return lookup_howto (rtype
);
522 /* Given a ELF reloc, return the matching HOWTO structure. */
525 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
526 bfd
*abfd ATTRIBUTE_UNUSED
;
528 ElfNN_Internal_Rela
*elf_reloc
;
530 bfd_reloc
->howto
= lookup_howto (ELFNN_R_TYPE (elf_reloc
->r_info
));
533 #define PLT_HEADER_SIZE (3 * 16)
534 #define PLT_MIN_ENTRY_SIZE (1 * 16)
535 #define PLT_FULL_ENTRY_SIZE (2 * 16)
536 #define PLT_RESERVED_WORDS 3
538 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
540 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
541 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
542 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
543 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
544 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
545 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
546 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
547 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
548 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
551 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
553 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
554 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
555 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
558 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
560 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
561 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
562 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
563 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
564 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
565 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
568 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
569 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
570 #define DYNAMIC_INTERPRETER(abfd) \
571 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
573 /* Select out of range branch fixup type. Note that Itanium does
574 not support brl, and so it gets emulated by the kernel. */
577 static const bfd_byte oor_brl
[16] =
579 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
581 0x00, 0x00, 0x00, 0xc0
584 static const bfd_byte oor_ip
[48] =
586 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
587 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
588 0x01, 0x00, 0x00, 0x60,
589 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
590 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
591 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
592 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
593 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
594 0x60, 0x00, 0x80, 0x00 /* br b6;; */
597 /* These functions do relaxation for IA-64 ELF.
599 This is primarily to support branches to targets out of range;
600 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
603 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
606 struct bfd_link_info
*link_info
;
611 struct one_fixup
*next
;
617 Elf_Internal_Shdr
*symtab_hdr
;
618 Elf_Internal_Rela
*internal_relocs
;
619 Elf_Internal_Rela
*free_relocs
= NULL
;
620 Elf_Internal_Rela
*irel
, *irelend
;
622 bfd_byte
*free_contents
= NULL
;
623 ElfNN_External_Sym
*extsyms
;
624 ElfNN_External_Sym
*free_extsyms
= NULL
;
625 struct elfNN_ia64_link_hash_table
*ia64_info
;
626 struct one_fixup
*fixups
= NULL
;
627 boolean changed_contents
= false;
628 boolean changed_relocs
= false;
630 /* Assume we're not going to change any sizes, and we'll only need
634 /* Nothing to do if there are no relocations. */
635 if ((sec
->flags
& SEC_RELOC
) == 0
636 || sec
->reloc_count
== 0)
639 /* If this is the first time we have been called for this section,
640 initialize the cooked size. */
641 if (sec
->_cooked_size
== 0)
642 sec
->_cooked_size
= sec
->_raw_size
;
644 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
646 /* Load the relocations for this section. */
647 internal_relocs
= (_bfd_elfNN_link_read_relocs
648 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
649 link_info
->keep_memory
));
650 if (internal_relocs
== NULL
)
653 if (! link_info
->keep_memory
)
654 free_relocs
= internal_relocs
;
656 ia64_info
= elfNN_ia64_hash_table (link_info
);
657 irelend
= internal_relocs
+ sec
->reloc_count
;
659 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
660 if (ELFNN_R_TYPE (irel
->r_info
) == (int) R_IA64_PCREL21B
)
663 /* No branch-type relocations. */
666 if (free_relocs
!= NULL
)
671 /* Get the section contents. */
672 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
673 contents
= elf_section_data (sec
)->this_hdr
.contents
;
676 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
677 if (contents
== NULL
)
679 free_contents
= contents
;
681 if (! bfd_get_section_contents (abfd
, sec
, contents
,
682 (file_ptr
) 0, sec
->_raw_size
))
686 /* Read this BFD's symbols. */
687 if (symtab_hdr
->contents
!= NULL
)
688 extsyms
= (ElfNN_External_Sym
*) symtab_hdr
->contents
;
691 extsyms
= (ElfNN_External_Sym
*) bfd_malloc (symtab_hdr
->sh_size
);
694 free_extsyms
= extsyms
;
695 if (bfd_seek (abfd
, symtab_hdr
->sh_offset
, SEEK_SET
) != 0
696 || (bfd_read (extsyms
, 1, symtab_hdr
->sh_size
, abfd
)
697 != symtab_hdr
->sh_size
))
701 for (; irel
< irelend
; irel
++)
703 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
704 Elf_Internal_Sym isym
;
708 if (ELFNN_R_TYPE (irel
->r_info
) != (int) R_IA64_PCREL21B
)
711 /* Get the value of the symbol referred to by the reloc. */
712 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
714 /* A local symbol. */
715 bfd_elfNN_swap_symbol_in (abfd
,
716 extsyms
+ ELFNN_R_SYM (irel
->r_info
),
718 if (isym
.st_shndx
== SHN_UNDEF
)
719 continue; /* We can't do anthing with undefined symbols. */
720 else if (isym
.st_shndx
== SHN_ABS
)
721 tsec
= bfd_abs_section_ptr
;
722 else if (isym
.st_shndx
== SHN_COMMON
)
723 tsec
= bfd_com_section_ptr
;
724 else if (isym
.st_shndx
> 0 && isym
.st_shndx
< SHN_LORESERVE
)
725 tsec
= bfd_section_from_elf_index (abfd
, isym
.st_shndx
);
727 continue; /* who knows. */
729 toff
= isym
.st_value
;
734 struct elf_link_hash_entry
*h
;
735 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
737 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
738 h
= elf_sym_hashes (abfd
)[indx
];
739 BFD_ASSERT (h
!= NULL
);
741 while (h
->root
.type
== bfd_link_hash_indirect
742 || h
->root
.type
== bfd_link_hash_warning
)
743 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
745 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, false);
747 /* For branches to dynamic symbols, we're interested instead
748 in a branch to the PLT entry. */
749 if (dyn_i
&& dyn_i
->want_plt2
)
751 tsec
= ia64_info
->plt_sec
;
752 toff
= dyn_i
->plt2_offset
;
756 /* We can't do anthing with undefined symbols. */
757 if (h
->root
.type
== bfd_link_hash_undefined
758 || h
->root
.type
== bfd_link_hash_undefweak
)
761 tsec
= h
->root
.u
.def
.section
;
762 toff
= h
->root
.u
.def
.value
;
766 symaddr
= (tsec
->output_section
->vma
767 + tsec
->output_offset
771 roff
= irel
->r_offset
;
772 reladdr
= (sec
->output_section
->vma
776 /* If the branch is in range, no need to do anything. */
777 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
778 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
781 /* If the branch and target are in the same section, you've
782 got one honking big section and we can't help you. You'll
783 get an error message later. */
787 /* Look for an existing fixup to this address. */
788 for (f
= fixups
; f
; f
= f
->next
)
789 if (f
->tsec
== tsec
&& f
->toff
== toff
)
794 /* Two alternatives: If it's a branch to a PLT entry, we can
795 make a copy of the FULL_PLT entry. Otherwise, we'll have
796 to use a `brl' insn to get where we're going. */
800 if (tsec
== ia64_info
->plt_sec
)
801 size
= sizeof (plt_full_entry
);
805 size
= sizeof (oor_brl
);
807 size
= sizeof (oor_ip
);
811 /* Resize the current section to make room for the new branch. */
812 trampoff
= (sec
->_cooked_size
+ 15) & -16;
813 contents
= (bfd_byte
*) bfd_realloc (contents
, trampoff
+ size
);
814 if (contents
== NULL
)
816 sec
->_cooked_size
= trampoff
+ size
;
818 if (tsec
== ia64_info
->plt_sec
)
820 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
822 /* Hijack the old relocation for use as the PLTOFF reloc. */
823 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
825 irel
->r_offset
= trampoff
;
830 memcpy (contents
+ trampoff
, oor_brl
, size
);
831 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
833 irel
->r_offset
= trampoff
+ 2;
835 memcpy (contents
+ trampoff
, oor_ip
, size
);
836 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
838 irel
->r_addend
-= 16;
839 irel
->r_offset
= trampoff
+ 2;
843 /* Record the fixup so we don't do it again this section. */
844 f
= (struct one_fixup
*) bfd_malloc (sizeof (*f
));
848 f
->trampoff
= trampoff
;
853 /* Nop out the reloc, since we're finalizing things here. */
854 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
857 /* Fix up the existing branch to hit the trampoline. Hope like
858 hell this doesn't overflow too. */
859 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
860 f
->trampoff
- (roff
& -4),
861 R_IA64_PCREL21B
) != bfd_reloc_ok
)
864 changed_contents
= true;
865 changed_relocs
= true;
868 /* Clean up and go home. */
871 struct one_fixup
*f
= fixups
;
872 fixups
= fixups
->next
;
877 elf_section_data (sec
)->relocs
= internal_relocs
;
878 else if (free_relocs
!= NULL
)
881 if (changed_contents
)
882 elf_section_data (sec
)->this_hdr
.contents
= contents
;
883 else if (free_contents
!= NULL
)
885 if (! link_info
->keep_memory
)
886 free (free_contents
);
889 /* Cache the section contents for elf_link_input_bfd. */
890 elf_section_data (sec
)->this_hdr
.contents
= contents
;
894 if (free_extsyms
!= NULL
)
896 if (! link_info
->keep_memory
)
900 /* Cache the symbols for elf_link_input_bfd. */
901 symtab_hdr
->contents
= extsyms
;
905 *again
= changed_contents
|| changed_relocs
;
909 if (free_relocs
!= NULL
)
911 if (free_contents
!= NULL
)
912 free (free_contents
);
913 if (free_extsyms
!= NULL
)
918 /* Return true if NAME is an unwind table section name. */
920 static inline boolean
921 is_unwind_section_name (name
)
926 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
927 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
928 return (strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
929 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0);
932 /* Handle an IA-64 specific section when reading an object file. This
933 is called when elfcode.h finds a section with an unknown type. */
936 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
938 ElfNN_Internal_Shdr
*hdr
;
943 /* There ought to be a place to keep ELF backend specific flags, but
944 at the moment there isn't one. We just keep track of the
945 sections by their name, instead. Fortunately, the ABI gives
946 suggested names for all the MIPS specific sections, so we will
947 probably get away with this. */
948 switch (hdr
->sh_type
)
950 case SHT_IA_64_UNWIND
:
954 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
962 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
964 newsect
= hdr
->bfd_section
;
969 /* Convert IA-64 specific section flags to bfd internal section flags. */
971 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
975 elfNN_ia64_section_flags (flags
, hdr
)
977 ElfNN_Internal_Shdr
*hdr
;
979 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
980 *flags
|= SEC_SMALL_DATA
;
985 /* Set the correct type for an IA-64 ELF section. We do this by the
986 section name, which is a hack, but ought to work. */
989 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
990 bfd
*abfd ATTRIBUTE_UNUSED
;
991 ElfNN_Internal_Shdr
*hdr
;
994 register const char *name
;
996 name
= bfd_get_section_name (abfd
, sec
);
998 if (is_unwind_section_name (name
))
1000 /* We don't have the sections numbered at this point, so sh_info
1001 is set later, in elfNN_ia64_final_write_processing. */
1002 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1003 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1005 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1006 hdr
->sh_type
= SHT_IA_64_EXT
;
1007 else if (strcmp (name
, ".reloc") == 0)
1009 * This is an ugly, but unfortunately necessary hack that is
1010 * needed when producing EFI binaries on IA-64. It tells
1011 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1012 * containing ELF relocation info. We need this hack in order to
1013 * be able to generate ELF binaries that can be translated into
1014 * EFI applications (which are essentially COFF objects). Those
1015 * files contain a COFF ".reloc" section inside an ELFNN object,
1016 * which would normally cause BFD to segfault because it would
1017 * attempt to interpret this section as containing relocation
1018 * entries for section "oc". With this hack enabled, ".reloc"
1019 * will be treated as a normal data section, which will avoid the
1020 * segfault. However, you won't be able to create an ELFNN binary
1021 * with a section named "oc" that needs relocations, but that's
1022 * the kind of ugly side-effects you get when detecting section
1023 * types based on their names... In practice, this limitation is
1026 hdr
->sh_type
= SHT_PROGBITS
;
1028 if (sec
->flags
& SEC_SMALL_DATA
)
1029 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1034 /* The final processing done just before writing out an IA-64 ELF
1038 elfNN_ia64_final_write_processing (abfd
, linker
)
1040 boolean linker ATTRIBUTE_UNUSED
;
1042 Elf_Internal_Shdr
*hdr
;
1044 asection
*text_sect
, *s
;
1047 for (s
= abfd
->sections
; s
; s
= s
->next
)
1049 hdr
= &elf_section_data (s
)->this_hdr
;
1050 switch (hdr
->sh_type
)
1052 case SHT_IA_64_UNWIND
:
1053 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1055 sname
= bfd_get_section_name (abfd
, s
);
1056 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1057 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1061 if (sname
[0] == '\0')
1062 /* .IA_64.unwind -> .text */
1063 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1065 /* .IA_64.unwindFOO -> FOO */
1066 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1069 /* last resort: fall back on .text */
1070 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1074 /* The IA-64 processor-specific ABI requires setting
1075 sh_link to the unwind section, whereas HP-UX requires
1076 sh_info to do so. For maximum compatibility, we'll
1077 set both for now... */
1078 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1079 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1086 /* Hook called by the linker routine which adds symbols from an object
1087 file. We use it to put .comm items in .sbss, and not .bss. */
1090 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1092 struct bfd_link_info
*info
;
1093 const Elf_Internal_Sym
*sym
;
1094 const char **namep ATTRIBUTE_UNUSED
;
1095 flagword
*flagsp ATTRIBUTE_UNUSED
;
1099 if (sym
->st_shndx
== SHN_COMMON
1100 && !info
->relocateable
1101 && sym
->st_size
<= (unsigned) bfd_get_gp_size (abfd
))
1103 /* Common symbols less than or equal to -G nn bytes are
1104 automatically put into .sbss. */
1106 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1110 scomm
= bfd_make_section (abfd
, ".scommon");
1112 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1114 | SEC_LINKER_CREATED
)))
1119 *valp
= sym
->st_size
;
1126 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1128 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1129 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1131 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1132 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1135 /* Hook called by the linker routine which adds symbols from an object
1136 file. We use it to handle OS-specific symbols. */
1139 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1141 struct bfd_link_info
*info
;
1142 const Elf_Internal_Sym
*sym
;
1148 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1150 /* Define __GLOB_DATA_PTR. This is expected to be a linker-defined
1151 symbol by the Aix C runtime startup code. Define the symbol
1152 when it is encountered. IBM sez no one else should use it b/c it is
1154 struct elf_link_hash_entry
*h
;
1156 h
= (struct elf_link_hash_entry
*) bfd_link_hash_lookup (info
->hash
, *namep
, false, false, false);
1159 struct elf_backend_data
*bed
;
1160 struct elfNN_ia64_link_hash_table
*ia64_info
;
1162 bed
= get_elf_backend_data (abfd
);
1163 ia64_info
= elfNN_ia64_hash_table (info
);
1165 if (!(_bfd_generic_link_add_one_symbol
1166 (info
, abfd
, *namep
, BSF_GLOBAL
, ia64_info
->got_sec
,
1167 bed
->got_symbol_offset
, (const char *) NULL
, false,
1168 bed
->collect
, (struct bfd_link_hash_entry
**) &h
)))
1171 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1172 h
->type
= STT_OBJECT
;
1175 && ! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1181 else if (sym
->st_shndx
== SHN_LOOS
)
1185 /* SHN_MONTEREY_SYSCALL (Description from IBM):
1186 Special symbols on AIX; if the value is non-zero, the value
1187 should be put in the gp member of the function descriptor. the
1188 function address member should be set to the address of the entry
1189 point of the user-space portion of the system call (epc insn in a
1190 priviledged page). If the symbol value is zero, look in the special
1191 table for extended system calls. The number for extended system
1192 calls will come from that table. The index is set when the linker
1193 sees an export file that contains the syscall attribute after an
1194 exported symbol. Kernel extensions indicate extended system calls
1195 they define by having STO_MONTEREY_SYSCALL in their st_other symbol
1196 table member. This is used by the system loader to add extended
1197 system calls to its table, which is subsequently provided to the
1198 runtime linker at each process startup. */
1199 for (i
= 1; i
< elf_elfheader (abfd
)->e_shnum
; i
++)
1201 asection
* sec
= bfd_section_from_elf_index (abfd
, i
);
1203 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1210 /* FIXME need to determine the proper section instead of defaulting to
1213 *secp
= bfd_abs_section_ptr
;
1215 *valp
= sym
->st_size
;
1221 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1222 namep
, flagsp
, secp
, valp
);
1227 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1229 struct bfd_link_info
*info
;
1231 /* Make sure dynamic sections are always created. */
1232 if (! elf_hash_table (info
)->dynamic_sections_created
1233 && abfd
->xvec
== info
->hash
->creator
)
1235 if (! bfd_elfNN_link_create_dynamic_sections (abfd
, info
))
1239 /* Now do the standard call. */
1240 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1243 /* Return the number of additional phdrs we will need. */
1246 elfNN_ia64_additional_program_headers (abfd
)
1252 /* See if we need a PT_IA_64_ARCHEXT segment. */
1253 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1254 if (s
&& (s
->flags
& SEC_LOAD
))
1257 /* Count how many PT_IA_64_UNWIND segments we need. */
1258 for (s
= abfd
->sections
; s
; s
= s
->next
)
1259 if (is_unwind_section_name(s
->name
) && (s
->flags
& SEC_LOAD
))
1266 elfNN_ia64_modify_segment_map (abfd
)
1269 struct elf_segment_map
*m
, **pm
;
1270 Elf_Internal_Shdr
*hdr
;
1273 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1274 all PT_LOAD segments. */
1275 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1276 if (s
&& (s
->flags
& SEC_LOAD
))
1278 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1279 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1283 m
= (struct elf_segment_map
*) bfd_zalloc (abfd
, sizeof *m
);
1287 m
->p_type
= PT_IA_64_ARCHEXT
;
1291 /* We want to put it after the PHDR and INTERP segments. */
1292 pm
= &elf_tdata (abfd
)->segment_map
;
1294 && ((*pm
)->p_type
== PT_PHDR
1295 || (*pm
)->p_type
== PT_INTERP
))
1303 /* Install PT_IA_64_UNWIND segments, if needed. */
1304 for (s
= abfd
->sections
; s
; s
= s
->next
)
1306 hdr
= &elf_section_data (s
)->this_hdr
;
1307 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1310 if (s
&& (s
->flags
& SEC_LOAD
))
1312 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1313 if (m
->p_type
== PT_IA_64_UNWIND
&& m
->sections
[0] == s
)
1318 m
= (struct elf_segment_map
*) bfd_zalloc (abfd
, sizeof *m
);
1322 m
->p_type
= PT_IA_64_UNWIND
;
1327 /* We want to put it last. */
1328 pm
= &elf_tdata (abfd
)->segment_map
;
1336 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1337 the input sections for each output section in the segment and testing
1338 for SHF_IA_64_NORECOV on each. */
1339 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1340 if (m
->p_type
== PT_LOAD
)
1343 for (i
= m
->count
- 1; i
>= 0; --i
)
1345 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1348 if (order
->type
== bfd_indirect_link_order
)
1350 asection
*is
= order
->u
.indirect
.section
;
1351 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1352 if (flags
& SHF_IA_64_NORECOV
)
1354 m
->p_flags
|= PF_IA_64_NORECOV
;
1358 order
= order
->next
;
1367 /* According to the Tahoe assembler spec, all labels starting with a
1371 elfNN_ia64_is_local_label_name (abfd
, name
)
1372 bfd
*abfd ATTRIBUTE_UNUSED
;
1375 return name
[0] == '.';
1378 /* Should we do dynamic things to this symbol? */
1381 elfNN_ia64_dynamic_symbol_p (h
, info
)
1382 struct elf_link_hash_entry
*h
;
1383 struct bfd_link_info
*info
;
1388 while (h
->root
.type
== bfd_link_hash_indirect
1389 || h
->root
.type
== bfd_link_hash_warning
)
1390 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1392 if (h
->dynindx
== -1)
1394 switch (ELF_ST_VISIBILITY (h
->other
))
1401 if (h
->root
.type
== bfd_link_hash_undefweak
1402 || h
->root
.type
== bfd_link_hash_defweak
)
1405 if ((info
->shared
&& !info
->symbolic
)
1406 || ((h
->elf_link_hash_flags
1407 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1408 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1415 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1416 struct elfNN_ia64_local_hash_table
*ht
;
1417 bfd
*abfd ATTRIBUTE_UNUSED
;
1418 new_hash_entry_func
new;
1420 memset (ht
, 0, sizeof (*ht
));
1421 return bfd_hash_table_init (&ht
->root
, new);
1424 static struct bfd_hash_entry
*
1425 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1426 struct bfd_hash_entry
*entry
;
1427 struct bfd_hash_table
*table
;
1430 struct elfNN_ia64_local_hash_entry
*ret
;
1431 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1433 /* Allocate the structure if it has not already been allocated by a
1436 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1441 /* Initialize our local data. All zeros, and definitely easier
1442 than setting a handful of bit fields. */
1443 memset (ret
, 0, sizeof (*ret
));
1445 /* Call the allocation method of the superclass. */
1446 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1447 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1449 return (struct bfd_hash_entry
*) ret
;
1452 static struct bfd_hash_entry
*
1453 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1454 struct bfd_hash_entry
*entry
;
1455 struct bfd_hash_table
*table
;
1458 struct elfNN_ia64_link_hash_entry
*ret
;
1459 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1461 /* Allocate the structure if it has not already been allocated by a
1464 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1469 /* Initialize our local data. All zeros, and definitely easier
1470 than setting a handful of bit fields. */
1471 memset (ret
, 0, sizeof (*ret
));
1473 /* Call the allocation method of the superclass. */
1474 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1475 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1478 return (struct bfd_hash_entry
*) ret
;
1482 elfNN_ia64_hash_copy_indirect (xdir
, xind
)
1483 struct elf_link_hash_entry
*xdir
, *xind
;
1485 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1487 dir
= (struct elfNN_ia64_link_hash_entry
*)xdir
;
1488 ind
= (struct elfNN_ia64_link_hash_entry
*)xind
;
1490 /* Copy down any references that we may have already seen to the
1491 symbol which just became indirect. */
1493 dir
->root
.elf_link_hash_flags
|=
1494 (ind
->root
.elf_link_hash_flags
1495 & (ELF_LINK_HASH_REF_DYNAMIC
1496 | ELF_LINK_HASH_REF_REGULAR
1497 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1499 /* Copy over the got and plt data. This would have been done
1502 if (dir
->info
== NULL
)
1504 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1506 dir
->info
= dyn_i
= ind
->info
;
1509 /* Fix up the dyn_sym_info pointers to the global symbol. */
1510 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1511 dyn_i
->h
= &dir
->root
;
1513 BFD_ASSERT (ind
->info
== NULL
);
1515 /* Copy over the dynindx. */
1517 if (dir
->root
.dynindx
== -1)
1519 dir
->root
.dynindx
= ind
->root
.dynindx
;
1520 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1521 ind
->root
.dynindx
= -1;
1522 ind
->root
.dynstr_index
= 0;
1524 BFD_ASSERT (ind
->root
.dynindx
== -1);
1528 elfNN_ia64_hash_hide_symbol (info
, xh
)
1529 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1530 struct elf_link_hash_entry
*xh
;
1532 struct elfNN_ia64_link_hash_entry
*h
;
1533 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1535 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1537 h
->root
.elf_link_hash_flags
&= ~ELF_LINK_HASH_NEEDS_PLT
;
1538 h
->root
.dynindx
= -1;
1540 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1541 dyn_i
->want_plt2
= 0;
1544 /* Create the derived linker hash table. The IA-64 ELF port uses this
1545 derived hash table to keep information specific to the IA-64 ElF
1546 linker (without using static variables). */
1548 static struct bfd_link_hash_table
*
1549 elfNN_ia64_hash_table_create (abfd
)
1552 struct elfNN_ia64_link_hash_table
*ret
;
1554 ret
= bfd_alloc (abfd
, sizeof (*ret
));
1557 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1558 elfNN_ia64_new_elf_hash_entry
))
1560 bfd_release (abfd
, ret
);
1564 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1565 elfNN_ia64_new_loc_hash_entry
))
1567 return &ret
->root
.root
;
1570 /* Look up an entry in a Alpha ELF linker hash table. */
1572 static INLINE
struct elfNN_ia64_local_hash_entry
*
1573 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1574 struct elfNN_ia64_local_hash_table
*table
;
1576 boolean create
, copy
;
1578 return ((struct elfNN_ia64_local_hash_entry
*)
1579 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1582 /* Traverse both local and global hash tables. */
1584 struct elfNN_ia64_dyn_sym_traverse_data
1586 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1591 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1592 struct bfd_hash_entry
*xentry
;
1595 struct elfNN_ia64_link_hash_entry
*entry
1596 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1597 struct elfNN_ia64_dyn_sym_traverse_data
*data
1598 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1599 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1601 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1602 if (! (*data
->func
) (dyn_i
, data
->data
))
1608 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1609 struct bfd_hash_entry
*xentry
;
1612 struct elfNN_ia64_local_hash_entry
*entry
1613 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1614 struct elfNN_ia64_dyn_sym_traverse_data
*data
1615 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1616 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1618 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1619 if (! (*data
->func
) (dyn_i
, data
->data
))
1625 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1626 struct elfNN_ia64_link_hash_table
*ia64_info
;
1627 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1630 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1635 elf_link_hash_traverse (&ia64_info
->root
,
1636 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1637 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1638 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1642 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1644 struct bfd_link_info
*info
;
1646 struct elfNN_ia64_link_hash_table
*ia64_info
;
1649 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1652 ia64_info
= elfNN_ia64_hash_table (info
);
1654 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1655 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1658 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1659 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1662 if (!get_pltoff (abfd
, info
, ia64_info
))
1665 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1667 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1670 | SEC_LINKER_CREATED
1672 || !bfd_set_section_alignment (abfd
, s
, 3))
1674 ia64_info
->rel_pltoff_sec
= s
;
1676 s
= bfd_make_section(abfd
, ".rela.got");
1678 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1681 | SEC_LINKER_CREATED
1683 || !bfd_set_section_alignment (abfd
, s
, 3))
1685 ia64_info
->rel_got_sec
= s
;
1690 /* Find and/or create a descriptor for dynamic symbol info. This will
1691 vary based on global or local symbol, and the addend to the reloc. */
1693 static struct elfNN_ia64_dyn_sym_info
*
1694 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1695 struct elfNN_ia64_link_hash_table
*ia64_info
;
1696 struct elf_link_hash_entry
*h
;
1698 const Elf_Internal_Rela
*rel
;
1701 struct elfNN_ia64_dyn_sym_info
**pp
;
1702 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1703 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1706 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1709 struct elfNN_ia64_local_hash_entry
*loc_h
;
1713 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1714 The name describes what was once anonymous memory. */
1716 len
= sizeof (void*)*2 + 1 + sizeof (bfd_vma
)*4 + 1 + 1;
1717 len
+= 10; /* %p slop */
1719 addr_name
= alloca (len
);
1720 sprintf (addr_name
, "%p:%lx", (void *) abfd
, ELFNN_R_SYM (rel
->r_info
));
1722 /* Collect the canonical entry data for this address. */
1723 loc_h
= elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1724 addr_name
, create
, create
);
1730 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
1733 if (dyn_i
== NULL
&& create
)
1735 dyn_i
= (struct elfNN_ia64_dyn_sym_info
*)
1736 bfd_zalloc (abfd
, sizeof *dyn_i
);
1738 dyn_i
->addend
= addend
;
1745 get_got (abfd
, info
, ia64_info
)
1747 struct bfd_link_info
*info
;
1748 struct elfNN_ia64_link_hash_table
*ia64_info
;
1753 got
= ia64_info
->got_sec
;
1758 dynobj
= ia64_info
->root
.dynobj
;
1760 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1761 if (!_bfd_elf_create_got_section (dynobj
, info
))
1764 got
= bfd_get_section_by_name (dynobj
, ".got");
1766 ia64_info
->got_sec
= got
;
1768 flags
= bfd_get_section_flags (abfd
, got
);
1769 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
1775 /* Create function descriptor section (.opd). This section is called .opd
1776 because it contains "official prodecure descriptors". The "official"
1777 refers to the fact that these descriptors are used when taking the address
1778 of a procedure, thus ensuring a unique address for each procedure. */
1781 get_fptr (abfd
, info
, ia64_info
)
1783 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1784 struct elfNN_ia64_link_hash_table
*ia64_info
;
1789 fptr
= ia64_info
->fptr_sec
;
1792 dynobj
= ia64_info
->root
.dynobj
;
1794 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1796 fptr
= bfd_make_section (dynobj
, ".opd");
1798 || !bfd_set_section_flags (dynobj
, fptr
,
1804 | SEC_LINKER_CREATED
))
1805 || !bfd_set_section_alignment (abfd
, fptr
, 4))
1811 ia64_info
->fptr_sec
= fptr
;
1818 get_pltoff (abfd
, info
, ia64_info
)
1820 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1821 struct elfNN_ia64_link_hash_table
*ia64_info
;
1826 pltoff
= ia64_info
->pltoff_sec
;
1829 dynobj
= ia64_info
->root
.dynobj
;
1831 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1833 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
1835 || !bfd_set_section_flags (dynobj
, pltoff
,
1841 | SEC_LINKER_CREATED
))
1842 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
1848 ia64_info
->pltoff_sec
= pltoff
;
1855 get_reloc_section (abfd
, ia64_info
, sec
, create
)
1857 struct elfNN_ia64_link_hash_table
*ia64_info
;
1861 const char *srel_name
;
1865 srel_name
= (bfd_elf_string_from_elf_section
1866 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
1867 elf_section_data(sec
)->rel_hdr
.sh_name
));
1868 if (srel_name
== NULL
)
1871 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
1872 && strcmp (bfd_get_section_name (abfd
, sec
),
1874 || (strncmp (srel_name
, ".rel", 4) == 0
1875 && strcmp (bfd_get_section_name (abfd
, sec
),
1876 srel_name
+4) == 0));
1878 dynobj
= ia64_info
->root
.dynobj
;
1880 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1882 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
1883 if (srel
== NULL
&& create
)
1885 srel
= bfd_make_section (dynobj
, srel_name
);
1887 || !bfd_set_section_flags (dynobj
, srel
,
1892 | SEC_LINKER_CREATED
1894 || !bfd_set_section_alignment (dynobj
, srel
, 3))
1902 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
1904 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1908 struct elfNN_ia64_dyn_reloc_entry
*rent
;
1910 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
1911 if (rent
->srel
== srel
&& rent
->type
== type
)
1916 rent
= (struct elfNN_ia64_dyn_reloc_entry
*)
1917 bfd_alloc (abfd
, sizeof (*rent
));
1921 rent
->next
= dyn_i
->reloc_entries
;
1925 dyn_i
->reloc_entries
= rent
;
1933 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
1935 struct bfd_link_info
*info
;
1937 const Elf_Internal_Rela
*relocs
;
1939 struct elfNN_ia64_link_hash_table
*ia64_info
;
1940 const Elf_Internal_Rela
*relend
;
1941 Elf_Internal_Shdr
*symtab_hdr
;
1942 const Elf_Internal_Rela
*rel
;
1943 asection
*got
, *fptr
, *srel
;
1945 if (info
->relocateable
)
1948 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1949 ia64_info
= elfNN_ia64_hash_table (info
);
1951 got
= fptr
= srel
= NULL
;
1953 relend
= relocs
+ sec
->reloc_count
;
1954 for (rel
= relocs
; rel
< relend
; ++rel
)
1963 NEED_LTOFF_FPTR
= 64,
1966 struct elf_link_hash_entry
*h
= NULL
;
1967 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
1968 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1970 boolean maybe_dynamic
;
1971 int dynrel_type
= R_IA64_NONE
;
1973 if (r_symndx
>= symtab_hdr
->sh_info
)
1975 /* We're dealing with a global symbol -- find its hash entry
1976 and mark it as being referenced. */
1977 long indx
= r_symndx
- symtab_hdr
->sh_info
;
1978 h
= elf_sym_hashes (abfd
)[indx
];
1979 while (h
->root
.type
== bfd_link_hash_indirect
1980 || h
->root
.type
== bfd_link_hash_warning
)
1981 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1983 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
1986 /* We can only get preliminary data on whether a symbol is
1987 locally or externally defined, as not all of the input files
1988 have yet been processed. Do something with what we know, as
1989 this may help reduce memory usage and processing time later. */
1990 maybe_dynamic
= false;
1991 if (h
&& ((info
->shared
&& ! info
->symbolic
)
1992 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
1993 || h
->root
.type
== bfd_link_hash_defweak
1994 || elfNN_ia64_aix_vec (abfd
->xvec
)))
1995 maybe_dynamic
= true;
1998 switch (ELFNN_R_TYPE (rel
->r_info
))
2000 case R_IA64_TPREL22
:
2001 case R_IA64_TPREL64MSB
:
2002 case R_IA64_TPREL64LSB
:
2003 case R_IA64_LTOFF_TP22
:
2006 case R_IA64_LTOFF_FPTR22
:
2007 case R_IA64_LTOFF_FPTR64I
:
2008 case R_IA64_LTOFF_FPTR64MSB
:
2009 case R_IA64_LTOFF_FPTR64LSB
:
2010 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2013 case R_IA64_FPTR64I
:
2014 case R_IA64_FPTR32MSB
:
2015 case R_IA64_FPTR32LSB
:
2016 case R_IA64_FPTR64MSB
:
2017 case R_IA64_FPTR64LSB
:
2018 if (elfNN_ia64_aix_vec (abfd
->xvec
))
2019 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2020 else if (info
->shared
|| h
)
2021 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2023 need_entry
= NEED_FPTR
;
2024 dynrel_type
= R_IA64_FPTR64LSB
;
2027 case R_IA64_LTOFF22
:
2028 case R_IA64_LTOFF22X
:
2029 case R_IA64_LTOFF64I
:
2030 need_entry
= NEED_GOT
;
2033 case R_IA64_PLTOFF22
:
2034 case R_IA64_PLTOFF64I
:
2035 case R_IA64_PLTOFF64MSB
:
2036 case R_IA64_PLTOFF64LSB
:
2037 need_entry
= NEED_PLTOFF
;
2041 need_entry
|= NEED_MIN_PLT
;
2045 (*info
->callbacks
->warning
)
2046 (info
, _("@pltoff reloc against local symbol"), 0,
2051 case R_IA64_PCREL21B
:
2052 case R_IA64_PCREL60B
:
2053 /* Depending on where this symbol is defined, we may or may not
2054 need a full plt entry. Only skip if we know we'll not need
2055 the entry -- static or symbolic, and the symbol definition
2056 has already been seen. */
2057 if (maybe_dynamic
&& rel
->r_addend
== 0)
2058 need_entry
= NEED_FULL_PLT
;
2064 case R_IA64_DIR32MSB
:
2065 case R_IA64_DIR32LSB
:
2066 case R_IA64_DIR64MSB
:
2067 case R_IA64_DIR64LSB
:
2068 /* Shared objects will always need at least a REL relocation. */
2069 if (info
->shared
|| maybe_dynamic
2070 /* On AIX, we always need a relocation, but make sure
2071 __GLOB_DATA_PTR doesn't get an entry. */
2072 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2073 && (!h
|| strcmp (h
->root
.root
.string
,
2074 "__GLOB_DATA_PTR") != 0)))
2075 need_entry
= NEED_DYNREL
;
2076 dynrel_type
= R_IA64_DIR64LSB
;
2079 case R_IA64_IPLTMSB
:
2080 case R_IA64_IPLTLSB
:
2081 /* Shared objects will always need at least a REL relocation. */
2082 if (info
->shared
|| maybe_dynamic
)
2083 need_entry
= NEED_DYNREL
;
2084 dynrel_type
= R_IA64_IPLTLSB
;
2087 case R_IA64_PCREL22
:
2088 case R_IA64_PCREL64I
:
2089 case R_IA64_PCREL32MSB
:
2090 case R_IA64_PCREL32LSB
:
2091 case R_IA64_PCREL64MSB
:
2092 case R_IA64_PCREL64LSB
:
2094 need_entry
= NEED_DYNREL
;
2095 dynrel_type
= R_IA64_PCREL64LSB
;
2102 if ((need_entry
& NEED_FPTR
) != 0
2105 (*info
->callbacks
->warning
)
2106 (info
, _("non-zero addend in @fptr reloc"), 0,
2110 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, true);
2112 /* Record whether or not this is a local symbol. */
2115 /* Create what's needed. */
2116 if (need_entry
& NEED_GOT
)
2120 got
= get_got (abfd
, info
, ia64_info
);
2124 dyn_i
->want_got
= 1;
2126 if (need_entry
& NEED_FPTR
)
2130 fptr
= get_fptr (abfd
, info
, ia64_info
);
2135 /* FPTRs for shared libraries are allocated by the dynamic
2136 linker. Make sure this local symbol will appear in the
2137 dynamic symbol table. */
2138 if (!h
&& (info
->shared
2139 /* AIX also needs one */
2140 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2142 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2143 (info
, abfd
, r_symndx
)))
2147 dyn_i
->want_fptr
= 1;
2149 if (need_entry
& NEED_LTOFF_FPTR
)
2150 dyn_i
->want_ltoff_fptr
= 1;
2151 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2153 if (!ia64_info
->root
.dynobj
)
2154 ia64_info
->root
.dynobj
= abfd
;
2155 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2156 dyn_i
->want_plt
= 1;
2158 if (need_entry
& NEED_FULL_PLT
)
2159 dyn_i
->want_plt2
= 1;
2160 if (need_entry
& NEED_PLTOFF
)
2161 dyn_i
->want_pltoff
= 1;
2162 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2166 srel
= get_reloc_section (abfd
, ia64_info
, sec
, true);
2170 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2178 struct elfNN_ia64_allocate_data
2180 struct bfd_link_info
*info
;
2184 /* For cleanliness, and potentially faster dynamic loading, allocate
2185 external GOT entries first. */
2188 allocate_global_data_got (dyn_i
, data
)
2189 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2192 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2195 && ! dyn_i
->want_fptr
2196 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2197 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2199 dyn_i
->got_offset
= x
->ofs
;
2205 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2208 allocate_global_fptr_got (dyn_i
, data
)
2209 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2212 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2216 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2217 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2219 dyn_i
->got_offset
= x
->ofs
;
2225 /* Lastly, allocate all the GOT entries for local data. */
2228 allocate_local_got (dyn_i
, data
)
2229 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2232 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2235 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2236 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2238 dyn_i
->got_offset
= x
->ofs
;
2244 /* Search for the index of a global symbol in it's defining object file. */
2246 static unsigned long
2247 global_sym_index (h
)
2248 struct elf_link_hash_entry
*h
;
2250 struct elf_link_hash_entry
**p
;
2253 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2254 || h
->root
.type
== bfd_link_hash_defweak
);
2256 obj
= h
->root
.u
.def
.section
->owner
;
2257 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2260 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2263 /* Allocate function descriptors. We can do these for every function
2264 in a main executable that is not exported. */
2267 allocate_fptr (dyn_i
, data
)
2268 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2271 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2273 if (dyn_i
->want_fptr
)
2275 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2278 while (h
->root
.type
== bfd_link_hash_indirect
2279 || h
->root
.type
== bfd_link_hash_warning
)
2280 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2283 /* AIX needs an FPTR in this case. */
2284 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2286 || h
->root
.type
== bfd_link_hash_defined
2287 || h
->root
.type
== bfd_link_hash_defweak
)))
2289 if (h
&& h
->dynindx
== -1)
2291 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2292 || (h
->root
.type
== bfd_link_hash_defweak
));
2294 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2295 (x
->info
, h
->root
.u
.def
.section
->owner
,
2296 global_sym_index (h
)))
2300 dyn_i
->want_fptr
= 0;
2302 else if (h
== NULL
|| h
->dynindx
== -1)
2304 dyn_i
->fptr_offset
= x
->ofs
;
2308 dyn_i
->want_fptr
= 0;
2313 /* Allocate all the minimal PLT entries. */
2316 allocate_plt_entries (dyn_i
, data
)
2317 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2320 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2322 if (dyn_i
->want_plt
)
2324 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2327 while (h
->root
.type
== bfd_link_hash_indirect
2328 || h
->root
.type
== bfd_link_hash_warning
)
2329 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2331 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2332 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2334 bfd_size_type offset
= x
->ofs
;
2336 offset
= PLT_HEADER_SIZE
;
2337 dyn_i
->plt_offset
= offset
;
2338 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2340 dyn_i
->want_pltoff
= 1;
2344 dyn_i
->want_plt
= 0;
2345 dyn_i
->want_plt2
= 0;
2351 /* Allocate all the full PLT entries. */
2354 allocate_plt2_entries (dyn_i
, data
)
2355 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2358 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2360 if (dyn_i
->want_plt2
)
2362 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2363 bfd_size_type ofs
= x
->ofs
;
2365 dyn_i
->plt2_offset
= ofs
;
2366 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2368 while (h
->root
.type
== bfd_link_hash_indirect
2369 || h
->root
.type
== bfd_link_hash_warning
)
2370 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2371 dyn_i
->h
->plt
.offset
= ofs
;
2376 /* Allocate all the PLTOFF entries requested by relocations and
2377 plt entries. We can't share space with allocated FPTR entries,
2378 because the latter are not necessarily addressable by the GP.
2379 ??? Relaxation might be able to determine that they are. */
2382 allocate_pltoff_entries (dyn_i
, data
)
2383 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2386 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2388 if (dyn_i
->want_pltoff
)
2390 dyn_i
->pltoff_offset
= x
->ofs
;
2396 /* Allocate dynamic relocations for those symbols that turned out
2400 allocate_dynrel_entries (dyn_i
, data
)
2401 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2404 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2405 struct elfNN_ia64_link_hash_table
*ia64_info
;
2406 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2407 boolean dynamic_symbol
, shared
;
2409 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2410 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2411 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
);
2412 shared
= x
->info
->shared
;
2414 /* Take care of the normal data relocations. */
2416 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2418 int count
= rent
->count
;
2422 case R_IA64_FPTR64LSB
:
2423 /* Allocate one iff !want_fptr, which by this point will
2424 be true only if we're actually allocating one statically
2425 in the main executable. */
2426 if (dyn_i
->want_fptr
)
2429 case R_IA64_PCREL64LSB
:
2430 if (!dynamic_symbol
)
2433 case R_IA64_DIR64LSB
:
2434 if (!dynamic_symbol
&& !shared
)
2437 case R_IA64_IPLTLSB
:
2438 if (!dynamic_symbol
&& !shared
)
2440 /* Use two REL relocations for IPLT relocations
2441 against local symbols. */
2442 if (!dynamic_symbol
)
2448 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2451 /* Take care of the GOT and PLT relocations. */
2453 if (((dynamic_symbol
|| shared
) && dyn_i
->want_got
)
2454 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2455 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2457 if (dyn_i
->want_pltoff
)
2459 bfd_size_type t
= 0;
2461 /* Dynamic symbols get one IPLT relocation. Local symbols in
2462 shared libraries get two REL relocations. Local symbols in
2463 main applications get nothing. */
2465 t
= sizeof (ElfNN_External_Rela
);
2467 t
= 2 * sizeof (ElfNN_External_Rela
);
2469 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2476 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2477 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2478 struct elf_link_hash_entry
*h
;
2480 /* ??? Undefined symbols with PLT entries should be re-defined
2481 to be the PLT entry. */
2483 /* If this is a weak symbol, and there is a real definition, the
2484 processor independent code will have arranged for us to see the
2485 real definition first, and we can just use the same value. */
2486 if (h
->weakdef
!= NULL
)
2488 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2489 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2490 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2491 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2495 /* If this is a reference to a symbol defined by a dynamic object which
2496 is not a function, we might allocate the symbol in our .dynbss section
2497 and allocate a COPY dynamic relocation.
2499 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2506 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2508 struct bfd_link_info
*info
;
2510 struct elfNN_ia64_allocate_data data
;
2511 struct elfNN_ia64_link_hash_table
*ia64_info
;
2514 boolean reltext
= false;
2515 boolean relplt
= false;
2517 dynobj
= elf_hash_table(info
)->dynobj
;
2518 ia64_info
= elfNN_ia64_hash_table (info
);
2519 BFD_ASSERT(dynobj
!= NULL
);
2522 /* Set the contents of the .interp section to the interpreter. */
2523 if (ia64_info
->root
.dynamic_sections_created
2526 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2527 BFD_ASSERT (sec
!= NULL
);
2528 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2529 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2532 /* Allocate the GOT entries. */
2534 if (ia64_info
->got_sec
)
2537 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2538 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2539 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2540 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2543 /* Allocate the FPTR entries. */
2545 if (ia64_info
->fptr_sec
)
2548 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2549 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2552 /* Now that we've seen all of the input files, we can decide which
2553 symbols need plt entries. Allocate the minimal PLT entries first.
2554 We do this even though dynamic_sections_created may be false, because
2555 this has the side-effect of clearing want_plt and want_plt2. */
2558 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2560 ia64_info
->minplt_entries
= 0;
2563 ia64_info
->minplt_entries
2564 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2567 /* Align the pointer for the plt2 entries. */
2568 data
.ofs
= (data
.ofs
+ 31) & -32;
2570 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2573 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2575 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2577 /* If we've got a .plt, we need some extra memory for the dynamic
2578 linker. We stuff these in .got.plt. */
2579 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2580 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2583 /* Allocate the PLTOFF entries. */
2585 if (ia64_info
->pltoff_sec
)
2588 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2589 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2592 if (ia64_info
->root
.dynamic_sections_created
)
2594 /* Allocate space for the dynamic relocations that turned out to be
2597 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2600 /* We have now determined the sizes of the various dynamic sections.
2601 Allocate memory for them. */
2602 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2606 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2609 /* If we don't need this section, strip it from the output file.
2610 There were several sections primarily related to dynamic
2611 linking that must be create before the linker maps input
2612 sections to output sections. The linker does that before
2613 bfd_elf_size_dynamic_sections is called, and it is that
2614 function which decides whether anything needs to go into
2617 strip
= (sec
->_raw_size
== 0);
2619 if (sec
== ia64_info
->got_sec
)
2621 else if (sec
== ia64_info
->rel_got_sec
)
2624 ia64_info
->rel_got_sec
= NULL
;
2626 /* We use the reloc_count field as a counter if we need to
2627 copy relocs into the output file. */
2628 sec
->reloc_count
= 0;
2630 else if (sec
== ia64_info
->fptr_sec
)
2633 ia64_info
->fptr_sec
= NULL
;
2635 else if (sec
== ia64_info
->plt_sec
)
2638 ia64_info
->plt_sec
= NULL
;
2640 else if (sec
== ia64_info
->pltoff_sec
)
2643 ia64_info
->pltoff_sec
= NULL
;
2645 else if (sec
== ia64_info
->rel_pltoff_sec
)
2648 ia64_info
->rel_pltoff_sec
= NULL
;
2652 /* We use the reloc_count field as a counter if we need to
2653 copy relocs into the output file. */
2654 sec
->reloc_count
= 0;
2661 /* It's OK to base decisions on the section name, because none
2662 of the dynobj section names depend upon the input files. */
2663 name
= bfd_get_section_name (dynobj
, sec
);
2665 if (strcmp (name
, ".got.plt") == 0)
2667 else if (strncmp (name
, ".rel", 4) == 0)
2671 const char *outname
;
2674 /* If this relocation section applies to a read only
2675 section, then we probably need a DT_TEXTREL entry. */
2676 outname
= bfd_get_section_name (output_bfd
,
2677 sec
->output_section
);
2678 if (outname
[4] == 'a')
2683 target
= bfd_get_section_by_name (output_bfd
, outname
);
2685 && (target
->flags
& SEC_READONLY
) != 0
2686 && (target
->flags
& SEC_ALLOC
) != 0)
2689 /* We use the reloc_count field as a counter if we need to
2690 copy relocs into the output file. */
2691 sec
->reloc_count
= 0;
2699 _bfd_strip_section_from_output (info
, sec
);
2702 /* Allocate memory for the section contents. */
2703 sec
->contents
= (bfd_byte
*) bfd_zalloc(dynobj
, sec
->_raw_size
);
2704 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
2709 if (elf_hash_table (info
)->dynamic_sections_created
)
2711 /* Add some entries to the .dynamic section. We fill in the values
2712 later (in finish_dynamic_sections) but we must add the entries now
2713 so that we get the correct size for the .dynamic section. */
2717 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2719 if (!bfd_elfNN_add_dynamic_entry (info
, DT_DEBUG
, 0))
2723 if (! bfd_elfNN_add_dynamic_entry (info
, DT_IA_64_PLT_RESERVE
, 0))
2725 if (! bfd_elfNN_add_dynamic_entry (info
, DT_PLTGOT
, 0))
2730 if (! bfd_elfNN_add_dynamic_entry (info
, DT_PLTRELSZ
, 0)
2731 || ! bfd_elfNN_add_dynamic_entry (info
, DT_PLTREL
, DT_RELA
)
2732 || ! bfd_elfNN_add_dynamic_entry (info
, DT_JMPREL
, 0))
2736 if (! bfd_elfNN_add_dynamic_entry (info
, DT_RELA
, 0)
2737 || ! bfd_elfNN_add_dynamic_entry (info
, DT_RELASZ
, 0)
2738 || ! bfd_elfNN_add_dynamic_entry (info
, DT_RELAENT
,
2739 sizeof (ElfNN_External_Rela
)))
2744 if (! bfd_elfNN_add_dynamic_entry (info
, DT_TEXTREL
, 0))
2746 info
->flags
|= DF_TEXTREL
;
2750 /* ??? Perhaps force __gp local. */
2755 static bfd_reloc_status_type
2756 elfNN_ia64_install_value (abfd
, hit_addr
, val
, r_type
)
2760 unsigned int r_type
;
2762 const struct ia64_operand
*op
;
2763 int bigendian
= 0, shift
= 0;
2764 bfd_vma t0
, t1
, insn
, dword
;
2765 enum ia64_opnd opnd
;
2769 opnd
= IA64_OPND_NIL
;
2774 return bfd_reloc_ok
;
2776 /* Instruction relocations. */
2778 case R_IA64_IMM14
: opnd
= IA64_OPND_IMM14
; break;
2780 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
2781 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
2782 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
2783 case R_IA64_PCREL21B
:
2784 case R_IA64_PCREL21BI
:
2785 opnd
= IA64_OPND_TGT25c
;
2789 case R_IA64_GPREL22
:
2790 case R_IA64_LTOFF22
:
2791 case R_IA64_LTOFF22X
:
2792 case R_IA64_PLTOFF22
:
2793 case R_IA64_PCREL22
:
2794 case R_IA64_LTOFF_FPTR22
:
2795 opnd
= IA64_OPND_IMM22
;
2799 case R_IA64_GPREL64I
:
2800 case R_IA64_LTOFF64I
:
2801 case R_IA64_PLTOFF64I
:
2802 case R_IA64_PCREL64I
:
2803 case R_IA64_FPTR64I
:
2804 case R_IA64_LTOFF_FPTR64I
:
2805 opnd
= IA64_OPND_IMMU64
;
2808 /* Data relocations. */
2810 case R_IA64_DIR32MSB
:
2811 case R_IA64_GPREL32MSB
:
2812 case R_IA64_FPTR32MSB
:
2813 case R_IA64_PCREL32MSB
:
2814 case R_IA64_SEGREL32MSB
:
2815 case R_IA64_SECREL32MSB
:
2816 case R_IA64_LTV32MSB
:
2817 size
= 4; bigendian
= 1;
2820 case R_IA64_DIR32LSB
:
2821 case R_IA64_GPREL32LSB
:
2822 case R_IA64_FPTR32LSB
:
2823 case R_IA64_PCREL32LSB
:
2824 case R_IA64_SEGREL32LSB
:
2825 case R_IA64_SECREL32LSB
:
2826 case R_IA64_LTV32LSB
:
2827 size
= 4; bigendian
= 0;
2830 case R_IA64_DIR64MSB
:
2831 case R_IA64_GPREL64MSB
:
2832 case R_IA64_PLTOFF64MSB
:
2833 case R_IA64_FPTR64MSB
:
2834 case R_IA64_PCREL64MSB
:
2835 case R_IA64_LTOFF_FPTR64MSB
:
2836 case R_IA64_SEGREL64MSB
:
2837 case R_IA64_SECREL64MSB
:
2838 case R_IA64_LTV64MSB
:
2839 size
= 8; bigendian
= 1;
2842 case R_IA64_DIR64LSB
:
2843 case R_IA64_GPREL64LSB
:
2844 case R_IA64_PLTOFF64LSB
:
2845 case R_IA64_FPTR64LSB
:
2846 case R_IA64_PCREL64LSB
:
2847 case R_IA64_LTOFF_FPTR64LSB
:
2848 case R_IA64_SEGREL64LSB
:
2849 case R_IA64_SECREL64LSB
:
2850 case R_IA64_LTV64LSB
:
2851 size
= 8; bigendian
= 0;
2854 /* Unsupported / Dynamic relocations. */
2856 return bfd_reloc_notsupported
;
2861 case IA64_OPND_IMMU64
:
2862 hit_addr
-= (long) hit_addr
& 0x3;
2863 t0
= bfd_get_64 (abfd
, hit_addr
);
2864 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2866 /* tmpl/s: bits 0.. 5 in t0
2867 slot 0: bits 5..45 in t0
2868 slot 1: bits 46..63 in t0, bits 0..22 in t1
2869 slot 2: bits 23..63 in t1 */
2871 /* First, clear the bits that form the 64 bit constant. */
2872 t0
&= ~(0x3ffffLL
<< 46);
2874 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
2875 | (0x01fLL
<< 22) | (0x001LL
<< 21)
2876 | (0x001LL
<< 36)) << 23));
2878 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
2879 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
2880 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
2881 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
2882 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
2883 | (((val
>> 21) & 0x001) << 21) /* ic */
2884 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
2886 bfd_put_64 (abfd
, t0
, hit_addr
);
2887 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2890 case IA64_OPND_TGT64
:
2891 hit_addr
-= (long) hit_addr
& 0x3;
2892 t0
= bfd_get_64 (abfd
, hit_addr
);
2893 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2895 /* tmpl/s: bits 0.. 5 in t0
2896 slot 0: bits 5..45 in t0
2897 slot 1: bits 46..63 in t0, bits 0..22 in t1
2898 slot 2: bits 23..63 in t1 */
2900 /* First, clear the bits that form the 64 bit constant. */
2901 t0
&= ~(0x3ffffLL
<< 46);
2903 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
2906 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
2907 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
2908 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
2909 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
2911 bfd_put_64 (abfd
, t0
, hit_addr
);
2912 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2916 switch ((long) hit_addr
& 0x3)
2918 case 0: shift
= 5; break;
2919 case 1: shift
= 14; hit_addr
+= 3; break;
2920 case 2: shift
= 23; hit_addr
+= 6; break;
2921 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
2923 dword
= bfd_get_64 (abfd
, hit_addr
);
2924 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
2926 op
= elf64_ia64_operands
+ opnd
;
2927 err
= (*op
->insert
) (op
, val
, &insn
);
2929 return bfd_reloc_overflow
;
2931 dword
&= ~(0x1ffffffffffLL
<< shift
);
2932 dword
|= (insn
<< shift
);
2933 bfd_put_64 (abfd
, dword
, hit_addr
);
2937 /* A data relocation. */
2940 bfd_putb32 (val
, hit_addr
);
2942 bfd_putb64 (val
, hit_addr
);
2945 bfd_putl32 (val
, hit_addr
);
2947 bfd_putl64 (val
, hit_addr
);
2951 return bfd_reloc_ok
;
2955 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
2958 struct bfd_link_info
*info
;
2966 Elf_Internal_Rela outrel
;
2968 outrel
.r_offset
= (sec
->output_section
->vma
2969 + sec
->output_offset
2972 BFD_ASSERT (dynindx
!= -1);
2973 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
2974 outrel
.r_addend
= addend
;
2976 if (elf_section_data (sec
)->stab_info
!= NULL
)
2978 /* This may be NULL for linker-generated relocations, as it is
2979 inconvenient to pass all the bits around. And this shouldn't
2981 BFD_ASSERT (info
!= NULL
);
2983 offset
= (_bfd_stab_section_offset
2984 (abfd
, &elf_hash_table (info
)->stab_info
, sec
,
2985 &elf_section_data (sec
)->stab_info
, offset
));
2986 if (offset
== (bfd_vma
) -1)
2988 /* Run for the hills. We shouldn't be outputting a relocation
2989 for this. So do what everyone else does and output a no-op. */
2990 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
2991 outrel
.r_addend
= 0;
2994 outrel
.r_offset
= offset
;
2997 bfd_elfNN_swap_reloca_out (abfd
, &outrel
,
2998 ((ElfNN_External_Rela
*) srel
->contents
2999 + srel
->reloc_count
++));
3000 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3001 <= srel
->_cooked_size
);
3004 /* Store an entry for target address TARGET_ADDR in the linkage table
3005 and return the gp-relative address of the linkage table entry. */
3008 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3010 struct bfd_link_info
*info
;
3011 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3015 unsigned int dyn_r_type
;
3017 struct elfNN_ia64_link_hash_table
*ia64_info
;
3020 ia64_info
= elfNN_ia64_hash_table (info
);
3021 got_sec
= ia64_info
->got_sec
;
3023 BFD_ASSERT ((dyn_i
->got_offset
& 7) == 0);
3025 if (! dyn_i
->got_done
)
3027 dyn_i
->got_done
= true;
3029 /* Store the target address in the linkage table entry. */
3030 bfd_put_64 (abfd
, value
, got_sec
->contents
+ dyn_i
->got_offset
);
3032 /* Install a dynamic relocation if needed. */
3034 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3035 || elfNN_ia64_aix_vec (abfd
->xvec
)
3036 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3040 dyn_r_type
= R_IA64_REL64LSB
;
3045 if (bfd_big_endian (abfd
))
3049 case R_IA64_REL64LSB
:
3050 dyn_r_type
= R_IA64_REL64MSB
;
3052 case R_IA64_DIR64LSB
:
3053 dyn_r_type
= R_IA64_DIR64MSB
;
3055 case R_IA64_FPTR64LSB
:
3056 dyn_r_type
= R_IA64_FPTR64MSB
;
3064 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3065 ia64_info
->rel_got_sec
,
3066 dyn_i
->got_offset
, dyn_r_type
,
3071 /* Return the address of the linkage table entry. */
3072 value
= (got_sec
->output_section
->vma
3073 + got_sec
->output_offset
3074 + dyn_i
->got_offset
);
3079 /* Fill in a function descriptor consisting of the function's code
3080 address and its global pointer. Return the descriptor's address. */
3083 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3085 struct bfd_link_info
*info
;
3086 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3089 struct elfNN_ia64_link_hash_table
*ia64_info
;
3092 ia64_info
= elfNN_ia64_hash_table (info
);
3093 fptr_sec
= ia64_info
->fptr_sec
;
3095 if (!dyn_i
->fptr_done
)
3097 dyn_i
->fptr_done
= 1;
3099 /* Fill in the function descriptor. */
3100 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3101 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3102 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3105 /* Return the descriptor's address. */
3106 value
= (fptr_sec
->output_section
->vma
3107 + fptr_sec
->output_offset
3108 + dyn_i
->fptr_offset
);
3113 /* Fill in a PLTOFF entry consisting of the function's code address
3114 and its global pointer. Return the descriptor's address. */
3117 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3119 struct bfd_link_info
*info
;
3120 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3124 struct elfNN_ia64_link_hash_table
*ia64_info
;
3125 asection
*pltoff_sec
;
3127 ia64_info
= elfNN_ia64_hash_table (info
);
3128 pltoff_sec
= ia64_info
->pltoff_sec
;
3130 /* Don't do anything if this symbol uses a real PLT entry. In
3131 that case, we'll fill this in during finish_dynamic_symbol. */
3132 if ((! dyn_i
->want_plt
|| is_plt
)
3133 && !dyn_i
->pltoff_done
)
3135 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3137 /* Fill in the function descriptor. */
3138 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3139 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3141 /* Install dynamic relocations if needed. */
3142 if (!is_plt
&& info
->shared
)
3144 unsigned int dyn_r_type
;
3146 if (bfd_big_endian (abfd
))
3147 dyn_r_type
= R_IA64_REL64MSB
;
3149 dyn_r_type
= R_IA64_REL64LSB
;
3151 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3152 ia64_info
->rel_pltoff_sec
,
3153 dyn_i
->pltoff_offset
,
3154 dyn_r_type
, 0, value
);
3155 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3156 ia64_info
->rel_pltoff_sec
,
3157 dyn_i
->pltoff_offset
+ 8,
3161 dyn_i
->pltoff_done
= 1;
3164 /* Return the descriptor's address. */
3165 value
= (pltoff_sec
->output_section
->vma
3166 + pltoff_sec
->output_offset
3167 + dyn_i
->pltoff_offset
);
3172 /* Called through qsort to sort the .IA_64.unwind section during a
3173 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3174 to the output bfd so we can do proper endianness frobbing. */
3176 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3179 elfNN_ia64_unwind_entry_compare (a
, b
)
3185 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3186 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3188 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3192 elfNN_ia64_final_link (abfd
, info
)
3194 struct bfd_link_info
*info
;
3196 struct elfNN_ia64_link_hash_table
*ia64_info
;
3197 asection
*unwind_output_sec
;
3199 ia64_info
= elfNN_ia64_hash_table (info
);
3201 /* Make sure we've got ourselves a nice fat __gp value. */
3202 if (!info
->relocateable
)
3204 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3205 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3206 struct elf_link_hash_entry
*gp
;
3210 /* Find the min and max vma of all sections marked short. Also
3211 collect min and max vma of any type, for use in selecting a
3213 for (os
= abfd
->sections
; os
; os
= os
->next
)
3217 if ((os
->flags
& SEC_ALLOC
) == 0)
3221 hi
= os
->vma
+ os
->_raw_size
;
3229 if (os
->flags
& SEC_SMALL_DATA
)
3231 if (min_short_vma
> lo
)
3233 if (max_short_vma
< hi
)
3238 /* See if the user wants to force a value. */
3239 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", false,
3243 && (gp
->root
.type
== bfd_link_hash_defined
3244 || gp
->root
.type
== bfd_link_hash_defweak
))
3246 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3247 gp_val
= (gp
->root
.u
.def
.value
3248 + gp_sec
->output_section
->vma
3249 + gp_sec
->output_offset
);
3253 /* Pick a sensible value. */
3255 asection
*got_sec
= ia64_info
->got_sec
;
3257 /* Start with just the address of the .got. */
3259 gp_val
= got_sec
->output_section
->vma
;
3260 else if (max_short_vma
!= 0)
3261 gp_val
= min_short_vma
;
3265 /* If it is possible to address the entire image, but we
3266 don't with the choice above, adjust. */
3267 if (max_vma
- min_vma
< 0x400000
3268 && max_vma
- gp_val
<= 0x200000
3269 && gp_val
- min_vma
> 0x200000)
3270 gp_val
= min_vma
+ 0x200000;
3271 else if (max_short_vma
!= 0)
3273 /* If we don't cover all the short data, adjust. */
3274 if (max_short_vma
- gp_val
>= 0x200000)
3275 gp_val
= min_short_vma
+ 0x200000;
3277 /* If we're addressing stuff past the end, adjust back. */
3278 if (gp_val
> max_vma
)
3279 gp_val
= max_vma
- 0x200000 + 8;
3283 /* Validate whether all SHF_IA_64_SHORT sections are within
3284 range of the chosen GP. */
3286 if (max_short_vma
!= 0)
3288 if (max_short_vma
- min_short_vma
>= 0x400000)
3290 (*_bfd_error_handler
)
3291 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3292 bfd_get_filename (abfd
),
3293 (unsigned long) (max_short_vma
- min_short_vma
));
3296 else if ((gp_val
> min_short_vma
3297 && gp_val
- min_short_vma
> 0x200000)
3298 || (gp_val
< max_short_vma
3299 && max_short_vma
- gp_val
>= 0x200000))
3301 (*_bfd_error_handler
)
3302 (_("%s: __gp does not cover short data segment"),
3303 bfd_get_filename (abfd
));
3308 _bfd_set_gp_value (abfd
, gp_val
);
3312 gp
->root
.type
= bfd_link_hash_defined
;
3313 gp
->root
.u
.def
.value
= gp_val
;
3314 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3318 /* If we're producing a final executable, we need to sort the contents
3319 of the .IA_64.unwind section. Force this section to be relocated
3320 into memory rather than written immediately to the output file. */
3321 unwind_output_sec
= NULL
;
3322 if (!info
->relocateable
)
3324 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3327 unwind_output_sec
= s
->output_section
;
3328 unwind_output_sec
->contents
3329 = bfd_malloc (unwind_output_sec
->_raw_size
);
3330 if (unwind_output_sec
->contents
== NULL
)
3335 /* Invoke the regular ELF backend linker to do all the work. */
3336 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3339 if (unwind_output_sec
)
3341 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3342 qsort (unwind_output_sec
->contents
, unwind_output_sec
->_raw_size
/ 24,
3343 24, elfNN_ia64_unwind_entry_compare
);
3345 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3346 unwind_output_sec
->contents
, 0,
3347 unwind_output_sec
->_raw_size
))
3355 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3356 contents
, relocs
, local_syms
, local_sections
)
3358 struct bfd_link_info
*info
;
3360 asection
*input_section
;
3362 Elf_Internal_Rela
*relocs
;
3363 Elf_Internal_Sym
*local_syms
;
3364 asection
**local_sections
;
3366 struct elfNN_ia64_link_hash_table
*ia64_info
;
3367 Elf_Internal_Shdr
*symtab_hdr
;
3368 Elf_Internal_Rela
*rel
;
3369 Elf_Internal_Rela
*relend
;
3371 boolean ret_val
= true; /* for non-fatal errors */
3374 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3375 ia64_info
= elfNN_ia64_hash_table (info
);
3377 /* Infect various flags from the input section to the output section. */
3378 if (info
->relocateable
)
3382 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3383 flags
&= SHF_IA_64_NORECOV
;
3385 elf_section_data(input_section
->output_section
)
3386 ->this_hdr
.sh_flags
|= flags
;
3389 gp_val
= _bfd_get_gp_value (output_bfd
);
3390 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, false);
3393 relend
= relocs
+ input_section
->reloc_count
;
3394 for (; rel
< relend
; ++rel
)
3396 struct elf_link_hash_entry
*h
;
3397 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3398 bfd_reloc_status_type r
;
3399 reloc_howto_type
*howto
;
3400 unsigned long r_symndx
;
3401 Elf_Internal_Sym
*sym
;
3402 unsigned int r_type
;
3406 boolean dynamic_symbol_p
;
3407 boolean undef_weak_ref
;
3409 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3410 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3412 (*_bfd_error_handler
)
3413 (_("%s: unknown relocation type %d"),
3414 bfd_get_filename (input_bfd
), (int)r_type
);
3415 bfd_set_error (bfd_error_bad_value
);
3419 howto
= lookup_howto (r_type
);
3420 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3422 if (info
->relocateable
)
3424 /* This is a relocateable link. We don't have to change
3425 anything, unless the reloc is against a section symbol,
3426 in which case we have to adjust according to where the
3427 section symbol winds up in the output section. */
3428 if (r_symndx
< symtab_hdr
->sh_info
)
3430 sym
= local_syms
+ r_symndx
;
3431 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
3433 sym_sec
= local_sections
[r_symndx
];
3434 rel
->r_addend
+= sym_sec
->output_offset
;
3440 /* This is a final link. */
3445 undef_weak_ref
= false;
3447 if (r_symndx
< symtab_hdr
->sh_info
)
3449 /* Reloc against local symbol. */
3450 sym
= local_syms
+ r_symndx
;
3451 sym_sec
= local_sections
[r_symndx
];
3452 value
= (sym_sec
->output_section
->vma
3453 + sym_sec
->output_offset
3460 /* Reloc against global symbol. */
3461 indx
= r_symndx
- symtab_hdr
->sh_info
;
3462 h
= elf_sym_hashes (input_bfd
)[indx
];
3463 while (h
->root
.type
== bfd_link_hash_indirect
3464 || h
->root
.type
== bfd_link_hash_warning
)
3465 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3468 if (h
->root
.type
== bfd_link_hash_defined
3469 || h
->root
.type
== bfd_link_hash_defweak
)
3471 sym_sec
= h
->root
.u
.def
.section
;
3473 /* Detect the cases that sym_sec->output_section is
3474 expected to be NULL -- all cases in which the symbol
3475 is defined in another shared module. This includes
3476 PLT relocs for which we've created a PLT entry and
3477 other relocs for which we're prepared to create
3478 dynamic relocations. */
3479 /* ??? Just accept it NULL and continue. */
3481 if (sym_sec
->output_section
!= NULL
)
3483 value
= (h
->root
.u
.def
.value
3484 + sym_sec
->output_section
->vma
3485 + sym_sec
->output_offset
);
3488 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3489 undef_weak_ref
= true;
3490 else if (info
->shared
&& !info
->symbolic
3491 && !info
->no_undefined
3492 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3496 if (! ((*info
->callbacks
->undefined_symbol
)
3497 (info
, h
->root
.root
.string
, input_bfd
,
3498 input_section
, rel
->r_offset
,
3499 (!info
->shared
|| info
->no_undefined
3500 || ELF_ST_VISIBILITY (h
->other
)))))
3507 hit_addr
= contents
+ rel
->r_offset
;
3508 value
+= rel
->r_addend
;
3509 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3520 case R_IA64_DIR32MSB
:
3521 case R_IA64_DIR32LSB
:
3522 case R_IA64_DIR64MSB
:
3523 case R_IA64_DIR64LSB
:
3524 /* Install a dynamic relocation for this reloc. */
3525 if ((dynamic_symbol_p
|| info
->shared
3526 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
3527 /* We want REL relocation for _GLOB_DATA_PTR, which would
3528 otherwise be an IMM64, which isn't handled below. The
3529 symbol comes from the C runtime. */
3531 strcmp (h
->root
.root
.string
, "__GLOB_DATA_PTR") != 0)))
3532 && (input_section
->flags
& SEC_ALLOC
) != 0)
3534 unsigned int dyn_r_type
;
3538 BFD_ASSERT (srel
!= NULL
);
3540 /* If we don't need dynamic symbol lookup, find a
3541 matching RELATIVE relocation. */
3542 dyn_r_type
= r_type
;
3543 if (dynamic_symbol_p
)
3545 dynindx
= h
->dynindx
;
3546 addend
= rel
->r_addend
;
3553 case R_IA64_DIR32MSB
:
3554 dyn_r_type
= R_IA64_REL32MSB
;
3556 case R_IA64_DIR32LSB
:
3557 dyn_r_type
= R_IA64_REL32LSB
;
3559 case R_IA64_DIR64MSB
:
3560 dyn_r_type
= R_IA64_REL64MSB
;
3562 case R_IA64_DIR64LSB
:
3563 dyn_r_type
= R_IA64_REL64LSB
;
3567 /* We can't represent this without a dynamic symbol.
3568 Adjust the relocation to be against an output
3569 section symbol, which are always present in the
3570 dynamic symbol table. */
3571 /* ??? People shouldn't be doing non-pic code in
3572 shared libraries. Hork. */
3573 (*_bfd_error_handler
)
3574 (_("%s: linking non-pic code in a shared library"),
3575 bfd_get_filename (input_bfd
));
3583 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
3584 rel
->r_addend
= value
;
3585 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3586 srel
, rel
->r_offset
, dyn_r_type
,
3591 case R_IA64_LTV32MSB
:
3592 case R_IA64_LTV32LSB
:
3593 case R_IA64_LTV64MSB
:
3594 case R_IA64_LTV64LSB
:
3595 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3598 case R_IA64_GPREL22
:
3599 case R_IA64_GPREL64I
:
3600 case R_IA64_GPREL32MSB
:
3601 case R_IA64_GPREL32LSB
:
3602 case R_IA64_GPREL64MSB
:
3603 case R_IA64_GPREL64LSB
:
3604 if (dynamic_symbol_p
)
3606 (*_bfd_error_handler
)
3607 (_("%s: @gprel relocation against dynamic symbol %s"),
3608 bfd_get_filename (input_bfd
), h
->root
.root
.string
);
3613 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3616 case R_IA64_LTOFF22
:
3617 case R_IA64_LTOFF22X
:
3618 case R_IA64_LTOFF64I
:
3619 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3620 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
3621 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
3623 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3626 case R_IA64_PLTOFF22
:
3627 case R_IA64_PLTOFF64I
:
3628 case R_IA64_PLTOFF64MSB
:
3629 case R_IA64_PLTOFF64LSB
:
3630 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3631 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, false);
3633 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3636 case R_IA64_FPTR64I
:
3637 case R_IA64_FPTR32MSB
:
3638 case R_IA64_FPTR32LSB
:
3639 case R_IA64_FPTR64MSB
:
3640 case R_IA64_FPTR64LSB
:
3641 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3642 if (dyn_i
->want_fptr
)
3644 if (!undef_weak_ref
)
3645 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3651 /* Otherwise, we expect the dynamic linker to create
3656 if (h
->dynindx
!= -1)
3657 dynindx
= h
->dynindx
;
3659 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3660 (info
, h
->root
.u
.def
.section
->owner
,
3661 global_sym_index (h
)));
3665 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3666 (info
, input_bfd
, r_symndx
));
3669 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3670 srel
, rel
->r_offset
, r_type
,
3671 dynindx
, rel
->r_addend
);
3675 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3678 case R_IA64_LTOFF_FPTR22
:
3679 case R_IA64_LTOFF_FPTR64I
:
3680 case R_IA64_LTOFF_FPTR64MSB
:
3681 case R_IA64_LTOFF_FPTR64LSB
:
3685 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3686 if (dyn_i
->want_fptr
)
3688 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
3689 if (!undef_weak_ref
)
3690 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3695 /* Otherwise, we expect the dynamic linker to create
3699 if (h
->dynindx
!= -1)
3700 dynindx
= h
->dynindx
;
3702 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3703 (info
, h
->root
.u
.def
.section
->owner
,
3704 global_sym_index (h
)));
3707 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3708 (info
, input_bfd
, r_symndx
));
3712 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
3713 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
3715 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3719 case R_IA64_PCREL32MSB
:
3720 case R_IA64_PCREL32LSB
:
3721 case R_IA64_PCREL64MSB
:
3722 case R_IA64_PCREL64LSB
:
3723 /* Install a dynamic relocation for this reloc. */
3724 if (dynamic_symbol_p
3725 || elfNN_ia64_aix_vec (info
->hash
->creator
))
3727 BFD_ASSERT (srel
!= NULL
);
3729 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3730 srel
, rel
->r_offset
, r_type
,
3731 h
->dynindx
, rel
->r_addend
);
3735 case R_IA64_PCREL21BI
:
3736 case R_IA64_PCREL21F
:
3737 case R_IA64_PCREL21M
:
3738 /* ??? These two are only used for speculation fixup code.
3739 They should never be dynamic. */
3740 if (dynamic_symbol_p
)
3742 (*_bfd_error_handler
)
3743 (_("%s: dynamic relocation against speculation fixup"),
3744 bfd_get_filename (input_bfd
));
3750 (*_bfd_error_handler
)
3751 (_("%s: speculation fixup against undefined weak symbol"),
3752 bfd_get_filename (input_bfd
));
3758 case R_IA64_PCREL21B
:
3759 case R_IA64_PCREL60B
:
3760 /* We should have created a PLT entry for any dynamic symbol. */
3763 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
3765 if (dyn_i
&& dyn_i
->want_plt2
)
3767 /* Should have caught this earlier. */
3768 BFD_ASSERT (rel
->r_addend
== 0);
3770 value
= (ia64_info
->plt_sec
->output_section
->vma
3771 + ia64_info
->plt_sec
->output_offset
3772 + dyn_i
->plt2_offset
);
3776 /* Since there's no PLT entry, Validate that this is
3778 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
3780 /* If the symbol is undef_weak, we shouldn't be trying
3781 to call it. There's every chance that we'd wind up
3782 with an out-of-range fixup here. Don't bother setting
3783 any value at all. */
3789 case R_IA64_PCREL22
:
3790 case R_IA64_PCREL64I
:
3792 /* Make pc-relative. */
3793 value
-= (input_section
->output_section
->vma
3794 + input_section
->output_offset
3795 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
3796 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3799 case R_IA64_SEGREL32MSB
:
3800 case R_IA64_SEGREL32LSB
:
3801 case R_IA64_SEGREL64MSB
:
3802 case R_IA64_SEGREL64LSB
:
3804 struct elf_segment_map
*m
;
3805 Elf_Internal_Phdr
*p
;
3807 /* Find the segment that contains the output_section. */
3808 for (m
= elf_tdata (output_bfd
)->segment_map
,
3809 p
= elf_tdata (output_bfd
)->phdr
;
3814 for (i
= m
->count
- 1; i
>= 0; i
--)
3815 if (m
->sections
[i
] == sym_sec
->output_section
)
3823 /* If the input section was discarded from the output, then
3826 if (bfd_is_abs_section (sym_sec
->output_section
))
3829 r
= bfd_reloc_notsupported
;
3833 /* The VMA of the segment is the vaddr of the associated
3835 if (value
> p
->p_vaddr
)
3836 value
-= p
->p_vaddr
;
3839 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
3845 case R_IA64_SECREL32MSB
:
3846 case R_IA64_SECREL32LSB
:
3847 case R_IA64_SECREL64MSB
:
3848 case R_IA64_SECREL64LSB
:
3849 /* Make output-section relative. */
3850 if (value
> input_section
->output_section
->vma
)
3851 value
-= input_section
->output_section
->vma
;
3854 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3857 case R_IA64_IPLTMSB
:
3858 case R_IA64_IPLTLSB
:
3859 /* Install a dynamic relocation for this reloc. */
3860 if ((dynamic_symbol_p
|| info
->shared
)
3861 && (input_section
->flags
& SEC_ALLOC
) != 0)
3863 BFD_ASSERT (srel
!= NULL
);
3865 /* If we don't need dynamic symbol lookup, install two
3866 RELATIVE relocations. */
3867 if (! dynamic_symbol_p
)
3869 unsigned int dyn_r_type
;
3871 if (r_type
== R_IA64_IPLTMSB
)
3872 dyn_r_type
= R_IA64_REL64MSB
;
3874 dyn_r_type
= R_IA64_REL64LSB
;
3876 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3878 srel
, rel
->r_offset
,
3879 dyn_r_type
, 0, value
);
3880 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3882 srel
, rel
->r_offset
+ 8,
3883 dyn_r_type
, 0, gp_val
);
3886 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3887 srel
, rel
->r_offset
, r_type
,
3888 h
->dynindx
, rel
->r_addend
);
3891 if (r_type
== R_IA64_IPLTMSB
)
3892 r_type
= R_IA64_DIR64MSB
;
3894 r_type
= R_IA64_DIR64LSB
;
3895 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3896 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
3901 r
= bfd_reloc_notsupported
;
3910 case bfd_reloc_undefined
:
3911 /* This can happen for global table relative relocs if
3912 __gp is undefined. This is a panic situation so we
3913 don't try to continue. */
3914 (*info
->callbacks
->undefined_symbol
)
3915 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
3918 case bfd_reloc_notsupported
:
3923 name
= h
->root
.root
.string
;
3926 name
= bfd_elf_string_from_elf_section (input_bfd
,
3927 symtab_hdr
->sh_link
,
3932 name
= bfd_section_name (input_bfd
, input_section
);
3934 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
3936 input_section
, rel
->r_offset
))
3942 case bfd_reloc_dangerous
:
3943 case bfd_reloc_outofrange
:
3944 case bfd_reloc_overflow
:
3950 name
= h
->root
.root
.string
;
3953 name
= bfd_elf_string_from_elf_section (input_bfd
,
3954 symtab_hdr
->sh_link
,
3959 name
= bfd_section_name (input_bfd
, input_section
);
3961 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
3977 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
3979 struct bfd_link_info
*info
;
3980 struct elf_link_hash_entry
*h
;
3981 Elf_Internal_Sym
*sym
;
3983 struct elfNN_ia64_link_hash_table
*ia64_info
;
3984 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3986 ia64_info
= elfNN_ia64_hash_table (info
);
3987 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
3989 /* Fill in the PLT data, if required. */
3990 if (dyn_i
&& dyn_i
->want_plt
)
3992 Elf_Internal_Rela outrel
;
3995 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
3996 ElfNN_External_Rela
*rel
;
3998 gp_val
= _bfd_get_gp_value (output_bfd
);
4000 /* Initialize the minimal PLT entry. */
4002 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4003 plt_sec
= ia64_info
->plt_sec
;
4004 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4006 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4007 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4008 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4011 plt_addr
= (plt_sec
->output_section
->vma
4012 + plt_sec
->output_offset
4013 + dyn_i
->plt_offset
);
4014 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, true);
4016 /* Initialize the FULL PLT entry, if needed. */
4017 if (dyn_i
->want_plt2
)
4019 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4021 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4022 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4025 /* Mark the symbol as undefined, rather than as defined in the
4026 plt section. Leave the value alone. */
4027 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4028 first place. But perhaps elflink.h did some for us. */
4029 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4030 sym
->st_shndx
= SHN_UNDEF
;
4033 /* Create the dynamic relocation. */
4034 outrel
.r_offset
= pltoff_addr
;
4035 if (bfd_little_endian (output_bfd
))
4036 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4038 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4039 outrel
.r_addend
= 0;
4041 /* This is fun. In the .IA_64.pltoff section, we've got entries
4042 that correspond both to real PLT entries, and those that
4043 happened to resolve to local symbols but need to be created
4044 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4045 relocations for the real PLT should come at the end of the
4046 section, so that they can be indexed by plt entry at runtime.
4048 We emitted all of the relocations for the non-PLT @pltoff
4049 entries during relocate_section. So we can consider the
4050 existing sec->reloc_count to be the base of the array of
4053 rel
= (ElfNN_External_Rela
*)ia64_info
->rel_pltoff_sec
->contents
;
4054 rel
+= ia64_info
->rel_pltoff_sec
->reloc_count
;
4056 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, rel
+ index
);
4059 /* Mark some specially defined symbols as absolute. */
4060 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4061 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4062 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4063 sym
->st_shndx
= SHN_ABS
;
4069 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4071 struct bfd_link_info
*info
;
4073 struct elfNN_ia64_link_hash_table
*ia64_info
;
4076 ia64_info
= elfNN_ia64_hash_table (info
);
4077 dynobj
= ia64_info
->root
.dynobj
;
4079 if (elf_hash_table (info
)->dynamic_sections_created
)
4081 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4082 asection
*sdyn
, *sgotplt
;
4085 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4086 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4087 BFD_ASSERT (sdyn
!= NULL
);
4088 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4089 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4091 gp_val
= _bfd_get_gp_value (abfd
);
4093 for (; dyncon
< dynconend
; dyncon
++)
4095 Elf_Internal_Dyn dyn
;
4097 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4102 dyn
.d_un
.d_ptr
= gp_val
;
4106 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4107 * sizeof (ElfNN_External_Rela
));
4111 /* See the comment above in finish_dynamic_symbol. */
4112 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4113 + ia64_info
->rel_pltoff_sec
->output_offset
4114 + (ia64_info
->rel_pltoff_sec
->reloc_count
4115 * sizeof (ElfNN_External_Rela
)));
4118 case DT_IA_64_PLT_RESERVE
:
4119 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4120 + sgotplt
->output_offset
);
4124 /* Do not have RELASZ include JMPREL. This makes things
4125 easier on ld.so. This is not what the rest of BFD set up. */
4126 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4127 * sizeof (ElfNN_External_Rela
));
4131 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4134 /* Initialize the PLT0 entry */
4135 if (ia64_info
->plt_sec
)
4137 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4140 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4142 pltres
= (sgotplt
->output_section
->vma
4143 + sgotplt
->output_offset
4146 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4153 /* ELF file flag handling: */
4155 /* Function to keep IA-64 specific file flags. */
4157 elfNN_ia64_set_private_flags (abfd
, flags
)
4161 BFD_ASSERT (!elf_flags_init (abfd
)
4162 || elf_elfheader (abfd
)->e_flags
== flags
);
4164 elf_elfheader (abfd
)->e_flags
= flags
;
4165 elf_flags_init (abfd
) = true;
4169 /* Copy backend specific data from one object module to another */
4171 elfNN_ia64_copy_private_bfd_data (ibfd
, obfd
)
4174 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4175 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4178 BFD_ASSERT (!elf_flags_init (obfd
)
4179 || (elf_elfheader (obfd
)->e_flags
4180 == elf_elfheader (ibfd
)->e_flags
));
4182 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
4183 elf_flags_init (obfd
) = true;
4187 /* Merge backend specific data from an object file to the output
4188 object file when linking. */
4190 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4197 /* Don't even pretend to support mixed-format linking. */
4198 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4199 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4202 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4203 out_flags
= elf_elfheader (obfd
)->e_flags
;
4205 if (! elf_flags_init (obfd
))
4207 elf_flags_init (obfd
) = true;
4208 elf_elfheader (obfd
)->e_flags
= in_flags
;
4210 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4211 && bfd_get_arch_info (obfd
)->the_default
)
4213 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4214 bfd_get_mach (ibfd
));
4220 /* Check flag compatibility. */
4221 if (in_flags
== out_flags
)
4224 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4225 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4226 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4228 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4230 (*_bfd_error_handler
)
4231 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4232 bfd_get_filename (ibfd
));
4234 bfd_set_error (bfd_error_bad_value
);
4237 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4239 (*_bfd_error_handler
)
4240 (_("%s: linking big-endian files with little-endian files"),
4241 bfd_get_filename (ibfd
));
4243 bfd_set_error (bfd_error_bad_value
);
4246 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4248 (*_bfd_error_handler
)
4249 (_("%s: linking 64-bit files with 32-bit files"),
4250 bfd_get_filename (ibfd
));
4252 bfd_set_error (bfd_error_bad_value
);
4255 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4257 (*_bfd_error_handler
)
4258 (_("%s: linking constant-gp files with non-constant-gp files"),
4259 bfd_get_filename (ibfd
));
4261 bfd_set_error (bfd_error_bad_value
);
4264 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4265 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4267 (*_bfd_error_handler
)
4268 (_("%s: linking auto-pic files with non-auto-pic files"),
4269 bfd_get_filename (ibfd
));
4271 bfd_set_error (bfd_error_bad_value
);
4279 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4283 FILE *file
= (FILE *) ptr
;
4284 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4286 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4288 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4289 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4290 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4291 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4292 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4293 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4294 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4295 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4296 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4298 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4302 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4303 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4304 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4305 #define TARGET_BIG_NAME "elfNN-ia64-big"
4306 #define ELF_ARCH bfd_arch_ia64
4307 #define ELF_MACHINE_CODE EM_IA_64
4308 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4309 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4310 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4312 #define elf_backend_section_from_shdr \
4313 elfNN_ia64_section_from_shdr
4314 #define elf_backend_section_flags \
4315 elfNN_ia64_section_flags
4316 #define elf_backend_fake_sections \
4317 elfNN_ia64_fake_sections
4318 #define elf_backend_final_write_processing \
4319 elfNN_ia64_final_write_processing
4320 #define elf_backend_add_symbol_hook \
4321 elfNN_ia64_add_symbol_hook
4322 #define elf_backend_additional_program_headers \
4323 elfNN_ia64_additional_program_headers
4324 #define elf_backend_modify_segment_map \
4325 elfNN_ia64_modify_segment_map
4326 #define elf_info_to_howto \
4327 elfNN_ia64_info_to_howto
4329 #define bfd_elfNN_bfd_reloc_type_lookup \
4330 elfNN_ia64_reloc_type_lookup
4331 #define bfd_elfNN_bfd_is_local_label_name \
4332 elfNN_ia64_is_local_label_name
4333 #define bfd_elfNN_bfd_relax_section \
4334 elfNN_ia64_relax_section
4336 /* Stuff for the BFD linker: */
4337 #define bfd_elfNN_bfd_link_hash_table_create \
4338 elfNN_ia64_hash_table_create
4339 #define elf_backend_create_dynamic_sections \
4340 elfNN_ia64_create_dynamic_sections
4341 #define elf_backend_check_relocs \
4342 elfNN_ia64_check_relocs
4343 #define elf_backend_adjust_dynamic_symbol \
4344 elfNN_ia64_adjust_dynamic_symbol
4345 #define elf_backend_size_dynamic_sections \
4346 elfNN_ia64_size_dynamic_sections
4347 #define elf_backend_relocate_section \
4348 elfNN_ia64_relocate_section
4349 #define elf_backend_finish_dynamic_symbol \
4350 elfNN_ia64_finish_dynamic_symbol
4351 #define elf_backend_finish_dynamic_sections \
4352 elfNN_ia64_finish_dynamic_sections
4353 #define bfd_elfNN_bfd_final_link \
4354 elfNN_ia64_final_link
4356 #define bfd_elfNN_bfd_copy_private_bfd_data \
4357 elfNN_ia64_copy_private_bfd_data
4358 #define bfd_elfNN_bfd_merge_private_bfd_data \
4359 elfNN_ia64_merge_private_bfd_data
4360 #define bfd_elfNN_bfd_set_private_flags \
4361 elfNN_ia64_set_private_flags
4362 #define bfd_elfNN_bfd_print_private_bfd_data \
4363 elfNN_ia64_print_private_bfd_data
4365 #define elf_backend_plt_readonly 1
4366 #define elf_backend_want_plt_sym 0
4367 #define elf_backend_plt_alignment 5
4368 #define elf_backend_got_header_size 0
4369 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4370 #define elf_backend_want_got_plt 1
4371 #define elf_backend_may_use_rel_p 1
4372 #define elf_backend_may_use_rela_p 1
4373 #define elf_backend_default_use_rela_p 1
4374 #define elf_backend_want_dynbss 0
4375 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4376 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4378 #include "elfNN-target.h"
4380 /* AIX-specific vectors. */
4382 #undef TARGET_LITTLE_SYM
4383 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4384 #undef TARGET_LITTLE_NAME
4385 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4386 #undef TARGET_BIG_SYM
4387 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4388 #undef TARGET_BIG_NAME
4389 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4391 #undef elf_backend_add_symbol_hook
4392 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4394 #undef bfd_elfNN_bfd_link_add_symbols
4395 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4397 #define elfNN_bed elfNN_ia64_aix_bed
4399 #include "elfNN-target.h"