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
;
115 /* True if this hash entry's addends was translated for
116 SHF_MERGE optimization. */
117 unsigned sec_merge_done
: 1;
120 struct elfNN_ia64_local_hash_table
122 struct bfd_hash_table root
;
123 /* No additional fields for now. */
126 struct elfNN_ia64_link_hash_entry
128 struct elf_link_hash_entry root
;
129 struct elfNN_ia64_dyn_sym_info
*info
;
132 struct elfNN_ia64_link_hash_table
134 /* The main hash table */
135 struct elf_link_hash_table root
;
137 asection
*got_sec
; /* the linkage table section (or NULL) */
138 asection
*rel_got_sec
; /* dynamic relocation section for same */
139 asection
*fptr_sec
; /* function descriptor table (or NULL) */
140 asection
*plt_sec
; /* the primary plt section (or NULL) */
141 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
142 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
144 bfd_size_type minplt_entries
; /* number of minplt entries */
145 unsigned reltext
: 1; /* are there relocs against readonly sections? */
147 struct elfNN_ia64_local_hash_table loc_hash_table
;
150 #define elfNN_ia64_hash_table(p) \
151 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
153 static bfd_reloc_status_type elfNN_ia64_reloc
154 PARAMS ((bfd
*abfd
, arelent
*reloc
, asymbol
*sym
, PTR data
,
155 asection
*input_section
, bfd
*output_bfd
, char **error_message
));
156 static reloc_howto_type
* lookup_howto
157 PARAMS ((unsigned int rtype
));
158 static reloc_howto_type
*elfNN_ia64_reloc_type_lookup
159 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type bfd_code
));
160 static void elfNN_ia64_info_to_howto
161 PARAMS ((bfd
*abfd
, arelent
*bfd_reloc
, ElfNN_Internal_Rela
*elf_reloc
));
162 static boolean elfNN_ia64_relax_section
163 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
165 static boolean is_unwind_section_name
166 PARAMS ((const char *));
167 static boolean elfNN_ia64_section_from_shdr
168 PARAMS ((bfd
*, ElfNN_Internal_Shdr
*, char *));
169 static boolean elfNN_ia64_section_flags
170 PARAMS ((flagword
*, ElfNN_Internal_Shdr
*));
171 static boolean elfNN_ia64_fake_sections
172 PARAMS ((bfd
*abfd
, ElfNN_Internal_Shdr
*hdr
, asection
*sec
));
173 static void elfNN_ia64_final_write_processing
174 PARAMS ((bfd
*abfd
, boolean linker
));
175 static boolean elfNN_ia64_add_symbol_hook
176 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
177 const char **namep
, flagword
*flagsp
, asection
**secp
,
179 static boolean elfNN_ia64_aix_vec
180 PARAMS ((const bfd_target
*vec
));
181 static boolean elfNN_ia64_aix_add_symbol_hook
182 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
183 const char **namep
, flagword
*flagsp
, asection
**secp
,
185 static boolean elfNN_ia64_aix_link_add_symbols
186 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
187 static int elfNN_ia64_additional_program_headers
188 PARAMS ((bfd
*abfd
));
189 static boolean elfNN_ia64_modify_segment_map
191 static boolean elfNN_ia64_is_local_label_name
192 PARAMS ((bfd
*abfd
, const char *name
));
193 static boolean elfNN_ia64_dynamic_symbol_p
194 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
));
195 static boolean elfNN_ia64_local_hash_table_init
196 PARAMS ((struct elfNN_ia64_local_hash_table
*ht
, bfd
*abfd
,
197 new_hash_entry_func
new));
198 static struct bfd_hash_entry
*elfNN_ia64_new_loc_hash_entry
199 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
200 const char *string
));
201 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
202 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
203 const char *string
));
204 static void elfNN_ia64_hash_copy_indirect
205 PARAMS ((struct elf_link_hash_entry
*, struct elf_link_hash_entry
*));
206 static void elfNN_ia64_hash_hide_symbol
207 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*));
208 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
209 PARAMS ((bfd
*abfd
));
210 static struct elfNN_ia64_local_hash_entry
*elfNN_ia64_local_hash_lookup
211 PARAMS ((struct elfNN_ia64_local_hash_table
*table
, const char *string
,
212 boolean create
, boolean copy
));
213 static boolean elfNN_ia64_global_dyn_sym_thunk
214 PARAMS ((struct bfd_hash_entry
*, PTR
));
215 static boolean elfNN_ia64_local_dyn_sym_thunk
216 PARAMS ((struct bfd_hash_entry
*, PTR
));
217 static void elfNN_ia64_dyn_sym_traverse
218 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
219 boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
221 static boolean elfNN_ia64_create_dynamic_sections
222 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
223 static struct elfNN_ia64_local_hash_entry
* get_local_sym_hash
224 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
225 bfd
*abfd
, const Elf_Internal_Rela
*rel
, boolean create
));
226 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
227 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
228 struct elf_link_hash_entry
*h
,
229 bfd
*abfd
, const Elf_Internal_Rela
*rel
, boolean create
));
230 static asection
*get_got
231 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
232 struct elfNN_ia64_link_hash_table
*ia64_info
));
233 static asection
*get_fptr
234 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
235 struct elfNN_ia64_link_hash_table
*ia64_info
));
236 static asection
*get_pltoff
237 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
238 struct elfNN_ia64_link_hash_table
*ia64_info
));
239 static asection
*get_reloc_section
240 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
241 asection
*sec
, boolean create
));
242 static boolean count_dyn_reloc
243 PARAMS ((bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
244 asection
*srel
, int type
));
245 static boolean elfNN_ia64_check_relocs
246 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
247 const Elf_Internal_Rela
*relocs
));
248 static boolean elfNN_ia64_adjust_dynamic_symbol
249 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
250 static long global_sym_index
251 PARAMS ((struct elf_link_hash_entry
*h
));
252 static boolean allocate_fptr
253 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
254 static boolean allocate_global_data_got
255 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
256 static boolean allocate_global_fptr_got
257 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
258 static boolean allocate_local_got
259 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
260 static boolean allocate_pltoff_entries
261 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
262 static boolean allocate_plt_entries
263 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
264 static boolean allocate_plt2_entries
265 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
266 static boolean allocate_dynrel_entries
267 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
268 static boolean elfNN_ia64_size_dynamic_sections
269 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
270 static bfd_reloc_status_type elfNN_ia64_install_value
271 PARAMS ((bfd
*abfd
, bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
272 static void elfNN_ia64_install_dyn_reloc
273 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
274 asection
*srel
, bfd_vma offset
, unsigned int type
,
275 long dynindx
, bfd_vma addend
));
276 static bfd_vma set_got_entry
277 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
278 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
279 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
280 static bfd_vma set_fptr_entry
281 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
282 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
284 static bfd_vma set_pltoff_entry
285 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
286 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
287 bfd_vma value
, boolean
));
288 static int elfNN_ia64_unwind_entry_compare
289 PARAMS ((const PTR
, const PTR
));
290 static boolean elfNN_ia64_final_link
291 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
292 static boolean elfNN_ia64_relocate_section
293 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
294 asection
*input_section
, bfd_byte
*contents
,
295 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
296 asection
**local_sections
));
297 static boolean elfNN_ia64_finish_dynamic_symbol
298 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
299 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
300 static boolean elfNN_ia64_finish_dynamic_sections
301 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
302 static boolean elfNN_ia64_set_private_flags
303 PARAMS ((bfd
*abfd
, flagword flags
));
304 static boolean elfNN_ia64_merge_private_bfd_data
305 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
306 static boolean elfNN_ia64_print_private_bfd_data
307 PARAMS ((bfd
*abfd
, PTR ptr
));
308 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
309 PARAMS ((const Elf_Internal_Rela
*));
310 static void elfNN_hpux_post_process_headers
311 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
313 /* ia64-specific relocation */
315 /* Perform a relocation. Not much to do here as all the hard work is
316 done in elfNN_ia64_final_link_relocate. */
317 static bfd_reloc_status_type
318 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
319 output_bfd
, error_message
)
320 bfd
*abfd ATTRIBUTE_UNUSED
;
322 asymbol
*sym ATTRIBUTE_UNUSED
;
323 PTR data ATTRIBUTE_UNUSED
;
324 asection
*input_section
;
326 char **error_message
;
330 reloc
->address
+= input_section
->output_offset
;
333 *error_message
= "Unsupported call to elfNN_ia64_reloc";
334 return bfd_reloc_notsupported
;
337 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
338 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
339 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
341 /* This table has to be sorted according to increasing number of the
343 static reloc_howto_type ia64_howto_table
[] =
345 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, false, true),
347 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, false, true),
348 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, false, true),
349 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, false, true),
350 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, false, true),
351 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, false, true),
352 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, false, true),
353 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, false, true),
355 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, false, true),
356 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, false, true),
357 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, false, true),
358 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, false, true),
359 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, false, true),
360 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, false, true),
362 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, false, true),
363 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, false, true),
365 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, false, true),
366 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, false, true),
367 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, false, true),
368 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, false, true),
370 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, false, true),
371 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, false, true),
372 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, false, true),
373 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, false, true),
374 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, false, true),
376 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, true, true),
377 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, true, true),
378 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, true, true),
379 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, true, true),
380 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, true, true),
381 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, true, true),
382 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, true, true),
383 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, true, true),
385 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, false, true),
386 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, false, true),
387 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, false, true),
388 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, false, true),
389 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, false, true),
390 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, false, true),
392 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, false, true),
393 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, false, true),
394 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, false, true),
395 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, false, true),
397 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, false, true),
398 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, false, true),
399 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, false, true),
400 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, false, true),
402 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, false, true),
403 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, false, true),
404 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, false, true),
405 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, false, true),
407 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, false, true),
408 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, false, true),
409 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, false, true),
410 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, false, true),
412 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, true, true),
413 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, true, true),
414 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, true, true),
416 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, false, true),
417 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, false, true),
418 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, false, true),
419 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, false, true),
420 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, false, true),
422 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, false, false),
423 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, false, false),
424 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, false, false),
425 IA64_HOWTO (R_IA64_LTOFF_TP22
, "LTOFF_TP22", 0, false, false),
428 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
430 /* Given a BFD reloc type, return the matching HOWTO structure. */
432 static reloc_howto_type
*
436 static int inited
= 0;
443 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
444 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
445 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
448 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
449 i
= elf_code_to_howto_index
[rtype
];
450 if (i
>= NELEMS (ia64_howto_table
))
452 return ia64_howto_table
+ i
;
455 static reloc_howto_type
*
456 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
457 bfd
*abfd ATTRIBUTE_UNUSED
;
458 bfd_reloc_code_real_type bfd_code
;
464 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
466 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
467 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
468 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
470 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
471 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
472 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
473 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
475 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
476 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
477 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
478 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
479 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
480 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
482 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
483 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
485 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
486 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
487 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
488 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
489 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
490 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
491 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
492 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
493 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
495 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
496 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
497 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
498 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
499 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
500 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
501 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
502 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
503 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
504 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
505 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
507 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
508 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
509 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
510 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
511 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
512 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
514 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
515 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
516 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
517 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
519 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
520 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
521 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
522 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
524 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
525 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
526 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
527 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
529 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
530 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
531 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
532 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
534 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
535 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
536 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
537 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
538 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
540 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
541 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
542 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
543 case BFD_RELOC_IA64_LTOFF_TP22
: rtype
= R_IA64_LTOFF_TP22
; break;
547 return lookup_howto (rtype
);
550 /* Given a ELF reloc, return the matching HOWTO structure. */
553 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
554 bfd
*abfd ATTRIBUTE_UNUSED
;
556 ElfNN_Internal_Rela
*elf_reloc
;
559 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
562 #define PLT_HEADER_SIZE (3 * 16)
563 #define PLT_MIN_ENTRY_SIZE (1 * 16)
564 #define PLT_FULL_ENTRY_SIZE (2 * 16)
565 #define PLT_RESERVED_WORDS 3
567 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
569 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
570 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
571 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
572 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
573 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
574 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
575 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
576 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
577 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
580 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
582 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
583 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
584 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
587 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
589 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
590 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
591 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
592 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
593 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
594 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
597 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
598 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
599 #define DYNAMIC_INTERPRETER(abfd) \
600 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
602 /* Select out of range branch fixup type. Note that Itanium does
603 not support brl, and so it gets emulated by the kernel. */
606 static const bfd_byte oor_brl
[16] =
608 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
610 0x00, 0x00, 0x00, 0xc0
613 static const bfd_byte oor_ip
[48] =
615 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
616 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
617 0x01, 0x00, 0x00, 0x60,
618 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
619 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
620 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
621 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
622 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
623 0x60, 0x00, 0x80, 0x00 /* br b6;; */
626 /* These functions do relaxation for IA-64 ELF.
628 This is primarily to support branches to targets out of range;
629 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
632 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
635 struct bfd_link_info
*link_info
;
640 struct one_fixup
*next
;
646 Elf_Internal_Shdr
*symtab_hdr
;
647 Elf_Internal_Shdr
*shndx_hdr
;
648 Elf_Internal_Rela
*internal_relocs
;
649 Elf_Internal_Rela
*free_relocs
= NULL
;
650 Elf_Internal_Rela
*irel
, *irelend
;
652 bfd_byte
*free_contents
= NULL
;
653 ElfNN_External_Sym
*extsyms
;
654 ElfNN_External_Sym
*free_extsyms
= NULL
;
655 Elf_External_Sym_Shndx
*shndx_buf
= NULL
;
656 struct elfNN_ia64_link_hash_table
*ia64_info
;
657 struct one_fixup
*fixups
= NULL
;
658 boolean changed_contents
= false;
659 boolean changed_relocs
= false;
661 /* Assume we're not going to change any sizes, and we'll only need
665 /* Nothing to do if there are no relocations. */
666 if ((sec
->flags
& SEC_RELOC
) == 0
667 || sec
->reloc_count
== 0)
670 /* If this is the first time we have been called for this section,
671 initialize the cooked size. */
672 if (sec
->_cooked_size
== 0)
673 sec
->_cooked_size
= sec
->_raw_size
;
675 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
677 /* Load the relocations for this section. */
678 internal_relocs
= (_bfd_elfNN_link_read_relocs
679 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
680 link_info
->keep_memory
));
681 if (internal_relocs
== NULL
)
684 if (! link_info
->keep_memory
)
685 free_relocs
= internal_relocs
;
687 ia64_info
= elfNN_ia64_hash_table (link_info
);
688 irelend
= internal_relocs
+ sec
->reloc_count
;
690 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
691 if (ELFNN_R_TYPE (irel
->r_info
) == (int) R_IA64_PCREL21B
)
694 /* No branch-type relocations. */
697 if (free_relocs
!= NULL
)
702 /* Get the section contents. */
703 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
704 contents
= elf_section_data (sec
)->this_hdr
.contents
;
707 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
708 if (contents
== NULL
)
710 free_contents
= contents
;
712 if (! bfd_get_section_contents (abfd
, sec
, contents
,
713 (file_ptr
) 0, sec
->_raw_size
))
717 /* Read this BFD's local symbols. */
718 if (symtab_hdr
->contents
!= NULL
)
719 extsyms
= (ElfNN_External_Sym
*) symtab_hdr
->contents
;
724 amt
= symtab_hdr
->sh_info
* sizeof (ElfNN_External_Sym
);
725 extsyms
= (ElfNN_External_Sym
*) bfd_malloc (amt
);
728 free_extsyms
= extsyms
;
729 if (bfd_seek (abfd
, symtab_hdr
->sh_offset
, SEEK_SET
) != 0
730 || bfd_bread (extsyms
, amt
, abfd
) != amt
)
734 shndx_hdr
= &elf_tdata (abfd
)->symtab_shndx_hdr
;
735 if (shndx_hdr
->sh_size
!= 0)
739 amt
= symtab_hdr
->sh_info
* sizeof (Elf_External_Sym_Shndx
);
740 shndx_buf
= (Elf_External_Sym_Shndx
*) bfd_malloc (amt
);
741 if (shndx_buf
== NULL
)
743 if (bfd_seek (abfd
, shndx_hdr
->sh_offset
, SEEK_SET
) != 0
744 || bfd_bread (shndx_buf
, amt
, abfd
) != amt
)
748 for (; irel
< irelend
; irel
++)
750 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
751 Elf_Internal_Sym isym
;
756 if (ELFNN_R_TYPE (irel
->r_info
) != (int) R_IA64_PCREL21B
)
759 /* Get the value of the symbol referred to by the reloc. */
760 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
762 ElfNN_External_Sym
*esym
;
763 Elf_External_Sym_Shndx
*shndx
;
765 /* A local symbol. */
766 esym
= extsyms
+ ELFNN_R_SYM (irel
->r_info
);
767 shndx
= shndx_buf
+ (shndx_buf
? ELFNN_R_SYM (irel
->r_info
) : 0);
768 bfd_elfNN_swap_symbol_in (abfd
, esym
, shndx
, &isym
);
769 if (isym
.st_shndx
== SHN_UNDEF
)
770 continue; /* We can't do anthing with undefined symbols. */
771 else if (isym
.st_shndx
== SHN_ABS
)
772 tsec
= bfd_abs_section_ptr
;
773 else if (isym
.st_shndx
== SHN_COMMON
)
774 tsec
= bfd_com_section_ptr
;
776 tsec
= bfd_section_from_elf_index (abfd
, isym
.st_shndx
);
778 toff
= isym
.st_value
;
783 struct elf_link_hash_entry
*h
;
784 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
786 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
787 h
= elf_sym_hashes (abfd
)[indx
];
788 BFD_ASSERT (h
!= NULL
);
790 while (h
->root
.type
== bfd_link_hash_indirect
791 || h
->root
.type
== bfd_link_hash_warning
)
792 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
794 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, false);
796 /* For branches to dynamic symbols, we're interested instead
797 in a branch to the PLT entry. */
798 if (dyn_i
&& dyn_i
->want_plt2
)
800 tsec
= ia64_info
->plt_sec
;
801 toff
= dyn_i
->plt2_offset
;
805 /* We can't do anthing with undefined symbols. */
806 if (h
->root
.type
== bfd_link_hash_undefined
807 || h
->root
.type
== bfd_link_hash_undefweak
)
810 tsec
= h
->root
.u
.def
.section
;
811 toff
= h
->root
.u
.def
.value
;
815 symaddr
= (tsec
->output_section
->vma
816 + tsec
->output_offset
820 roff
= irel
->r_offset
;
821 reladdr
= (sec
->output_section
->vma
823 + roff
) & (bfd_vma
) -4;
825 /* If the branch is in range, no need to do anything. */
826 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
827 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
830 /* If the branch and target are in the same section, you've
831 got one honking big section and we can't help you. You'll
832 get an error message later. */
836 /* Look for an existing fixup to this address. */
837 for (f
= fixups
; f
; f
= f
->next
)
838 if (f
->tsec
== tsec
&& f
->toff
== toff
)
843 /* Two alternatives: If it's a branch to a PLT entry, we can
844 make a copy of the FULL_PLT entry. Otherwise, we'll have
845 to use a `brl' insn to get where we're going. */
849 if (tsec
== ia64_info
->plt_sec
)
850 size
= sizeof (plt_full_entry
);
854 size
= sizeof (oor_brl
);
856 size
= sizeof (oor_ip
);
860 /* Resize the current section to make room for the new branch. */
861 trampoff
= (sec
->_cooked_size
+ 15) & (bfd_vma
) -16;
862 amt
= trampoff
+ size
;
863 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
864 if (contents
== NULL
)
866 sec
->_cooked_size
= amt
;
868 if (tsec
== ia64_info
->plt_sec
)
870 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
872 /* Hijack the old relocation for use as the PLTOFF reloc. */
873 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
875 irel
->r_offset
= trampoff
;
880 memcpy (contents
+ trampoff
, oor_brl
, size
);
881 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
883 irel
->r_offset
= trampoff
+ 2;
885 memcpy (contents
+ trampoff
, oor_ip
, size
);
886 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
888 irel
->r_addend
-= 16;
889 irel
->r_offset
= trampoff
+ 2;
893 /* Record the fixup so we don't do it again this section. */
894 f
= (struct one_fixup
*) bfd_malloc ((bfd_size_type
) sizeof (*f
));
898 f
->trampoff
= trampoff
;
903 /* Nop out the reloc, since we're finalizing things here. */
904 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
907 /* Fix up the existing branch to hit the trampoline. Hope like
908 hell this doesn't overflow too. */
909 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
910 f
->trampoff
- (roff
& (bfd_vma
) -4),
911 R_IA64_PCREL21B
) != bfd_reloc_ok
)
914 changed_contents
= true;
915 changed_relocs
= true;
918 /* Clean up and go home. */
921 struct one_fixup
*f
= fixups
;
922 fixups
= fixups
->next
;
927 elf_section_data (sec
)->relocs
= internal_relocs
;
928 else if (free_relocs
!= NULL
)
931 if (changed_contents
)
932 elf_section_data (sec
)->this_hdr
.contents
= contents
;
933 else if (free_contents
!= NULL
)
935 if (! link_info
->keep_memory
)
936 free (free_contents
);
939 /* Cache the section contents for elf_link_input_bfd. */
940 elf_section_data (sec
)->this_hdr
.contents
= contents
;
944 if (shndx_buf
!= NULL
)
947 if (free_extsyms
!= NULL
)
949 if (! link_info
->keep_memory
)
953 /* Cache the symbols for elf_link_input_bfd. */
954 symtab_hdr
->contents
= (unsigned char *) extsyms
;
958 *again
= changed_contents
|| changed_relocs
;
962 if (free_relocs
!= NULL
)
964 if (free_contents
!= NULL
)
965 free (free_contents
);
966 if (shndx_buf
!= NULL
)
968 if (free_extsyms
!= NULL
)
973 /* Return true if NAME is an unwind table section name. */
975 static inline boolean
976 is_unwind_section_name (name
)
979 size_t len1
, len2
, len3
;
981 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
982 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
983 len3
= sizeof (ELF_STRING_ia64_unwind_once
) - 1;
984 return ((strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
985 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0)
986 || strncmp (name
, ELF_STRING_ia64_unwind_once
, len3
) == 0);
989 /* Handle an IA-64 specific section when reading an object file. This
990 is called when elfcode.h finds a section with an unknown type. */
993 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
995 ElfNN_Internal_Shdr
*hdr
;
1000 /* There ought to be a place to keep ELF backend specific flags, but
1001 at the moment there isn't one. We just keep track of the
1002 sections by their name, instead. Fortunately, the ABI gives
1003 suggested names for all the MIPS specific sections, so we will
1004 probably get away with this. */
1005 switch (hdr
->sh_type
)
1007 case SHT_IA_64_UNWIND
:
1011 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1019 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
1021 newsect
= hdr
->bfd_section
;
1026 /* Convert IA-64 specific section flags to bfd internal section flags. */
1028 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1032 elfNN_ia64_section_flags (flags
, hdr
)
1034 ElfNN_Internal_Shdr
*hdr
;
1036 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1037 *flags
|= SEC_SMALL_DATA
;
1042 /* Set the correct type for an IA-64 ELF section. We do this by the
1043 section name, which is a hack, but ought to work. */
1046 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1047 bfd
*abfd ATTRIBUTE_UNUSED
;
1048 ElfNN_Internal_Shdr
*hdr
;
1051 register const char *name
;
1053 name
= bfd_get_section_name (abfd
, sec
);
1055 if (is_unwind_section_name (name
))
1057 /* We don't have the sections numbered at this point, so sh_info
1058 is set later, in elfNN_ia64_final_write_processing. */
1059 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1060 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1062 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1063 hdr
->sh_type
= SHT_IA_64_EXT
;
1064 else if (strcmp (name
, ".reloc") == 0)
1066 * This is an ugly, but unfortunately necessary hack that is
1067 * needed when producing EFI binaries on IA-64. It tells
1068 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1069 * containing ELF relocation info. We need this hack in order to
1070 * be able to generate ELF binaries that can be translated into
1071 * EFI applications (which are essentially COFF objects). Those
1072 * files contain a COFF ".reloc" section inside an ELFNN object,
1073 * which would normally cause BFD to segfault because it would
1074 * attempt to interpret this section as containing relocation
1075 * entries for section "oc". With this hack enabled, ".reloc"
1076 * will be treated as a normal data section, which will avoid the
1077 * segfault. However, you won't be able to create an ELFNN binary
1078 * with a section named "oc" that needs relocations, but that's
1079 * the kind of ugly side-effects you get when detecting section
1080 * types based on their names... In practice, this limitation is
1083 hdr
->sh_type
= SHT_PROGBITS
;
1085 if (sec
->flags
& SEC_SMALL_DATA
)
1086 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1091 /* The final processing done just before writing out an IA-64 ELF
1095 elfNN_ia64_final_write_processing (abfd
, linker
)
1097 boolean linker ATTRIBUTE_UNUSED
;
1099 Elf_Internal_Shdr
*hdr
;
1101 asection
*text_sect
, *s
;
1104 for (s
= abfd
->sections
; s
; s
= s
->next
)
1106 hdr
= &elf_section_data (s
)->this_hdr
;
1107 switch (hdr
->sh_type
)
1109 case SHT_IA_64_UNWIND
:
1110 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1112 sname
= bfd_get_section_name (abfd
, s
);
1113 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1114 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1118 if (sname
[0] == '\0')
1119 /* .IA_64.unwind -> .text */
1120 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1122 /* .IA_64.unwindFOO -> FOO */
1123 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1126 && (len
= sizeof (ELF_STRING_ia64_unwind_once
) - 1,
1127 strncmp (sname
, ELF_STRING_ia64_unwind_once
, len
)) == 0)
1129 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1130 size_t len2
= sizeof (".gnu.linkonce.t.") - 1;
1131 char *once_name
= bfd_malloc (len2
+ strlen (sname
+ len
) + 1);
1133 if (once_name
!= NULL
)
1135 memcpy (once_name
, ".gnu.linkonce.t.", len2
);
1136 strcpy (once_name
+ len2
, sname
+ len
);
1137 text_sect
= bfd_get_section_by_name (abfd
, once_name
);
1141 /* Should only happen if we run out of memory, in
1142 which case we're probably toast anyway. Try to
1143 cope by finding the section the slow way. */
1144 for (text_sect
= abfd
->sections
;
1146 text_sect
= text_sect
->next
)
1148 if (strncmp (bfd_section_name (abfd
, text_sect
),
1149 ".gnu.linkonce.t.", len2
) == 0
1150 && strcmp (bfd_section_name (abfd
, text_sect
) + len2
,
1156 /* last resort: fall back on .text */
1157 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1161 /* The IA-64 processor-specific ABI requires setting
1162 sh_link to the unwind section, whereas HP-UX requires
1163 sh_info to do so. For maximum compatibility, we'll
1164 set both for now... */
1165 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1166 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1173 /* Hook called by the linker routine which adds symbols from an object
1174 file. We use it to put .comm items in .sbss, and not .bss. */
1177 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1179 struct bfd_link_info
*info
;
1180 const Elf_Internal_Sym
*sym
;
1181 const char **namep ATTRIBUTE_UNUSED
;
1182 flagword
*flagsp ATTRIBUTE_UNUSED
;
1186 if (sym
->st_shndx
== SHN_COMMON
1187 && !info
->relocateable
1188 && sym
->st_size
<= elf_gp_size (abfd
))
1190 /* Common symbols less than or equal to -G nn bytes are
1191 automatically put into .sbss. */
1193 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1197 scomm
= bfd_make_section (abfd
, ".scommon");
1199 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1201 | SEC_LINKER_CREATED
)))
1206 *valp
= sym
->st_size
;
1213 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1215 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1216 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1218 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1219 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1222 /* Hook called by the linker routine which adds symbols from an object
1223 file. We use it to handle OS-specific symbols. */
1226 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1228 struct bfd_link_info
*info
;
1229 const Elf_Internal_Sym
*sym
;
1235 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1237 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1238 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1239 no one else should use it b/c it is undocumented. */
1240 struct elf_link_hash_entry
*h
;
1242 h
= elf_link_hash_lookup (elf_hash_table (info
), *namep
,
1243 false, false, false);
1246 struct elf_backend_data
*bed
;
1247 struct elfNN_ia64_link_hash_table
*ia64_info
;
1249 bed
= get_elf_backend_data (abfd
);
1250 ia64_info
= elfNN_ia64_hash_table (info
);
1252 if (!(_bfd_generic_link_add_one_symbol
1253 (info
, abfd
, *namep
, BSF_GLOBAL
,
1254 bfd_get_section_by_name (abfd
, ".bss"),
1255 bed
->got_symbol_offset
, (const char *) NULL
, false,
1256 bed
->collect
, (struct bfd_link_hash_entry
**) &h
)))
1259 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1260 h
->type
= STT_OBJECT
;
1262 if (! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1268 else if (sym
->st_shndx
== SHN_LOOS
)
1272 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1273 is only relevant when compiling code for extended system calls.
1274 Replace the "special" section with .text, if possible.
1275 Note that these symbols are always assumed to be in .text. */
1276 for (i
= 1; i
< elf_numsections (abfd
); i
++)
1278 asection
* sec
= bfd_section_from_elf_index (abfd
, i
);
1280 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1288 *secp
= bfd_abs_section_ptr
;
1290 *valp
= sym
->st_size
;
1296 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1297 namep
, flagsp
, secp
, valp
);
1302 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1304 struct bfd_link_info
*info
;
1306 /* Make sure dynamic sections are always created. */
1307 if (! elf_hash_table (info
)->dynamic_sections_created
1308 && abfd
->xvec
== info
->hash
->creator
)
1310 if (! bfd_elfNN_link_create_dynamic_sections (abfd
, info
))
1314 /* Now do the standard call. */
1315 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1318 /* Return the number of additional phdrs we will need. */
1321 elfNN_ia64_additional_program_headers (abfd
)
1327 /* See if we need a PT_IA_64_ARCHEXT segment. */
1328 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1329 if (s
&& (s
->flags
& SEC_LOAD
))
1332 /* Count how many PT_IA_64_UNWIND segments we need. */
1333 for (s
= abfd
->sections
; s
; s
= s
->next
)
1334 if (is_unwind_section_name(s
->name
) && (s
->flags
& SEC_LOAD
))
1341 elfNN_ia64_modify_segment_map (abfd
)
1344 struct elf_segment_map
*m
, **pm
;
1345 Elf_Internal_Shdr
*hdr
;
1348 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1349 all PT_LOAD segments. */
1350 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1351 if (s
&& (s
->flags
& SEC_LOAD
))
1353 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1354 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1358 m
= ((struct elf_segment_map
*)
1359 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1363 m
->p_type
= PT_IA_64_ARCHEXT
;
1367 /* We want to put it after the PHDR and INTERP segments. */
1368 pm
= &elf_tdata (abfd
)->segment_map
;
1370 && ((*pm
)->p_type
== PT_PHDR
1371 || (*pm
)->p_type
== PT_INTERP
))
1379 /* Install PT_IA_64_UNWIND segments, if needed. */
1380 for (s
= abfd
->sections
; s
; s
= s
->next
)
1382 hdr
= &elf_section_data (s
)->this_hdr
;
1383 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1386 if (s
&& (s
->flags
& SEC_LOAD
))
1388 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1389 if (m
->p_type
== PT_IA_64_UNWIND
&& m
->sections
[0] == s
)
1394 m
= ((struct elf_segment_map
*)
1395 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1399 m
->p_type
= PT_IA_64_UNWIND
;
1404 /* We want to put it last. */
1405 pm
= &elf_tdata (abfd
)->segment_map
;
1413 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1414 the input sections for each output section in the segment and testing
1415 for SHF_IA_64_NORECOV on each. */
1416 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1417 if (m
->p_type
== PT_LOAD
)
1420 for (i
= m
->count
- 1; i
>= 0; --i
)
1422 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1425 if (order
->type
== bfd_indirect_link_order
)
1427 asection
*is
= order
->u
.indirect
.section
;
1428 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1429 if (flags
& SHF_IA_64_NORECOV
)
1431 m
->p_flags
|= PF_IA_64_NORECOV
;
1435 order
= order
->next
;
1444 /* According to the Tahoe assembler spec, all labels starting with a
1448 elfNN_ia64_is_local_label_name (abfd
, name
)
1449 bfd
*abfd ATTRIBUTE_UNUSED
;
1452 return name
[0] == '.';
1455 /* Should we do dynamic things to this symbol? */
1458 elfNN_ia64_dynamic_symbol_p (h
, info
)
1459 struct elf_link_hash_entry
*h
;
1460 struct bfd_link_info
*info
;
1465 while (h
->root
.type
== bfd_link_hash_indirect
1466 || h
->root
.type
== bfd_link_hash_warning
)
1467 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1469 if (h
->dynindx
== -1)
1471 switch (ELF_ST_VISIBILITY (h
->other
))
1478 if (h
->root
.type
== bfd_link_hash_undefweak
1479 || h
->root
.type
== bfd_link_hash_defweak
)
1482 if ((info
->shared
&& (!info
->symbolic
|| info
->allow_shlib_undefined
))
1483 || ((h
->elf_link_hash_flags
1484 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1485 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1492 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1493 struct elfNN_ia64_local_hash_table
*ht
;
1494 bfd
*abfd ATTRIBUTE_UNUSED
;
1495 new_hash_entry_func
new;
1497 memset (ht
, 0, sizeof (*ht
));
1498 return bfd_hash_table_init (&ht
->root
, new);
1501 static struct bfd_hash_entry
*
1502 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1503 struct bfd_hash_entry
*entry
;
1504 struct bfd_hash_table
*table
;
1507 struct elfNN_ia64_local_hash_entry
*ret
;
1508 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1510 /* Allocate the structure if it has not already been allocated by a
1513 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1518 /* Initialize our local data. All zeros, and definitely easier
1519 than setting a handful of bit fields. */
1520 memset (ret
, 0, sizeof (*ret
));
1522 /* Call the allocation method of the superclass. */
1523 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1524 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1526 return (struct bfd_hash_entry
*) ret
;
1529 static struct bfd_hash_entry
*
1530 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1531 struct bfd_hash_entry
*entry
;
1532 struct bfd_hash_table
*table
;
1535 struct elfNN_ia64_link_hash_entry
*ret
;
1536 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1538 /* Allocate the structure if it has not already been allocated by a
1541 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1546 /* Initialize our local data. All zeros, and definitely easier
1547 than setting a handful of bit fields. */
1548 memset (ret
, 0, sizeof (*ret
));
1550 /* Call the allocation method of the superclass. */
1551 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1552 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1555 return (struct bfd_hash_entry
*) ret
;
1559 elfNN_ia64_hash_copy_indirect (xdir
, xind
)
1560 struct elf_link_hash_entry
*xdir
, *xind
;
1562 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1564 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1565 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1567 /* Copy down any references that we may have already seen to the
1568 symbol which just became indirect. */
1570 dir
->root
.elf_link_hash_flags
|=
1571 (ind
->root
.elf_link_hash_flags
1572 & (ELF_LINK_HASH_REF_DYNAMIC
1573 | ELF_LINK_HASH_REF_REGULAR
1574 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1576 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1579 /* Copy over the got and plt data. This would have been done
1582 if (dir
->info
== NULL
)
1584 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1586 dir
->info
= dyn_i
= ind
->info
;
1589 /* Fix up the dyn_sym_info pointers to the global symbol. */
1590 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1591 dyn_i
->h
= &dir
->root
;
1593 BFD_ASSERT (ind
->info
== NULL
);
1595 /* Copy over the dynindx. */
1597 if (dir
->root
.dynindx
== -1)
1599 dir
->root
.dynindx
= ind
->root
.dynindx
;
1600 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1601 ind
->root
.dynindx
= -1;
1602 ind
->root
.dynstr_index
= 0;
1604 BFD_ASSERT (ind
->root
.dynindx
== -1);
1608 elfNN_ia64_hash_hide_symbol (info
, xh
)
1609 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1610 struct elf_link_hash_entry
*xh
;
1612 struct elfNN_ia64_link_hash_entry
*h
;
1613 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1615 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1617 h
->root
.elf_link_hash_flags
&= ~ELF_LINK_HASH_NEEDS_PLT
;
1618 if ((h
->root
.elf_link_hash_flags
& ELF_LINK_FORCED_LOCAL
) != 0)
1619 h
->root
.dynindx
= -1;
1621 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1622 dyn_i
->want_plt2
= 0;
1625 /* Create the derived linker hash table. The IA-64 ELF port uses this
1626 derived hash table to keep information specific to the IA-64 ElF
1627 linker (without using static variables). */
1629 static struct bfd_link_hash_table
*
1630 elfNN_ia64_hash_table_create (abfd
)
1633 struct elfNN_ia64_link_hash_table
*ret
;
1635 ret
= bfd_zalloc (abfd
, (bfd_size_type
) sizeof (*ret
));
1638 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1639 elfNN_ia64_new_elf_hash_entry
))
1641 bfd_release (abfd
, ret
);
1645 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1646 elfNN_ia64_new_loc_hash_entry
))
1648 return &ret
->root
.root
;
1651 /* Look up an entry in a Alpha ELF linker hash table. */
1653 static INLINE
struct elfNN_ia64_local_hash_entry
*
1654 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1655 struct elfNN_ia64_local_hash_table
*table
;
1657 boolean create
, copy
;
1659 return ((struct elfNN_ia64_local_hash_entry
*)
1660 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1663 /* Traverse both local and global hash tables. */
1665 struct elfNN_ia64_dyn_sym_traverse_data
1667 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1672 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1673 struct bfd_hash_entry
*xentry
;
1676 struct elfNN_ia64_link_hash_entry
*entry
1677 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1678 struct elfNN_ia64_dyn_sym_traverse_data
*data
1679 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1680 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1682 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1683 if (! (*data
->func
) (dyn_i
, data
->data
))
1689 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1690 struct bfd_hash_entry
*xentry
;
1693 struct elfNN_ia64_local_hash_entry
*entry
1694 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1695 struct elfNN_ia64_dyn_sym_traverse_data
*data
1696 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1697 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1699 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1700 if (! (*data
->func
) (dyn_i
, data
->data
))
1706 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1707 struct elfNN_ia64_link_hash_table
*ia64_info
;
1708 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1711 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1716 elf_link_hash_traverse (&ia64_info
->root
,
1717 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1718 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1719 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1723 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1725 struct bfd_link_info
*info
;
1727 struct elfNN_ia64_link_hash_table
*ia64_info
;
1730 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1733 ia64_info
= elfNN_ia64_hash_table (info
);
1735 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1736 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1739 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1740 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1743 if (!get_pltoff (abfd
, info
, ia64_info
))
1746 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1748 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1751 | SEC_LINKER_CREATED
1753 || !bfd_set_section_alignment (abfd
, s
, 3))
1755 ia64_info
->rel_pltoff_sec
= s
;
1757 s
= bfd_make_section(abfd
, ".rela.got");
1759 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1762 | SEC_LINKER_CREATED
1764 || !bfd_set_section_alignment (abfd
, s
, 3))
1766 ia64_info
->rel_got_sec
= s
;
1771 /* Find and/or create a hash entry for local symbol. */
1772 static struct elfNN_ia64_local_hash_entry
*
1773 get_local_sym_hash (ia64_info
, abfd
, rel
, create
)
1774 struct elfNN_ia64_link_hash_table
*ia64_info
;
1776 const Elf_Internal_Rela
*rel
;
1781 struct elfNN_ia64_local_hash_entry
*ret
;
1783 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1784 name describes what was once anonymous memory. */
1786 len
= sizeof (void*)*2 + 1 + sizeof (bfd_vma
)*4 + 1 + 1;
1787 len
+= 10; /* %p slop */
1789 addr_name
= bfd_malloc (len
);
1790 if (addr_name
== NULL
)
1792 sprintf (addr_name
, "%p:%lx",
1793 (void *) abfd
, (unsigned long) ELFNN_R_SYM (rel
->r_info
));
1795 /* Collect the canonical entry data for this address. */
1796 ret
= elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1797 addr_name
, create
, create
);
1802 /* Find and/or create a descriptor for dynamic symbol info. This will
1803 vary based on global or local symbol, and the addend to the reloc. */
1805 static struct elfNN_ia64_dyn_sym_info
*
1806 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1807 struct elfNN_ia64_link_hash_table
*ia64_info
;
1808 struct elf_link_hash_entry
*h
;
1810 const Elf_Internal_Rela
*rel
;
1813 struct elfNN_ia64_dyn_sym_info
**pp
;
1814 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1815 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1818 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1821 struct elfNN_ia64_local_hash_entry
*loc_h
;
1823 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
1829 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
1832 if (dyn_i
== NULL
&& create
)
1834 dyn_i
= ((struct elfNN_ia64_dyn_sym_info
*)
1835 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *dyn_i
));
1837 dyn_i
->addend
= addend
;
1844 get_got (abfd
, info
, ia64_info
)
1846 struct bfd_link_info
*info
;
1847 struct elfNN_ia64_link_hash_table
*ia64_info
;
1852 got
= ia64_info
->got_sec
;
1857 dynobj
= ia64_info
->root
.dynobj
;
1859 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1860 if (!_bfd_elf_create_got_section (dynobj
, info
))
1863 got
= bfd_get_section_by_name (dynobj
, ".got");
1865 ia64_info
->got_sec
= got
;
1867 flags
= bfd_get_section_flags (abfd
, got
);
1868 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
1874 /* Create function descriptor section (.opd). This section is called .opd
1875 because it contains "official prodecure descriptors". The "official"
1876 refers to the fact that these descriptors are used when taking the address
1877 of a procedure, thus ensuring a unique address for each procedure. */
1880 get_fptr (abfd
, info
, ia64_info
)
1882 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1883 struct elfNN_ia64_link_hash_table
*ia64_info
;
1888 fptr
= ia64_info
->fptr_sec
;
1891 dynobj
= ia64_info
->root
.dynobj
;
1893 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1895 fptr
= bfd_make_section (dynobj
, ".opd");
1897 || !bfd_set_section_flags (dynobj
, fptr
,
1903 | SEC_LINKER_CREATED
))
1904 || !bfd_set_section_alignment (abfd
, fptr
, 4))
1910 ia64_info
->fptr_sec
= fptr
;
1917 get_pltoff (abfd
, info
, ia64_info
)
1919 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1920 struct elfNN_ia64_link_hash_table
*ia64_info
;
1925 pltoff
= ia64_info
->pltoff_sec
;
1928 dynobj
= ia64_info
->root
.dynobj
;
1930 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1932 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
1934 || !bfd_set_section_flags (dynobj
, pltoff
,
1940 | SEC_LINKER_CREATED
))
1941 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
1947 ia64_info
->pltoff_sec
= pltoff
;
1954 get_reloc_section (abfd
, ia64_info
, sec
, create
)
1956 struct elfNN_ia64_link_hash_table
*ia64_info
;
1960 const char *srel_name
;
1964 srel_name
= (bfd_elf_string_from_elf_section
1965 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
1966 elf_section_data(sec
)->rel_hdr
.sh_name
));
1967 if (srel_name
== NULL
)
1970 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
1971 && strcmp (bfd_get_section_name (abfd
, sec
),
1973 || (strncmp (srel_name
, ".rel", 4) == 0
1974 && strcmp (bfd_get_section_name (abfd
, sec
),
1975 srel_name
+4) == 0));
1977 dynobj
= ia64_info
->root
.dynobj
;
1979 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1981 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
1982 if (srel
== NULL
&& create
)
1984 srel
= bfd_make_section (dynobj
, srel_name
);
1986 || !bfd_set_section_flags (dynobj
, srel
,
1991 | SEC_LINKER_CREATED
1993 || !bfd_set_section_alignment (dynobj
, srel
, 3))
1997 if (sec
->flags
& SEC_READONLY
)
1998 ia64_info
->reltext
= 1;
2004 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
2006 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2010 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2012 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2013 if (rent
->srel
== srel
&& rent
->type
== type
)
2018 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
2019 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
2023 rent
->next
= dyn_i
->reloc_entries
;
2027 dyn_i
->reloc_entries
= rent
;
2035 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
2037 struct bfd_link_info
*info
;
2039 const Elf_Internal_Rela
*relocs
;
2041 struct elfNN_ia64_link_hash_table
*ia64_info
;
2042 const Elf_Internal_Rela
*relend
;
2043 Elf_Internal_Shdr
*symtab_hdr
;
2044 const Elf_Internal_Rela
*rel
;
2045 asection
*got
, *fptr
, *srel
;
2047 if (info
->relocateable
)
2050 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2051 ia64_info
= elfNN_ia64_hash_table (info
);
2053 got
= fptr
= srel
= NULL
;
2055 relend
= relocs
+ sec
->reloc_count
;
2056 for (rel
= relocs
; rel
< relend
; ++rel
)
2065 NEED_LTOFF_FPTR
= 64,
2068 struct elf_link_hash_entry
*h
= NULL
;
2069 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2070 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2072 boolean maybe_dynamic
;
2073 int dynrel_type
= R_IA64_NONE
;
2075 if (r_symndx
>= symtab_hdr
->sh_info
)
2077 /* We're dealing with a global symbol -- find its hash entry
2078 and mark it as being referenced. */
2079 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2080 h
= elf_sym_hashes (abfd
)[indx
];
2081 while (h
->root
.type
== bfd_link_hash_indirect
2082 || h
->root
.type
== bfd_link_hash_warning
)
2083 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2085 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
2088 /* We can only get preliminary data on whether a symbol is
2089 locally or externally defined, as not all of the input files
2090 have yet been processed. Do something with what we know, as
2091 this may help reduce memory usage and processing time later. */
2092 maybe_dynamic
= false;
2093 if (h
&& ((info
->shared
2094 && (!info
->symbolic
|| info
->allow_shlib_undefined
))
2095 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
2096 || h
->root
.type
== bfd_link_hash_defweak
2097 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2098 maybe_dynamic
= true;
2101 switch (ELFNN_R_TYPE (rel
->r_info
))
2103 case R_IA64_TPREL22
:
2104 case R_IA64_TPREL64MSB
:
2105 case R_IA64_TPREL64LSB
:
2106 case R_IA64_LTOFF_TP22
:
2109 case R_IA64_LTOFF_FPTR22
:
2110 case R_IA64_LTOFF_FPTR64I
:
2111 case R_IA64_LTOFF_FPTR32MSB
:
2112 case R_IA64_LTOFF_FPTR32LSB
:
2113 case R_IA64_LTOFF_FPTR64MSB
:
2114 case R_IA64_LTOFF_FPTR64LSB
:
2115 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2118 case R_IA64_FPTR64I
:
2119 case R_IA64_FPTR32MSB
:
2120 case R_IA64_FPTR32LSB
:
2121 case R_IA64_FPTR64MSB
:
2122 case R_IA64_FPTR64LSB
:
2123 if (info
->shared
|| h
|| elfNN_ia64_aix_vec (abfd
->xvec
))
2124 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2126 need_entry
= NEED_FPTR
;
2127 dynrel_type
= R_IA64_FPTR64LSB
;
2130 case R_IA64_LTOFF22
:
2131 case R_IA64_LTOFF22X
:
2132 case R_IA64_LTOFF64I
:
2133 need_entry
= NEED_GOT
;
2136 case R_IA64_PLTOFF22
:
2137 case R_IA64_PLTOFF64I
:
2138 case R_IA64_PLTOFF64MSB
:
2139 case R_IA64_PLTOFF64LSB
:
2140 need_entry
= NEED_PLTOFF
;
2144 need_entry
|= NEED_MIN_PLT
;
2148 (*info
->callbacks
->warning
)
2149 (info
, _("@pltoff reloc against local symbol"), 0,
2150 abfd
, 0, (bfd_vma
) 0);
2154 case R_IA64_PCREL21B
:
2155 case R_IA64_PCREL60B
:
2156 /* Depending on where this symbol is defined, we may or may not
2157 need a full plt entry. Only skip if we know we'll not need
2158 the entry -- static or symbolic, and the symbol definition
2159 has already been seen. */
2160 if (maybe_dynamic
&& rel
->r_addend
== 0)
2161 need_entry
= NEED_FULL_PLT
;
2167 case R_IA64_DIR32MSB
:
2168 case R_IA64_DIR32LSB
:
2169 case R_IA64_DIR64MSB
:
2170 case R_IA64_DIR64LSB
:
2171 /* Shared objects will always need at least a REL relocation. */
2172 if (info
->shared
|| maybe_dynamic
2173 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2174 && (!h
|| strcmp (h
->root
.root
.string
,
2175 "__GLOB_DATA_PTR") != 0)))
2176 need_entry
= NEED_DYNREL
;
2177 dynrel_type
= R_IA64_DIR64LSB
;
2180 case R_IA64_IPLTMSB
:
2181 case R_IA64_IPLTLSB
:
2182 /* Shared objects will always need at least a REL relocation. */
2183 if (info
->shared
|| maybe_dynamic
)
2184 need_entry
= NEED_DYNREL
;
2185 dynrel_type
= R_IA64_IPLTLSB
;
2188 case R_IA64_PCREL22
:
2189 case R_IA64_PCREL64I
:
2190 case R_IA64_PCREL32MSB
:
2191 case R_IA64_PCREL32LSB
:
2192 case R_IA64_PCREL64MSB
:
2193 case R_IA64_PCREL64LSB
:
2195 need_entry
= NEED_DYNREL
;
2196 dynrel_type
= R_IA64_PCREL64LSB
;
2203 if ((need_entry
& NEED_FPTR
) != 0
2206 (*info
->callbacks
->warning
)
2207 (info
, _("non-zero addend in @fptr reloc"), 0,
2208 abfd
, 0, (bfd_vma
) 0);
2211 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, true);
2213 /* Record whether or not this is a local symbol. */
2216 /* Create what's needed. */
2217 if (need_entry
& NEED_GOT
)
2221 got
= get_got (abfd
, info
, ia64_info
);
2225 dyn_i
->want_got
= 1;
2227 if (need_entry
& NEED_FPTR
)
2231 fptr
= get_fptr (abfd
, info
, ia64_info
);
2236 /* FPTRs for shared libraries are allocated by the dynamic
2237 linker. Make sure this local symbol will appear in the
2238 dynamic symbol table. */
2239 if (!h
&& (info
->shared
2240 /* AIX also needs one */
2241 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2243 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2244 (info
, abfd
, (long) r_symndx
)))
2248 dyn_i
->want_fptr
= 1;
2250 if (need_entry
& NEED_LTOFF_FPTR
)
2251 dyn_i
->want_ltoff_fptr
= 1;
2252 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2254 if (!ia64_info
->root
.dynobj
)
2255 ia64_info
->root
.dynobj
= abfd
;
2256 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2257 dyn_i
->want_plt
= 1;
2259 if (need_entry
& NEED_FULL_PLT
)
2260 dyn_i
->want_plt2
= 1;
2261 if (need_entry
& NEED_PLTOFF
)
2262 dyn_i
->want_pltoff
= 1;
2263 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2267 srel
= get_reloc_section (abfd
, ia64_info
, sec
, true);
2271 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2279 struct elfNN_ia64_allocate_data
2281 struct bfd_link_info
*info
;
2285 /* For cleanliness, and potentially faster dynamic loading, allocate
2286 external GOT entries first. */
2289 allocate_global_data_got (dyn_i
, data
)
2290 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2293 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2296 && ! dyn_i
->want_fptr
2297 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2298 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2299 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2300 "__GLOB_DATA_PTR") != 0))))
2302 dyn_i
->got_offset
= x
->ofs
;
2308 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2311 allocate_global_fptr_got (dyn_i
, data
)
2312 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2315 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2319 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2320 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2322 dyn_i
->got_offset
= x
->ofs
;
2328 /* Lastly, allocate all the GOT entries for local data. */
2331 allocate_local_got (dyn_i
, data
)
2332 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2335 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2338 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2339 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2341 dyn_i
->got_offset
= x
->ofs
;
2347 /* Search for the index of a global symbol in it's defining object file. */
2350 global_sym_index (h
)
2351 struct elf_link_hash_entry
*h
;
2353 struct elf_link_hash_entry
**p
;
2356 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2357 || h
->root
.type
== bfd_link_hash_defweak
);
2359 obj
= h
->root
.u
.def
.section
->owner
;
2360 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2363 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2366 /* Allocate function descriptors. We can do these for every function
2367 in a main executable that is not exported. */
2370 allocate_fptr (dyn_i
, data
)
2371 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2374 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2376 if (dyn_i
->want_fptr
)
2378 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2381 while (h
->root
.type
== bfd_link_hash_indirect
2382 || h
->root
.type
== bfd_link_hash_warning
)
2383 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2386 /* AIX needs an FPTR in this case. */
2387 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2389 || h
->root
.type
== bfd_link_hash_defined
2390 || h
->root
.type
== bfd_link_hash_defweak
)))
2392 if (h
&& h
->dynindx
== -1)
2394 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2395 || (h
->root
.type
== bfd_link_hash_defweak
));
2397 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2398 (x
->info
, h
->root
.u
.def
.section
->owner
,
2399 global_sym_index (h
)))
2403 dyn_i
->want_fptr
= 0;
2405 else if (h
== NULL
|| h
->dynindx
== -1)
2407 dyn_i
->fptr_offset
= x
->ofs
;
2411 dyn_i
->want_fptr
= 0;
2416 /* Allocate all the minimal PLT entries. */
2419 allocate_plt_entries (dyn_i
, data
)
2420 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2423 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2425 if (dyn_i
->want_plt
)
2427 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2430 while (h
->root
.type
== bfd_link_hash_indirect
2431 || h
->root
.type
== bfd_link_hash_warning
)
2432 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2434 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2435 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2437 bfd_size_type offset
= x
->ofs
;
2439 offset
= PLT_HEADER_SIZE
;
2440 dyn_i
->plt_offset
= offset
;
2441 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2443 dyn_i
->want_pltoff
= 1;
2447 dyn_i
->want_plt
= 0;
2448 dyn_i
->want_plt2
= 0;
2454 /* Allocate all the full PLT entries. */
2457 allocate_plt2_entries (dyn_i
, data
)
2458 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2461 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2463 if (dyn_i
->want_plt2
)
2465 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2466 bfd_size_type ofs
= x
->ofs
;
2468 dyn_i
->plt2_offset
= ofs
;
2469 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2471 while (h
->root
.type
== bfd_link_hash_indirect
2472 || h
->root
.type
== bfd_link_hash_warning
)
2473 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2474 dyn_i
->h
->plt
.offset
= ofs
;
2479 /* Allocate all the PLTOFF entries requested by relocations and
2480 plt entries. We can't share space with allocated FPTR entries,
2481 because the latter are not necessarily addressable by the GP.
2482 ??? Relaxation might be able to determine that they are. */
2485 allocate_pltoff_entries (dyn_i
, data
)
2486 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2489 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2491 if (dyn_i
->want_pltoff
)
2493 dyn_i
->pltoff_offset
= x
->ofs
;
2499 /* Allocate dynamic relocations for those symbols that turned out
2503 allocate_dynrel_entries (dyn_i
, data
)
2504 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2507 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2508 struct elfNN_ia64_link_hash_table
*ia64_info
;
2509 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2510 boolean dynamic_symbol
, shared
;
2512 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2513 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2514 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2515 /* Don't allocate an entry for __GLOB_DATA_PTR */
2516 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2517 "__GLOB_DATA_PTR") != 0));
2518 shared
= x
->info
->shared
;
2520 /* Take care of the normal data relocations. */
2522 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2524 int count
= rent
->count
;
2528 case R_IA64_FPTR64LSB
:
2529 /* Allocate one iff !want_fptr, which by this point will
2530 be true only if we're actually allocating one statically
2531 in the main executable. */
2532 if (dyn_i
->want_fptr
)
2535 case R_IA64_PCREL64LSB
:
2536 if (!dynamic_symbol
)
2539 case R_IA64_DIR64LSB
:
2540 if (!dynamic_symbol
&& !shared
)
2543 case R_IA64_IPLTLSB
:
2544 if (!dynamic_symbol
&& !shared
)
2546 /* Use two REL relocations for IPLT relocations
2547 against local symbols. */
2548 if (!dynamic_symbol
)
2554 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2557 /* Take care of the GOT and PLT relocations. */
2559 if (((dynamic_symbol
|| shared
) && dyn_i
->want_got
)
2560 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2561 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2563 if (dyn_i
->want_pltoff
)
2565 bfd_size_type t
= 0;
2567 /* Dynamic symbols get one IPLT relocation. Local symbols in
2568 shared libraries get two REL relocations. Local symbols in
2569 main applications get nothing. */
2571 t
= sizeof (ElfNN_External_Rela
);
2573 t
= 2 * sizeof (ElfNN_External_Rela
);
2575 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2582 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2583 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2584 struct elf_link_hash_entry
*h
;
2586 /* ??? Undefined symbols with PLT entries should be re-defined
2587 to be the PLT entry. */
2589 /* If this is a weak symbol, and there is a real definition, the
2590 processor independent code will have arranged for us to see the
2591 real definition first, and we can just use the same value. */
2592 if (h
->weakdef
!= NULL
)
2594 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2595 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2596 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2597 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2601 /* If this is a reference to a symbol defined by a dynamic object which
2602 is not a function, we might allocate the symbol in our .dynbss section
2603 and allocate a COPY dynamic relocation.
2605 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2612 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2614 struct bfd_link_info
*info
;
2616 struct elfNN_ia64_allocate_data data
;
2617 struct elfNN_ia64_link_hash_table
*ia64_info
;
2620 boolean relplt
= false;
2622 dynobj
= elf_hash_table(info
)->dynobj
;
2623 ia64_info
= elfNN_ia64_hash_table (info
);
2624 BFD_ASSERT(dynobj
!= NULL
);
2627 /* Set the contents of the .interp section to the interpreter. */
2628 if (ia64_info
->root
.dynamic_sections_created
2631 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2632 BFD_ASSERT (sec
!= NULL
);
2633 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2634 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2637 /* Allocate the GOT entries. */
2639 if (ia64_info
->got_sec
)
2642 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2643 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2644 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2645 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2648 /* Allocate the FPTR entries. */
2650 if (ia64_info
->fptr_sec
)
2653 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2654 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2657 /* Now that we've seen all of the input files, we can decide which
2658 symbols need plt entries. Allocate the minimal PLT entries first.
2659 We do this even though dynamic_sections_created may be false, because
2660 this has the side-effect of clearing want_plt and want_plt2. */
2663 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2665 ia64_info
->minplt_entries
= 0;
2668 ia64_info
->minplt_entries
2669 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2672 /* Align the pointer for the plt2 entries. */
2673 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
2675 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2678 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2680 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2682 /* If we've got a .plt, we need some extra memory for the dynamic
2683 linker. We stuff these in .got.plt. */
2684 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2685 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2688 /* Allocate the PLTOFF entries. */
2690 if (ia64_info
->pltoff_sec
)
2693 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2694 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2697 if (ia64_info
->root
.dynamic_sections_created
)
2699 /* Allocate space for the dynamic relocations that turned out to be
2702 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2705 /* We have now determined the sizes of the various dynamic sections.
2706 Allocate memory for them. */
2707 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2711 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2714 /* If we don't need this section, strip it from the output file.
2715 There were several sections primarily related to dynamic
2716 linking that must be create before the linker maps input
2717 sections to output sections. The linker does that before
2718 bfd_elf_size_dynamic_sections is called, and it is that
2719 function which decides whether anything needs to go into
2722 strip
= (sec
->_raw_size
== 0);
2724 if (sec
== ia64_info
->got_sec
)
2726 else if (sec
== ia64_info
->rel_got_sec
)
2729 ia64_info
->rel_got_sec
= NULL
;
2731 /* We use the reloc_count field as a counter if we need to
2732 copy relocs into the output file. */
2733 sec
->reloc_count
= 0;
2735 else if (sec
== ia64_info
->fptr_sec
)
2738 ia64_info
->fptr_sec
= NULL
;
2740 else if (sec
== ia64_info
->plt_sec
)
2743 ia64_info
->plt_sec
= NULL
;
2745 else if (sec
== ia64_info
->pltoff_sec
)
2748 ia64_info
->pltoff_sec
= NULL
;
2750 else if (sec
== ia64_info
->rel_pltoff_sec
)
2753 ia64_info
->rel_pltoff_sec
= NULL
;
2757 /* We use the reloc_count field as a counter if we need to
2758 copy relocs into the output file. */
2759 sec
->reloc_count
= 0;
2766 /* It's OK to base decisions on the section name, because none
2767 of the dynobj section names depend upon the input files. */
2768 name
= bfd_get_section_name (dynobj
, sec
);
2770 if (strcmp (name
, ".got.plt") == 0)
2772 else if (strncmp (name
, ".rel", 4) == 0)
2776 /* We use the reloc_count field as a counter if we need to
2777 copy relocs into the output file. */
2778 sec
->reloc_count
= 0;
2786 _bfd_strip_section_from_output (info
, sec
);
2789 /* Allocate memory for the section contents. */
2790 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->_raw_size
);
2791 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
2796 if (elf_hash_table (info
)->dynamic_sections_created
)
2798 /* Add some entries to the .dynamic section. We fill in the values
2799 later (in finish_dynamic_sections) but we must add the entries now
2800 so that we get the correct size for the .dynamic section. */
2804 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2806 #define add_dynamic_entry(TAG, VAL) \
2807 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
2809 if (!add_dynamic_entry (DT_DEBUG
, 0))
2813 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
2815 if (!add_dynamic_entry (DT_PLTGOT
, 0))
2820 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
2821 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
2822 || !add_dynamic_entry (DT_JMPREL
, 0))
2826 if (!add_dynamic_entry (DT_RELA
, 0)
2827 || !add_dynamic_entry (DT_RELASZ
, 0)
2828 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
2831 if (ia64_info
->reltext
)
2833 if (!add_dynamic_entry (DT_TEXTREL
, 0))
2835 info
->flags
|= DF_TEXTREL
;
2839 /* ??? Perhaps force __gp local. */
2844 static bfd_reloc_status_type
2845 elfNN_ia64_install_value (abfd
, hit_addr
, v
, r_type
)
2849 unsigned int r_type
;
2851 const struct ia64_operand
*op
;
2852 int bigendian
= 0, shift
= 0;
2853 bfd_vma t0
, t1
, insn
, dword
;
2854 enum ia64_opnd opnd
;
2857 #ifdef BFD_HOST_U_64_BIT
2858 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
2863 opnd
= IA64_OPND_NIL
;
2868 return bfd_reloc_ok
;
2870 /* Instruction relocations. */
2872 case R_IA64_IMM14
: opnd
= IA64_OPND_IMM14
; break;
2874 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
2875 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
2876 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
2877 case R_IA64_PCREL21B
:
2878 case R_IA64_PCREL21BI
:
2879 opnd
= IA64_OPND_TGT25c
;
2883 case R_IA64_GPREL22
:
2884 case R_IA64_LTOFF22
:
2885 case R_IA64_LTOFF22X
:
2886 case R_IA64_PLTOFF22
:
2887 case R_IA64_PCREL22
:
2888 case R_IA64_LTOFF_FPTR22
:
2889 opnd
= IA64_OPND_IMM22
;
2893 case R_IA64_GPREL64I
:
2894 case R_IA64_LTOFF64I
:
2895 case R_IA64_PLTOFF64I
:
2896 case R_IA64_PCREL64I
:
2897 case R_IA64_FPTR64I
:
2898 case R_IA64_LTOFF_FPTR64I
:
2899 opnd
= IA64_OPND_IMMU64
;
2902 /* Data relocations. */
2904 case R_IA64_DIR32MSB
:
2905 case R_IA64_GPREL32MSB
:
2906 case R_IA64_FPTR32MSB
:
2907 case R_IA64_PCREL32MSB
:
2908 case R_IA64_LTOFF_FPTR32MSB
:
2909 case R_IA64_SEGREL32MSB
:
2910 case R_IA64_SECREL32MSB
:
2911 case R_IA64_LTV32MSB
:
2912 size
= 4; bigendian
= 1;
2915 case R_IA64_DIR32LSB
:
2916 case R_IA64_GPREL32LSB
:
2917 case R_IA64_FPTR32LSB
:
2918 case R_IA64_PCREL32LSB
:
2919 case R_IA64_LTOFF_FPTR32LSB
:
2920 case R_IA64_SEGREL32LSB
:
2921 case R_IA64_SECREL32LSB
:
2922 case R_IA64_LTV32LSB
:
2923 size
= 4; bigendian
= 0;
2926 case R_IA64_DIR64MSB
:
2927 case R_IA64_GPREL64MSB
:
2928 case R_IA64_PLTOFF64MSB
:
2929 case R_IA64_FPTR64MSB
:
2930 case R_IA64_PCREL64MSB
:
2931 case R_IA64_LTOFF_FPTR64MSB
:
2932 case R_IA64_SEGREL64MSB
:
2933 case R_IA64_SECREL64MSB
:
2934 case R_IA64_LTV64MSB
:
2935 size
= 8; bigendian
= 1;
2938 case R_IA64_DIR64LSB
:
2939 case R_IA64_GPREL64LSB
:
2940 case R_IA64_PLTOFF64LSB
:
2941 case R_IA64_FPTR64LSB
:
2942 case R_IA64_PCREL64LSB
:
2943 case R_IA64_LTOFF_FPTR64LSB
:
2944 case R_IA64_SEGREL64LSB
:
2945 case R_IA64_SECREL64LSB
:
2946 case R_IA64_LTV64LSB
:
2947 size
= 8; bigendian
= 0;
2950 /* Unsupported / Dynamic relocations. */
2952 return bfd_reloc_notsupported
;
2957 case IA64_OPND_IMMU64
:
2958 hit_addr
-= (long) hit_addr
& 0x3;
2959 t0
= bfd_get_64 (abfd
, hit_addr
);
2960 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2962 /* tmpl/s: bits 0.. 5 in t0
2963 slot 0: bits 5..45 in t0
2964 slot 1: bits 46..63 in t0, bits 0..22 in t1
2965 slot 2: bits 23..63 in t1 */
2967 /* First, clear the bits that form the 64 bit constant. */
2968 t0
&= ~(0x3ffffLL
<< 46);
2970 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
2971 | (0x01fLL
<< 22) | (0x001LL
<< 21)
2972 | (0x001LL
<< 36)) << 23));
2974 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
2975 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
2976 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
2977 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
2978 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
2979 | (((val
>> 21) & 0x001) << 21) /* ic */
2980 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
2982 bfd_put_64 (abfd
, t0
, hit_addr
);
2983 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2986 case IA64_OPND_TGT64
:
2987 hit_addr
-= (long) hit_addr
& 0x3;
2988 t0
= bfd_get_64 (abfd
, hit_addr
);
2989 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2991 /* tmpl/s: bits 0.. 5 in t0
2992 slot 0: bits 5..45 in t0
2993 slot 1: bits 46..63 in t0, bits 0..22 in t1
2994 slot 2: bits 23..63 in t1 */
2996 /* First, clear the bits that form the 64 bit constant. */
2997 t0
&= ~(0x3ffffLL
<< 46);
2999 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
3002 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
3003 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
3004 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
3005 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
3007 bfd_put_64 (abfd
, t0
, hit_addr
);
3008 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3012 switch ((long) hit_addr
& 0x3)
3014 case 0: shift
= 5; break;
3015 case 1: shift
= 14; hit_addr
+= 3; break;
3016 case 2: shift
= 23; hit_addr
+= 6; break;
3017 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
3019 dword
= bfd_get_64 (abfd
, hit_addr
);
3020 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
3022 op
= elf64_ia64_operands
+ opnd
;
3023 err
= (*op
->insert
) (op
, val
, (ia64_insn
*)& insn
);
3025 return bfd_reloc_overflow
;
3027 dword
&= ~(0x1ffffffffffLL
<< shift
);
3028 dword
|= (insn
<< shift
);
3029 bfd_put_64 (abfd
, dword
, hit_addr
);
3033 /* A data relocation. */
3036 bfd_putb32 (val
, hit_addr
);
3038 bfd_putb64 (val
, hit_addr
);
3041 bfd_putl32 (val
, hit_addr
);
3043 bfd_putl64 (val
, hit_addr
);
3047 return bfd_reloc_ok
;
3051 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
3054 struct bfd_link_info
*info
;
3062 Elf_Internal_Rela outrel
;
3064 offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3066 BFD_ASSERT (dynindx
!= -1);
3067 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3068 outrel
.r_addend
= addend
;
3069 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3070 if (outrel
.r_offset
== (bfd_vma
) -1)
3072 /* Run for the hills. We shouldn't be outputting a relocation
3073 for this. So do what everyone else does and output a no-op. */
3074 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3075 outrel
.r_addend
= 0;
3076 outrel
.r_offset
= 0;
3079 bfd_elfNN_swap_reloca_out (abfd
, &outrel
,
3080 ((ElfNN_External_Rela
*) srel
->contents
3081 + srel
->reloc_count
++));
3082 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3083 <= srel
->_cooked_size
);
3086 /* Store an entry for target address TARGET_ADDR in the linkage table
3087 and return the gp-relative address of the linkage table entry. */
3090 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3092 struct bfd_link_info
*info
;
3093 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3097 unsigned int dyn_r_type
;
3099 struct elfNN_ia64_link_hash_table
*ia64_info
;
3102 ia64_info
= elfNN_ia64_hash_table (info
);
3103 got_sec
= ia64_info
->got_sec
;
3105 BFD_ASSERT ((dyn_i
->got_offset
& 7) == 0);
3107 if (! dyn_i
->got_done
)
3109 dyn_i
->got_done
= true;
3111 /* Store the target address in the linkage table entry. */
3112 bfd_put_64 (abfd
, value
, got_sec
->contents
+ dyn_i
->got_offset
);
3114 /* Install a dynamic relocation if needed. */
3116 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3117 || elfNN_ia64_aix_vec (abfd
->xvec
)
3118 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3122 dyn_r_type
= R_IA64_REL64LSB
;
3127 if (bfd_big_endian (abfd
))
3131 case R_IA64_REL64LSB
:
3132 dyn_r_type
= R_IA64_REL64MSB
;
3134 case R_IA64_DIR64LSB
:
3135 dyn_r_type
= R_IA64_DIR64MSB
;
3137 case R_IA64_FPTR64LSB
:
3138 dyn_r_type
= R_IA64_FPTR64MSB
;
3146 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3147 ia64_info
->rel_got_sec
,
3148 dyn_i
->got_offset
, dyn_r_type
,
3153 /* Return the address of the linkage table entry. */
3154 value
= (got_sec
->output_section
->vma
3155 + got_sec
->output_offset
3156 + dyn_i
->got_offset
);
3161 /* Fill in a function descriptor consisting of the function's code
3162 address and its global pointer. Return the descriptor's address. */
3165 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3167 struct bfd_link_info
*info
;
3168 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3171 struct elfNN_ia64_link_hash_table
*ia64_info
;
3174 ia64_info
= elfNN_ia64_hash_table (info
);
3175 fptr_sec
= ia64_info
->fptr_sec
;
3177 if (!dyn_i
->fptr_done
)
3179 dyn_i
->fptr_done
= 1;
3181 /* Fill in the function descriptor. */
3182 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3183 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3184 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3187 /* Return the descriptor's address. */
3188 value
= (fptr_sec
->output_section
->vma
3189 + fptr_sec
->output_offset
3190 + dyn_i
->fptr_offset
);
3195 /* Fill in a PLTOFF entry consisting of the function's code address
3196 and its global pointer. Return the descriptor's address. */
3199 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3201 struct bfd_link_info
*info
;
3202 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3206 struct elfNN_ia64_link_hash_table
*ia64_info
;
3207 asection
*pltoff_sec
;
3209 ia64_info
= elfNN_ia64_hash_table (info
);
3210 pltoff_sec
= ia64_info
->pltoff_sec
;
3212 /* Don't do anything if this symbol uses a real PLT entry. In
3213 that case, we'll fill this in during finish_dynamic_symbol. */
3214 if ((! dyn_i
->want_plt
|| is_plt
)
3215 && !dyn_i
->pltoff_done
)
3217 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3219 /* Fill in the function descriptor. */
3220 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3221 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3223 /* Install dynamic relocations if needed. */
3224 if (!is_plt
&& info
->shared
)
3226 unsigned int dyn_r_type
;
3228 if (bfd_big_endian (abfd
))
3229 dyn_r_type
= R_IA64_REL64MSB
;
3231 dyn_r_type
= R_IA64_REL64LSB
;
3233 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3234 ia64_info
->rel_pltoff_sec
,
3235 dyn_i
->pltoff_offset
,
3236 dyn_r_type
, 0, value
);
3237 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3238 ia64_info
->rel_pltoff_sec
,
3239 dyn_i
->pltoff_offset
+ 8,
3243 dyn_i
->pltoff_done
= 1;
3246 /* Return the descriptor's address. */
3247 value
= (pltoff_sec
->output_section
->vma
3248 + pltoff_sec
->output_offset
3249 + dyn_i
->pltoff_offset
);
3254 /* Called through qsort to sort the .IA_64.unwind section during a
3255 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3256 to the output bfd so we can do proper endianness frobbing. */
3258 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3261 elfNN_ia64_unwind_entry_compare (a
, b
)
3267 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3268 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3270 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3274 elfNN_ia64_final_link (abfd
, info
)
3276 struct bfd_link_info
*info
;
3278 struct elfNN_ia64_link_hash_table
*ia64_info
;
3279 asection
*unwind_output_sec
;
3281 ia64_info
= elfNN_ia64_hash_table (info
);
3283 /* Make sure we've got ourselves a nice fat __gp value. */
3284 if (!info
->relocateable
)
3286 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3287 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3288 struct elf_link_hash_entry
*gp
;
3292 /* Find the min and max vma of all sections marked short. Also
3293 collect min and max vma of any type, for use in selecting a
3295 for (os
= abfd
->sections
; os
; os
= os
->next
)
3299 if ((os
->flags
& SEC_ALLOC
) == 0)
3303 hi
= os
->vma
+ os
->_raw_size
;
3311 if (os
->flags
& SEC_SMALL_DATA
)
3313 if (min_short_vma
> lo
)
3315 if (max_short_vma
< hi
)
3320 /* See if the user wants to force a value. */
3321 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", false,
3325 && (gp
->root
.type
== bfd_link_hash_defined
3326 || gp
->root
.type
== bfd_link_hash_defweak
))
3328 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3329 gp_val
= (gp
->root
.u
.def
.value
3330 + gp_sec
->output_section
->vma
3331 + gp_sec
->output_offset
);
3335 /* Pick a sensible value. */
3337 asection
*got_sec
= ia64_info
->got_sec
;
3339 /* Start with just the address of the .got. */
3341 gp_val
= got_sec
->output_section
->vma
;
3342 else if (max_short_vma
!= 0)
3343 gp_val
= min_short_vma
;
3347 /* If it is possible to address the entire image, but we
3348 don't with the choice above, adjust. */
3349 if (max_vma
- min_vma
< 0x400000
3350 && max_vma
- gp_val
<= 0x200000
3351 && gp_val
- min_vma
> 0x200000)
3352 gp_val
= min_vma
+ 0x200000;
3353 else if (max_short_vma
!= 0)
3355 /* If we don't cover all the short data, adjust. */
3356 if (max_short_vma
- gp_val
>= 0x200000)
3357 gp_val
= min_short_vma
+ 0x200000;
3359 /* If we're addressing stuff past the end, adjust back. */
3360 if (gp_val
> max_vma
)
3361 gp_val
= max_vma
- 0x200000 + 8;
3365 /* Validate whether all SHF_IA_64_SHORT sections are within
3366 range of the chosen GP. */
3368 if (max_short_vma
!= 0)
3370 if (max_short_vma
- min_short_vma
>= 0x400000)
3372 (*_bfd_error_handler
)
3373 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3374 bfd_get_filename (abfd
),
3375 (unsigned long) (max_short_vma
- min_short_vma
));
3378 else if ((gp_val
> min_short_vma
3379 && gp_val
- min_short_vma
> 0x200000)
3380 || (gp_val
< max_short_vma
3381 && max_short_vma
- gp_val
>= 0x200000))
3383 (*_bfd_error_handler
)
3384 (_("%s: __gp does not cover short data segment"),
3385 bfd_get_filename (abfd
));
3390 _bfd_set_gp_value (abfd
, gp_val
);
3394 gp
->root
.type
= bfd_link_hash_defined
;
3395 gp
->root
.u
.def
.value
= gp_val
;
3396 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3400 /* If we're producing a final executable, we need to sort the contents
3401 of the .IA_64.unwind section. Force this section to be relocated
3402 into memory rather than written immediately to the output file. */
3403 unwind_output_sec
= NULL
;
3404 if (!info
->relocateable
)
3406 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3409 unwind_output_sec
= s
->output_section
;
3410 unwind_output_sec
->contents
3411 = bfd_malloc (unwind_output_sec
->_raw_size
);
3412 if (unwind_output_sec
->contents
== NULL
)
3417 /* Invoke the regular ELF backend linker to do all the work. */
3418 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3421 if (unwind_output_sec
)
3423 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3424 qsort (unwind_output_sec
->contents
,
3425 (size_t) (unwind_output_sec
->_raw_size
/ 24),
3427 elfNN_ia64_unwind_entry_compare
);
3429 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3430 unwind_output_sec
->contents
, (bfd_vma
) 0,
3431 unwind_output_sec
->_raw_size
))
3439 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3440 contents
, relocs
, local_syms
, local_sections
)
3442 struct bfd_link_info
*info
;
3444 asection
*input_section
;
3446 Elf_Internal_Rela
*relocs
;
3447 Elf_Internal_Sym
*local_syms
;
3448 asection
**local_sections
;
3450 struct elfNN_ia64_link_hash_table
*ia64_info
;
3451 Elf_Internal_Shdr
*symtab_hdr
;
3452 Elf_Internal_Rela
*rel
;
3453 Elf_Internal_Rela
*relend
;
3455 boolean ret_val
= true; /* for non-fatal errors */
3458 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3459 ia64_info
= elfNN_ia64_hash_table (info
);
3461 /* Infect various flags from the input section to the output section. */
3462 if (info
->relocateable
)
3466 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3467 flags
&= SHF_IA_64_NORECOV
;
3469 elf_section_data(input_section
->output_section
)
3470 ->this_hdr
.sh_flags
|= flags
;
3473 gp_val
= _bfd_get_gp_value (output_bfd
);
3474 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, false);
3477 relend
= relocs
+ input_section
->reloc_count
;
3478 for (; rel
< relend
; ++rel
)
3480 struct elf_link_hash_entry
*h
;
3481 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3482 bfd_reloc_status_type r
;
3483 reloc_howto_type
*howto
;
3484 unsigned long r_symndx
;
3485 Elf_Internal_Sym
*sym
;
3486 unsigned int r_type
;
3490 boolean dynamic_symbol_p
;
3491 boolean undef_weak_ref
;
3493 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3494 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3496 (*_bfd_error_handler
)
3497 (_("%s: unknown relocation type %d"),
3498 bfd_archive_filename (input_bfd
), (int)r_type
);
3499 bfd_set_error (bfd_error_bad_value
);
3503 howto
= lookup_howto (r_type
);
3504 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3506 if (info
->relocateable
)
3508 /* This is a relocateable link. We don't have to change
3509 anything, unless the reloc is against a section symbol,
3510 in which case we have to adjust according to where the
3511 section symbol winds up in the output section. */
3512 if (r_symndx
< symtab_hdr
->sh_info
)
3514 sym
= local_syms
+ r_symndx
;
3515 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
3517 sym_sec
= local_sections
[r_symndx
];
3518 rel
->r_addend
+= sym_sec
->output_offset
;
3524 /* This is a final link. */
3529 undef_weak_ref
= false;
3531 if (r_symndx
< symtab_hdr
->sh_info
)
3533 /* Reloc against local symbol. */
3534 sym
= local_syms
+ r_symndx
;
3535 sym_sec
= local_sections
[r_symndx
];
3536 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, sym_sec
, rel
);
3537 if ((sym_sec
->flags
& SEC_MERGE
)
3538 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
3539 && (elf_section_data (sym_sec
)->sec_info_type
3540 == ELF_INFO_TYPE_MERGE
))
3542 struct elfNN_ia64_local_hash_entry
*loc_h
;
3544 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, false);
3545 if (loc_h
&& ! loc_h
->sec_merge_done
)
3547 struct elfNN_ia64_dyn_sym_info
*dynent
;
3550 for (dynent
= loc_h
->info
; dynent
; dynent
= dynent
->next
)
3554 _bfd_merged_section_offset (output_bfd
, &msec
,
3555 elf_section_data (msec
)->
3560 dynent
->addend
-= sym
->st_value
;
3561 dynent
->addend
+= msec
->output_section
->vma
3562 + msec
->output_offset
3563 - sym_sec
->output_section
->vma
3564 - sym_sec
->output_offset
;
3566 loc_h
->sec_merge_done
= 1;
3574 /* Reloc against global symbol. */
3575 indx
= r_symndx
- symtab_hdr
->sh_info
;
3576 h
= elf_sym_hashes (input_bfd
)[indx
];
3577 while (h
->root
.type
== bfd_link_hash_indirect
3578 || h
->root
.type
== bfd_link_hash_warning
)
3579 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3582 if (h
->root
.type
== bfd_link_hash_defined
3583 || h
->root
.type
== bfd_link_hash_defweak
)
3585 sym_sec
= h
->root
.u
.def
.section
;
3587 /* Detect the cases that sym_sec->output_section is
3588 expected to be NULL -- all cases in which the symbol
3589 is defined in another shared module. This includes
3590 PLT relocs for which we've created a PLT entry and
3591 other relocs for which we're prepared to create
3592 dynamic relocations. */
3593 /* ??? Just accept it NULL and continue. */
3595 if (sym_sec
->output_section
!= NULL
)
3597 value
= (h
->root
.u
.def
.value
3598 + sym_sec
->output_section
->vma
3599 + sym_sec
->output_offset
);
3602 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3603 undef_weak_ref
= true;
3604 else if (info
->shared
3605 && (!info
->symbolic
|| info
->allow_shlib_undefined
)
3606 && !info
->no_undefined
3607 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3611 if (! ((*info
->callbacks
->undefined_symbol
)
3612 (info
, h
->root
.root
.string
, input_bfd
,
3613 input_section
, rel
->r_offset
,
3614 (!info
->shared
|| info
->no_undefined
3615 || ELF_ST_VISIBILITY (h
->other
)))))
3622 hit_addr
= contents
+ rel
->r_offset
;
3623 value
+= rel
->r_addend
;
3624 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3635 case R_IA64_DIR32MSB
:
3636 case R_IA64_DIR32LSB
:
3637 case R_IA64_DIR64MSB
:
3638 case R_IA64_DIR64LSB
:
3639 /* Install a dynamic relocation for this reloc. */
3640 if ((dynamic_symbol_p
|| info
->shared
3641 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
3642 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3643 && (!h
|| strcmp (h
->root
.root
.string
,
3644 "__GLOB_DATA_PTR") != 0)))
3646 && (input_section
->flags
& SEC_ALLOC
) != 0)
3648 unsigned int dyn_r_type
;
3652 BFD_ASSERT (srel
!= NULL
);
3654 /* If we don't need dynamic symbol lookup, find a
3655 matching RELATIVE relocation. */
3656 dyn_r_type
= r_type
;
3657 if (dynamic_symbol_p
)
3659 dynindx
= h
->dynindx
;
3660 addend
= rel
->r_addend
;
3667 case R_IA64_DIR32MSB
:
3668 dyn_r_type
= R_IA64_REL32MSB
;
3670 case R_IA64_DIR32LSB
:
3671 dyn_r_type
= R_IA64_REL32LSB
;
3673 case R_IA64_DIR64MSB
:
3674 dyn_r_type
= R_IA64_REL64MSB
;
3676 case R_IA64_DIR64LSB
:
3677 dyn_r_type
= R_IA64_REL64LSB
;
3681 /* We can't represent this without a dynamic symbol.
3682 Adjust the relocation to be against an output
3683 section symbol, which are always present in the
3684 dynamic symbol table. */
3685 /* ??? People shouldn't be doing non-pic code in
3686 shared libraries. Hork. */
3687 (*_bfd_error_handler
)
3688 (_("%s: linking non-pic code in a shared library"),
3689 bfd_archive_filename (input_bfd
));
3697 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
3698 rel
->r_addend
= value
;
3699 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3700 srel
, rel
->r_offset
, dyn_r_type
,
3705 case R_IA64_LTV32MSB
:
3706 case R_IA64_LTV32LSB
:
3707 case R_IA64_LTV64MSB
:
3708 case R_IA64_LTV64LSB
:
3709 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3712 case R_IA64_GPREL22
:
3713 case R_IA64_GPREL64I
:
3714 case R_IA64_GPREL32MSB
:
3715 case R_IA64_GPREL32LSB
:
3716 case R_IA64_GPREL64MSB
:
3717 case R_IA64_GPREL64LSB
:
3718 if (dynamic_symbol_p
)
3720 (*_bfd_error_handler
)
3721 (_("%s: @gprel relocation against dynamic symbol %s"),
3722 bfd_archive_filename (input_bfd
), h
->root
.root
.string
);
3727 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3730 case R_IA64_LTOFF22
:
3731 case R_IA64_LTOFF22X
:
3732 case R_IA64_LTOFF64I
:
3733 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3734 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
3735 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
3737 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3740 case R_IA64_PLTOFF22
:
3741 case R_IA64_PLTOFF64I
:
3742 case R_IA64_PLTOFF64MSB
:
3743 case R_IA64_PLTOFF64LSB
:
3744 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3745 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, false);
3747 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3750 case R_IA64_FPTR64I
:
3751 case R_IA64_FPTR32MSB
:
3752 case R_IA64_FPTR32LSB
:
3753 case R_IA64_FPTR64MSB
:
3754 case R_IA64_FPTR64LSB
:
3755 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3756 if (dyn_i
->want_fptr
)
3758 if (!undef_weak_ref
)
3759 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3765 /* Otherwise, we expect the dynamic linker to create
3770 if (h
->dynindx
!= -1)
3771 dynindx
= h
->dynindx
;
3773 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3774 (info
, h
->root
.u
.def
.section
->owner
,
3775 global_sym_index (h
)));
3779 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3780 (info
, input_bfd
, (long) r_symndx
));
3783 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3784 srel
, rel
->r_offset
, r_type
,
3785 dynindx
, rel
->r_addend
);
3789 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3792 case R_IA64_LTOFF_FPTR22
:
3793 case R_IA64_LTOFF_FPTR64I
:
3794 case R_IA64_LTOFF_FPTR32MSB
:
3795 case R_IA64_LTOFF_FPTR32LSB
:
3796 case R_IA64_LTOFF_FPTR64MSB
:
3797 case R_IA64_LTOFF_FPTR64LSB
:
3801 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3802 if (dyn_i
->want_fptr
)
3804 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
3805 if (!undef_weak_ref
)
3806 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3811 /* Otherwise, we expect the dynamic linker to create
3815 if (h
->dynindx
!= -1)
3816 dynindx
= h
->dynindx
;
3818 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3819 (info
, h
->root
.u
.def
.section
->owner
,
3820 global_sym_index (h
)));
3823 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3824 (info
, input_bfd
, (long) r_symndx
));
3828 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
3829 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
3831 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3835 case R_IA64_PCREL32MSB
:
3836 case R_IA64_PCREL32LSB
:
3837 case R_IA64_PCREL64MSB
:
3838 case R_IA64_PCREL64LSB
:
3839 /* Install a dynamic relocation for this reloc. */
3840 if ((dynamic_symbol_p
3841 || elfNN_ia64_aix_vec (info
->hash
->creator
))
3844 BFD_ASSERT (srel
!= NULL
);
3846 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3847 srel
, rel
->r_offset
, r_type
,
3848 h
->dynindx
, rel
->r_addend
);
3852 case R_IA64_PCREL21BI
:
3853 case R_IA64_PCREL21F
:
3854 case R_IA64_PCREL21M
:
3855 /* ??? These two are only used for speculation fixup code.
3856 They should never be dynamic. */
3857 if (dynamic_symbol_p
)
3859 (*_bfd_error_handler
)
3860 (_("%s: dynamic relocation against speculation fixup"),
3861 bfd_archive_filename (input_bfd
));
3867 (*_bfd_error_handler
)
3868 (_("%s: speculation fixup against undefined weak symbol"),
3869 bfd_archive_filename (input_bfd
));
3875 case R_IA64_PCREL21B
:
3876 case R_IA64_PCREL60B
:
3877 /* We should have created a PLT entry for any dynamic symbol. */
3880 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
3882 if (dyn_i
&& dyn_i
->want_plt2
)
3884 /* Should have caught this earlier. */
3885 BFD_ASSERT (rel
->r_addend
== 0);
3887 value
= (ia64_info
->plt_sec
->output_section
->vma
3888 + ia64_info
->plt_sec
->output_offset
3889 + dyn_i
->plt2_offset
);
3893 /* Since there's no PLT entry, Validate that this is
3895 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
3897 /* If the symbol is undef_weak, we shouldn't be trying
3898 to call it. There's every chance that we'd wind up
3899 with an out-of-range fixup here. Don't bother setting
3900 any value at all. */
3906 case R_IA64_PCREL22
:
3907 case R_IA64_PCREL64I
:
3909 /* Make pc-relative. */
3910 value
-= (input_section
->output_section
->vma
3911 + input_section
->output_offset
3912 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
3913 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3916 case R_IA64_SEGREL32MSB
:
3917 case R_IA64_SEGREL32LSB
:
3918 case R_IA64_SEGREL64MSB
:
3919 case R_IA64_SEGREL64LSB
:
3922 /* If the input section was discarded from the output, then
3928 struct elf_segment_map
*m
;
3929 Elf_Internal_Phdr
*p
;
3931 /* Find the segment that contains the output_section. */
3932 for (m
= elf_tdata (output_bfd
)->segment_map
,
3933 p
= elf_tdata (output_bfd
)->phdr
;
3938 for (i
= m
->count
- 1; i
>= 0; i
--)
3939 if (m
->sections
[i
] == sym_sec
->output_section
)
3947 r
= bfd_reloc_notsupported
;
3951 /* The VMA of the segment is the vaddr of the associated
3953 if (value
> p
->p_vaddr
)
3954 value
-= p
->p_vaddr
;
3957 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
3963 case R_IA64_SECREL32MSB
:
3964 case R_IA64_SECREL32LSB
:
3965 case R_IA64_SECREL64MSB
:
3966 case R_IA64_SECREL64LSB
:
3967 /* Make output-section relative. */
3968 if (value
> input_section
->output_section
->vma
)
3969 value
-= input_section
->output_section
->vma
;
3972 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3975 case R_IA64_IPLTMSB
:
3976 case R_IA64_IPLTLSB
:
3977 /* Install a dynamic relocation for this reloc. */
3978 if ((dynamic_symbol_p
|| info
->shared
)
3979 && (input_section
->flags
& SEC_ALLOC
) != 0)
3981 BFD_ASSERT (srel
!= NULL
);
3983 /* If we don't need dynamic symbol lookup, install two
3984 RELATIVE relocations. */
3985 if (! dynamic_symbol_p
)
3987 unsigned int dyn_r_type
;
3989 if (r_type
== R_IA64_IPLTMSB
)
3990 dyn_r_type
= R_IA64_REL64MSB
;
3992 dyn_r_type
= R_IA64_REL64LSB
;
3994 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3996 srel
, rel
->r_offset
,
3997 dyn_r_type
, 0, value
);
3998 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4000 srel
, rel
->r_offset
+ 8,
4001 dyn_r_type
, 0, gp_val
);
4004 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4005 srel
, rel
->r_offset
, r_type
,
4006 h
->dynindx
, rel
->r_addend
);
4009 if (r_type
== R_IA64_IPLTMSB
)
4010 r_type
= R_IA64_DIR64MSB
;
4012 r_type
= R_IA64_DIR64LSB
;
4013 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4014 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
4019 r
= bfd_reloc_notsupported
;
4028 case bfd_reloc_undefined
:
4029 /* This can happen for global table relative relocs if
4030 __gp is undefined. This is a panic situation so we
4031 don't try to continue. */
4032 (*info
->callbacks
->undefined_symbol
)
4033 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
4036 case bfd_reloc_notsupported
:
4041 name
= h
->root
.root
.string
;
4044 name
= bfd_elf_string_from_elf_section (input_bfd
,
4045 symtab_hdr
->sh_link
,
4050 name
= bfd_section_name (input_bfd
, input_section
);
4052 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
4054 input_section
, rel
->r_offset
))
4060 case bfd_reloc_dangerous
:
4061 case bfd_reloc_outofrange
:
4062 case bfd_reloc_overflow
:
4068 name
= h
->root
.root
.string
;
4071 name
= bfd_elf_string_from_elf_section (input_bfd
,
4072 symtab_hdr
->sh_link
,
4077 name
= bfd_section_name (input_bfd
, input_section
);
4079 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
4096 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
4098 struct bfd_link_info
*info
;
4099 struct elf_link_hash_entry
*h
;
4100 Elf_Internal_Sym
*sym
;
4102 struct elfNN_ia64_link_hash_table
*ia64_info
;
4103 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4105 ia64_info
= elfNN_ia64_hash_table (info
);
4106 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
4108 /* Fill in the PLT data, if required. */
4109 if (dyn_i
&& dyn_i
->want_plt
)
4111 Elf_Internal_Rela outrel
;
4114 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
4115 ElfNN_External_Rela
*rel
;
4117 gp_val
= _bfd_get_gp_value (output_bfd
);
4119 /* Initialize the minimal PLT entry. */
4121 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4122 plt_sec
= ia64_info
->plt_sec
;
4123 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4125 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4126 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4127 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4130 plt_addr
= (plt_sec
->output_section
->vma
4131 + plt_sec
->output_offset
4132 + dyn_i
->plt_offset
);
4133 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, true);
4135 /* Initialize the FULL PLT entry, if needed. */
4136 if (dyn_i
->want_plt2
)
4138 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4140 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4141 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4144 /* Mark the symbol as undefined, rather than as defined in the
4145 plt section. Leave the value alone. */
4146 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4147 first place. But perhaps elflink.h did some for us. */
4148 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4149 sym
->st_shndx
= SHN_UNDEF
;
4152 /* Create the dynamic relocation. */
4153 outrel
.r_offset
= pltoff_addr
;
4154 if (bfd_little_endian (output_bfd
))
4155 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4157 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4158 outrel
.r_addend
= 0;
4160 /* This is fun. In the .IA_64.pltoff section, we've got entries
4161 that correspond both to real PLT entries, and those that
4162 happened to resolve to local symbols but need to be created
4163 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4164 relocations for the real PLT should come at the end of the
4165 section, so that they can be indexed by plt entry at runtime.
4167 We emitted all of the relocations for the non-PLT @pltoff
4168 entries during relocate_section. So we can consider the
4169 existing sec->reloc_count to be the base of the array of
4172 rel
= (ElfNN_External_Rela
*)ia64_info
->rel_pltoff_sec
->contents
;
4173 rel
+= ia64_info
->rel_pltoff_sec
->reloc_count
;
4175 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, rel
+ index
);
4178 /* Mark some specially defined symbols as absolute. */
4179 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4180 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4181 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4182 sym
->st_shndx
= SHN_ABS
;
4188 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4190 struct bfd_link_info
*info
;
4192 struct elfNN_ia64_link_hash_table
*ia64_info
;
4195 ia64_info
= elfNN_ia64_hash_table (info
);
4196 dynobj
= ia64_info
->root
.dynobj
;
4198 if (elf_hash_table (info
)->dynamic_sections_created
)
4200 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4201 asection
*sdyn
, *sgotplt
;
4204 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4205 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4206 BFD_ASSERT (sdyn
!= NULL
);
4207 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4208 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4210 gp_val
= _bfd_get_gp_value (abfd
);
4212 for (; dyncon
< dynconend
; dyncon
++)
4214 Elf_Internal_Dyn dyn
;
4216 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4221 dyn
.d_un
.d_ptr
= gp_val
;
4225 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4226 * sizeof (ElfNN_External_Rela
));
4230 /* See the comment above in finish_dynamic_symbol. */
4231 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4232 + ia64_info
->rel_pltoff_sec
->output_offset
4233 + (ia64_info
->rel_pltoff_sec
->reloc_count
4234 * sizeof (ElfNN_External_Rela
)));
4237 case DT_IA_64_PLT_RESERVE
:
4238 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4239 + sgotplt
->output_offset
);
4243 /* Do not have RELASZ include JMPREL. This makes things
4244 easier on ld.so. This is not what the rest of BFD set up. */
4245 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4246 * sizeof (ElfNN_External_Rela
));
4250 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4253 /* Initialize the PLT0 entry */
4254 if (ia64_info
->plt_sec
)
4256 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4259 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4261 pltres
= (sgotplt
->output_section
->vma
4262 + sgotplt
->output_offset
4265 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4272 /* ELF file flag handling: */
4274 /* Function to keep IA-64 specific file flags. */
4276 elfNN_ia64_set_private_flags (abfd
, flags
)
4280 BFD_ASSERT (!elf_flags_init (abfd
)
4281 || elf_elfheader (abfd
)->e_flags
== flags
);
4283 elf_elfheader (abfd
)->e_flags
= flags
;
4284 elf_flags_init (abfd
) = true;
4288 /* Merge backend specific data from an object file to the output
4289 object file when linking. */
4291 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4298 /* Don't even pretend to support mixed-format linking. */
4299 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4300 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4303 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4304 out_flags
= elf_elfheader (obfd
)->e_flags
;
4306 if (! elf_flags_init (obfd
))
4308 elf_flags_init (obfd
) = true;
4309 elf_elfheader (obfd
)->e_flags
= in_flags
;
4311 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4312 && bfd_get_arch_info (obfd
)->the_default
)
4314 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4315 bfd_get_mach (ibfd
));
4321 /* Check flag compatibility. */
4322 if (in_flags
== out_flags
)
4325 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4326 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4327 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4329 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4331 (*_bfd_error_handler
)
4332 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4333 bfd_archive_filename (ibfd
));
4335 bfd_set_error (bfd_error_bad_value
);
4338 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4340 (*_bfd_error_handler
)
4341 (_("%s: linking big-endian files with little-endian files"),
4342 bfd_archive_filename (ibfd
));
4344 bfd_set_error (bfd_error_bad_value
);
4347 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4349 (*_bfd_error_handler
)
4350 (_("%s: linking 64-bit files with 32-bit files"),
4351 bfd_archive_filename (ibfd
));
4353 bfd_set_error (bfd_error_bad_value
);
4356 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4358 (*_bfd_error_handler
)
4359 (_("%s: linking constant-gp files with non-constant-gp files"),
4360 bfd_archive_filename (ibfd
));
4362 bfd_set_error (bfd_error_bad_value
);
4365 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4366 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4368 (*_bfd_error_handler
)
4369 (_("%s: linking auto-pic files with non-auto-pic files"),
4370 bfd_archive_filename (ibfd
));
4372 bfd_set_error (bfd_error_bad_value
);
4380 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4384 FILE *file
= (FILE *) ptr
;
4385 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4387 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4389 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4390 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4391 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4392 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4393 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4394 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4395 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4396 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4397 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4399 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4403 static enum elf_reloc_type_class
4404 elfNN_ia64_reloc_type_class (rela
)
4405 const Elf_Internal_Rela
*rela
;
4407 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
4409 case R_IA64_REL32MSB
:
4410 case R_IA64_REL32LSB
:
4411 case R_IA64_REL64MSB
:
4412 case R_IA64_REL64LSB
:
4413 return reloc_class_relative
;
4414 case R_IA64_IPLTMSB
:
4415 case R_IA64_IPLTLSB
:
4416 return reloc_class_plt
;
4418 return reloc_class_copy
;
4420 return reloc_class_normal
;
4425 elfNN_hpux_post_process_headers (abfd
, info
)
4427 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
4429 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
4431 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_HPUX
;
4432 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 1;
4435 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4436 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4437 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4438 #define TARGET_BIG_NAME "elfNN-ia64-big"
4439 #define ELF_ARCH bfd_arch_ia64
4440 #define ELF_MACHINE_CODE EM_IA_64
4441 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4442 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4443 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4445 #define elf_backend_section_from_shdr \
4446 elfNN_ia64_section_from_shdr
4447 #define elf_backend_section_flags \
4448 elfNN_ia64_section_flags
4449 #define elf_backend_fake_sections \
4450 elfNN_ia64_fake_sections
4451 #define elf_backend_final_write_processing \
4452 elfNN_ia64_final_write_processing
4453 #define elf_backend_add_symbol_hook \
4454 elfNN_ia64_add_symbol_hook
4455 #define elf_backend_additional_program_headers \
4456 elfNN_ia64_additional_program_headers
4457 #define elf_backend_modify_segment_map \
4458 elfNN_ia64_modify_segment_map
4459 #define elf_info_to_howto \
4460 elfNN_ia64_info_to_howto
4462 #define bfd_elfNN_bfd_reloc_type_lookup \
4463 elfNN_ia64_reloc_type_lookup
4464 #define bfd_elfNN_bfd_is_local_label_name \
4465 elfNN_ia64_is_local_label_name
4466 #define bfd_elfNN_bfd_relax_section \
4467 elfNN_ia64_relax_section
4469 /* Stuff for the BFD linker: */
4470 #define bfd_elfNN_bfd_link_hash_table_create \
4471 elfNN_ia64_hash_table_create
4472 #define elf_backend_create_dynamic_sections \
4473 elfNN_ia64_create_dynamic_sections
4474 #define elf_backend_check_relocs \
4475 elfNN_ia64_check_relocs
4476 #define elf_backend_adjust_dynamic_symbol \
4477 elfNN_ia64_adjust_dynamic_symbol
4478 #define elf_backend_size_dynamic_sections \
4479 elfNN_ia64_size_dynamic_sections
4480 #define elf_backend_relocate_section \
4481 elfNN_ia64_relocate_section
4482 #define elf_backend_finish_dynamic_symbol \
4483 elfNN_ia64_finish_dynamic_symbol
4484 #define elf_backend_finish_dynamic_sections \
4485 elfNN_ia64_finish_dynamic_sections
4486 #define bfd_elfNN_bfd_final_link \
4487 elfNN_ia64_final_link
4489 #define bfd_elfNN_bfd_merge_private_bfd_data \
4490 elfNN_ia64_merge_private_bfd_data
4491 #define bfd_elfNN_bfd_set_private_flags \
4492 elfNN_ia64_set_private_flags
4493 #define bfd_elfNN_bfd_print_private_bfd_data \
4494 elfNN_ia64_print_private_bfd_data
4496 #define elf_backend_plt_readonly 1
4497 #define elf_backend_want_plt_sym 0
4498 #define elf_backend_plt_alignment 5
4499 #define elf_backend_got_header_size 0
4500 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4501 #define elf_backend_want_got_plt 1
4502 #define elf_backend_may_use_rel_p 1
4503 #define elf_backend_may_use_rela_p 1
4504 #define elf_backend_default_use_rela_p 1
4505 #define elf_backend_want_dynbss 0
4506 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4507 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4508 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4510 #include "elfNN-target.h"
4512 /* AIX-specific vectors. */
4514 #undef TARGET_LITTLE_SYM
4515 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4516 #undef TARGET_LITTLE_NAME
4517 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4518 #undef TARGET_BIG_SYM
4519 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4520 #undef TARGET_BIG_NAME
4521 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4523 #undef elf_backend_add_symbol_hook
4524 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4526 #undef bfd_elfNN_bfd_link_add_symbols
4527 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4529 #define elfNN_bed elfNN_ia64_aix_bed
4531 #include "elfNN-target.h"
4533 /* HPUX-specific vectors. */
4535 #undef TARGET_LITTLE_SYM
4536 #undef TARGET_LITTLE_NAME
4537 #undef TARGET_BIG_SYM
4538 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4539 #undef TARGET_BIG_NAME
4540 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4542 #undef elf_backend_post_process_headers
4543 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4545 #undef ELF_MAXPAGESIZE
4546 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4549 #define elfNN_bed elfNN_ia64_hpux_bed
4551 #include "elfNN-target.h"