1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003 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"
28 /* THE RULES for all the stuff the linker creates --
30 GOT Entries created in response to LTOFF or LTOFF_FPTR
31 relocations. Dynamic relocs created for dynamic
32 symbols in an application; REL relocs for locals
35 FPTR The canonical function descriptor. Created for local
36 symbols in applications. Descriptors for dynamic symbols
37 and local symbols in shared libraries are created by
38 ld.so. Thus there are no dynamic relocs against these
39 objects. The FPTR relocs for such _are_ passed through
40 to the dynamic relocation tables.
42 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
43 Requires the creation of a PLTOFF entry. This does not
44 require any dynamic relocations.
46 PLTOFF Created by PLTOFF relocations. For local symbols, this
47 is an alternate function descriptor, and in shared libraries
48 requires two REL relocations. Note that this cannot be
49 transformed into an FPTR relocation, since it must be in
50 range of the GP. For dynamic symbols, this is a function
51 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
53 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
54 does not reqire dynamic relocations. */
56 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
58 typedef struct bfd_hash_entry
*(*new_hash_entry_func
)
59 PARAMS ((struct bfd_hash_entry
*, struct bfd_hash_table
*, const char *));
61 /* In dynamically (linker-) created sections, we generally need to keep track
62 of the place a symbol or expression got allocated to. This is done via hash
63 tables that store entries of the following type. */
65 struct elfNN_ia64_dyn_sym_info
67 /* The addend for which this entry is relevant. */
70 /* Next addend in the list. */
71 struct elfNN_ia64_dyn_sym_info
*next
;
75 bfd_vma pltoff_offset
;
79 bfd_vma dtpmod_offset
;
80 bfd_vma dtprel_offset
;
82 /* The symbol table entry, if any, that this was derrived from. */
83 struct elf_link_hash_entry
*h
;
85 /* Used to count non-got, non-plt relocations for delayed sizing
86 of relocation sections. */
87 struct elfNN_ia64_dyn_reloc_entry
89 struct elfNN_ia64_dyn_reloc_entry
*next
;
95 /* TRUE when the section contents have been updated. */
96 unsigned got_done
: 1;
97 unsigned fptr_done
: 1;
98 unsigned pltoff_done
: 1;
99 unsigned tprel_done
: 1;
100 unsigned dtpmod_done
: 1;
101 unsigned dtprel_done
: 1;
103 /* TRUE for the different kinds of linker data we want created. */
104 unsigned want_got
: 1;
105 unsigned want_gotx
: 1;
106 unsigned want_fptr
: 1;
107 unsigned want_ltoff_fptr
: 1;
108 unsigned want_plt
: 1;
109 unsigned want_plt2
: 1;
110 unsigned want_pltoff
: 1;
111 unsigned want_tprel
: 1;
112 unsigned want_dtpmod
: 1;
113 unsigned want_dtprel
: 1;
116 struct elfNN_ia64_local_hash_entry
118 struct bfd_hash_entry root
;
119 struct elfNN_ia64_dyn_sym_info
*info
;
121 /* TRUE if this hash entry's addends was translated for
122 SHF_MERGE optimization. */
123 unsigned sec_merge_done
: 1;
126 struct elfNN_ia64_local_hash_table
128 struct bfd_hash_table root
;
129 /* No additional fields for now. */
132 struct elfNN_ia64_link_hash_entry
134 struct elf_link_hash_entry root
;
135 struct elfNN_ia64_dyn_sym_info
*info
;
138 struct elfNN_ia64_link_hash_table
140 /* The main hash table. */
141 struct elf_link_hash_table root
;
143 asection
*got_sec
; /* the linkage table section (or NULL) */
144 asection
*rel_got_sec
; /* dynamic relocation section for same */
145 asection
*fptr_sec
; /* function descriptor table (or NULL) */
146 asection
*plt_sec
; /* the primary plt section (or NULL) */
147 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
148 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
150 bfd_size_type minplt_entries
; /* number of minplt entries */
151 unsigned reltext
: 1; /* are there relocs against readonly sections? */
152 unsigned self_dtpmod_done
: 1;/* has self DTPMOD entry been finished? */
153 bfd_vma self_dtpmod_offset
; /* .got offset to self DTPMOD entry */
155 struct elfNN_ia64_local_hash_table loc_hash_table
;
158 struct elfNN_ia64_allocate_data
160 struct bfd_link_info
*info
;
164 #define elfNN_ia64_hash_table(p) \
165 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
167 static bfd_reloc_status_type elfNN_ia64_reloc
168 PARAMS ((bfd
*abfd
, arelent
*reloc
, asymbol
*sym
, PTR data
,
169 asection
*input_section
, bfd
*output_bfd
, char **error_message
));
170 static reloc_howto_type
* lookup_howto
171 PARAMS ((unsigned int rtype
));
172 static reloc_howto_type
*elfNN_ia64_reloc_type_lookup
173 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type bfd_code
));
174 static void elfNN_ia64_info_to_howto
175 PARAMS ((bfd
*abfd
, arelent
*bfd_reloc
, Elf_Internal_Rela
*elf_reloc
));
176 static bfd_boolean elfNN_ia64_relax_section
177 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
178 bfd_boolean
*again
));
179 static void elfNN_ia64_relax_ldxmov
180 PARAMS((bfd
*abfd
, bfd_byte
*contents
, bfd_vma off
));
181 static bfd_boolean is_unwind_section_name
182 PARAMS ((bfd
*abfd
, const char *));
183 static bfd_boolean elfNN_ia64_section_from_shdr
184 PARAMS ((bfd
*, Elf_Internal_Shdr
*, const char *));
185 static bfd_boolean elfNN_ia64_section_flags
186 PARAMS ((flagword
*, Elf_Internal_Shdr
*));
187 static bfd_boolean elfNN_ia64_fake_sections
188 PARAMS ((bfd
*abfd
, Elf_Internal_Shdr
*hdr
, asection
*sec
));
189 static void elfNN_ia64_final_write_processing
190 PARAMS ((bfd
*abfd
, bfd_boolean linker
));
191 static bfd_boolean elfNN_ia64_add_symbol_hook
192 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
193 const char **namep
, flagword
*flagsp
, asection
**secp
,
195 static bfd_boolean elfNN_ia64_aix_vec
196 PARAMS ((const bfd_target
*vec
));
197 static bfd_boolean elfNN_ia64_aix_add_symbol_hook
198 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
199 const char **namep
, flagword
*flagsp
, asection
**secp
,
201 static bfd_boolean elfNN_ia64_aix_link_add_symbols
202 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
203 static int elfNN_ia64_additional_program_headers
204 PARAMS ((bfd
*abfd
));
205 static bfd_boolean elfNN_ia64_modify_segment_map
207 static bfd_boolean elfNN_ia64_is_local_label_name
208 PARAMS ((bfd
*abfd
, const char *name
));
209 static bfd_boolean elfNN_ia64_dynamic_symbol_p
210 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
));
211 static bfd_boolean elfNN_ia64_local_hash_table_init
212 PARAMS ((struct elfNN_ia64_local_hash_table
*ht
, bfd
*abfd
,
213 new_hash_entry_func
new));
214 static struct bfd_hash_entry
*elfNN_ia64_new_loc_hash_entry
215 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
216 const char *string
));
217 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
218 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
219 const char *string
));
220 static void elfNN_ia64_hash_copy_indirect
221 PARAMS ((struct elf_backend_data
*, struct elf_link_hash_entry
*,
222 struct elf_link_hash_entry
*));
223 static void elfNN_ia64_hash_hide_symbol
224 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*, bfd_boolean
));
225 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
226 PARAMS ((bfd
*abfd
));
227 static struct elfNN_ia64_local_hash_entry
*elfNN_ia64_local_hash_lookup
228 PARAMS ((struct elfNN_ia64_local_hash_table
*table
, const char *string
,
229 bfd_boolean create
, bfd_boolean copy
));
230 static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
231 PARAMS ((struct bfd_hash_entry
*, PTR
));
232 static bfd_boolean elfNN_ia64_local_dyn_sym_thunk
233 PARAMS ((struct bfd_hash_entry
*, PTR
));
234 static void elfNN_ia64_dyn_sym_traverse
235 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
236 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
238 static bfd_boolean elfNN_ia64_create_dynamic_sections
239 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
240 static struct elfNN_ia64_local_hash_entry
* get_local_sym_hash
241 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
242 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
));
243 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
244 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
245 struct elf_link_hash_entry
*h
,
246 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
));
247 static asection
*get_got
248 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
249 struct elfNN_ia64_link_hash_table
*ia64_info
));
250 static asection
*get_fptr
251 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
252 struct elfNN_ia64_link_hash_table
*ia64_info
));
253 static asection
*get_pltoff
254 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
255 struct elfNN_ia64_link_hash_table
*ia64_info
));
256 static asection
*get_reloc_section
257 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
258 asection
*sec
, bfd_boolean create
));
259 static bfd_boolean count_dyn_reloc
260 PARAMS ((bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
261 asection
*srel
, int type
));
262 static bfd_boolean elfNN_ia64_check_relocs
263 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
264 const Elf_Internal_Rela
*relocs
));
265 static bfd_boolean elfNN_ia64_adjust_dynamic_symbol
266 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
267 static long global_sym_index
268 PARAMS ((struct elf_link_hash_entry
*h
));
269 static bfd_boolean allocate_fptr
270 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
271 static bfd_boolean allocate_global_data_got
272 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
273 static bfd_boolean allocate_global_fptr_got
274 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
275 static bfd_boolean allocate_local_got
276 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
277 static bfd_boolean allocate_pltoff_entries
278 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
279 static bfd_boolean allocate_plt_entries
280 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
281 static bfd_boolean allocate_plt2_entries
282 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
283 static bfd_boolean allocate_dynrel_entries
284 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
285 static bfd_boolean elfNN_ia64_size_dynamic_sections
286 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
287 static bfd_reloc_status_type elfNN_ia64_install_value
288 PARAMS ((bfd
*abfd
, bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
289 static void elfNN_ia64_install_dyn_reloc
290 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
291 asection
*srel
, bfd_vma offset
, unsigned int type
,
292 long dynindx
, bfd_vma addend
));
293 static bfd_vma set_got_entry
294 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
295 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
296 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
297 static bfd_vma set_fptr_entry
298 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
299 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
301 static bfd_vma set_pltoff_entry
302 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
303 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
304 bfd_vma value
, bfd_boolean
));
305 static bfd_vma elfNN_ia64_tprel_base
306 PARAMS ((struct bfd_link_info
*info
));
307 static bfd_vma elfNN_ia64_dtprel_base
308 PARAMS ((struct bfd_link_info
*info
));
309 static int elfNN_ia64_unwind_entry_compare
310 PARAMS ((const PTR
, const PTR
));
311 static bfd_boolean elfNN_ia64_choose_gp
312 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
313 static bfd_boolean elfNN_ia64_final_link
314 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
315 static bfd_boolean elfNN_ia64_relocate_section
316 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
317 asection
*input_section
, bfd_byte
*contents
,
318 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
319 asection
**local_sections
));
320 static bfd_boolean elfNN_ia64_finish_dynamic_symbol
321 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
322 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
323 static bfd_boolean elfNN_ia64_finish_dynamic_sections
324 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
325 static bfd_boolean elfNN_ia64_set_private_flags
326 PARAMS ((bfd
*abfd
, flagword flags
));
327 static bfd_boolean elfNN_ia64_merge_private_bfd_data
328 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
329 static bfd_boolean elfNN_ia64_print_private_bfd_data
330 PARAMS ((bfd
*abfd
, PTR ptr
));
331 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
332 PARAMS ((const Elf_Internal_Rela
*));
333 static bfd_boolean elfNN_ia64_hpux_vec
334 PARAMS ((const bfd_target
*vec
));
335 static void elfNN_hpux_post_process_headers
336 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
337 bfd_boolean elfNN_hpux_backend_section_from_bfd_section
338 PARAMS ((bfd
*abfd
, asection
*sec
, int *retval
));
340 /* ia64-specific relocation. */
342 /* Perform a relocation. Not much to do here as all the hard work is
343 done in elfNN_ia64_final_link_relocate. */
344 static bfd_reloc_status_type
345 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
346 output_bfd
, error_message
)
347 bfd
*abfd ATTRIBUTE_UNUSED
;
349 asymbol
*sym ATTRIBUTE_UNUSED
;
350 PTR data ATTRIBUTE_UNUSED
;
351 asection
*input_section
;
353 char **error_message
;
357 reloc
->address
+= input_section
->output_offset
;
360 *error_message
= "Unsupported call to elfNN_ia64_reloc";
361 return bfd_reloc_notsupported
;
364 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
365 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
366 elfNN_ia64_reloc, NAME, FALSE, 0, 0, IN)
368 /* This table has to be sorted according to increasing number of the
370 static reloc_howto_type ia64_howto_table
[] =
372 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, FALSE
, TRUE
),
374 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, FALSE
, TRUE
),
375 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, FALSE
, TRUE
),
376 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, FALSE
, TRUE
),
377 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, FALSE
, TRUE
),
378 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, FALSE
, TRUE
),
379 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, FALSE
, TRUE
),
380 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, FALSE
, TRUE
),
382 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, FALSE
, TRUE
),
383 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, FALSE
, TRUE
),
384 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, FALSE
, TRUE
),
385 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, FALSE
, TRUE
),
386 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, FALSE
, TRUE
),
387 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, FALSE
, TRUE
),
389 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, FALSE
, TRUE
),
390 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, FALSE
, TRUE
),
392 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, FALSE
, TRUE
),
393 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, FALSE
, TRUE
),
394 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, FALSE
, TRUE
),
395 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, FALSE
, TRUE
),
397 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, FALSE
, TRUE
),
398 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, FALSE
, TRUE
),
399 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, FALSE
, TRUE
),
400 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, FALSE
, TRUE
),
401 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, FALSE
, TRUE
),
403 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, TRUE
, TRUE
),
404 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, TRUE
, TRUE
),
405 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, TRUE
, TRUE
),
406 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, TRUE
, TRUE
),
407 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, TRUE
, TRUE
),
408 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, TRUE
, TRUE
),
409 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, TRUE
, TRUE
),
410 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, TRUE
, TRUE
),
412 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, FALSE
, TRUE
),
413 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, FALSE
, TRUE
),
414 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, FALSE
, TRUE
),
415 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, FALSE
, TRUE
),
416 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, FALSE
, TRUE
),
417 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, FALSE
, TRUE
),
419 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, FALSE
, TRUE
),
420 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, FALSE
, TRUE
),
421 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, FALSE
, TRUE
),
422 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, FALSE
, TRUE
),
424 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, FALSE
, TRUE
),
425 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, FALSE
, TRUE
),
426 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, FALSE
, TRUE
),
427 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, FALSE
, TRUE
),
429 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, FALSE
, TRUE
),
430 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, FALSE
, TRUE
),
431 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, FALSE
, TRUE
),
432 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, FALSE
, TRUE
),
434 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, FALSE
, TRUE
),
435 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, FALSE
, TRUE
),
436 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, FALSE
, TRUE
),
437 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, FALSE
, TRUE
),
439 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, TRUE
, TRUE
),
440 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, TRUE
, TRUE
),
441 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, TRUE
, TRUE
),
443 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, FALSE
, TRUE
),
444 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, FALSE
, TRUE
),
445 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, FALSE
, TRUE
),
446 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, FALSE
, TRUE
),
447 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, FALSE
, TRUE
),
449 IA64_HOWTO (R_IA64_TPREL14
, "TPREL14", 0, FALSE
, FALSE
),
450 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, FALSE
, FALSE
),
451 IA64_HOWTO (R_IA64_TPREL64I
, "TPREL64I", 0, FALSE
, FALSE
),
452 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, FALSE
, FALSE
),
453 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, FALSE
, FALSE
),
454 IA64_HOWTO (R_IA64_LTOFF_TPREL22
, "LTOFF_TPREL22", 0, FALSE
, FALSE
),
456 IA64_HOWTO (R_IA64_DTPMOD64MSB
, "TPREL64MSB", 8, FALSE
, FALSE
),
457 IA64_HOWTO (R_IA64_DTPMOD64LSB
, "TPREL64LSB", 8, FALSE
, FALSE
),
458 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22
, "LTOFF_DTPMOD22", 0, FALSE
, FALSE
),
460 IA64_HOWTO (R_IA64_DTPREL14
, "DTPREL14", 0, FALSE
, FALSE
),
461 IA64_HOWTO (R_IA64_DTPREL22
, "DTPREL22", 0, FALSE
, FALSE
),
462 IA64_HOWTO (R_IA64_DTPREL64I
, "DTPREL64I", 0, FALSE
, FALSE
),
463 IA64_HOWTO (R_IA64_DTPREL32MSB
, "DTPREL32MSB", 4, FALSE
, FALSE
),
464 IA64_HOWTO (R_IA64_DTPREL32LSB
, "DTPREL32LSB", 4, FALSE
, FALSE
),
465 IA64_HOWTO (R_IA64_DTPREL64MSB
, "DTPREL64MSB", 8, FALSE
, FALSE
),
466 IA64_HOWTO (R_IA64_DTPREL64LSB
, "DTPREL64LSB", 8, FALSE
, FALSE
),
467 IA64_HOWTO (R_IA64_LTOFF_DTPREL22
, "LTOFF_DTPREL22", 0, FALSE
, FALSE
),
470 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
472 /* Given a BFD reloc type, return the matching HOWTO structure. */
474 static reloc_howto_type
*
478 static int inited
= 0;
485 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
486 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
487 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
490 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
491 i
= elf_code_to_howto_index
[rtype
];
492 if (i
>= NELEMS (ia64_howto_table
))
494 return ia64_howto_table
+ i
;
497 static reloc_howto_type
*
498 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
499 bfd
*abfd ATTRIBUTE_UNUSED
;
500 bfd_reloc_code_real_type bfd_code
;
506 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
508 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
509 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
510 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
512 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
513 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
514 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
515 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
517 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
518 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
519 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
520 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
521 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
522 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
524 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
525 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
527 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
528 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
529 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
530 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
531 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
532 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
533 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
534 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
535 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
537 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
538 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
539 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
540 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
541 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
542 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
543 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
544 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
545 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
546 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
547 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
549 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
550 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
551 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
552 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
553 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
554 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
556 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
557 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
558 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
559 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
561 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
562 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
563 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
564 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
566 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
567 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
568 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
569 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
571 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
572 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
573 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
574 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
576 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
577 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
578 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
579 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
580 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
582 case BFD_RELOC_IA64_TPREL14
: rtype
= R_IA64_TPREL14
; break;
583 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
584 case BFD_RELOC_IA64_TPREL64I
: rtype
= R_IA64_TPREL64I
; break;
585 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
586 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
587 case BFD_RELOC_IA64_LTOFF_TPREL22
: rtype
= R_IA64_LTOFF_TPREL22
; break;
589 case BFD_RELOC_IA64_DTPMOD64MSB
: rtype
= R_IA64_DTPMOD64MSB
; break;
590 case BFD_RELOC_IA64_DTPMOD64LSB
: rtype
= R_IA64_DTPMOD64LSB
; break;
591 case BFD_RELOC_IA64_LTOFF_DTPMOD22
: rtype
= R_IA64_LTOFF_DTPMOD22
; break;
593 case BFD_RELOC_IA64_DTPREL14
: rtype
= R_IA64_DTPREL14
; break;
594 case BFD_RELOC_IA64_DTPREL22
: rtype
= R_IA64_DTPREL22
; break;
595 case BFD_RELOC_IA64_DTPREL64I
: rtype
= R_IA64_DTPREL64I
; break;
596 case BFD_RELOC_IA64_DTPREL32MSB
: rtype
= R_IA64_DTPREL32MSB
; break;
597 case BFD_RELOC_IA64_DTPREL32LSB
: rtype
= R_IA64_DTPREL32LSB
; break;
598 case BFD_RELOC_IA64_DTPREL64MSB
: rtype
= R_IA64_DTPREL64MSB
; break;
599 case BFD_RELOC_IA64_DTPREL64LSB
: rtype
= R_IA64_DTPREL64LSB
; break;
600 case BFD_RELOC_IA64_LTOFF_DTPREL22
: rtype
= R_IA64_LTOFF_DTPREL22
; break;
604 return lookup_howto (rtype
);
607 /* Given a ELF reloc, return the matching HOWTO structure. */
610 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
611 bfd
*abfd ATTRIBUTE_UNUSED
;
613 Elf_Internal_Rela
*elf_reloc
;
616 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
619 #define PLT_HEADER_SIZE (3 * 16)
620 #define PLT_MIN_ENTRY_SIZE (1 * 16)
621 #define PLT_FULL_ENTRY_SIZE (2 * 16)
622 #define PLT_RESERVED_WORDS 3
624 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
626 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
627 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
628 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
629 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
630 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
631 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
632 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
633 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
634 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
637 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
639 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
640 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
641 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
644 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
646 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
647 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
648 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
649 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
650 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
651 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
654 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
655 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
656 #define DYNAMIC_INTERPRETER(abfd) \
657 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
659 static const bfd_byte oor_brl
[16] =
661 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
663 0x00, 0x00, 0x00, 0xc0
666 /* These functions do relaxation for IA-64 ELF. */
669 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
672 struct bfd_link_info
*link_info
;
677 struct one_fixup
*next
;
683 Elf_Internal_Shdr
*symtab_hdr
;
684 Elf_Internal_Rela
*internal_relocs
;
685 Elf_Internal_Rela
*irel
, *irelend
;
687 Elf_Internal_Sym
*isymbuf
= NULL
;
688 struct elfNN_ia64_link_hash_table
*ia64_info
;
689 struct one_fixup
*fixups
= NULL
;
690 bfd_boolean changed_contents
= FALSE
;
691 bfd_boolean changed_relocs
= FALSE
;
692 bfd_boolean changed_got
= FALSE
;
695 /* Assume we're not going to change any sizes, and we'll only need
699 /* Don't even try to relax for non-ELF outputs. */
700 if (link_info
->hash
->creator
->flavour
!= bfd_target_elf_flavour
)
703 /* Nothing to do if there are no relocations. */
704 if ((sec
->flags
& SEC_RELOC
) == 0
705 || sec
->reloc_count
== 0)
708 /* If this is the first time we have been called for this section,
709 initialize the cooked size. */
710 if (sec
->_cooked_size
== 0)
711 sec
->_cooked_size
= sec
->_raw_size
;
713 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
715 /* Load the relocations for this section. */
716 internal_relocs
= (_bfd_elfNN_link_read_relocs
717 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
718 link_info
->keep_memory
));
719 if (internal_relocs
== NULL
)
722 ia64_info
= elfNN_ia64_hash_table (link_info
);
723 irelend
= internal_relocs
+ sec
->reloc_count
;
725 /* Get the section contents. */
726 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
727 contents
= elf_section_data (sec
)->this_hdr
.contents
;
730 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
731 if (contents
== NULL
)
734 if (! bfd_get_section_contents (abfd
, sec
, contents
,
735 (file_ptr
) 0, sec
->_raw_size
))
739 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
741 unsigned long r_type
= ELFNN_R_TYPE (irel
->r_info
);
742 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
746 bfd_boolean is_branch
;
747 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
751 case R_IA64_PCREL21B
:
752 case R_IA64_PCREL21BI
:
753 case R_IA64_PCREL21M
:
754 case R_IA64_PCREL21F
:
758 case R_IA64_LTOFF22X
:
767 /* Get the value of the symbol referred to by the reloc. */
768 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
770 /* A local symbol. */
771 Elf_Internal_Sym
*isym
;
773 /* Read this BFD's local symbols. */
776 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
778 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
779 symtab_hdr
->sh_info
, 0,
785 isym
= isymbuf
+ ELF64_R_SYM (irel
->r_info
);
786 if (isym
->st_shndx
== SHN_UNDEF
)
787 continue; /* We can't do anthing with undefined symbols. */
788 else if (isym
->st_shndx
== SHN_ABS
)
789 tsec
= bfd_abs_section_ptr
;
790 else if (isym
->st_shndx
== SHN_COMMON
)
791 tsec
= bfd_com_section_ptr
;
792 else if (isym
->st_shndx
== SHN_IA_64_ANSI_COMMON
)
793 tsec
= bfd_com_section_ptr
;
795 tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
797 toff
= isym
->st_value
;
798 dyn_i
= get_dyn_sym_info (ia64_info
, NULL
, abfd
, irel
, FALSE
);
803 struct elf_link_hash_entry
*h
;
805 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
806 h
= elf_sym_hashes (abfd
)[indx
];
807 BFD_ASSERT (h
!= NULL
);
809 while (h
->root
.type
== bfd_link_hash_indirect
810 || h
->root
.type
== bfd_link_hash_warning
)
811 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
813 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, FALSE
);
815 /* For branches to dynamic symbols, we're interested instead
816 in a branch to the PLT entry. */
817 if (is_branch
&& dyn_i
&& dyn_i
->want_plt2
)
819 /* Internal branches shouldn't be sent to the PLT.
820 Leave this for now and we'll give an error later. */
821 if (r_type
!= R_IA64_PCREL21B
)
824 tsec
= ia64_info
->plt_sec
;
825 toff
= dyn_i
->plt2_offset
;
826 BFD_ASSERT (irel
->r_addend
== 0);
829 /* Can't do anything else with dynamic symbols. */
830 else if (elfNN_ia64_dynamic_symbol_p (h
, link_info
))
835 /* We can't do anthing with undefined symbols. */
836 if (h
->root
.type
== bfd_link_hash_undefined
837 || h
->root
.type
== bfd_link_hash_undefweak
)
840 tsec
= h
->root
.u
.def
.section
;
841 toff
= h
->root
.u
.def
.value
;
845 if (tsec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
846 toff
= _bfd_merged_section_offset (abfd
, &tsec
,
847 elf_section_data (tsec
)->sec_info
,
848 toff
+ irel
->r_addend
,
851 toff
+= irel
->r_addend
;
853 symaddr
= tsec
->output_section
->vma
+ tsec
->output_offset
+ toff
;
855 roff
= irel
->r_offset
;
859 reladdr
= (sec
->output_section
->vma
861 + roff
) & (bfd_vma
) -4;
863 /* If the branch is in range, no need to do anything. */
864 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
865 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
868 /* If the branch and target are in the same section, you've
869 got one honking big section and we can't help you. You'll
870 get an error message later. */
874 /* Look for an existing fixup to this address. */
875 for (f
= fixups
; f
; f
= f
->next
)
876 if (f
->tsec
== tsec
&& f
->toff
== toff
)
881 /* Two alternatives: If it's a branch to a PLT entry, we can
882 make a copy of the FULL_PLT entry. Otherwise, we'll have
883 to use a `brl' insn to get where we're going. */
887 if (tsec
== ia64_info
->plt_sec
)
888 size
= sizeof (plt_full_entry
);
891 size
= sizeof (oor_brl
);
894 /* Resize the current section to make room for the new branch. */
895 trampoff
= (sec
->_cooked_size
+ 15) & (bfd_vma
) -16;
896 amt
= trampoff
+ size
;
897 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
898 if (contents
== NULL
)
900 sec
->_cooked_size
= amt
;
902 if (tsec
== ia64_info
->plt_sec
)
904 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
906 /* Hijack the old relocation for use as the PLTOFF reloc. */
907 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
909 irel
->r_offset
= trampoff
;
913 memcpy (contents
+ trampoff
, oor_brl
, size
);
914 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
916 irel
->r_offset
= trampoff
+ 2;
919 /* Record the fixup so we don't do it again this section. */
920 f
= (struct one_fixup
*)
921 bfd_malloc ((bfd_size_type
) sizeof (*f
));
925 f
->trampoff
= trampoff
;
930 /* Nop out the reloc, since we're finalizing things here. */
931 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
934 /* Fix up the existing branch to hit the trampoline. Hope like
935 hell this doesn't overflow too. */
936 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
937 f
->trampoff
- (roff
& (bfd_vma
) -4),
938 r_type
) != bfd_reloc_ok
)
941 changed_contents
= TRUE
;
942 changed_relocs
= TRUE
;
949 bfd
*obfd
= sec
->output_section
->owner
;
950 gp
= _bfd_get_gp_value (obfd
);
953 if (!elfNN_ia64_choose_gp (obfd
, link_info
))
955 gp
= _bfd_get_gp_value (obfd
);
959 /* If the data is out of range, do nothing. */
960 if ((bfd_signed_vma
) (symaddr
- gp
) >= 0x200000
961 ||(bfd_signed_vma
) (symaddr
- gp
) < -0x200000)
964 if (r_type
== R_IA64_LTOFF22X
)
966 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
968 changed_relocs
= TRUE
;
969 if (dyn_i
->want_gotx
)
971 dyn_i
->want_gotx
= 0;
972 changed_got
|= !dyn_i
->want_got
;
977 elfNN_ia64_relax_ldxmov (abfd
, contents
, roff
);
978 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
979 changed_contents
= TRUE
;
980 changed_relocs
= TRUE
;
985 /* ??? If we created fixups, this may push the code segment large
986 enough that the data segment moves, which will change the GP.
987 Reset the GP so that we re-calculate next round. We need to
988 do this at the _beginning_ of the next round; now will not do. */
990 /* Clean up and go home. */
993 struct one_fixup
*f
= fixups
;
994 fixups
= fixups
->next
;
999 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1001 if (! link_info
->keep_memory
)
1005 /* Cache the symbols for elf_link_input_bfd. */
1006 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1010 if (contents
!= NULL
1011 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1013 if (!changed_contents
&& !link_info
->keep_memory
)
1017 /* Cache the section contents for elf_link_input_bfd. */
1018 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1022 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
1024 if (!changed_relocs
)
1025 free (internal_relocs
);
1027 elf_section_data (sec
)->relocs
= internal_relocs
;
1032 struct elfNN_ia64_allocate_data data
;
1033 data
.info
= link_info
;
1035 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
1037 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
1038 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
1039 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
1040 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
1041 ia64_info
->got_sec
->_cooked_size
= data
.ofs
;
1043 /* ??? Resize .rela.got too. */
1046 *again
= changed_contents
|| changed_relocs
;
1050 if (isymbuf
!= NULL
&& (unsigned char *) isymbuf
!= symtab_hdr
->contents
)
1052 if (contents
!= NULL
1053 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1055 if (internal_relocs
!= NULL
1056 && elf_section_data (sec
)->relocs
!= internal_relocs
)
1057 free (internal_relocs
);
1062 elfNN_ia64_relax_ldxmov (abfd
, contents
, off
)
1068 bfd_vma dword
, insn
;
1070 switch ((int)off
& 0x3)
1072 case 0: shift
= 5; break;
1073 case 1: shift
= 14; off
+= 3; break;
1074 case 2: shift
= 23; off
+= 6; break;
1079 dword
= bfd_get_64 (abfd
, contents
+ off
);
1080 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
1082 r1
= (insn
>> 6) & 127;
1083 r3
= (insn
>> 20) & 127;
1085 insn
= 0x8000000; /* nop */
1087 insn
= (insn
& 0x7f01fff) | 0x10800000000LL
; /* (qp) mov r1 = r3 */
1089 dword
&= ~(0x1ffffffffffLL
<< shift
);
1090 dword
|= (insn
<< shift
);
1091 bfd_put_64 (abfd
, dword
, contents
+ off
);
1094 /* Return TRUE if NAME is an unwind table section name. */
1096 static inline bfd_boolean
1097 is_unwind_section_name (abfd
, name
)
1101 size_t len1
, len2
, len3
;
1103 if (elfNN_ia64_hpux_vec (abfd
->xvec
)
1104 && !strcmp (name
, ELF_STRING_ia64_unwind_hdr
))
1107 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1108 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
1109 len3
= sizeof (ELF_STRING_ia64_unwind_once
) - 1;
1110 return ((strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
1111 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0)
1112 || strncmp (name
, ELF_STRING_ia64_unwind_once
, len3
) == 0);
1115 /* Handle an IA-64 specific section when reading an object file. This
1116 is called when elfcode.h finds a section with an unknown type. */
1119 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
1121 Elf_Internal_Shdr
*hdr
;
1126 /* There ought to be a place to keep ELF backend specific flags, but
1127 at the moment there isn't one. We just keep track of the
1128 sections by their name, instead. Fortunately, the ABI gives
1129 suggested names for all the MIPS specific sections, so we will
1130 probably get away with this. */
1131 switch (hdr
->sh_type
)
1133 case SHT_IA_64_UNWIND
:
1134 case SHT_IA_64_HP_OPT_ANOT
:
1138 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1146 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
1148 newsect
= hdr
->bfd_section
;
1153 /* Convert IA-64 specific section flags to bfd internal section flags. */
1155 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1159 elfNN_ia64_section_flags (flags
, hdr
)
1161 Elf_Internal_Shdr
*hdr
;
1163 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1164 *flags
|= SEC_SMALL_DATA
;
1169 /* Set the correct type for an IA-64 ELF section. We do this by the
1170 section name, which is a hack, but ought to work. */
1173 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1174 bfd
*abfd ATTRIBUTE_UNUSED
;
1175 Elf_Internal_Shdr
*hdr
;
1178 register const char *name
;
1180 name
= bfd_get_section_name (abfd
, sec
);
1182 if (is_unwind_section_name (abfd
, name
))
1184 /* We don't have the sections numbered at this point, so sh_info
1185 is set later, in elfNN_ia64_final_write_processing. */
1186 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1187 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1189 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1190 hdr
->sh_type
= SHT_IA_64_EXT
;
1191 else if (strcmp (name
, ".HP.opt_annot") == 0)
1192 hdr
->sh_type
= SHT_IA_64_HP_OPT_ANOT
;
1193 else if (strcmp (name
, ".reloc") == 0)
1194 /* This is an ugly, but unfortunately necessary hack that is
1195 needed when producing EFI binaries on IA-64. It tells
1196 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1197 containing ELF relocation info. We need this hack in order to
1198 be able to generate ELF binaries that can be translated into
1199 EFI applications (which are essentially COFF objects). Those
1200 files contain a COFF ".reloc" section inside an ELFNN object,
1201 which would normally cause BFD to segfault because it would
1202 attempt to interpret this section as containing relocation
1203 entries for section "oc". With this hack enabled, ".reloc"
1204 will be treated as a normal data section, which will avoid the
1205 segfault. However, you won't be able to create an ELFNN binary
1206 with a section named "oc" that needs relocations, but that's
1207 the kind of ugly side-effects you get when detecting section
1208 types based on their names... In practice, this limitation is
1209 unlikely to bite. */
1210 hdr
->sh_type
= SHT_PROGBITS
;
1212 if (sec
->flags
& SEC_SMALL_DATA
)
1213 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1218 /* The final processing done just before writing out an IA-64 ELF
1222 elfNN_ia64_final_write_processing (abfd
, linker
)
1224 bfd_boolean linker ATTRIBUTE_UNUSED
;
1226 Elf_Internal_Shdr
*hdr
;
1228 asection
*text_sect
, *s
;
1231 for (s
= abfd
->sections
; s
; s
= s
->next
)
1233 hdr
= &elf_section_data (s
)->this_hdr
;
1234 switch (hdr
->sh_type
)
1236 case SHT_IA_64_UNWIND
:
1237 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1239 sname
= bfd_get_section_name (abfd
, s
);
1240 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1241 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1245 if (sname
[0] == '\0')
1246 /* .IA_64.unwind -> .text */
1247 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1249 /* .IA_64.unwindFOO -> FOO */
1250 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1253 && (len
= sizeof (ELF_STRING_ia64_unwind_once
) - 1,
1254 strncmp (sname
, ELF_STRING_ia64_unwind_once
, len
)) == 0)
1256 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1257 size_t len2
= sizeof (".gnu.linkonce.t.") - 1;
1258 char *once_name
= bfd_malloc (len2
+ strlen (sname
+ len
) + 1);
1260 if (once_name
!= NULL
)
1262 memcpy (once_name
, ".gnu.linkonce.t.", len2
);
1263 strcpy (once_name
+ len2
, sname
+ len
);
1264 text_sect
= bfd_get_section_by_name (abfd
, once_name
);
1268 /* Should only happen if we run out of memory, in
1269 which case we're probably toast anyway. Try to
1270 cope by finding the section the slow way. */
1271 for (text_sect
= abfd
->sections
;
1273 text_sect
= text_sect
->next
)
1275 if (strncmp (bfd_section_name (abfd
, text_sect
),
1276 ".gnu.linkonce.t.", len2
) == 0
1277 && strcmp (bfd_section_name (abfd
, text_sect
) + len2
,
1283 /* last resort: fall back on .text */
1284 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1288 /* The IA-64 processor-specific ABI requires setting
1289 sh_link to the unwind section, whereas HP-UX requires
1290 sh_info to do so. For maximum compatibility, we'll
1291 set both for now... */
1292 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1293 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1299 if (! elf_flags_init (abfd
))
1301 unsigned long flags
= 0;
1303 if (abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
)
1304 flags
|= EF_IA_64_BE
;
1305 if (bfd_get_mach (abfd
) == bfd_mach_ia64_elf64
)
1306 flags
|= EF_IA_64_ABI64
;
1308 elf_elfheader(abfd
)->e_flags
= flags
;
1309 elf_flags_init (abfd
) = TRUE
;
1313 /* Hook called by the linker routine which adds symbols from an object
1314 file. We use it to put .comm items in .sbss, and not .bss. */
1317 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1319 struct bfd_link_info
*info
;
1320 const Elf_Internal_Sym
*sym
;
1321 const char **namep ATTRIBUTE_UNUSED
;
1322 flagword
*flagsp ATTRIBUTE_UNUSED
;
1326 if (sym
->st_shndx
== SHN_COMMON
1327 && !info
->relocateable
1328 && sym
->st_size
<= elf_gp_size (abfd
))
1330 /* Common symbols less than or equal to -G nn bytes are
1331 automatically put into .sbss. */
1333 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1337 scomm
= bfd_make_section (abfd
, ".scommon");
1339 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1341 | SEC_LINKER_CREATED
)))
1346 *valp
= sym
->st_size
;
1353 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1355 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1356 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1358 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1359 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1362 /* Hook called by the linker routine which adds symbols from an object
1363 file. We use it to handle OS-specific symbols. */
1366 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1368 struct bfd_link_info
*info
;
1369 const Elf_Internal_Sym
*sym
;
1375 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1377 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1378 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1379 no one else should use it b/c it is undocumented. */
1380 struct elf_link_hash_entry
*h
;
1382 h
= elf_link_hash_lookup (elf_hash_table (info
), *namep
,
1383 FALSE
, FALSE
, FALSE
);
1386 struct elf_backend_data
*bed
;
1387 struct elfNN_ia64_link_hash_table
*ia64_info
;
1388 struct bfd_link_hash_entry
*bh
= NULL
;
1390 bed
= get_elf_backend_data (abfd
);
1391 ia64_info
= elfNN_ia64_hash_table (info
);
1393 if (!(_bfd_generic_link_add_one_symbol
1394 (info
, abfd
, *namep
, BSF_GLOBAL
,
1395 bfd_get_section_by_name (abfd
, ".bss"),
1396 bed
->got_symbol_offset
, (const char *) NULL
, FALSE
,
1397 bed
->collect
, &bh
)))
1400 h
= (struct elf_link_hash_entry
*) bh
;
1401 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1402 h
->type
= STT_OBJECT
;
1404 if (! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1410 else if (sym
->st_shndx
== SHN_LOOS
)
1414 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1415 is only relevant when compiling code for extended system calls.
1416 Replace the "special" section with .text, if possible.
1417 Note that these symbols are always assumed to be in .text. */
1418 for (i
= 1; i
< elf_numsections (abfd
); i
++)
1420 asection
* sec
= bfd_section_from_elf_index (abfd
, i
);
1422 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1430 *secp
= bfd_abs_section_ptr
;
1432 *valp
= sym
->st_size
;
1438 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1439 namep
, flagsp
, secp
, valp
);
1444 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1446 struct bfd_link_info
*info
;
1448 /* Make sure dynamic sections are always created. */
1449 if (! elf_hash_table (info
)->dynamic_sections_created
1450 && abfd
->xvec
== info
->hash
->creator
)
1452 if (! bfd_elfNN_link_create_dynamic_sections (abfd
, info
))
1456 /* Now do the standard call. */
1457 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1460 /* Return the number of additional phdrs we will need. */
1463 elfNN_ia64_additional_program_headers (abfd
)
1469 /* See if we need a PT_IA_64_ARCHEXT segment. */
1470 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1471 if (s
&& (s
->flags
& SEC_LOAD
))
1474 /* Count how many PT_IA_64_UNWIND segments we need. */
1475 for (s
= abfd
->sections
; s
; s
= s
->next
)
1476 if (is_unwind_section_name (abfd
, s
->name
) && (s
->flags
& SEC_LOAD
))
1483 elfNN_ia64_modify_segment_map (abfd
)
1486 struct elf_segment_map
*m
, **pm
;
1487 Elf_Internal_Shdr
*hdr
;
1490 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1491 all PT_LOAD segments. */
1492 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1493 if (s
&& (s
->flags
& SEC_LOAD
))
1495 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1496 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1500 m
= ((struct elf_segment_map
*)
1501 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1505 m
->p_type
= PT_IA_64_ARCHEXT
;
1509 /* We want to put it after the PHDR and INTERP segments. */
1510 pm
= &elf_tdata (abfd
)->segment_map
;
1512 && ((*pm
)->p_type
== PT_PHDR
1513 || (*pm
)->p_type
== PT_INTERP
))
1521 /* Install PT_IA_64_UNWIND segments, if needed. */
1522 for (s
= abfd
->sections
; s
; s
= s
->next
)
1524 hdr
= &elf_section_data (s
)->this_hdr
;
1525 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1528 if (s
&& (s
->flags
& SEC_LOAD
))
1530 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1531 if (m
->p_type
== PT_IA_64_UNWIND
)
1535 /* Look through all sections in the unwind segment
1536 for a match since there may be multiple sections
1538 for (i
= m
->count
- 1; i
>= 0; --i
)
1539 if (m
->sections
[i
] == s
)
1548 m
= ((struct elf_segment_map
*)
1549 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1553 m
->p_type
= PT_IA_64_UNWIND
;
1558 /* We want to put it last. */
1559 pm
= &elf_tdata (abfd
)->segment_map
;
1567 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1568 the input sections for each output section in the segment and testing
1569 for SHF_IA_64_NORECOV on each. */
1570 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1571 if (m
->p_type
== PT_LOAD
)
1574 for (i
= m
->count
- 1; i
>= 0; --i
)
1576 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1579 if (order
->type
== bfd_indirect_link_order
)
1581 asection
*is
= order
->u
.indirect
.section
;
1582 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1583 if (flags
& SHF_IA_64_NORECOV
)
1585 m
->p_flags
|= PF_IA_64_NORECOV
;
1589 order
= order
->next
;
1598 /* According to the Tahoe assembler spec, all labels starting with a
1602 elfNN_ia64_is_local_label_name (abfd
, name
)
1603 bfd
*abfd ATTRIBUTE_UNUSED
;
1606 return name
[0] == '.';
1609 /* Should we do dynamic things to this symbol? */
1612 elfNN_ia64_dynamic_symbol_p (h
, info
)
1613 struct elf_link_hash_entry
*h
;
1614 struct bfd_link_info
*info
;
1619 while (h
->root
.type
== bfd_link_hash_indirect
1620 || h
->root
.type
== bfd_link_hash_warning
)
1621 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1623 if (h
->dynindx
== -1)
1625 switch (ELF_ST_VISIBILITY (h
->other
))
1634 if (h
->root
.type
== bfd_link_hash_undefweak
1635 || h
->root
.type
== bfd_link_hash_defweak
)
1638 if ((info
->shared
&& (!info
->symbolic
|| info
->allow_shlib_undefined
))
1639 || ((h
->elf_link_hash_flags
1640 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1641 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1648 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1649 struct elfNN_ia64_local_hash_table
*ht
;
1650 bfd
*abfd ATTRIBUTE_UNUSED
;
1651 new_hash_entry_func
new;
1653 memset (ht
, 0, sizeof (*ht
));
1654 return bfd_hash_table_init (&ht
->root
, new);
1657 static struct bfd_hash_entry
*
1658 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1659 struct bfd_hash_entry
*entry
;
1660 struct bfd_hash_table
*table
;
1663 struct elfNN_ia64_local_hash_entry
*ret
;
1664 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1666 /* Allocate the structure if it has not already been allocated by a
1669 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1674 /* Initialize our local data. All zeros, and definitely easier
1675 than setting a handful of bit fields. */
1676 memset (ret
, 0, sizeof (*ret
));
1678 /* Call the allocation method of the superclass. */
1679 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1680 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1682 return (struct bfd_hash_entry
*) ret
;
1685 static struct bfd_hash_entry
*
1686 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1687 struct bfd_hash_entry
*entry
;
1688 struct bfd_hash_table
*table
;
1691 struct elfNN_ia64_link_hash_entry
*ret
;
1692 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1694 /* Allocate the structure if it has not already been allocated by a
1697 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1702 /* Initialize our local data. All zeros, and definitely easier
1703 than setting a handful of bit fields. */
1704 memset (ret
, 0, sizeof (*ret
));
1706 /* Call the allocation method of the superclass. */
1707 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1708 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1711 return (struct bfd_hash_entry
*) ret
;
1715 elfNN_ia64_hash_copy_indirect (bed
, xdir
, xind
)
1716 struct elf_backend_data
*bed ATTRIBUTE_UNUSED
;
1717 struct elf_link_hash_entry
*xdir
, *xind
;
1719 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1721 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1722 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1724 /* Copy down any references that we may have already seen to the
1725 symbol which just became indirect. */
1727 dir
->root
.elf_link_hash_flags
|=
1728 (ind
->root
.elf_link_hash_flags
1729 & (ELF_LINK_HASH_REF_DYNAMIC
1730 | ELF_LINK_HASH_REF_REGULAR
1731 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1733 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1736 /* Copy over the got and plt data. This would have been done
1739 if (dir
->info
== NULL
)
1741 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1743 dir
->info
= dyn_i
= ind
->info
;
1746 /* Fix up the dyn_sym_info pointers to the global symbol. */
1747 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1748 dyn_i
->h
= &dir
->root
;
1750 BFD_ASSERT (ind
->info
== NULL
);
1752 /* Copy over the dynindx. */
1754 if (dir
->root
.dynindx
== -1)
1756 dir
->root
.dynindx
= ind
->root
.dynindx
;
1757 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1758 ind
->root
.dynindx
= -1;
1759 ind
->root
.dynstr_index
= 0;
1761 BFD_ASSERT (ind
->root
.dynindx
== -1);
1765 elfNN_ia64_hash_hide_symbol (info
, xh
, force_local
)
1766 struct bfd_link_info
*info
;
1767 struct elf_link_hash_entry
*xh
;
1768 bfd_boolean force_local
;
1770 struct elfNN_ia64_link_hash_entry
*h
;
1771 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1773 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1775 _bfd_elf_link_hash_hide_symbol (info
, &h
->root
, force_local
);
1777 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1778 dyn_i
->want_plt2
= 0;
1781 /* Create the derived linker hash table. The IA-64 ELF port uses this
1782 derived hash table to keep information specific to the IA-64 ElF
1783 linker (without using static variables). */
1785 static struct bfd_link_hash_table
*
1786 elfNN_ia64_hash_table_create (abfd
)
1789 struct elfNN_ia64_link_hash_table
*ret
;
1791 ret
= bfd_zalloc (abfd
, (bfd_size_type
) sizeof (*ret
));
1794 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1795 elfNN_ia64_new_elf_hash_entry
))
1797 bfd_release (abfd
, ret
);
1801 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1802 elfNN_ia64_new_loc_hash_entry
))
1804 return &ret
->root
.root
;
1807 /* Look up an entry in a Alpha ELF linker hash table. */
1809 static INLINE
struct elfNN_ia64_local_hash_entry
*
1810 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1811 struct elfNN_ia64_local_hash_table
*table
;
1813 bfd_boolean create
, copy
;
1815 return ((struct elfNN_ia64_local_hash_entry
*)
1816 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1819 /* Traverse both local and global hash tables. */
1821 struct elfNN_ia64_dyn_sym_traverse_data
1823 bfd_boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1828 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1829 struct bfd_hash_entry
*xentry
;
1832 struct elfNN_ia64_link_hash_entry
*entry
1833 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1834 struct elfNN_ia64_dyn_sym_traverse_data
*data
1835 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1836 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1838 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
1839 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
1841 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1842 if (! (*data
->func
) (dyn_i
, data
->data
))
1848 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1849 struct bfd_hash_entry
*xentry
;
1852 struct elfNN_ia64_local_hash_entry
*entry
1853 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1854 struct elfNN_ia64_dyn_sym_traverse_data
*data
1855 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1856 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1858 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1859 if (! (*data
->func
) (dyn_i
, data
->data
))
1865 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1866 struct elfNN_ia64_link_hash_table
*ia64_info
;
1867 bfd_boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1870 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1875 elf_link_hash_traverse (&ia64_info
->root
,
1876 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1877 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1878 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1882 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1884 struct bfd_link_info
*info
;
1886 struct elfNN_ia64_link_hash_table
*ia64_info
;
1889 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1892 ia64_info
= elfNN_ia64_hash_table (info
);
1894 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1895 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1898 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1899 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1902 if (!get_pltoff (abfd
, info
, ia64_info
))
1905 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1907 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1910 | SEC_LINKER_CREATED
1912 || !bfd_set_section_alignment (abfd
, s
, 3))
1914 ia64_info
->rel_pltoff_sec
= s
;
1916 s
= bfd_make_section(abfd
, ".rela.got");
1918 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1921 | SEC_LINKER_CREATED
1923 || !bfd_set_section_alignment (abfd
, s
, 3))
1925 ia64_info
->rel_got_sec
= s
;
1930 /* Find and/or create a hash entry for local symbol. */
1931 static struct elfNN_ia64_local_hash_entry
*
1932 get_local_sym_hash (ia64_info
, abfd
, rel
, create
)
1933 struct elfNN_ia64_link_hash_table
*ia64_info
;
1935 const Elf_Internal_Rela
*rel
;
1938 struct elfNN_ia64_local_hash_entry
*ret
;
1939 asection
*sec
= abfd
->sections
;
1940 char addr_name
[34];
1942 BFD_ASSERT ((sizeof (sec
->id
)*2 + 1 + sizeof (unsigned long)*2 + 1) <= 34);
1945 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1946 name describes what was once anonymous memory. */
1948 sprintf (addr_name
, "%x:%lx",
1949 sec
->id
, (unsigned long) ELFNN_R_SYM (rel
->r_info
));
1951 /* Collect the canonical entry data for this address. */
1952 ret
= elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1953 addr_name
, create
, create
);
1957 /* Find and/or create a descriptor for dynamic symbol info. This will
1958 vary based on global or local symbol, and the addend to the reloc. */
1960 static struct elfNN_ia64_dyn_sym_info
*
1961 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1962 struct elfNN_ia64_link_hash_table
*ia64_info
;
1963 struct elf_link_hash_entry
*h
;
1965 const Elf_Internal_Rela
*rel
;
1968 struct elfNN_ia64_dyn_sym_info
**pp
;
1969 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1970 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1973 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1976 struct elfNN_ia64_local_hash_entry
*loc_h
;
1978 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
1981 BFD_ASSERT (!create
);
1988 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
1991 if (dyn_i
== NULL
&& create
)
1993 dyn_i
= ((struct elfNN_ia64_dyn_sym_info
*)
1994 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *dyn_i
));
1996 dyn_i
->addend
= addend
;
2003 get_got (abfd
, info
, ia64_info
)
2005 struct bfd_link_info
*info
;
2006 struct elfNN_ia64_link_hash_table
*ia64_info
;
2011 got
= ia64_info
->got_sec
;
2016 dynobj
= ia64_info
->root
.dynobj
;
2018 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2019 if (!_bfd_elf_create_got_section (dynobj
, info
))
2022 got
= bfd_get_section_by_name (dynobj
, ".got");
2024 ia64_info
->got_sec
= got
;
2026 flags
= bfd_get_section_flags (abfd
, got
);
2027 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
2033 /* Create function descriptor section (.opd). This section is called .opd
2034 because it contains "official prodecure descriptors". The "official"
2035 refers to the fact that these descriptors are used when taking the address
2036 of a procedure, thus ensuring a unique address for each procedure. */
2039 get_fptr (abfd
, info
, ia64_info
)
2041 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2042 struct elfNN_ia64_link_hash_table
*ia64_info
;
2047 fptr
= ia64_info
->fptr_sec
;
2050 dynobj
= ia64_info
->root
.dynobj
;
2052 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2054 fptr
= bfd_make_section (dynobj
, ".opd");
2056 || !bfd_set_section_flags (dynobj
, fptr
,
2062 | SEC_LINKER_CREATED
))
2063 || !bfd_set_section_alignment (abfd
, fptr
, 4))
2069 ia64_info
->fptr_sec
= fptr
;
2076 get_pltoff (abfd
, info
, ia64_info
)
2078 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2079 struct elfNN_ia64_link_hash_table
*ia64_info
;
2084 pltoff
= ia64_info
->pltoff_sec
;
2087 dynobj
= ia64_info
->root
.dynobj
;
2089 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2091 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
2093 || !bfd_set_section_flags (dynobj
, pltoff
,
2099 | SEC_LINKER_CREATED
))
2100 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
2106 ia64_info
->pltoff_sec
= pltoff
;
2113 get_reloc_section (abfd
, ia64_info
, sec
, create
)
2115 struct elfNN_ia64_link_hash_table
*ia64_info
;
2119 const char *srel_name
;
2123 srel_name
= (bfd_elf_string_from_elf_section
2124 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
2125 elf_section_data(sec
)->rel_hdr
.sh_name
));
2126 if (srel_name
== NULL
)
2129 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
2130 && strcmp (bfd_get_section_name (abfd
, sec
),
2132 || (strncmp (srel_name
, ".rel", 4) == 0
2133 && strcmp (bfd_get_section_name (abfd
, sec
),
2134 srel_name
+4) == 0));
2136 dynobj
= ia64_info
->root
.dynobj
;
2138 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2140 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
2141 if (srel
== NULL
&& create
)
2143 srel
= bfd_make_section (dynobj
, srel_name
);
2145 || !bfd_set_section_flags (dynobj
, srel
,
2150 | SEC_LINKER_CREATED
2152 || !bfd_set_section_alignment (dynobj
, srel
, 3))
2156 if (sec
->flags
& SEC_READONLY
)
2157 ia64_info
->reltext
= 1;
2163 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
2165 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2169 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2171 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2172 if (rent
->srel
== srel
&& rent
->type
== type
)
2177 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
2178 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
2182 rent
->next
= dyn_i
->reloc_entries
;
2186 dyn_i
->reloc_entries
= rent
;
2194 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
2196 struct bfd_link_info
*info
;
2198 const Elf_Internal_Rela
*relocs
;
2200 struct elfNN_ia64_link_hash_table
*ia64_info
;
2201 const Elf_Internal_Rela
*relend
;
2202 Elf_Internal_Shdr
*symtab_hdr
;
2203 const Elf_Internal_Rela
*rel
;
2204 asection
*got
, *fptr
, *srel
;
2206 if (info
->relocateable
)
2209 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2210 ia64_info
= elfNN_ia64_hash_table (info
);
2212 got
= fptr
= srel
= NULL
;
2214 relend
= relocs
+ sec
->reloc_count
;
2215 for (rel
= relocs
; rel
< relend
; ++rel
)
2225 NEED_LTOFF_FPTR
= 128,
2231 struct elf_link_hash_entry
*h
= NULL
;
2232 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2233 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2235 bfd_boolean maybe_dynamic
;
2236 int dynrel_type
= R_IA64_NONE
;
2238 if (r_symndx
>= symtab_hdr
->sh_info
)
2240 /* We're dealing with a global symbol -- find its hash entry
2241 and mark it as being referenced. */
2242 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2243 h
= elf_sym_hashes (abfd
)[indx
];
2244 while (h
->root
.type
== bfd_link_hash_indirect
2245 || h
->root
.type
== bfd_link_hash_warning
)
2246 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2248 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
2251 /* We can only get preliminary data on whether a symbol is
2252 locally or externally defined, as not all of the input files
2253 have yet been processed. Do something with what we know, as
2254 this may help reduce memory usage and processing time later. */
2255 maybe_dynamic
= FALSE
;
2256 if (h
&& ((info
->shared
2257 && (!info
->symbolic
|| info
->allow_shlib_undefined
))
2258 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
2259 || h
->root
.type
== bfd_link_hash_defweak
2260 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2261 maybe_dynamic
= TRUE
;
2264 switch (ELFNN_R_TYPE (rel
->r_info
))
2266 case R_IA64_TPREL64MSB
:
2267 case R_IA64_TPREL64LSB
:
2268 if (info
->shared
|| maybe_dynamic
)
2269 need_entry
= NEED_DYNREL
;
2270 dynrel_type
= R_IA64_TPREL64LSB
;
2272 info
->flags
|= DF_STATIC_TLS
;
2275 case R_IA64_LTOFF_TPREL22
:
2276 need_entry
= NEED_TPREL
;
2278 info
->flags
|= DF_STATIC_TLS
;
2281 case R_IA64_DTPREL64MSB
:
2282 case R_IA64_DTPREL64LSB
:
2283 if (info
->shared
|| maybe_dynamic
)
2284 need_entry
= NEED_DYNREL
;
2285 dynrel_type
= R_IA64_DTPREL64LSB
;
2288 case R_IA64_LTOFF_DTPREL22
:
2289 need_entry
= NEED_DTPREL
;
2292 case R_IA64_DTPMOD64MSB
:
2293 case R_IA64_DTPMOD64LSB
:
2294 if (info
->shared
|| maybe_dynamic
)
2295 need_entry
= NEED_DYNREL
;
2296 dynrel_type
= R_IA64_DTPMOD64LSB
;
2299 case R_IA64_LTOFF_DTPMOD22
:
2300 need_entry
= NEED_DTPMOD
;
2303 case R_IA64_LTOFF_FPTR22
:
2304 case R_IA64_LTOFF_FPTR64I
:
2305 case R_IA64_LTOFF_FPTR32MSB
:
2306 case R_IA64_LTOFF_FPTR32LSB
:
2307 case R_IA64_LTOFF_FPTR64MSB
:
2308 case R_IA64_LTOFF_FPTR64LSB
:
2309 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2312 case R_IA64_FPTR64I
:
2313 case R_IA64_FPTR32MSB
:
2314 case R_IA64_FPTR32LSB
:
2315 case R_IA64_FPTR64MSB
:
2316 case R_IA64_FPTR64LSB
:
2317 if (info
->shared
|| h
|| elfNN_ia64_aix_vec (abfd
->xvec
))
2318 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2320 need_entry
= NEED_FPTR
;
2321 dynrel_type
= R_IA64_FPTR64LSB
;
2324 case R_IA64_LTOFF22
:
2325 case R_IA64_LTOFF64I
:
2326 need_entry
= NEED_GOT
;
2329 case R_IA64_LTOFF22X
:
2330 need_entry
= NEED_GOTX
;
2333 case R_IA64_PLTOFF22
:
2334 case R_IA64_PLTOFF64I
:
2335 case R_IA64_PLTOFF64MSB
:
2336 case R_IA64_PLTOFF64LSB
:
2337 need_entry
= NEED_PLTOFF
;
2341 need_entry
|= NEED_MIN_PLT
;
2345 (*info
->callbacks
->warning
)
2346 (info
, _("@pltoff reloc against local symbol"), 0,
2347 abfd
, 0, (bfd_vma
) 0);
2351 case R_IA64_PCREL21B
:
2352 case R_IA64_PCREL60B
:
2353 /* Depending on where this symbol is defined, we may or may not
2354 need a full plt entry. Only skip if we know we'll not need
2355 the entry -- static or symbolic, and the symbol definition
2356 has already been seen. */
2357 if (maybe_dynamic
&& rel
->r_addend
== 0)
2358 need_entry
= NEED_FULL_PLT
;
2364 case R_IA64_DIR32MSB
:
2365 case R_IA64_DIR32LSB
:
2366 case R_IA64_DIR64MSB
:
2367 case R_IA64_DIR64LSB
:
2368 /* Shared objects will always need at least a REL relocation. */
2369 if (info
->shared
|| maybe_dynamic
2370 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2371 && (!h
|| strcmp (h
->root
.root
.string
,
2372 "__GLOB_DATA_PTR") != 0)))
2373 need_entry
= NEED_DYNREL
;
2374 dynrel_type
= R_IA64_DIR64LSB
;
2377 case R_IA64_IPLTMSB
:
2378 case R_IA64_IPLTLSB
:
2379 /* Shared objects will always need at least a REL relocation. */
2380 if (info
->shared
|| maybe_dynamic
)
2381 need_entry
= NEED_DYNREL
;
2382 dynrel_type
= R_IA64_IPLTLSB
;
2385 case R_IA64_PCREL22
:
2386 case R_IA64_PCREL64I
:
2387 case R_IA64_PCREL32MSB
:
2388 case R_IA64_PCREL32LSB
:
2389 case R_IA64_PCREL64MSB
:
2390 case R_IA64_PCREL64LSB
:
2392 need_entry
= NEED_DYNREL
;
2393 dynrel_type
= R_IA64_PCREL64LSB
;
2400 if ((need_entry
& NEED_FPTR
) != 0
2403 (*info
->callbacks
->warning
)
2404 (info
, _("non-zero addend in @fptr reloc"), 0,
2405 abfd
, 0, (bfd_vma
) 0);
2408 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, TRUE
);
2410 /* Record whether or not this is a local symbol. */
2413 /* Create what's needed. */
2414 if (need_entry
& (NEED_GOT
| NEED_GOTX
| NEED_TPREL
2415 | NEED_DTPMOD
| NEED_DTPREL
))
2419 got
= get_got (abfd
, info
, ia64_info
);
2423 if (need_entry
& NEED_GOT
)
2424 dyn_i
->want_got
= 1;
2425 if (need_entry
& NEED_GOTX
)
2426 dyn_i
->want_gotx
= 1;
2427 if (need_entry
& NEED_TPREL
)
2428 dyn_i
->want_tprel
= 1;
2429 if (need_entry
& NEED_DTPMOD
)
2430 dyn_i
->want_dtpmod
= 1;
2431 if (need_entry
& NEED_DTPREL
)
2432 dyn_i
->want_dtprel
= 1;
2434 if (need_entry
& NEED_FPTR
)
2438 fptr
= get_fptr (abfd
, info
, ia64_info
);
2443 /* FPTRs for shared libraries are allocated by the dynamic
2444 linker. Make sure this local symbol will appear in the
2445 dynamic symbol table. */
2446 if (!h
&& (info
->shared
2447 /* AIX also needs one */
2448 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2450 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2451 (info
, abfd
, (long) r_symndx
)))
2455 dyn_i
->want_fptr
= 1;
2457 if (need_entry
& NEED_LTOFF_FPTR
)
2458 dyn_i
->want_ltoff_fptr
= 1;
2459 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2461 if (!ia64_info
->root
.dynobj
)
2462 ia64_info
->root
.dynobj
= abfd
;
2463 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2464 dyn_i
->want_plt
= 1;
2466 if (need_entry
& NEED_FULL_PLT
)
2467 dyn_i
->want_plt2
= 1;
2468 if (need_entry
& NEED_PLTOFF
)
2469 dyn_i
->want_pltoff
= 1;
2470 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2474 srel
= get_reloc_section (abfd
, ia64_info
, sec
, TRUE
);
2478 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2486 /* For cleanliness, and potentially faster dynamic loading, allocate
2487 external GOT entries first. */
2490 allocate_global_data_got (dyn_i
, data
)
2491 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2494 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2496 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
2497 && ! dyn_i
->want_fptr
2498 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2499 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2500 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2501 "__GLOB_DATA_PTR") != 0))))
2503 dyn_i
->got_offset
= x
->ofs
;
2506 if (dyn_i
->want_tprel
)
2508 dyn_i
->tprel_offset
= x
->ofs
;
2511 if (dyn_i
->want_dtpmod
)
2513 if (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
))
2515 dyn_i
->dtpmod_offset
= x
->ofs
;
2520 struct elfNN_ia64_link_hash_table
*ia64_info
;
2522 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2523 if (ia64_info
->self_dtpmod_offset
== (bfd_vma
) -1)
2525 ia64_info
->self_dtpmod_offset
= x
->ofs
;
2528 dyn_i
->dtpmod_offset
= ia64_info
->self_dtpmod_offset
;
2531 if (dyn_i
->want_dtprel
)
2533 dyn_i
->dtprel_offset
= x
->ofs
;
2539 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2542 allocate_global_fptr_got (dyn_i
, data
)
2543 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2546 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2550 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2551 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2553 dyn_i
->got_offset
= x
->ofs
;
2559 /* Lastly, allocate all the GOT entries for local data. */
2562 allocate_local_got (dyn_i
, data
)
2563 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2566 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2568 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
2569 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2570 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2572 dyn_i
->got_offset
= x
->ofs
;
2578 /* Search for the index of a global symbol in it's defining object file. */
2581 global_sym_index (h
)
2582 struct elf_link_hash_entry
*h
;
2584 struct elf_link_hash_entry
**p
;
2587 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2588 || h
->root
.type
== bfd_link_hash_defweak
);
2590 obj
= h
->root
.u
.def
.section
->owner
;
2591 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2594 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2597 /* Allocate function descriptors. We can do these for every function
2598 in a main executable that is not exported. */
2601 allocate_fptr (dyn_i
, data
)
2602 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2605 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2607 if (dyn_i
->want_fptr
)
2609 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2612 while (h
->root
.type
== bfd_link_hash_indirect
2613 || h
->root
.type
== bfd_link_hash_warning
)
2614 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2617 /* AIX needs an FPTR in this case. */
2618 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2620 || h
->root
.type
== bfd_link_hash_defined
2621 || h
->root
.type
== bfd_link_hash_defweak
)))
2623 if (h
&& h
->dynindx
== -1)
2625 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2626 || (h
->root
.type
== bfd_link_hash_defweak
));
2628 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2629 (x
->info
, h
->root
.u
.def
.section
->owner
,
2630 global_sym_index (h
)))
2634 dyn_i
->want_fptr
= 0;
2636 else if (h
== NULL
|| h
->dynindx
== -1)
2638 dyn_i
->fptr_offset
= x
->ofs
;
2642 dyn_i
->want_fptr
= 0;
2647 /* Allocate all the minimal PLT entries. */
2650 allocate_plt_entries (dyn_i
, data
)
2651 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2654 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2656 if (dyn_i
->want_plt
)
2658 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2661 while (h
->root
.type
== bfd_link_hash_indirect
2662 || h
->root
.type
== bfd_link_hash_warning
)
2663 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2665 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2666 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2668 bfd_size_type offset
= x
->ofs
;
2670 offset
= PLT_HEADER_SIZE
;
2671 dyn_i
->plt_offset
= offset
;
2672 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2674 dyn_i
->want_pltoff
= 1;
2678 dyn_i
->want_plt
= 0;
2679 dyn_i
->want_plt2
= 0;
2685 /* Allocate all the full PLT entries. */
2688 allocate_plt2_entries (dyn_i
, data
)
2689 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2692 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2694 if (dyn_i
->want_plt2
)
2696 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2697 bfd_size_type ofs
= x
->ofs
;
2699 dyn_i
->plt2_offset
= ofs
;
2700 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2702 while (h
->root
.type
== bfd_link_hash_indirect
2703 || h
->root
.type
== bfd_link_hash_warning
)
2704 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2705 dyn_i
->h
->plt
.offset
= ofs
;
2710 /* Allocate all the PLTOFF entries requested by relocations and
2711 plt entries. We can't share space with allocated FPTR entries,
2712 because the latter are not necessarily addressable by the GP.
2713 ??? Relaxation might be able to determine that they are. */
2716 allocate_pltoff_entries (dyn_i
, data
)
2717 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2720 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2722 if (dyn_i
->want_pltoff
)
2724 dyn_i
->pltoff_offset
= x
->ofs
;
2730 /* Allocate dynamic relocations for those symbols that turned out
2734 allocate_dynrel_entries (dyn_i
, data
)
2735 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2738 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2739 struct elfNN_ia64_link_hash_table
*ia64_info
;
2740 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2741 bfd_boolean dynamic_symbol
, shared
;
2743 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2744 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2745 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2746 /* Don't allocate an entry for __GLOB_DATA_PTR */
2747 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2748 "__GLOB_DATA_PTR") != 0));
2749 shared
= x
->info
->shared
;
2751 /* Take care of the normal data relocations. */
2753 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2755 int count
= rent
->count
;
2759 case R_IA64_FPTR64LSB
:
2760 /* Allocate one iff !want_fptr, which by this point will
2761 be true only if we're actually allocating one statically
2762 in the main executable. */
2763 if (dyn_i
->want_fptr
)
2766 case R_IA64_PCREL64LSB
:
2767 if (!dynamic_symbol
)
2770 case R_IA64_DIR64LSB
:
2771 if (!dynamic_symbol
&& !shared
)
2774 case R_IA64_IPLTLSB
:
2775 if (!dynamic_symbol
&& !shared
)
2777 /* Use two REL relocations for IPLT relocations
2778 against local symbols. */
2779 if (!dynamic_symbol
)
2782 case R_IA64_TPREL64LSB
:
2783 case R_IA64_DTPREL64LSB
:
2784 case R_IA64_DTPMOD64LSB
:
2789 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2792 /* Take care of the GOT and PLT relocations. */
2794 if (((dynamic_symbol
|| shared
) && (dyn_i
->want_got
|| dyn_i
->want_gotx
))
2795 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2796 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2797 if ((dynamic_symbol
|| shared
) && dyn_i
->want_tprel
)
2798 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2799 if (dynamic_symbol
&& dyn_i
->want_dtpmod
)
2800 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2801 if (dynamic_symbol
&& dyn_i
->want_dtprel
)
2802 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2804 if (dyn_i
->want_pltoff
)
2806 bfd_size_type t
= 0;
2808 /* Dynamic symbols get one IPLT relocation. Local symbols in
2809 shared libraries get two REL relocations. Local symbols in
2810 main applications get nothing. */
2812 t
= sizeof (ElfNN_External_Rela
);
2814 t
= 2 * sizeof (ElfNN_External_Rela
);
2816 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2823 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2824 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2825 struct elf_link_hash_entry
*h
;
2827 /* ??? Undefined symbols with PLT entries should be re-defined
2828 to be the PLT entry. */
2830 /* If this is a weak symbol, and there is a real definition, the
2831 processor independent code will have arranged for us to see the
2832 real definition first, and we can just use the same value. */
2833 if (h
->weakdef
!= NULL
)
2835 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2836 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2837 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2838 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2842 /* If this is a reference to a symbol defined by a dynamic object which
2843 is not a function, we might allocate the symbol in our .dynbss section
2844 and allocate a COPY dynamic relocation.
2846 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2853 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2855 struct bfd_link_info
*info
;
2857 struct elfNN_ia64_allocate_data data
;
2858 struct elfNN_ia64_link_hash_table
*ia64_info
;
2861 bfd_boolean relplt
= FALSE
;
2863 dynobj
= elf_hash_table(info
)->dynobj
;
2864 ia64_info
= elfNN_ia64_hash_table (info
);
2865 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
2866 BFD_ASSERT(dynobj
!= NULL
);
2869 /* Set the contents of the .interp section to the interpreter. */
2870 if (ia64_info
->root
.dynamic_sections_created
2873 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2874 BFD_ASSERT (sec
!= NULL
);
2875 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2876 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2879 /* Allocate the GOT entries. */
2881 if (ia64_info
->got_sec
)
2884 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2885 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2886 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2887 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2890 /* Allocate the FPTR entries. */
2892 if (ia64_info
->fptr_sec
)
2895 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2896 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2899 /* Now that we've seen all of the input files, we can decide which
2900 symbols need plt entries. Allocate the minimal PLT entries first.
2901 We do this even though dynamic_sections_created may be FALSE, because
2902 this has the side-effect of clearing want_plt and want_plt2. */
2905 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2907 ia64_info
->minplt_entries
= 0;
2910 ia64_info
->minplt_entries
2911 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2914 /* Align the pointer for the plt2 entries. */
2915 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
2917 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2920 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2922 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2924 /* If we've got a .plt, we need some extra memory for the dynamic
2925 linker. We stuff these in .got.plt. */
2926 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2927 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2930 /* Allocate the PLTOFF entries. */
2932 if (ia64_info
->pltoff_sec
)
2935 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2936 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2939 if (ia64_info
->root
.dynamic_sections_created
)
2941 /* Allocate space for the dynamic relocations that turned out to be
2944 if (info
->shared
&& ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
2945 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2946 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2949 /* We have now determined the sizes of the various dynamic sections.
2950 Allocate memory for them. */
2951 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2955 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2958 /* If we don't need this section, strip it from the output file.
2959 There were several sections primarily related to dynamic
2960 linking that must be create before the linker maps input
2961 sections to output sections. The linker does that before
2962 bfd_elf_size_dynamic_sections is called, and it is that
2963 function which decides whether anything needs to go into
2966 strip
= (sec
->_raw_size
== 0);
2968 if (sec
== ia64_info
->got_sec
)
2970 else if (sec
== ia64_info
->rel_got_sec
)
2973 ia64_info
->rel_got_sec
= NULL
;
2975 /* We use the reloc_count field as a counter if we need to
2976 copy relocs into the output file. */
2977 sec
->reloc_count
= 0;
2979 else if (sec
== ia64_info
->fptr_sec
)
2982 ia64_info
->fptr_sec
= NULL
;
2984 else if (sec
== ia64_info
->plt_sec
)
2987 ia64_info
->plt_sec
= NULL
;
2989 else if (sec
== ia64_info
->pltoff_sec
)
2992 ia64_info
->pltoff_sec
= NULL
;
2994 else if (sec
== ia64_info
->rel_pltoff_sec
)
2997 ia64_info
->rel_pltoff_sec
= NULL
;
3001 /* We use the reloc_count field as a counter if we need to
3002 copy relocs into the output file. */
3003 sec
->reloc_count
= 0;
3010 /* It's OK to base decisions on the section name, because none
3011 of the dynobj section names depend upon the input files. */
3012 name
= bfd_get_section_name (dynobj
, sec
);
3014 if (strcmp (name
, ".got.plt") == 0)
3016 else if (strncmp (name
, ".rel", 4) == 0)
3020 /* We use the reloc_count field as a counter if we need to
3021 copy relocs into the output file. */
3022 sec
->reloc_count
= 0;
3030 _bfd_strip_section_from_output (info
, sec
);
3033 /* Allocate memory for the section contents. */
3034 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->_raw_size
);
3035 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
3040 if (elf_hash_table (info
)->dynamic_sections_created
)
3042 /* Add some entries to the .dynamic section. We fill in the values
3043 later (in finish_dynamic_sections) but we must add the entries now
3044 so that we get the correct size for the .dynamic section. */
3048 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3050 #define add_dynamic_entry(TAG, VAL) \
3051 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
3053 if (!add_dynamic_entry (DT_DEBUG
, 0))
3057 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
3059 if (!add_dynamic_entry (DT_PLTGOT
, 0))
3064 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
3065 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
3066 || !add_dynamic_entry (DT_JMPREL
, 0))
3070 if (!add_dynamic_entry (DT_RELA
, 0)
3071 || !add_dynamic_entry (DT_RELASZ
, 0)
3072 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
3075 if (ia64_info
->reltext
)
3077 if (!add_dynamic_entry (DT_TEXTREL
, 0))
3079 info
->flags
|= DF_TEXTREL
;
3083 /* ??? Perhaps force __gp local. */
3088 static bfd_reloc_status_type
3089 elfNN_ia64_install_value (abfd
, hit_addr
, v
, r_type
)
3093 unsigned int r_type
;
3095 const struct ia64_operand
*op
;
3096 int bigendian
= 0, shift
= 0;
3097 bfd_vma t0
, t1
, insn
, dword
;
3098 enum ia64_opnd opnd
;
3101 #ifdef BFD_HOST_U_64_BIT
3102 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
3107 opnd
= IA64_OPND_NIL
;
3112 return bfd_reloc_ok
;
3114 /* Instruction relocations. */
3117 case R_IA64_TPREL14
:
3118 case R_IA64_DTPREL14
:
3119 opnd
= IA64_OPND_IMM14
;
3122 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
3123 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
3124 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
3125 case R_IA64_PCREL21B
:
3126 case R_IA64_PCREL21BI
:
3127 opnd
= IA64_OPND_TGT25c
;
3131 case R_IA64_GPREL22
:
3132 case R_IA64_LTOFF22
:
3133 case R_IA64_LTOFF22X
:
3134 case R_IA64_PLTOFF22
:
3135 case R_IA64_PCREL22
:
3136 case R_IA64_LTOFF_FPTR22
:
3137 case R_IA64_TPREL22
:
3138 case R_IA64_DTPREL22
:
3139 case R_IA64_LTOFF_TPREL22
:
3140 case R_IA64_LTOFF_DTPMOD22
:
3141 case R_IA64_LTOFF_DTPREL22
:
3142 opnd
= IA64_OPND_IMM22
;
3146 case R_IA64_GPREL64I
:
3147 case R_IA64_LTOFF64I
:
3148 case R_IA64_PLTOFF64I
:
3149 case R_IA64_PCREL64I
:
3150 case R_IA64_FPTR64I
:
3151 case R_IA64_LTOFF_FPTR64I
:
3152 case R_IA64_TPREL64I
:
3153 case R_IA64_DTPREL64I
:
3154 opnd
= IA64_OPND_IMMU64
;
3157 /* Data relocations. */
3159 case R_IA64_DIR32MSB
:
3160 case R_IA64_GPREL32MSB
:
3161 case R_IA64_FPTR32MSB
:
3162 case R_IA64_PCREL32MSB
:
3163 case R_IA64_LTOFF_FPTR32MSB
:
3164 case R_IA64_SEGREL32MSB
:
3165 case R_IA64_SECREL32MSB
:
3166 case R_IA64_LTV32MSB
:
3167 case R_IA64_DTPREL32MSB
:
3168 size
= 4; bigendian
= 1;
3171 case R_IA64_DIR32LSB
:
3172 case R_IA64_GPREL32LSB
:
3173 case R_IA64_FPTR32LSB
:
3174 case R_IA64_PCREL32LSB
:
3175 case R_IA64_LTOFF_FPTR32LSB
:
3176 case R_IA64_SEGREL32LSB
:
3177 case R_IA64_SECREL32LSB
:
3178 case R_IA64_LTV32LSB
:
3179 case R_IA64_DTPREL32LSB
:
3180 size
= 4; bigendian
= 0;
3183 case R_IA64_DIR64MSB
:
3184 case R_IA64_GPREL64MSB
:
3185 case R_IA64_PLTOFF64MSB
:
3186 case R_IA64_FPTR64MSB
:
3187 case R_IA64_PCREL64MSB
:
3188 case R_IA64_LTOFF_FPTR64MSB
:
3189 case R_IA64_SEGREL64MSB
:
3190 case R_IA64_SECREL64MSB
:
3191 case R_IA64_LTV64MSB
:
3192 case R_IA64_TPREL64MSB
:
3193 case R_IA64_DTPMOD64MSB
:
3194 case R_IA64_DTPREL64MSB
:
3195 size
= 8; bigendian
= 1;
3198 case R_IA64_DIR64LSB
:
3199 case R_IA64_GPREL64LSB
:
3200 case R_IA64_PLTOFF64LSB
:
3201 case R_IA64_FPTR64LSB
:
3202 case R_IA64_PCREL64LSB
:
3203 case R_IA64_LTOFF_FPTR64LSB
:
3204 case R_IA64_SEGREL64LSB
:
3205 case R_IA64_SECREL64LSB
:
3206 case R_IA64_LTV64LSB
:
3207 case R_IA64_TPREL64LSB
:
3208 case R_IA64_DTPMOD64LSB
:
3209 case R_IA64_DTPREL64LSB
:
3210 size
= 8; bigendian
= 0;
3213 /* Unsupported / Dynamic relocations. */
3215 return bfd_reloc_notsupported
;
3220 case IA64_OPND_IMMU64
:
3221 hit_addr
-= (long) hit_addr
& 0x3;
3222 t0
= bfd_get_64 (abfd
, hit_addr
);
3223 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
3225 /* tmpl/s: bits 0.. 5 in t0
3226 slot 0: bits 5..45 in t0
3227 slot 1: bits 46..63 in t0, bits 0..22 in t1
3228 slot 2: bits 23..63 in t1 */
3230 /* First, clear the bits that form the 64 bit constant. */
3231 t0
&= ~(0x3ffffLL
<< 46);
3233 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
3234 | (0x01fLL
<< 22) | (0x001LL
<< 21)
3235 | (0x001LL
<< 36)) << 23));
3237 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
3238 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
3239 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
3240 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
3241 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
3242 | (((val
>> 21) & 0x001) << 21) /* ic */
3243 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
3245 bfd_put_64 (abfd
, t0
, hit_addr
);
3246 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3249 case IA64_OPND_TGT64
:
3250 hit_addr
-= (long) hit_addr
& 0x3;
3251 t0
= bfd_get_64 (abfd
, hit_addr
);
3252 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
3254 /* tmpl/s: bits 0.. 5 in t0
3255 slot 0: bits 5..45 in t0
3256 slot 1: bits 46..63 in t0, bits 0..22 in t1
3257 slot 2: bits 23..63 in t1 */
3259 /* First, clear the bits that form the 64 bit constant. */
3260 t0
&= ~(0x3ffffLL
<< 46);
3262 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
3265 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
3266 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
3267 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
3268 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
3270 bfd_put_64 (abfd
, t0
, hit_addr
);
3271 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3275 switch ((long) hit_addr
& 0x3)
3277 case 0: shift
= 5; break;
3278 case 1: shift
= 14; hit_addr
+= 3; break;
3279 case 2: shift
= 23; hit_addr
+= 6; break;
3280 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
3282 dword
= bfd_get_64 (abfd
, hit_addr
);
3283 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
3285 op
= elf64_ia64_operands
+ opnd
;
3286 err
= (*op
->insert
) (op
, val
, (ia64_insn
*)& insn
);
3288 return bfd_reloc_overflow
;
3290 dword
&= ~(0x1ffffffffffLL
<< shift
);
3291 dword
|= (insn
<< shift
);
3292 bfd_put_64 (abfd
, dword
, hit_addr
);
3296 /* A data relocation. */
3299 bfd_putb32 (val
, hit_addr
);
3301 bfd_putb64 (val
, hit_addr
);
3304 bfd_putl32 (val
, hit_addr
);
3306 bfd_putl64 (val
, hit_addr
);
3310 return bfd_reloc_ok
;
3314 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
3317 struct bfd_link_info
*info
;
3325 Elf_Internal_Rela outrel
;
3328 BFD_ASSERT (dynindx
!= -1);
3329 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3330 outrel
.r_addend
= addend
;
3331 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3332 if (outrel
.r_offset
>= (bfd_vma
) -2)
3334 /* Run for the hills. We shouldn't be outputting a relocation
3335 for this. So do what everyone else does and output a no-op. */
3336 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3337 outrel
.r_addend
= 0;
3338 outrel
.r_offset
= 0;
3341 outrel
.r_offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3343 loc
= srel
->contents
;
3344 loc
+= srel
->reloc_count
++ * sizeof (ElfNN_External_Rela
);
3345 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
3346 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3347 <= srel
->_cooked_size
);
3350 /* Store an entry for target address TARGET_ADDR in the linkage table
3351 and return the gp-relative address of the linkage table entry. */
3354 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3356 struct bfd_link_info
*info
;
3357 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3361 unsigned int dyn_r_type
;
3363 struct elfNN_ia64_link_hash_table
*ia64_info
;
3368 ia64_info
= elfNN_ia64_hash_table (info
);
3369 got_sec
= ia64_info
->got_sec
;
3373 case R_IA64_TPREL64LSB
:
3374 done
= dyn_i
->tprel_done
;
3375 dyn_i
->tprel_done
= TRUE
;
3376 got_offset
= dyn_i
->tprel_offset
;
3378 case R_IA64_DTPMOD64LSB
:
3379 if (dyn_i
->dtpmod_offset
!= ia64_info
->self_dtpmod_offset
)
3381 done
= dyn_i
->dtpmod_done
;
3382 dyn_i
->dtpmod_done
= TRUE
;
3386 done
= ia64_info
->self_dtpmod_done
;
3387 ia64_info
->self_dtpmod_done
= TRUE
;
3390 got_offset
= dyn_i
->dtpmod_offset
;
3392 case R_IA64_DTPREL64LSB
:
3393 done
= dyn_i
->dtprel_done
;
3394 dyn_i
->dtprel_done
= TRUE
;
3395 got_offset
= dyn_i
->dtprel_offset
;
3398 done
= dyn_i
->got_done
;
3399 dyn_i
->got_done
= TRUE
;
3400 got_offset
= dyn_i
->got_offset
;
3404 BFD_ASSERT ((got_offset
& 7) == 0);
3408 /* Store the target address in the linkage table entry. */
3409 bfd_put_64 (abfd
, value
, got_sec
->contents
+ got_offset
);
3411 /* Install a dynamic relocation if needed. */
3412 if ((info
->shared
&& dyn_r_type
!= R_IA64_DTPREL64LSB
)
3413 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3414 || elfNN_ia64_aix_vec (abfd
->xvec
)
3415 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3418 && dyn_r_type
!= R_IA64_TPREL64LSB
3419 && dyn_r_type
!= R_IA64_DTPMOD64LSB
3420 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
3422 dyn_r_type
= R_IA64_REL64LSB
;
3427 if (bfd_big_endian (abfd
))
3431 case R_IA64_REL64LSB
:
3432 dyn_r_type
= R_IA64_REL64MSB
;
3434 case R_IA64_DIR64LSB
:
3435 dyn_r_type
= R_IA64_DIR64MSB
;
3437 case R_IA64_FPTR64LSB
:
3438 dyn_r_type
= R_IA64_FPTR64MSB
;
3440 case R_IA64_TPREL64LSB
:
3441 dyn_r_type
= R_IA64_TPREL64MSB
;
3443 case R_IA64_DTPMOD64LSB
:
3444 dyn_r_type
= R_IA64_DTPMOD64MSB
;
3446 case R_IA64_DTPREL64LSB
:
3447 dyn_r_type
= R_IA64_DTPREL64MSB
;
3455 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3456 ia64_info
->rel_got_sec
,
3457 got_offset
, dyn_r_type
,
3462 /* Return the address of the linkage table entry. */
3463 value
= (got_sec
->output_section
->vma
3464 + got_sec
->output_offset
3470 /* Fill in a function descriptor consisting of the function's code
3471 address and its global pointer. Return the descriptor's address. */
3474 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3476 struct bfd_link_info
*info
;
3477 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3480 struct elfNN_ia64_link_hash_table
*ia64_info
;
3483 ia64_info
= elfNN_ia64_hash_table (info
);
3484 fptr_sec
= ia64_info
->fptr_sec
;
3486 if (!dyn_i
->fptr_done
)
3488 dyn_i
->fptr_done
= 1;
3490 /* Fill in the function descriptor. */
3491 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3492 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3493 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3496 /* Return the descriptor's address. */
3497 value
= (fptr_sec
->output_section
->vma
3498 + fptr_sec
->output_offset
3499 + dyn_i
->fptr_offset
);
3504 /* Fill in a PLTOFF entry consisting of the function's code address
3505 and its global pointer. Return the descriptor's address. */
3508 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3510 struct bfd_link_info
*info
;
3511 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3515 struct elfNN_ia64_link_hash_table
*ia64_info
;
3516 asection
*pltoff_sec
;
3518 ia64_info
= elfNN_ia64_hash_table (info
);
3519 pltoff_sec
= ia64_info
->pltoff_sec
;
3521 /* Don't do anything if this symbol uses a real PLT entry. In
3522 that case, we'll fill this in during finish_dynamic_symbol. */
3523 if ((! dyn_i
->want_plt
|| is_plt
)
3524 && !dyn_i
->pltoff_done
)
3526 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3528 /* Fill in the function descriptor. */
3529 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3530 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3532 /* Install dynamic relocations if needed. */
3533 if (!is_plt
&& info
->shared
)
3535 unsigned int dyn_r_type
;
3537 if (bfd_big_endian (abfd
))
3538 dyn_r_type
= R_IA64_REL64MSB
;
3540 dyn_r_type
= R_IA64_REL64LSB
;
3542 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3543 ia64_info
->rel_pltoff_sec
,
3544 dyn_i
->pltoff_offset
,
3545 dyn_r_type
, 0, value
);
3546 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3547 ia64_info
->rel_pltoff_sec
,
3548 dyn_i
->pltoff_offset
+ 8,
3552 dyn_i
->pltoff_done
= 1;
3555 /* Return the descriptor's address. */
3556 value
= (pltoff_sec
->output_section
->vma
3557 + pltoff_sec
->output_offset
3558 + dyn_i
->pltoff_offset
);
3563 /* Return the base VMA address which should be subtracted from real addresses
3564 when resolving @tprel() relocation.
3565 Main program TLS (whose template starts at PT_TLS p_vaddr)
3566 is assigned offset round(16, PT_TLS p_align). */
3569 elfNN_ia64_tprel_base (info
)
3570 struct bfd_link_info
*info
;
3572 struct elf_link_tls_segment
*tls_segment
3573 = elf_hash_table (info
)->tls_segment
;
3575 BFD_ASSERT (tls_segment
!= NULL
);
3576 return (tls_segment
->start
3577 - align_power ((bfd_vma
) 16, tls_segment
->align
));
3580 /* Return the base VMA address which should be subtracted from real addresses
3581 when resolving @dtprel() relocation.
3582 This is PT_TLS segment p_vaddr. */
3585 elfNN_ia64_dtprel_base (info
)
3586 struct bfd_link_info
*info
;
3588 BFD_ASSERT (elf_hash_table (info
)->tls_segment
!= NULL
);
3589 return elf_hash_table (info
)->tls_segment
->start
;
3592 /* Called through qsort to sort the .IA_64.unwind section during a
3593 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3594 to the output bfd so we can do proper endianness frobbing. */
3596 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3599 elfNN_ia64_unwind_entry_compare (a
, b
)
3605 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3606 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3608 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3611 /* Make sure we've got ourselves a nice fat __gp value. */
3613 elfNN_ia64_choose_gp (abfd
, info
)
3615 struct bfd_link_info
*info
;
3617 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3618 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3619 struct elf_link_hash_entry
*gp
;
3622 struct elfNN_ia64_link_hash_table
*ia64_info
;
3624 ia64_info
= elfNN_ia64_hash_table (info
);
3626 /* Find the min and max vma of all sections marked short. Also collect
3627 min and max vma of any type, for use in selecting a nice gp. */
3628 for (os
= abfd
->sections
; os
; os
= os
->next
)
3632 if ((os
->flags
& SEC_ALLOC
) == 0)
3636 hi
= os
->vma
+ os
->_raw_size
;
3644 if (os
->flags
& SEC_SMALL_DATA
)
3646 if (min_short_vma
> lo
)
3648 if (max_short_vma
< hi
)
3653 /* See if the user wants to force a value. */
3654 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
3658 && (gp
->root
.type
== bfd_link_hash_defined
3659 || gp
->root
.type
== bfd_link_hash_defweak
))
3661 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3662 gp_val
= (gp
->root
.u
.def
.value
3663 + gp_sec
->output_section
->vma
3664 + gp_sec
->output_offset
);
3668 /* Pick a sensible value. */
3670 asection
*got_sec
= ia64_info
->got_sec
;
3672 /* Start with just the address of the .got. */
3674 gp_val
= got_sec
->output_section
->vma
;
3675 else if (max_short_vma
!= 0)
3676 gp_val
= min_short_vma
;
3680 /* If it is possible to address the entire image, but we
3681 don't with the choice above, adjust. */
3682 if (max_vma
- min_vma
< 0x400000
3683 && max_vma
- gp_val
<= 0x200000
3684 && gp_val
- min_vma
> 0x200000)
3685 gp_val
= min_vma
+ 0x200000;
3686 else if (max_short_vma
!= 0)
3688 /* If we don't cover all the short data, adjust. */
3689 if (max_short_vma
- gp_val
>= 0x200000)
3690 gp_val
= min_short_vma
+ 0x200000;
3692 /* If we're addressing stuff past the end, adjust back. */
3693 if (gp_val
> max_vma
)
3694 gp_val
= max_vma
- 0x200000 + 8;
3698 /* Validate whether all SHF_IA_64_SHORT sections are within
3699 range of the chosen GP. */
3701 if (max_short_vma
!= 0)
3703 if (max_short_vma
- min_short_vma
>= 0x400000)
3705 (*_bfd_error_handler
)
3706 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3707 bfd_get_filename (abfd
),
3708 (unsigned long) (max_short_vma
- min_short_vma
));
3711 else if ((gp_val
> min_short_vma
3712 && gp_val
- min_short_vma
> 0x200000)
3713 || (gp_val
< max_short_vma
3714 && max_short_vma
- gp_val
>= 0x200000))
3716 (*_bfd_error_handler
)
3717 (_("%s: __gp does not cover short data segment"),
3718 bfd_get_filename (abfd
));
3723 _bfd_set_gp_value (abfd
, gp_val
);
3729 elfNN_ia64_final_link (abfd
, info
)
3731 struct bfd_link_info
*info
;
3733 struct elfNN_ia64_link_hash_table
*ia64_info
;
3734 asection
*unwind_output_sec
;
3736 ia64_info
= elfNN_ia64_hash_table (info
);
3738 /* Make sure we've got ourselves a nice fat __gp value. */
3739 if (!info
->relocateable
)
3741 bfd_vma gp_val
= _bfd_get_gp_value (abfd
);
3742 struct elf_link_hash_entry
*gp
;
3746 if (! elfNN_ia64_choose_gp (abfd
, info
))
3748 gp_val
= _bfd_get_gp_value (abfd
);
3751 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
3755 gp
->root
.type
= bfd_link_hash_defined
;
3756 gp
->root
.u
.def
.value
= gp_val
;
3757 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3761 /* If we're producing a final executable, we need to sort the contents
3762 of the .IA_64.unwind section. Force this section to be relocated
3763 into memory rather than written immediately to the output file. */
3764 unwind_output_sec
= NULL
;
3765 if (!info
->relocateable
)
3767 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3770 unwind_output_sec
= s
->output_section
;
3771 unwind_output_sec
->contents
3772 = bfd_malloc (unwind_output_sec
->_raw_size
);
3773 if (unwind_output_sec
->contents
== NULL
)
3778 /* Invoke the regular ELF backend linker to do all the work. */
3779 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3782 if (unwind_output_sec
)
3784 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3785 qsort (unwind_output_sec
->contents
,
3786 (size_t) (unwind_output_sec
->_raw_size
/ 24),
3788 elfNN_ia64_unwind_entry_compare
);
3790 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3791 unwind_output_sec
->contents
, (bfd_vma
) 0,
3792 unwind_output_sec
->_raw_size
))
3800 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3801 contents
, relocs
, local_syms
, local_sections
)
3803 struct bfd_link_info
*info
;
3805 asection
*input_section
;
3807 Elf_Internal_Rela
*relocs
;
3808 Elf_Internal_Sym
*local_syms
;
3809 asection
**local_sections
;
3811 struct elfNN_ia64_link_hash_table
*ia64_info
;
3812 Elf_Internal_Shdr
*symtab_hdr
;
3813 Elf_Internal_Rela
*rel
;
3814 Elf_Internal_Rela
*relend
;
3816 bfd_boolean ret_val
= TRUE
; /* for non-fatal errors */
3819 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3820 ia64_info
= elfNN_ia64_hash_table (info
);
3822 /* Infect various flags from the input section to the output section. */
3823 if (info
->relocateable
)
3827 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3828 flags
&= SHF_IA_64_NORECOV
;
3830 elf_section_data(input_section
->output_section
)
3831 ->this_hdr
.sh_flags
|= flags
;
3835 gp_val
= _bfd_get_gp_value (output_bfd
);
3836 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, FALSE
);
3839 relend
= relocs
+ input_section
->reloc_count
;
3840 for (; rel
< relend
; ++rel
)
3842 struct elf_link_hash_entry
*h
;
3843 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3844 bfd_reloc_status_type r
;
3845 reloc_howto_type
*howto
;
3846 unsigned long r_symndx
;
3847 Elf_Internal_Sym
*sym
;
3848 unsigned int r_type
;
3852 bfd_boolean dynamic_symbol_p
;
3853 bfd_boolean undef_weak_ref
;
3855 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3856 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3858 (*_bfd_error_handler
)
3859 (_("%s: unknown relocation type %d"),
3860 bfd_archive_filename (input_bfd
), (int)r_type
);
3861 bfd_set_error (bfd_error_bad_value
);
3866 howto
= lookup_howto (r_type
);
3867 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3871 undef_weak_ref
= FALSE
;
3873 if (r_symndx
< symtab_hdr
->sh_info
)
3875 /* Reloc against local symbol. */
3876 sym
= local_syms
+ r_symndx
;
3877 sym_sec
= local_sections
[r_symndx
];
3878 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, sym_sec
, rel
);
3879 if ((sym_sec
->flags
& SEC_MERGE
)
3880 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
3881 && sym_sec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
3883 struct elfNN_ia64_local_hash_entry
*loc_h
;
3885 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, FALSE
);
3886 if (loc_h
&& ! loc_h
->sec_merge_done
)
3888 struct elfNN_ia64_dyn_sym_info
*dynent
;
3891 for (dynent
= loc_h
->info
; dynent
; dynent
= dynent
->next
)
3895 _bfd_merged_section_offset (output_bfd
, &msec
,
3896 elf_section_data (msec
)->
3901 dynent
->addend
-= sym
->st_value
;
3902 dynent
->addend
+= msec
->output_section
->vma
3903 + msec
->output_offset
3904 - sym_sec
->output_section
->vma
3905 - sym_sec
->output_offset
;
3907 loc_h
->sec_merge_done
= 1;
3915 /* Reloc against global symbol. */
3916 indx
= r_symndx
- symtab_hdr
->sh_info
;
3917 h
= elf_sym_hashes (input_bfd
)[indx
];
3918 while (h
->root
.type
== bfd_link_hash_indirect
3919 || h
->root
.type
== bfd_link_hash_warning
)
3920 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3923 if (h
->root
.type
== bfd_link_hash_defined
3924 || h
->root
.type
== bfd_link_hash_defweak
)
3926 sym_sec
= h
->root
.u
.def
.section
;
3928 /* Detect the cases that sym_sec->output_section is
3929 expected to be NULL -- all cases in which the symbol
3930 is defined in another shared module. This includes
3931 PLT relocs for which we've created a PLT entry and
3932 other relocs for which we're prepared to create
3933 dynamic relocations. */
3934 /* ??? Just accept it NULL and continue. */
3936 if (sym_sec
->output_section
!= NULL
)
3938 value
= (h
->root
.u
.def
.value
3939 + sym_sec
->output_section
->vma
3940 + sym_sec
->output_offset
);
3943 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3944 undef_weak_ref
= TRUE
;
3945 else if (info
->shared
3946 && !info
->no_undefined
3947 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3951 if (! ((*info
->callbacks
->undefined_symbol
)
3952 (info
, h
->root
.root
.string
, input_bfd
,
3953 input_section
, rel
->r_offset
,
3954 (!info
->shared
|| info
->no_undefined
3955 || ELF_ST_VISIBILITY (h
->other
)))))
3962 hit_addr
= contents
+ rel
->r_offset
;
3963 value
+= rel
->r_addend
;
3964 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3975 case R_IA64_DIR32MSB
:
3976 case R_IA64_DIR32LSB
:
3977 case R_IA64_DIR64MSB
:
3978 case R_IA64_DIR64LSB
:
3979 /* Install a dynamic relocation for this reloc. */
3980 if ((dynamic_symbol_p
|| info
->shared
3981 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
3982 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3983 && (!h
|| strcmp (h
->root
.root
.string
,
3984 "__GLOB_DATA_PTR") != 0)))
3986 && (input_section
->flags
& SEC_ALLOC
) != 0)
3988 unsigned int dyn_r_type
;
3992 BFD_ASSERT (srel
!= NULL
);
3994 /* If we don't need dynamic symbol lookup, find a
3995 matching RELATIVE relocation. */
3996 dyn_r_type
= r_type
;
3997 if (dynamic_symbol_p
)
3999 dynindx
= h
->dynindx
;
4000 addend
= rel
->r_addend
;
4007 case R_IA64_DIR32MSB
:
4008 dyn_r_type
= R_IA64_REL32MSB
;
4010 case R_IA64_DIR32LSB
:
4011 dyn_r_type
= R_IA64_REL32LSB
;
4013 case R_IA64_DIR64MSB
:
4014 dyn_r_type
= R_IA64_REL64MSB
;
4016 case R_IA64_DIR64LSB
:
4017 dyn_r_type
= R_IA64_REL64LSB
;
4021 /* We can't represent this without a dynamic symbol.
4022 Adjust the relocation to be against an output
4023 section symbol, which are always present in the
4024 dynamic symbol table. */
4025 /* ??? People shouldn't be doing non-pic code in
4026 shared libraries. Hork. */
4027 (*_bfd_error_handler
)
4028 (_("%s: linking non-pic code in a shared library"),
4029 bfd_archive_filename (input_bfd
));
4037 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
4038 rel
->r_addend
= value
;
4039 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4040 srel
, rel
->r_offset
, dyn_r_type
,
4045 case R_IA64_LTV32MSB
:
4046 case R_IA64_LTV32LSB
:
4047 case R_IA64_LTV64MSB
:
4048 case R_IA64_LTV64LSB
:
4049 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4052 case R_IA64_GPREL22
:
4053 case R_IA64_GPREL64I
:
4054 case R_IA64_GPREL32MSB
:
4055 case R_IA64_GPREL32LSB
:
4056 case R_IA64_GPREL64MSB
:
4057 case R_IA64_GPREL64LSB
:
4058 if (dynamic_symbol_p
)
4060 (*_bfd_error_handler
)
4061 (_("%s: @gprel relocation against dynamic symbol %s"),
4062 bfd_archive_filename (input_bfd
), h
->root
.root
.string
);
4067 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4070 case R_IA64_LTOFF22
:
4071 case R_IA64_LTOFF22X
:
4072 case R_IA64_LTOFF64I
:
4073 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4074 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
4075 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
4077 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4080 case R_IA64_PLTOFF22
:
4081 case R_IA64_PLTOFF64I
:
4082 case R_IA64_PLTOFF64MSB
:
4083 case R_IA64_PLTOFF64LSB
:
4084 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4085 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, FALSE
);
4087 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4090 case R_IA64_FPTR64I
:
4091 case R_IA64_FPTR32MSB
:
4092 case R_IA64_FPTR32LSB
:
4093 case R_IA64_FPTR64MSB
:
4094 case R_IA64_FPTR64LSB
:
4095 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4096 if (dyn_i
->want_fptr
)
4098 if (!undef_weak_ref
)
4099 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4105 /* Otherwise, we expect the dynamic linker to create
4110 if (h
->dynindx
!= -1)
4111 dynindx
= h
->dynindx
;
4113 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4114 (info
, h
->root
.u
.def
.section
->owner
,
4115 global_sym_index (h
)));
4119 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4120 (info
, input_bfd
, (long) r_symndx
));
4123 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4124 srel
, rel
->r_offset
, r_type
,
4125 dynindx
, rel
->r_addend
);
4129 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4132 case R_IA64_LTOFF_FPTR22
:
4133 case R_IA64_LTOFF_FPTR64I
:
4134 case R_IA64_LTOFF_FPTR32MSB
:
4135 case R_IA64_LTOFF_FPTR32LSB
:
4136 case R_IA64_LTOFF_FPTR64MSB
:
4137 case R_IA64_LTOFF_FPTR64LSB
:
4141 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4142 if (dyn_i
->want_fptr
)
4144 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
4145 if (!undef_weak_ref
)
4146 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4151 /* Otherwise, we expect the dynamic linker to create
4155 if (h
->dynindx
!= -1)
4156 dynindx
= h
->dynindx
;
4158 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4159 (info
, h
->root
.u
.def
.section
->owner
,
4160 global_sym_index (h
)));
4163 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4164 (info
, input_bfd
, (long) r_symndx
));
4168 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
4169 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
4171 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4175 case R_IA64_PCREL32MSB
:
4176 case R_IA64_PCREL32LSB
:
4177 case R_IA64_PCREL64MSB
:
4178 case R_IA64_PCREL64LSB
:
4179 /* Install a dynamic relocation for this reloc. */
4180 if ((dynamic_symbol_p
4181 || elfNN_ia64_aix_vec (info
->hash
->creator
))
4184 BFD_ASSERT (srel
!= NULL
);
4186 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4187 srel
, rel
->r_offset
, r_type
,
4188 h
->dynindx
, rel
->r_addend
);
4192 case R_IA64_PCREL21B
:
4193 case R_IA64_PCREL60B
:
4194 /* We should have created a PLT entry for any dynamic symbol. */
4197 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4199 if (dyn_i
&& dyn_i
->want_plt2
)
4201 /* Should have caught this earlier. */
4202 BFD_ASSERT (rel
->r_addend
== 0);
4204 value
= (ia64_info
->plt_sec
->output_section
->vma
4205 + ia64_info
->plt_sec
->output_offset
4206 + dyn_i
->plt2_offset
);
4210 /* Since there's no PLT entry, Validate that this is
4212 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
4214 /* If the symbol is undef_weak, we shouldn't be trying
4215 to call it. There's every chance that we'd wind up
4216 with an out-of-range fixup here. Don't bother setting
4217 any value at all. */
4223 case R_IA64_PCREL21BI
:
4224 case R_IA64_PCREL21F
:
4225 case R_IA64_PCREL21M
:
4226 case R_IA64_PCREL22
:
4227 case R_IA64_PCREL64I
:
4228 /* The PCREL21BI reloc is specifically not intended for use with
4229 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4230 fixup code, and thus probably ought not be dynamic. The
4231 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4232 if (dynamic_symbol_p
)
4236 if (r_type
== R_IA64_PCREL21BI
)
4237 msg
= _("%s: @internal branch to dynamic symbol %s");
4238 else if (r_type
== R_IA64_PCREL21F
|| r_type
== R_IA64_PCREL21M
)
4239 msg
= _("%s: speculation fixup to dynamic symbol %s");
4241 msg
= _("%s: @pcrel relocation against dynamic symbol %s");
4242 (*_bfd_error_handler
) (msg
, bfd_archive_filename (input_bfd
),
4243 h
->root
.root
.string
);
4250 /* Make pc-relative. */
4251 value
-= (input_section
->output_section
->vma
4252 + input_section
->output_offset
4253 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
4254 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4257 case R_IA64_SEGREL32MSB
:
4258 case R_IA64_SEGREL32LSB
:
4259 case R_IA64_SEGREL64MSB
:
4260 case R_IA64_SEGREL64LSB
:
4263 /* If the input section was discarded from the output, then
4269 struct elf_segment_map
*m
;
4270 Elf_Internal_Phdr
*p
;
4272 /* Find the segment that contains the output_section. */
4273 for (m
= elf_tdata (output_bfd
)->segment_map
,
4274 p
= elf_tdata (output_bfd
)->phdr
;
4279 for (i
= m
->count
- 1; i
>= 0; i
--)
4280 if (m
->sections
[i
] == sym_sec
->output_section
)
4288 r
= bfd_reloc_notsupported
;
4292 /* The VMA of the segment is the vaddr of the associated
4294 if (value
> p
->p_vaddr
)
4295 value
-= p
->p_vaddr
;
4298 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
4304 case R_IA64_SECREL32MSB
:
4305 case R_IA64_SECREL32LSB
:
4306 case R_IA64_SECREL64MSB
:
4307 case R_IA64_SECREL64LSB
:
4308 /* Make output-section relative. */
4309 if (value
> input_section
->output_section
->vma
)
4310 value
-= input_section
->output_section
->vma
;
4313 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4316 case R_IA64_IPLTMSB
:
4317 case R_IA64_IPLTLSB
:
4318 /* Install a dynamic relocation for this reloc. */
4319 if ((dynamic_symbol_p
|| info
->shared
)
4320 && (input_section
->flags
& SEC_ALLOC
) != 0)
4322 BFD_ASSERT (srel
!= NULL
);
4324 /* If we don't need dynamic symbol lookup, install two
4325 RELATIVE relocations. */
4326 if (! dynamic_symbol_p
)
4328 unsigned int dyn_r_type
;
4330 if (r_type
== R_IA64_IPLTMSB
)
4331 dyn_r_type
= R_IA64_REL64MSB
;
4333 dyn_r_type
= R_IA64_REL64LSB
;
4335 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4337 srel
, rel
->r_offset
,
4338 dyn_r_type
, 0, value
);
4339 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4341 srel
, rel
->r_offset
+ 8,
4342 dyn_r_type
, 0, gp_val
);
4345 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4346 srel
, rel
->r_offset
, r_type
,
4347 h
->dynindx
, rel
->r_addend
);
4350 if (r_type
== R_IA64_IPLTMSB
)
4351 r_type
= R_IA64_DIR64MSB
;
4353 r_type
= R_IA64_DIR64LSB
;
4354 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4355 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
4359 case R_IA64_TPREL14
:
4360 case R_IA64_TPREL22
:
4361 case R_IA64_TPREL64I
:
4362 value
-= elfNN_ia64_tprel_base (info
);
4363 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4366 case R_IA64_DTPREL14
:
4367 case R_IA64_DTPREL22
:
4368 case R_IA64_DTPREL64I
:
4369 case R_IA64_DTPREL64LSB
:
4370 case R_IA64_DTPREL64MSB
:
4371 value
-= elfNN_ia64_dtprel_base (info
);
4372 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4375 case R_IA64_LTOFF_TPREL22
:
4376 case R_IA64_LTOFF_DTPMOD22
:
4377 case R_IA64_LTOFF_DTPREL22
:
4380 long dynindx
= h
? h
->dynindx
: -1;
4381 bfd_vma r_addend
= rel
->r_addend
;
4386 case R_IA64_LTOFF_TPREL22
:
4387 if (!dynamic_symbol_p
)
4390 value
-= elfNN_ia64_tprel_base (info
);
4393 r_addend
+= value
- elfNN_ia64_dtprel_base (info
);
4397 got_r_type
= R_IA64_TPREL64LSB
;
4399 case R_IA64_LTOFF_DTPMOD22
:
4400 if (!dynamic_symbol_p
&& !info
->shared
)
4402 got_r_type
= R_IA64_DTPMOD64LSB
;
4404 case R_IA64_LTOFF_DTPREL22
:
4405 if (!dynamic_symbol_p
)
4406 value
-= elfNN_ia64_dtprel_base (info
);
4407 got_r_type
= R_IA64_DTPREL64LSB
;
4410 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4411 value
= set_got_entry (input_bfd
, info
, dyn_i
, dynindx
, r_addend
,
4414 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
4420 r
= bfd_reloc_notsupported
;
4429 case bfd_reloc_undefined
:
4430 /* This can happen for global table relative relocs if
4431 __gp is undefined. This is a panic situation so we
4432 don't try to continue. */
4433 (*info
->callbacks
->undefined_symbol
)
4434 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
4437 case bfd_reloc_notsupported
:
4442 name
= h
->root
.root
.string
;
4445 name
= bfd_elf_string_from_elf_section (input_bfd
,
4446 symtab_hdr
->sh_link
,
4451 name
= bfd_section_name (input_bfd
, input_section
);
4453 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
4455 input_section
, rel
->r_offset
))
4461 case bfd_reloc_dangerous
:
4462 case bfd_reloc_outofrange
:
4463 case bfd_reloc_overflow
:
4469 name
= h
->root
.root
.string
;
4472 name
= bfd_elf_string_from_elf_section (input_bfd
,
4473 symtab_hdr
->sh_link
,
4478 name
= bfd_section_name (input_bfd
, input_section
);
4480 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
4497 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
4499 struct bfd_link_info
*info
;
4500 struct elf_link_hash_entry
*h
;
4501 Elf_Internal_Sym
*sym
;
4503 struct elfNN_ia64_link_hash_table
*ia64_info
;
4504 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4506 ia64_info
= elfNN_ia64_hash_table (info
);
4507 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4509 /* Fill in the PLT data, if required. */
4510 if (dyn_i
&& dyn_i
->want_plt
)
4512 Elf_Internal_Rela outrel
;
4515 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
4517 gp_val
= _bfd_get_gp_value (output_bfd
);
4519 /* Initialize the minimal PLT entry. */
4521 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4522 plt_sec
= ia64_info
->plt_sec
;
4523 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4525 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4526 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4527 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4530 plt_addr
= (plt_sec
->output_section
->vma
4531 + plt_sec
->output_offset
4532 + dyn_i
->plt_offset
);
4533 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, TRUE
);
4535 /* Initialize the FULL PLT entry, if needed. */
4536 if (dyn_i
->want_plt2
)
4538 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4540 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4541 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4544 /* Mark the symbol as undefined, rather than as defined in the
4545 plt section. Leave the value alone. */
4546 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4547 first place. But perhaps elflink.h did some for us. */
4548 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4549 sym
->st_shndx
= SHN_UNDEF
;
4552 /* Create the dynamic relocation. */
4553 outrel
.r_offset
= pltoff_addr
;
4554 if (bfd_little_endian (output_bfd
))
4555 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4557 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4558 outrel
.r_addend
= 0;
4560 /* This is fun. In the .IA_64.pltoff section, we've got entries
4561 that correspond both to real PLT entries, and those that
4562 happened to resolve to local symbols but need to be created
4563 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4564 relocations for the real PLT should come at the end of the
4565 section, so that they can be indexed by plt entry at runtime.
4567 We emitted all of the relocations for the non-PLT @pltoff
4568 entries during relocate_section. So we can consider the
4569 existing sec->reloc_count to be the base of the array of
4572 loc
= ia64_info
->rel_pltoff_sec
->contents
;
4573 loc
+= ((ia64_info
->rel_pltoff_sec
->reloc_count
+ index
)
4574 * sizeof (Elf64_External_Rela
));
4575 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
4578 /* Mark some specially defined symbols as absolute. */
4579 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4580 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4581 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4582 sym
->st_shndx
= SHN_ABS
;
4588 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4590 struct bfd_link_info
*info
;
4592 struct elfNN_ia64_link_hash_table
*ia64_info
;
4595 ia64_info
= elfNN_ia64_hash_table (info
);
4596 dynobj
= ia64_info
->root
.dynobj
;
4598 if (elf_hash_table (info
)->dynamic_sections_created
)
4600 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4601 asection
*sdyn
, *sgotplt
;
4604 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4605 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4606 BFD_ASSERT (sdyn
!= NULL
);
4607 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4608 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4610 gp_val
= _bfd_get_gp_value (abfd
);
4612 for (; dyncon
< dynconend
; dyncon
++)
4614 Elf_Internal_Dyn dyn
;
4616 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4621 dyn
.d_un
.d_ptr
= gp_val
;
4625 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4626 * sizeof (ElfNN_External_Rela
));
4630 /* See the comment above in finish_dynamic_symbol. */
4631 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4632 + ia64_info
->rel_pltoff_sec
->output_offset
4633 + (ia64_info
->rel_pltoff_sec
->reloc_count
4634 * sizeof (ElfNN_External_Rela
)));
4637 case DT_IA_64_PLT_RESERVE
:
4638 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4639 + sgotplt
->output_offset
);
4643 /* Do not have RELASZ include JMPREL. This makes things
4644 easier on ld.so. This is not what the rest of BFD set up. */
4645 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4646 * sizeof (ElfNN_External_Rela
));
4650 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4653 /* Initialize the PLT0 entry. */
4654 if (ia64_info
->plt_sec
)
4656 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4659 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4661 pltres
= (sgotplt
->output_section
->vma
4662 + sgotplt
->output_offset
4665 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4672 /* ELF file flag handling: */
4674 /* Function to keep IA-64 specific file flags. */
4676 elfNN_ia64_set_private_flags (abfd
, flags
)
4680 BFD_ASSERT (!elf_flags_init (abfd
)
4681 || elf_elfheader (abfd
)->e_flags
== flags
);
4683 elf_elfheader (abfd
)->e_flags
= flags
;
4684 elf_flags_init (abfd
) = TRUE
;
4688 /* Merge backend specific data from an object file to the output
4689 object file when linking. */
4691 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4696 bfd_boolean ok
= TRUE
;
4698 /* Don't even pretend to support mixed-format linking. */
4699 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4700 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4703 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4704 out_flags
= elf_elfheader (obfd
)->e_flags
;
4706 if (! elf_flags_init (obfd
))
4708 elf_flags_init (obfd
) = TRUE
;
4709 elf_elfheader (obfd
)->e_flags
= in_flags
;
4711 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4712 && bfd_get_arch_info (obfd
)->the_default
)
4714 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4715 bfd_get_mach (ibfd
));
4721 /* Check flag compatibility. */
4722 if (in_flags
== out_flags
)
4725 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4726 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4727 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4729 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4731 (*_bfd_error_handler
)
4732 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4733 bfd_archive_filename (ibfd
));
4735 bfd_set_error (bfd_error_bad_value
);
4738 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4740 (*_bfd_error_handler
)
4741 (_("%s: linking big-endian files with little-endian files"),
4742 bfd_archive_filename (ibfd
));
4744 bfd_set_error (bfd_error_bad_value
);
4747 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4749 (*_bfd_error_handler
)
4750 (_("%s: linking 64-bit files with 32-bit files"),
4751 bfd_archive_filename (ibfd
));
4753 bfd_set_error (bfd_error_bad_value
);
4756 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4758 (*_bfd_error_handler
)
4759 (_("%s: linking constant-gp files with non-constant-gp files"),
4760 bfd_archive_filename (ibfd
));
4762 bfd_set_error (bfd_error_bad_value
);
4765 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4766 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4768 (*_bfd_error_handler
)
4769 (_("%s: linking auto-pic files with non-auto-pic files"),
4770 bfd_archive_filename (ibfd
));
4772 bfd_set_error (bfd_error_bad_value
);
4780 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4784 FILE *file
= (FILE *) ptr
;
4785 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4787 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4789 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4790 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4791 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4792 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4793 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4794 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4795 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4796 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4797 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4799 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4803 static enum elf_reloc_type_class
4804 elfNN_ia64_reloc_type_class (rela
)
4805 const Elf_Internal_Rela
*rela
;
4807 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
4809 case R_IA64_REL32MSB
:
4810 case R_IA64_REL32LSB
:
4811 case R_IA64_REL64MSB
:
4812 case R_IA64_REL64LSB
:
4813 return reloc_class_relative
;
4814 case R_IA64_IPLTMSB
:
4815 case R_IA64_IPLTLSB
:
4816 return reloc_class_plt
;
4818 return reloc_class_copy
;
4820 return reloc_class_normal
;
4825 elfNN_ia64_hpux_vec (const bfd_target
*vec
)
4827 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec
;
4828 return (vec
== & bfd_elfNN_ia64_hpux_big_vec
);
4832 elfNN_hpux_post_process_headers (abfd
, info
)
4834 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
4836 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
4838 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_HPUX
;
4839 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 1;
4843 elfNN_hpux_backend_section_from_bfd_section (abfd
, sec
, retval
)
4844 bfd
*abfd ATTRIBUTE_UNUSED
;
4848 if (bfd_is_com_section (sec
))
4850 *retval
= SHN_IA_64_ANSI_COMMON
;
4856 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4857 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4858 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4859 #define TARGET_BIG_NAME "elfNN-ia64-big"
4860 #define ELF_ARCH bfd_arch_ia64
4861 #define ELF_MACHINE_CODE EM_IA_64
4862 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4863 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4864 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4866 #define elf_backend_section_from_shdr \
4867 elfNN_ia64_section_from_shdr
4868 #define elf_backend_section_flags \
4869 elfNN_ia64_section_flags
4870 #define elf_backend_fake_sections \
4871 elfNN_ia64_fake_sections
4872 #define elf_backend_final_write_processing \
4873 elfNN_ia64_final_write_processing
4874 #define elf_backend_add_symbol_hook \
4875 elfNN_ia64_add_symbol_hook
4876 #define elf_backend_additional_program_headers \
4877 elfNN_ia64_additional_program_headers
4878 #define elf_backend_modify_segment_map \
4879 elfNN_ia64_modify_segment_map
4880 #define elf_info_to_howto \
4881 elfNN_ia64_info_to_howto
4883 #define bfd_elfNN_bfd_reloc_type_lookup \
4884 elfNN_ia64_reloc_type_lookup
4885 #define bfd_elfNN_bfd_is_local_label_name \
4886 elfNN_ia64_is_local_label_name
4887 #define bfd_elfNN_bfd_relax_section \
4888 elfNN_ia64_relax_section
4890 /* Stuff for the BFD linker: */
4891 #define bfd_elfNN_bfd_link_hash_table_create \
4892 elfNN_ia64_hash_table_create
4893 #define elf_backend_create_dynamic_sections \
4894 elfNN_ia64_create_dynamic_sections
4895 #define elf_backend_check_relocs \
4896 elfNN_ia64_check_relocs
4897 #define elf_backend_adjust_dynamic_symbol \
4898 elfNN_ia64_adjust_dynamic_symbol
4899 #define elf_backend_size_dynamic_sections \
4900 elfNN_ia64_size_dynamic_sections
4901 #define elf_backend_relocate_section \
4902 elfNN_ia64_relocate_section
4903 #define elf_backend_finish_dynamic_symbol \
4904 elfNN_ia64_finish_dynamic_symbol
4905 #define elf_backend_finish_dynamic_sections \
4906 elfNN_ia64_finish_dynamic_sections
4907 #define bfd_elfNN_bfd_final_link \
4908 elfNN_ia64_final_link
4910 #define bfd_elfNN_bfd_merge_private_bfd_data \
4911 elfNN_ia64_merge_private_bfd_data
4912 #define bfd_elfNN_bfd_set_private_flags \
4913 elfNN_ia64_set_private_flags
4914 #define bfd_elfNN_bfd_print_private_bfd_data \
4915 elfNN_ia64_print_private_bfd_data
4917 #define elf_backend_plt_readonly 1
4918 #define elf_backend_want_plt_sym 0
4919 #define elf_backend_plt_alignment 5
4920 #define elf_backend_got_header_size 0
4921 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4922 #define elf_backend_want_got_plt 1
4923 #define elf_backend_may_use_rel_p 1
4924 #define elf_backend_may_use_rela_p 1
4925 #define elf_backend_default_use_rela_p 1
4926 #define elf_backend_want_dynbss 0
4927 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4928 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4929 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4930 #define elf_backend_rela_normal 1
4932 #include "elfNN-target.h"
4934 /* AIX-specific vectors. */
4936 #undef TARGET_LITTLE_SYM
4937 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4938 #undef TARGET_LITTLE_NAME
4939 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4940 #undef TARGET_BIG_SYM
4941 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4942 #undef TARGET_BIG_NAME
4943 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4945 #undef elf_backend_add_symbol_hook
4946 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4948 #undef bfd_elfNN_bfd_link_add_symbols
4949 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4951 #define elfNN_bed elfNN_ia64_aix_bed
4953 #include "elfNN-target.h"
4955 /* HPUX-specific vectors. */
4957 #undef TARGET_LITTLE_SYM
4958 #undef TARGET_LITTLE_NAME
4959 #undef TARGET_BIG_SYM
4960 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4961 #undef TARGET_BIG_NAME
4962 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4964 /* We need to undo the AIX specific functions. */
4966 #undef elf_backend_add_symbol_hook
4967 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
4969 #undef bfd_elfNN_bfd_link_add_symbols
4970 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
4972 /* These are HP-UX specific functions. */
4974 #undef elf_backend_post_process_headers
4975 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4977 #undef elf_backend_section_from_bfd_section
4978 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4980 #undef elf_backend_want_p_paddr_set_to_zero
4981 #define elf_backend_want_p_paddr_set_to_zero 1
4983 #undef ELF_MAXPAGESIZE
4984 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4987 #define elfNN_bed elfNN_ia64_hpux_bed
4989 #include "elfNN-target.h"
4991 #undef elf_backend_want_p_paddr_set_to_zero