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
;
1036 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
1037 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
1038 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
1039 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
1040 ia64_info
->got_sec
->_cooked_size
= data
.ofs
;
1042 /* ??? Resize .rela.got too. */
1045 *again
= changed_contents
|| changed_relocs
;
1049 if (isymbuf
!= NULL
&& (unsigned char *) isymbuf
!= symtab_hdr
->contents
)
1051 if (contents
!= NULL
1052 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1054 if (internal_relocs
!= NULL
1055 && elf_section_data (sec
)->relocs
!= internal_relocs
)
1056 free (internal_relocs
);
1061 elfNN_ia64_relax_ldxmov (abfd
, contents
, off
)
1067 bfd_vma dword
, insn
;
1069 switch ((int)off
& 0x3)
1071 case 0: shift
= 5; break;
1072 case 1: shift
= 14; off
+= 3; break;
1073 case 2: shift
= 23; off
+= 6; break;
1078 dword
= bfd_get_64 (abfd
, contents
+ off
);
1079 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
1081 r1
= (insn
>> 6) & 127;
1082 r3
= (insn
>> 20) & 127;
1084 insn
= 0x8000000; /* nop */
1086 insn
= (insn
& 0x7f01fff) | 0x10800000000LL
; /* (qp) mov r1 = r3 */
1088 dword
&= ~(0x1ffffffffffLL
<< shift
);
1089 dword
|= (insn
<< shift
);
1090 bfd_put_64 (abfd
, dword
, contents
+ off
);
1093 /* Return TRUE if NAME is an unwind table section name. */
1095 static inline bfd_boolean
1096 is_unwind_section_name (abfd
, name
)
1100 size_t len1
, len2
, len3
;
1102 if (elfNN_ia64_hpux_vec (abfd
->xvec
)
1103 && !strcmp (name
, ELF_STRING_ia64_unwind_hdr
))
1106 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1107 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
1108 len3
= sizeof (ELF_STRING_ia64_unwind_once
) - 1;
1109 return ((strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
1110 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0)
1111 || strncmp (name
, ELF_STRING_ia64_unwind_once
, len3
) == 0);
1114 /* Handle an IA-64 specific section when reading an object file. This
1115 is called when elfcode.h finds a section with an unknown type. */
1118 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
1120 Elf_Internal_Shdr
*hdr
;
1125 /* There ought to be a place to keep ELF backend specific flags, but
1126 at the moment there isn't one. We just keep track of the
1127 sections by their name, instead. Fortunately, the ABI gives
1128 suggested names for all the MIPS specific sections, so we will
1129 probably get away with this. */
1130 switch (hdr
->sh_type
)
1132 case SHT_IA_64_UNWIND
:
1133 case SHT_IA_64_HP_OPT_ANOT
:
1137 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1145 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
1147 newsect
= hdr
->bfd_section
;
1152 /* Convert IA-64 specific section flags to bfd internal section flags. */
1154 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1158 elfNN_ia64_section_flags (flags
, hdr
)
1160 Elf_Internal_Shdr
*hdr
;
1162 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1163 *flags
|= SEC_SMALL_DATA
;
1168 /* Set the correct type for an IA-64 ELF section. We do this by the
1169 section name, which is a hack, but ought to work. */
1172 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1173 bfd
*abfd ATTRIBUTE_UNUSED
;
1174 Elf_Internal_Shdr
*hdr
;
1177 register const char *name
;
1179 name
= bfd_get_section_name (abfd
, sec
);
1181 if (is_unwind_section_name (abfd
, name
))
1183 /* We don't have the sections numbered at this point, so sh_info
1184 is set later, in elfNN_ia64_final_write_processing. */
1185 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1186 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1188 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1189 hdr
->sh_type
= SHT_IA_64_EXT
;
1190 else if (strcmp (name
, ".HP.opt_annot") == 0)
1191 hdr
->sh_type
= SHT_IA_64_HP_OPT_ANOT
;
1192 else if (strcmp (name
, ".reloc") == 0)
1193 /* This is an ugly, but unfortunately necessary hack that is
1194 needed when producing EFI binaries on IA-64. It tells
1195 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1196 containing ELF relocation info. We need this hack in order to
1197 be able to generate ELF binaries that can be translated into
1198 EFI applications (which are essentially COFF objects). Those
1199 files contain a COFF ".reloc" section inside an ELFNN object,
1200 which would normally cause BFD to segfault because it would
1201 attempt to interpret this section as containing relocation
1202 entries for section "oc". With this hack enabled, ".reloc"
1203 will be treated as a normal data section, which will avoid the
1204 segfault. However, you won't be able to create an ELFNN binary
1205 with a section named "oc" that needs relocations, but that's
1206 the kind of ugly side-effects you get when detecting section
1207 types based on their names... In practice, this limitation is
1208 unlikely to bite. */
1209 hdr
->sh_type
= SHT_PROGBITS
;
1211 if (sec
->flags
& SEC_SMALL_DATA
)
1212 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1217 /* The final processing done just before writing out an IA-64 ELF
1221 elfNN_ia64_final_write_processing (abfd
, linker
)
1223 bfd_boolean linker ATTRIBUTE_UNUSED
;
1225 Elf_Internal_Shdr
*hdr
;
1227 asection
*text_sect
, *s
;
1230 for (s
= abfd
->sections
; s
; s
= s
->next
)
1232 hdr
= &elf_section_data (s
)->this_hdr
;
1233 switch (hdr
->sh_type
)
1235 case SHT_IA_64_UNWIND
:
1236 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1238 sname
= bfd_get_section_name (abfd
, s
);
1239 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1240 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1244 if (sname
[0] == '\0')
1245 /* .IA_64.unwind -> .text */
1246 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1248 /* .IA_64.unwindFOO -> FOO */
1249 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1252 && (len
= sizeof (ELF_STRING_ia64_unwind_once
) - 1,
1253 strncmp (sname
, ELF_STRING_ia64_unwind_once
, len
)) == 0)
1255 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1256 size_t len2
= sizeof (".gnu.linkonce.t.") - 1;
1257 char *once_name
= bfd_malloc (len2
+ strlen (sname
+ len
) + 1);
1259 if (once_name
!= NULL
)
1261 memcpy (once_name
, ".gnu.linkonce.t.", len2
);
1262 strcpy (once_name
+ len2
, sname
+ len
);
1263 text_sect
= bfd_get_section_by_name (abfd
, once_name
);
1267 /* Should only happen if we run out of memory, in
1268 which case we're probably toast anyway. Try to
1269 cope by finding the section the slow way. */
1270 for (text_sect
= abfd
->sections
;
1272 text_sect
= text_sect
->next
)
1274 if (strncmp (bfd_section_name (abfd
, text_sect
),
1275 ".gnu.linkonce.t.", len2
) == 0
1276 && strcmp (bfd_section_name (abfd
, text_sect
) + len2
,
1282 /* last resort: fall back on .text */
1283 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1287 /* The IA-64 processor-specific ABI requires setting
1288 sh_link to the unwind section, whereas HP-UX requires
1289 sh_info to do so. For maximum compatibility, we'll
1290 set both for now... */
1291 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1292 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1298 if (! elf_flags_init (abfd
))
1300 unsigned long flags
= 0;
1302 if (abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
)
1303 flags
|= EF_IA_64_BE
;
1304 if (bfd_get_mach (abfd
) == bfd_mach_ia64_elf64
)
1305 flags
|= EF_IA_64_ABI64
;
1307 elf_elfheader(abfd
)->e_flags
= flags
;
1308 elf_flags_init (abfd
) = TRUE
;
1312 /* Hook called by the linker routine which adds symbols from an object
1313 file. We use it to put .comm items in .sbss, and not .bss. */
1316 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1318 struct bfd_link_info
*info
;
1319 const Elf_Internal_Sym
*sym
;
1320 const char **namep ATTRIBUTE_UNUSED
;
1321 flagword
*flagsp ATTRIBUTE_UNUSED
;
1325 if (sym
->st_shndx
== SHN_COMMON
1326 && !info
->relocateable
1327 && sym
->st_size
<= elf_gp_size (abfd
))
1329 /* Common symbols less than or equal to -G nn bytes are
1330 automatically put into .sbss. */
1332 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1336 scomm
= bfd_make_section (abfd
, ".scommon");
1338 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1340 | SEC_LINKER_CREATED
)))
1345 *valp
= sym
->st_size
;
1352 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1354 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1355 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1357 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1358 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1361 /* Hook called by the linker routine which adds symbols from an object
1362 file. We use it to handle OS-specific symbols. */
1365 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1367 struct bfd_link_info
*info
;
1368 const Elf_Internal_Sym
*sym
;
1374 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1376 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1377 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1378 no one else should use it b/c it is undocumented. */
1379 struct elf_link_hash_entry
*h
;
1381 h
= elf_link_hash_lookup (elf_hash_table (info
), *namep
,
1382 FALSE
, FALSE
, FALSE
);
1385 struct elf_backend_data
*bed
;
1386 struct elfNN_ia64_link_hash_table
*ia64_info
;
1387 struct bfd_link_hash_entry
*bh
= NULL
;
1389 bed
= get_elf_backend_data (abfd
);
1390 ia64_info
= elfNN_ia64_hash_table (info
);
1392 if (!(_bfd_generic_link_add_one_symbol
1393 (info
, abfd
, *namep
, BSF_GLOBAL
,
1394 bfd_get_section_by_name (abfd
, ".bss"),
1395 bed
->got_symbol_offset
, (const char *) NULL
, FALSE
,
1396 bed
->collect
, &bh
)))
1399 h
= (struct elf_link_hash_entry
*) bh
;
1400 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1401 h
->type
= STT_OBJECT
;
1403 if (! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1409 else if (sym
->st_shndx
== SHN_LOOS
)
1413 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1414 is only relevant when compiling code for extended system calls.
1415 Replace the "special" section with .text, if possible.
1416 Note that these symbols are always assumed to be in .text. */
1417 for (i
= 1; i
< elf_numsections (abfd
); i
++)
1419 asection
* sec
= bfd_section_from_elf_index (abfd
, i
);
1421 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1429 *secp
= bfd_abs_section_ptr
;
1431 *valp
= sym
->st_size
;
1437 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1438 namep
, flagsp
, secp
, valp
);
1443 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1445 struct bfd_link_info
*info
;
1447 /* Make sure dynamic sections are always created. */
1448 if (! elf_hash_table (info
)->dynamic_sections_created
1449 && abfd
->xvec
== info
->hash
->creator
)
1451 if (! bfd_elfNN_link_create_dynamic_sections (abfd
, info
))
1455 /* Now do the standard call. */
1456 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1459 /* Return the number of additional phdrs we will need. */
1462 elfNN_ia64_additional_program_headers (abfd
)
1468 /* See if we need a PT_IA_64_ARCHEXT segment. */
1469 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1470 if (s
&& (s
->flags
& SEC_LOAD
))
1473 /* Count how many PT_IA_64_UNWIND segments we need. */
1474 for (s
= abfd
->sections
; s
; s
= s
->next
)
1475 if (is_unwind_section_name (abfd
, s
->name
) && (s
->flags
& SEC_LOAD
))
1482 elfNN_ia64_modify_segment_map (abfd
)
1485 struct elf_segment_map
*m
, **pm
;
1486 Elf_Internal_Shdr
*hdr
;
1489 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1490 all PT_LOAD segments. */
1491 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1492 if (s
&& (s
->flags
& SEC_LOAD
))
1494 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1495 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1499 m
= ((struct elf_segment_map
*)
1500 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1504 m
->p_type
= PT_IA_64_ARCHEXT
;
1508 /* We want to put it after the PHDR and INTERP segments. */
1509 pm
= &elf_tdata (abfd
)->segment_map
;
1511 && ((*pm
)->p_type
== PT_PHDR
1512 || (*pm
)->p_type
== PT_INTERP
))
1520 /* Install PT_IA_64_UNWIND segments, if needed. */
1521 for (s
= abfd
->sections
; s
; s
= s
->next
)
1523 hdr
= &elf_section_data (s
)->this_hdr
;
1524 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1527 if (s
&& (s
->flags
& SEC_LOAD
))
1529 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1530 if (m
->p_type
== PT_IA_64_UNWIND
)
1534 /* Look through all sections in the unwind segment
1535 for a match since there may be multiple sections
1537 for (i
= m
->count
- 1; i
>= 0; --i
)
1538 if (m
->sections
[i
] == s
)
1547 m
= ((struct elf_segment_map
*)
1548 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1552 m
->p_type
= PT_IA_64_UNWIND
;
1557 /* We want to put it last. */
1558 pm
= &elf_tdata (abfd
)->segment_map
;
1566 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1567 the input sections for each output section in the segment and testing
1568 for SHF_IA_64_NORECOV on each. */
1569 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1570 if (m
->p_type
== PT_LOAD
)
1573 for (i
= m
->count
- 1; i
>= 0; --i
)
1575 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1578 if (order
->type
== bfd_indirect_link_order
)
1580 asection
*is
= order
->u
.indirect
.section
;
1581 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1582 if (flags
& SHF_IA_64_NORECOV
)
1584 m
->p_flags
|= PF_IA_64_NORECOV
;
1588 order
= order
->next
;
1597 /* According to the Tahoe assembler spec, all labels starting with a
1601 elfNN_ia64_is_local_label_name (abfd
, name
)
1602 bfd
*abfd ATTRIBUTE_UNUSED
;
1605 return name
[0] == '.';
1608 /* Should we do dynamic things to this symbol? */
1611 elfNN_ia64_dynamic_symbol_p (h
, info
)
1612 struct elf_link_hash_entry
*h
;
1613 struct bfd_link_info
*info
;
1618 while (h
->root
.type
== bfd_link_hash_indirect
1619 || h
->root
.type
== bfd_link_hash_warning
)
1620 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1622 if (h
->dynindx
== -1)
1624 switch (ELF_ST_VISIBILITY (h
->other
))
1633 if (h
->root
.type
== bfd_link_hash_undefweak
1634 || h
->root
.type
== bfd_link_hash_defweak
)
1637 if ((info
->shared
&& (!info
->symbolic
|| info
->allow_shlib_undefined
))
1638 || ((h
->elf_link_hash_flags
1639 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1640 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1647 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1648 struct elfNN_ia64_local_hash_table
*ht
;
1649 bfd
*abfd ATTRIBUTE_UNUSED
;
1650 new_hash_entry_func
new;
1652 memset (ht
, 0, sizeof (*ht
));
1653 return bfd_hash_table_init (&ht
->root
, new);
1656 static struct bfd_hash_entry
*
1657 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1658 struct bfd_hash_entry
*entry
;
1659 struct bfd_hash_table
*table
;
1662 struct elfNN_ia64_local_hash_entry
*ret
;
1663 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1665 /* Allocate the structure if it has not already been allocated by a
1668 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1673 /* Initialize our local data. All zeros, and definitely easier
1674 than setting a handful of bit fields. */
1675 memset (ret
, 0, sizeof (*ret
));
1677 /* Call the allocation method of the superclass. */
1678 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1679 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1681 return (struct bfd_hash_entry
*) ret
;
1684 static struct bfd_hash_entry
*
1685 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1686 struct bfd_hash_entry
*entry
;
1687 struct bfd_hash_table
*table
;
1690 struct elfNN_ia64_link_hash_entry
*ret
;
1691 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1693 /* Allocate the structure if it has not already been allocated by a
1696 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1701 /* Initialize our local data. All zeros, and definitely easier
1702 than setting a handful of bit fields. */
1703 memset (ret
, 0, sizeof (*ret
));
1705 /* Call the allocation method of the superclass. */
1706 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1707 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1710 return (struct bfd_hash_entry
*) ret
;
1714 elfNN_ia64_hash_copy_indirect (bed
, xdir
, xind
)
1715 struct elf_backend_data
*bed ATTRIBUTE_UNUSED
;
1716 struct elf_link_hash_entry
*xdir
, *xind
;
1718 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1720 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1721 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1723 /* Copy down any references that we may have already seen to the
1724 symbol which just became indirect. */
1726 dir
->root
.elf_link_hash_flags
|=
1727 (ind
->root
.elf_link_hash_flags
1728 & (ELF_LINK_HASH_REF_DYNAMIC
1729 | ELF_LINK_HASH_REF_REGULAR
1730 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1732 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1735 /* Copy over the got and plt data. This would have been done
1738 if (dir
->info
== NULL
)
1740 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1742 dir
->info
= dyn_i
= ind
->info
;
1745 /* Fix up the dyn_sym_info pointers to the global symbol. */
1746 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1747 dyn_i
->h
= &dir
->root
;
1749 BFD_ASSERT (ind
->info
== NULL
);
1751 /* Copy over the dynindx. */
1753 if (dir
->root
.dynindx
== -1)
1755 dir
->root
.dynindx
= ind
->root
.dynindx
;
1756 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1757 ind
->root
.dynindx
= -1;
1758 ind
->root
.dynstr_index
= 0;
1760 BFD_ASSERT (ind
->root
.dynindx
== -1);
1764 elfNN_ia64_hash_hide_symbol (info
, xh
, force_local
)
1765 struct bfd_link_info
*info
;
1766 struct elf_link_hash_entry
*xh
;
1767 bfd_boolean force_local
;
1769 struct elfNN_ia64_link_hash_entry
*h
;
1770 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1772 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1774 _bfd_elf_link_hash_hide_symbol (info
, &h
->root
, force_local
);
1776 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1777 dyn_i
->want_plt2
= 0;
1780 /* Create the derived linker hash table. The IA-64 ELF port uses this
1781 derived hash table to keep information specific to the IA-64 ElF
1782 linker (without using static variables). */
1784 static struct bfd_link_hash_table
*
1785 elfNN_ia64_hash_table_create (abfd
)
1788 struct elfNN_ia64_link_hash_table
*ret
;
1790 ret
= bfd_zalloc (abfd
, (bfd_size_type
) sizeof (*ret
));
1793 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1794 elfNN_ia64_new_elf_hash_entry
))
1796 bfd_release (abfd
, ret
);
1800 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1801 elfNN_ia64_new_loc_hash_entry
))
1803 return &ret
->root
.root
;
1806 /* Look up an entry in a Alpha ELF linker hash table. */
1808 static INLINE
struct elfNN_ia64_local_hash_entry
*
1809 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1810 struct elfNN_ia64_local_hash_table
*table
;
1812 bfd_boolean create
, copy
;
1814 return ((struct elfNN_ia64_local_hash_entry
*)
1815 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1818 /* Traverse both local and global hash tables. */
1820 struct elfNN_ia64_dyn_sym_traverse_data
1822 bfd_boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1827 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1828 struct bfd_hash_entry
*xentry
;
1831 struct elfNN_ia64_link_hash_entry
*entry
1832 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1833 struct elfNN_ia64_dyn_sym_traverse_data
*data
1834 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1835 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1837 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
1838 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
1840 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1841 if (! (*data
->func
) (dyn_i
, data
->data
))
1847 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1848 struct bfd_hash_entry
*xentry
;
1851 struct elfNN_ia64_local_hash_entry
*entry
1852 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1853 struct elfNN_ia64_dyn_sym_traverse_data
*data
1854 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1855 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1857 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1858 if (! (*data
->func
) (dyn_i
, data
->data
))
1864 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1865 struct elfNN_ia64_link_hash_table
*ia64_info
;
1866 bfd_boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1869 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1874 elf_link_hash_traverse (&ia64_info
->root
,
1875 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1876 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1877 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1881 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1883 struct bfd_link_info
*info
;
1885 struct elfNN_ia64_link_hash_table
*ia64_info
;
1888 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1891 ia64_info
= elfNN_ia64_hash_table (info
);
1893 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1894 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1897 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1898 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1901 if (!get_pltoff (abfd
, info
, ia64_info
))
1904 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1906 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1909 | SEC_LINKER_CREATED
1911 || !bfd_set_section_alignment (abfd
, s
, 3))
1913 ia64_info
->rel_pltoff_sec
= s
;
1915 s
= bfd_make_section(abfd
, ".rela.got");
1917 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1920 | SEC_LINKER_CREATED
1922 || !bfd_set_section_alignment (abfd
, s
, 3))
1924 ia64_info
->rel_got_sec
= s
;
1929 /* Find and/or create a hash entry for local symbol. */
1930 static struct elfNN_ia64_local_hash_entry
*
1931 get_local_sym_hash (ia64_info
, abfd
, rel
, create
)
1932 struct elfNN_ia64_link_hash_table
*ia64_info
;
1934 const Elf_Internal_Rela
*rel
;
1937 struct elfNN_ia64_local_hash_entry
*ret
;
1938 asection
*sec
= abfd
->sections
;
1939 char addr_name
[34];
1941 BFD_ASSERT ((sizeof (sec
->id
)*2 + 1 + sizeof (unsigned long)*2 + 1) <= 34);
1944 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1945 name describes what was once anonymous memory. */
1947 sprintf (addr_name
, "%x:%lx",
1948 sec
->id
, (unsigned long) ELFNN_R_SYM (rel
->r_info
));
1950 /* Collect the canonical entry data for this address. */
1951 ret
= elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1952 addr_name
, create
, create
);
1956 /* Find and/or create a descriptor for dynamic symbol info. This will
1957 vary based on global or local symbol, and the addend to the reloc. */
1959 static struct elfNN_ia64_dyn_sym_info
*
1960 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1961 struct elfNN_ia64_link_hash_table
*ia64_info
;
1962 struct elf_link_hash_entry
*h
;
1964 const Elf_Internal_Rela
*rel
;
1967 struct elfNN_ia64_dyn_sym_info
**pp
;
1968 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1969 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1972 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1975 struct elfNN_ia64_local_hash_entry
*loc_h
;
1977 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
1980 BFD_ASSERT (!create
);
1987 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
1990 if (dyn_i
== NULL
&& create
)
1992 dyn_i
= ((struct elfNN_ia64_dyn_sym_info
*)
1993 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *dyn_i
));
1995 dyn_i
->addend
= addend
;
2002 get_got (abfd
, info
, ia64_info
)
2004 struct bfd_link_info
*info
;
2005 struct elfNN_ia64_link_hash_table
*ia64_info
;
2010 got
= ia64_info
->got_sec
;
2015 dynobj
= ia64_info
->root
.dynobj
;
2017 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2018 if (!_bfd_elf_create_got_section (dynobj
, info
))
2021 got
= bfd_get_section_by_name (dynobj
, ".got");
2023 ia64_info
->got_sec
= got
;
2025 flags
= bfd_get_section_flags (abfd
, got
);
2026 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
2032 /* Create function descriptor section (.opd). This section is called .opd
2033 because it contains "official prodecure descriptors". The "official"
2034 refers to the fact that these descriptors are used when taking the address
2035 of a procedure, thus ensuring a unique address for each procedure. */
2038 get_fptr (abfd
, info
, ia64_info
)
2040 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2041 struct elfNN_ia64_link_hash_table
*ia64_info
;
2046 fptr
= ia64_info
->fptr_sec
;
2049 dynobj
= ia64_info
->root
.dynobj
;
2051 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2053 fptr
= bfd_make_section (dynobj
, ".opd");
2055 || !bfd_set_section_flags (dynobj
, fptr
,
2061 | SEC_LINKER_CREATED
))
2062 || !bfd_set_section_alignment (abfd
, fptr
, 4))
2068 ia64_info
->fptr_sec
= fptr
;
2075 get_pltoff (abfd
, info
, ia64_info
)
2077 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2078 struct elfNN_ia64_link_hash_table
*ia64_info
;
2083 pltoff
= ia64_info
->pltoff_sec
;
2086 dynobj
= ia64_info
->root
.dynobj
;
2088 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2090 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
2092 || !bfd_set_section_flags (dynobj
, pltoff
,
2098 | SEC_LINKER_CREATED
))
2099 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
2105 ia64_info
->pltoff_sec
= pltoff
;
2112 get_reloc_section (abfd
, ia64_info
, sec
, create
)
2114 struct elfNN_ia64_link_hash_table
*ia64_info
;
2118 const char *srel_name
;
2122 srel_name
= (bfd_elf_string_from_elf_section
2123 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
2124 elf_section_data(sec
)->rel_hdr
.sh_name
));
2125 if (srel_name
== NULL
)
2128 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
2129 && strcmp (bfd_get_section_name (abfd
, sec
),
2131 || (strncmp (srel_name
, ".rel", 4) == 0
2132 && strcmp (bfd_get_section_name (abfd
, sec
),
2133 srel_name
+4) == 0));
2135 dynobj
= ia64_info
->root
.dynobj
;
2137 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2139 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
2140 if (srel
== NULL
&& create
)
2142 srel
= bfd_make_section (dynobj
, srel_name
);
2144 || !bfd_set_section_flags (dynobj
, srel
,
2149 | SEC_LINKER_CREATED
2151 || !bfd_set_section_alignment (dynobj
, srel
, 3))
2155 if (sec
->flags
& SEC_READONLY
)
2156 ia64_info
->reltext
= 1;
2162 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
2164 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2168 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2170 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2171 if (rent
->srel
== srel
&& rent
->type
== type
)
2176 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
2177 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
2181 rent
->next
= dyn_i
->reloc_entries
;
2185 dyn_i
->reloc_entries
= rent
;
2193 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
2195 struct bfd_link_info
*info
;
2197 const Elf_Internal_Rela
*relocs
;
2199 struct elfNN_ia64_link_hash_table
*ia64_info
;
2200 const Elf_Internal_Rela
*relend
;
2201 Elf_Internal_Shdr
*symtab_hdr
;
2202 const Elf_Internal_Rela
*rel
;
2203 asection
*got
, *fptr
, *srel
;
2205 if (info
->relocateable
)
2208 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2209 ia64_info
= elfNN_ia64_hash_table (info
);
2211 got
= fptr
= srel
= NULL
;
2213 relend
= relocs
+ sec
->reloc_count
;
2214 for (rel
= relocs
; rel
< relend
; ++rel
)
2224 NEED_LTOFF_FPTR
= 128,
2230 struct elf_link_hash_entry
*h
= NULL
;
2231 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2232 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2234 bfd_boolean maybe_dynamic
;
2235 int dynrel_type
= R_IA64_NONE
;
2237 if (r_symndx
>= symtab_hdr
->sh_info
)
2239 /* We're dealing with a global symbol -- find its hash entry
2240 and mark it as being referenced. */
2241 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2242 h
= elf_sym_hashes (abfd
)[indx
];
2243 while (h
->root
.type
== bfd_link_hash_indirect
2244 || h
->root
.type
== bfd_link_hash_warning
)
2245 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2247 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
2250 /* We can only get preliminary data on whether a symbol is
2251 locally or externally defined, as not all of the input files
2252 have yet been processed. Do something with what we know, as
2253 this may help reduce memory usage and processing time later. */
2254 maybe_dynamic
= FALSE
;
2255 if (h
&& ((info
->shared
2256 && (!info
->symbolic
|| info
->allow_shlib_undefined
))
2257 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
2258 || h
->root
.type
== bfd_link_hash_defweak
2259 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2260 maybe_dynamic
= TRUE
;
2263 switch (ELFNN_R_TYPE (rel
->r_info
))
2265 case R_IA64_TPREL64MSB
:
2266 case R_IA64_TPREL64LSB
:
2267 if (info
->shared
|| maybe_dynamic
)
2268 need_entry
= NEED_DYNREL
;
2269 dynrel_type
= R_IA64_TPREL64LSB
;
2271 info
->flags
|= DF_STATIC_TLS
;
2274 case R_IA64_LTOFF_TPREL22
:
2275 need_entry
= NEED_TPREL
;
2277 info
->flags
|= DF_STATIC_TLS
;
2280 case R_IA64_DTPREL64MSB
:
2281 case R_IA64_DTPREL64LSB
:
2282 if (info
->shared
|| maybe_dynamic
)
2283 need_entry
= NEED_DYNREL
;
2284 dynrel_type
= R_IA64_DTPREL64LSB
;
2287 case R_IA64_LTOFF_DTPREL22
:
2288 need_entry
= NEED_DTPREL
;
2291 case R_IA64_DTPMOD64MSB
:
2292 case R_IA64_DTPMOD64LSB
:
2293 if (info
->shared
|| maybe_dynamic
)
2294 need_entry
= NEED_DYNREL
;
2295 dynrel_type
= R_IA64_DTPMOD64LSB
;
2298 case R_IA64_LTOFF_DTPMOD22
:
2299 need_entry
= NEED_DTPMOD
;
2302 case R_IA64_LTOFF_FPTR22
:
2303 case R_IA64_LTOFF_FPTR64I
:
2304 case R_IA64_LTOFF_FPTR32MSB
:
2305 case R_IA64_LTOFF_FPTR32LSB
:
2306 case R_IA64_LTOFF_FPTR64MSB
:
2307 case R_IA64_LTOFF_FPTR64LSB
:
2308 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2311 case R_IA64_FPTR64I
:
2312 case R_IA64_FPTR32MSB
:
2313 case R_IA64_FPTR32LSB
:
2314 case R_IA64_FPTR64MSB
:
2315 case R_IA64_FPTR64LSB
:
2316 if (info
->shared
|| h
|| elfNN_ia64_aix_vec (abfd
->xvec
))
2317 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2319 need_entry
= NEED_FPTR
;
2320 dynrel_type
= R_IA64_FPTR64LSB
;
2323 case R_IA64_LTOFF22
:
2324 case R_IA64_LTOFF64I
:
2325 need_entry
= NEED_GOT
;
2328 case R_IA64_LTOFF22X
:
2329 need_entry
= NEED_GOTX
;
2332 case R_IA64_PLTOFF22
:
2333 case R_IA64_PLTOFF64I
:
2334 case R_IA64_PLTOFF64MSB
:
2335 case R_IA64_PLTOFF64LSB
:
2336 need_entry
= NEED_PLTOFF
;
2340 need_entry
|= NEED_MIN_PLT
;
2344 (*info
->callbacks
->warning
)
2345 (info
, _("@pltoff reloc against local symbol"), 0,
2346 abfd
, 0, (bfd_vma
) 0);
2350 case R_IA64_PCREL21B
:
2351 case R_IA64_PCREL60B
:
2352 /* Depending on where this symbol is defined, we may or may not
2353 need a full plt entry. Only skip if we know we'll not need
2354 the entry -- static or symbolic, and the symbol definition
2355 has already been seen. */
2356 if (maybe_dynamic
&& rel
->r_addend
== 0)
2357 need_entry
= NEED_FULL_PLT
;
2363 case R_IA64_DIR32MSB
:
2364 case R_IA64_DIR32LSB
:
2365 case R_IA64_DIR64MSB
:
2366 case R_IA64_DIR64LSB
:
2367 /* Shared objects will always need at least a REL relocation. */
2368 if (info
->shared
|| maybe_dynamic
2369 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2370 && (!h
|| strcmp (h
->root
.root
.string
,
2371 "__GLOB_DATA_PTR") != 0)))
2372 need_entry
= NEED_DYNREL
;
2373 dynrel_type
= R_IA64_DIR64LSB
;
2376 case R_IA64_IPLTMSB
:
2377 case R_IA64_IPLTLSB
:
2378 /* Shared objects will always need at least a REL relocation. */
2379 if (info
->shared
|| maybe_dynamic
)
2380 need_entry
= NEED_DYNREL
;
2381 dynrel_type
= R_IA64_IPLTLSB
;
2384 case R_IA64_PCREL22
:
2385 case R_IA64_PCREL64I
:
2386 case R_IA64_PCREL32MSB
:
2387 case R_IA64_PCREL32LSB
:
2388 case R_IA64_PCREL64MSB
:
2389 case R_IA64_PCREL64LSB
:
2391 need_entry
= NEED_DYNREL
;
2392 dynrel_type
= R_IA64_PCREL64LSB
;
2399 if ((need_entry
& NEED_FPTR
) != 0
2402 (*info
->callbacks
->warning
)
2403 (info
, _("non-zero addend in @fptr reloc"), 0,
2404 abfd
, 0, (bfd_vma
) 0);
2407 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, TRUE
);
2409 /* Record whether or not this is a local symbol. */
2412 /* Create what's needed. */
2413 if (need_entry
& (NEED_GOT
| NEED_GOTX
| NEED_TPREL
2414 | NEED_DTPMOD
| NEED_DTPREL
))
2418 got
= get_got (abfd
, info
, ia64_info
);
2422 if (need_entry
& NEED_GOT
)
2423 dyn_i
->want_got
= 1;
2424 if (need_entry
& NEED_GOTX
)
2425 dyn_i
->want_gotx
= 1;
2426 if (need_entry
& NEED_TPREL
)
2427 dyn_i
->want_tprel
= 1;
2428 if (need_entry
& NEED_DTPMOD
)
2429 dyn_i
->want_dtpmod
= 1;
2430 if (need_entry
& NEED_DTPREL
)
2431 dyn_i
->want_dtprel
= 1;
2433 if (need_entry
& NEED_FPTR
)
2437 fptr
= get_fptr (abfd
, info
, ia64_info
);
2442 /* FPTRs for shared libraries are allocated by the dynamic
2443 linker. Make sure this local symbol will appear in the
2444 dynamic symbol table. */
2445 if (!h
&& (info
->shared
2446 /* AIX also needs one */
2447 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2449 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2450 (info
, abfd
, (long) r_symndx
)))
2454 dyn_i
->want_fptr
= 1;
2456 if (need_entry
& NEED_LTOFF_FPTR
)
2457 dyn_i
->want_ltoff_fptr
= 1;
2458 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2460 if (!ia64_info
->root
.dynobj
)
2461 ia64_info
->root
.dynobj
= abfd
;
2462 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2463 dyn_i
->want_plt
= 1;
2465 if (need_entry
& NEED_FULL_PLT
)
2466 dyn_i
->want_plt2
= 1;
2467 if (need_entry
& NEED_PLTOFF
)
2468 dyn_i
->want_pltoff
= 1;
2469 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2473 srel
= get_reloc_section (abfd
, ia64_info
, sec
, TRUE
);
2477 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2485 /* For cleanliness, and potentially faster dynamic loading, allocate
2486 external GOT entries first. */
2489 allocate_global_data_got (dyn_i
, data
)
2490 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2493 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2495 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
2496 && ! dyn_i
->want_fptr
2497 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2498 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2499 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2500 "__GLOB_DATA_PTR") != 0))))
2502 dyn_i
->got_offset
= x
->ofs
;
2505 if (dyn_i
->want_tprel
)
2507 dyn_i
->tprel_offset
= x
->ofs
;
2510 if (dyn_i
->want_dtpmod
)
2512 if (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
))
2514 dyn_i
->dtpmod_offset
= x
->ofs
;
2519 struct elfNN_ia64_link_hash_table
*ia64_info
;
2521 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2522 if (ia64_info
->self_dtpmod_offset
== (bfd_vma
) -1)
2524 ia64_info
->self_dtpmod_offset
= x
->ofs
;
2527 dyn_i
->dtpmod_offset
= ia64_info
->self_dtpmod_offset
;
2530 if (dyn_i
->want_dtprel
)
2532 dyn_i
->dtprel_offset
= x
->ofs
;
2538 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2541 allocate_global_fptr_got (dyn_i
, data
)
2542 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2545 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2549 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2550 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2552 dyn_i
->got_offset
= x
->ofs
;
2558 /* Lastly, allocate all the GOT entries for local data. */
2561 allocate_local_got (dyn_i
, data
)
2562 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2565 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2567 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
2568 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2569 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2571 dyn_i
->got_offset
= x
->ofs
;
2577 /* Search for the index of a global symbol in it's defining object file. */
2580 global_sym_index (h
)
2581 struct elf_link_hash_entry
*h
;
2583 struct elf_link_hash_entry
**p
;
2586 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2587 || h
->root
.type
== bfd_link_hash_defweak
);
2589 obj
= h
->root
.u
.def
.section
->owner
;
2590 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2593 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2596 /* Allocate function descriptors. We can do these for every function
2597 in a main executable that is not exported. */
2600 allocate_fptr (dyn_i
, data
)
2601 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2604 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2606 if (dyn_i
->want_fptr
)
2608 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2611 while (h
->root
.type
== bfd_link_hash_indirect
2612 || h
->root
.type
== bfd_link_hash_warning
)
2613 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2616 /* AIX needs an FPTR in this case. */
2617 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2619 || h
->root
.type
== bfd_link_hash_defined
2620 || h
->root
.type
== bfd_link_hash_defweak
)))
2622 if (h
&& h
->dynindx
== -1)
2624 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2625 || (h
->root
.type
== bfd_link_hash_defweak
));
2627 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2628 (x
->info
, h
->root
.u
.def
.section
->owner
,
2629 global_sym_index (h
)))
2633 dyn_i
->want_fptr
= 0;
2635 else if (h
== NULL
|| h
->dynindx
== -1)
2637 dyn_i
->fptr_offset
= x
->ofs
;
2641 dyn_i
->want_fptr
= 0;
2646 /* Allocate all the minimal PLT entries. */
2649 allocate_plt_entries (dyn_i
, data
)
2650 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2653 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2655 if (dyn_i
->want_plt
)
2657 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2660 while (h
->root
.type
== bfd_link_hash_indirect
2661 || h
->root
.type
== bfd_link_hash_warning
)
2662 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2664 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2665 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2667 bfd_size_type offset
= x
->ofs
;
2669 offset
= PLT_HEADER_SIZE
;
2670 dyn_i
->plt_offset
= offset
;
2671 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2673 dyn_i
->want_pltoff
= 1;
2677 dyn_i
->want_plt
= 0;
2678 dyn_i
->want_plt2
= 0;
2684 /* Allocate all the full PLT entries. */
2687 allocate_plt2_entries (dyn_i
, data
)
2688 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2691 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2693 if (dyn_i
->want_plt2
)
2695 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2696 bfd_size_type ofs
= x
->ofs
;
2698 dyn_i
->plt2_offset
= ofs
;
2699 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2701 while (h
->root
.type
== bfd_link_hash_indirect
2702 || h
->root
.type
== bfd_link_hash_warning
)
2703 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2704 dyn_i
->h
->plt
.offset
= ofs
;
2709 /* Allocate all the PLTOFF entries requested by relocations and
2710 plt entries. We can't share space with allocated FPTR entries,
2711 because the latter are not necessarily addressable by the GP.
2712 ??? Relaxation might be able to determine that they are. */
2715 allocate_pltoff_entries (dyn_i
, data
)
2716 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2719 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2721 if (dyn_i
->want_pltoff
)
2723 dyn_i
->pltoff_offset
= x
->ofs
;
2729 /* Allocate dynamic relocations for those symbols that turned out
2733 allocate_dynrel_entries (dyn_i
, data
)
2734 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2737 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2738 struct elfNN_ia64_link_hash_table
*ia64_info
;
2739 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2740 bfd_boolean dynamic_symbol
, shared
;
2742 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2743 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2744 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2745 /* Don't allocate an entry for __GLOB_DATA_PTR */
2746 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2747 "__GLOB_DATA_PTR") != 0));
2748 shared
= x
->info
->shared
;
2750 /* Take care of the normal data relocations. */
2752 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2754 int count
= rent
->count
;
2758 case R_IA64_FPTR64LSB
:
2759 /* Allocate one iff !want_fptr, which by this point will
2760 be true only if we're actually allocating one statically
2761 in the main executable. */
2762 if (dyn_i
->want_fptr
)
2765 case R_IA64_PCREL64LSB
:
2766 if (!dynamic_symbol
)
2769 case R_IA64_DIR64LSB
:
2770 if (!dynamic_symbol
&& !shared
)
2773 case R_IA64_IPLTLSB
:
2774 if (!dynamic_symbol
&& !shared
)
2776 /* Use two REL relocations for IPLT relocations
2777 against local symbols. */
2778 if (!dynamic_symbol
)
2781 case R_IA64_TPREL64LSB
:
2782 case R_IA64_DTPREL64LSB
:
2783 case R_IA64_DTPMOD64LSB
:
2788 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2791 /* Take care of the GOT and PLT relocations. */
2793 if (((dynamic_symbol
|| shared
) && (dyn_i
->want_got
|| dyn_i
->want_gotx
))
2794 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2795 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2796 if ((dynamic_symbol
|| shared
) && dyn_i
->want_tprel
)
2797 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2798 if (dynamic_symbol
&& dyn_i
->want_dtpmod
)
2799 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2800 if (dynamic_symbol
&& dyn_i
->want_dtprel
)
2801 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2803 if (dyn_i
->want_pltoff
)
2805 bfd_size_type t
= 0;
2807 /* Dynamic symbols get one IPLT relocation. Local symbols in
2808 shared libraries get two REL relocations. Local symbols in
2809 main applications get nothing. */
2811 t
= sizeof (ElfNN_External_Rela
);
2813 t
= 2 * sizeof (ElfNN_External_Rela
);
2815 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2822 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2823 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2824 struct elf_link_hash_entry
*h
;
2826 /* ??? Undefined symbols with PLT entries should be re-defined
2827 to be the PLT entry. */
2829 /* If this is a weak symbol, and there is a real definition, the
2830 processor independent code will have arranged for us to see the
2831 real definition first, and we can just use the same value. */
2832 if (h
->weakdef
!= NULL
)
2834 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2835 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2836 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2837 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2841 /* If this is a reference to a symbol defined by a dynamic object which
2842 is not a function, we might allocate the symbol in our .dynbss section
2843 and allocate a COPY dynamic relocation.
2845 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2852 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2854 struct bfd_link_info
*info
;
2856 struct elfNN_ia64_allocate_data data
;
2857 struct elfNN_ia64_link_hash_table
*ia64_info
;
2860 bfd_boolean relplt
= FALSE
;
2862 dynobj
= elf_hash_table(info
)->dynobj
;
2863 ia64_info
= elfNN_ia64_hash_table (info
);
2864 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
2865 BFD_ASSERT(dynobj
!= NULL
);
2868 /* Set the contents of the .interp section to the interpreter. */
2869 if (ia64_info
->root
.dynamic_sections_created
2872 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2873 BFD_ASSERT (sec
!= NULL
);
2874 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2875 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2878 /* Allocate the GOT entries. */
2880 if (ia64_info
->got_sec
)
2883 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2884 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2885 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2886 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2889 /* Allocate the FPTR entries. */
2891 if (ia64_info
->fptr_sec
)
2894 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2895 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2898 /* Now that we've seen all of the input files, we can decide which
2899 symbols need plt entries. Allocate the minimal PLT entries first.
2900 We do this even though dynamic_sections_created may be FALSE, because
2901 this has the side-effect of clearing want_plt and want_plt2. */
2904 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2906 ia64_info
->minplt_entries
= 0;
2909 ia64_info
->minplt_entries
2910 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2913 /* Align the pointer for the plt2 entries. */
2914 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
2916 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2919 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2921 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2923 /* If we've got a .plt, we need some extra memory for the dynamic
2924 linker. We stuff these in .got.plt. */
2925 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2926 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2929 /* Allocate the PLTOFF entries. */
2931 if (ia64_info
->pltoff_sec
)
2934 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2935 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2938 if (ia64_info
->root
.dynamic_sections_created
)
2940 /* Allocate space for the dynamic relocations that turned out to be
2943 if (info
->shared
&& ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
2944 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2945 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2948 /* We have now determined the sizes of the various dynamic sections.
2949 Allocate memory for them. */
2950 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2954 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2957 /* If we don't need this section, strip it from the output file.
2958 There were several sections primarily related to dynamic
2959 linking that must be create before the linker maps input
2960 sections to output sections. The linker does that before
2961 bfd_elf_size_dynamic_sections is called, and it is that
2962 function which decides whether anything needs to go into
2965 strip
= (sec
->_raw_size
== 0);
2967 if (sec
== ia64_info
->got_sec
)
2969 else if (sec
== ia64_info
->rel_got_sec
)
2972 ia64_info
->rel_got_sec
= NULL
;
2974 /* We use the reloc_count field as a counter if we need to
2975 copy relocs into the output file. */
2976 sec
->reloc_count
= 0;
2978 else if (sec
== ia64_info
->fptr_sec
)
2981 ia64_info
->fptr_sec
= NULL
;
2983 else if (sec
== ia64_info
->plt_sec
)
2986 ia64_info
->plt_sec
= NULL
;
2988 else if (sec
== ia64_info
->pltoff_sec
)
2991 ia64_info
->pltoff_sec
= NULL
;
2993 else if (sec
== ia64_info
->rel_pltoff_sec
)
2996 ia64_info
->rel_pltoff_sec
= NULL
;
3000 /* We use the reloc_count field as a counter if we need to
3001 copy relocs into the output file. */
3002 sec
->reloc_count
= 0;
3009 /* It's OK to base decisions on the section name, because none
3010 of the dynobj section names depend upon the input files. */
3011 name
= bfd_get_section_name (dynobj
, sec
);
3013 if (strcmp (name
, ".got.plt") == 0)
3015 else if (strncmp (name
, ".rel", 4) == 0)
3019 /* We use the reloc_count field as a counter if we need to
3020 copy relocs into the output file. */
3021 sec
->reloc_count
= 0;
3029 _bfd_strip_section_from_output (info
, sec
);
3032 /* Allocate memory for the section contents. */
3033 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->_raw_size
);
3034 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
3039 if (elf_hash_table (info
)->dynamic_sections_created
)
3041 /* Add some entries to the .dynamic section. We fill in the values
3042 later (in finish_dynamic_sections) but we must add the entries now
3043 so that we get the correct size for the .dynamic section. */
3047 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3049 #define add_dynamic_entry(TAG, VAL) \
3050 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
3052 if (!add_dynamic_entry (DT_DEBUG
, 0))
3056 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
3058 if (!add_dynamic_entry (DT_PLTGOT
, 0))
3063 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
3064 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
3065 || !add_dynamic_entry (DT_JMPREL
, 0))
3069 if (!add_dynamic_entry (DT_RELA
, 0)
3070 || !add_dynamic_entry (DT_RELASZ
, 0)
3071 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
3074 if (ia64_info
->reltext
)
3076 if (!add_dynamic_entry (DT_TEXTREL
, 0))
3078 info
->flags
|= DF_TEXTREL
;
3082 /* ??? Perhaps force __gp local. */
3087 static bfd_reloc_status_type
3088 elfNN_ia64_install_value (abfd
, hit_addr
, v
, r_type
)
3092 unsigned int r_type
;
3094 const struct ia64_operand
*op
;
3095 int bigendian
= 0, shift
= 0;
3096 bfd_vma t0
, t1
, insn
, dword
;
3097 enum ia64_opnd opnd
;
3100 #ifdef BFD_HOST_U_64_BIT
3101 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
3106 opnd
= IA64_OPND_NIL
;
3111 return bfd_reloc_ok
;
3113 /* Instruction relocations. */
3116 case R_IA64_TPREL14
:
3117 case R_IA64_DTPREL14
:
3118 opnd
= IA64_OPND_IMM14
;
3121 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
3122 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
3123 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
3124 case R_IA64_PCREL21B
:
3125 case R_IA64_PCREL21BI
:
3126 opnd
= IA64_OPND_TGT25c
;
3130 case R_IA64_GPREL22
:
3131 case R_IA64_LTOFF22
:
3132 case R_IA64_LTOFF22X
:
3133 case R_IA64_PLTOFF22
:
3134 case R_IA64_PCREL22
:
3135 case R_IA64_LTOFF_FPTR22
:
3136 case R_IA64_TPREL22
:
3137 case R_IA64_DTPREL22
:
3138 case R_IA64_LTOFF_TPREL22
:
3139 case R_IA64_LTOFF_DTPMOD22
:
3140 case R_IA64_LTOFF_DTPREL22
:
3141 opnd
= IA64_OPND_IMM22
;
3145 case R_IA64_GPREL64I
:
3146 case R_IA64_LTOFF64I
:
3147 case R_IA64_PLTOFF64I
:
3148 case R_IA64_PCREL64I
:
3149 case R_IA64_FPTR64I
:
3150 case R_IA64_LTOFF_FPTR64I
:
3151 case R_IA64_TPREL64I
:
3152 case R_IA64_DTPREL64I
:
3153 opnd
= IA64_OPND_IMMU64
;
3156 /* Data relocations. */
3158 case R_IA64_DIR32MSB
:
3159 case R_IA64_GPREL32MSB
:
3160 case R_IA64_FPTR32MSB
:
3161 case R_IA64_PCREL32MSB
:
3162 case R_IA64_LTOFF_FPTR32MSB
:
3163 case R_IA64_SEGREL32MSB
:
3164 case R_IA64_SECREL32MSB
:
3165 case R_IA64_LTV32MSB
:
3166 case R_IA64_DTPREL32MSB
:
3167 size
= 4; bigendian
= 1;
3170 case R_IA64_DIR32LSB
:
3171 case R_IA64_GPREL32LSB
:
3172 case R_IA64_FPTR32LSB
:
3173 case R_IA64_PCREL32LSB
:
3174 case R_IA64_LTOFF_FPTR32LSB
:
3175 case R_IA64_SEGREL32LSB
:
3176 case R_IA64_SECREL32LSB
:
3177 case R_IA64_LTV32LSB
:
3178 case R_IA64_DTPREL32LSB
:
3179 size
= 4; bigendian
= 0;
3182 case R_IA64_DIR64MSB
:
3183 case R_IA64_GPREL64MSB
:
3184 case R_IA64_PLTOFF64MSB
:
3185 case R_IA64_FPTR64MSB
:
3186 case R_IA64_PCREL64MSB
:
3187 case R_IA64_LTOFF_FPTR64MSB
:
3188 case R_IA64_SEGREL64MSB
:
3189 case R_IA64_SECREL64MSB
:
3190 case R_IA64_LTV64MSB
:
3191 case R_IA64_TPREL64MSB
:
3192 case R_IA64_DTPMOD64MSB
:
3193 case R_IA64_DTPREL64MSB
:
3194 size
= 8; bigendian
= 1;
3197 case R_IA64_DIR64LSB
:
3198 case R_IA64_GPREL64LSB
:
3199 case R_IA64_PLTOFF64LSB
:
3200 case R_IA64_FPTR64LSB
:
3201 case R_IA64_PCREL64LSB
:
3202 case R_IA64_LTOFF_FPTR64LSB
:
3203 case R_IA64_SEGREL64LSB
:
3204 case R_IA64_SECREL64LSB
:
3205 case R_IA64_LTV64LSB
:
3206 case R_IA64_TPREL64LSB
:
3207 case R_IA64_DTPMOD64LSB
:
3208 case R_IA64_DTPREL64LSB
:
3209 size
= 8; bigendian
= 0;
3212 /* Unsupported / Dynamic relocations. */
3214 return bfd_reloc_notsupported
;
3219 case IA64_OPND_IMMU64
:
3220 hit_addr
-= (long) hit_addr
& 0x3;
3221 t0
= bfd_get_64 (abfd
, hit_addr
);
3222 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
3224 /* tmpl/s: bits 0.. 5 in t0
3225 slot 0: bits 5..45 in t0
3226 slot 1: bits 46..63 in t0, bits 0..22 in t1
3227 slot 2: bits 23..63 in t1 */
3229 /* First, clear the bits that form the 64 bit constant. */
3230 t0
&= ~(0x3ffffLL
<< 46);
3232 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
3233 | (0x01fLL
<< 22) | (0x001LL
<< 21)
3234 | (0x001LL
<< 36)) << 23));
3236 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
3237 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
3238 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
3239 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
3240 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
3241 | (((val
>> 21) & 0x001) << 21) /* ic */
3242 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
3244 bfd_put_64 (abfd
, t0
, hit_addr
);
3245 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3248 case IA64_OPND_TGT64
:
3249 hit_addr
-= (long) hit_addr
& 0x3;
3250 t0
= bfd_get_64 (abfd
, hit_addr
);
3251 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
3253 /* tmpl/s: bits 0.. 5 in t0
3254 slot 0: bits 5..45 in t0
3255 slot 1: bits 46..63 in t0, bits 0..22 in t1
3256 slot 2: bits 23..63 in t1 */
3258 /* First, clear the bits that form the 64 bit constant. */
3259 t0
&= ~(0x3ffffLL
<< 46);
3261 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
3264 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
3265 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
3266 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
3267 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
3269 bfd_put_64 (abfd
, t0
, hit_addr
);
3270 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3274 switch ((long) hit_addr
& 0x3)
3276 case 0: shift
= 5; break;
3277 case 1: shift
= 14; hit_addr
+= 3; break;
3278 case 2: shift
= 23; hit_addr
+= 6; break;
3279 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
3281 dword
= bfd_get_64 (abfd
, hit_addr
);
3282 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
3284 op
= elf64_ia64_operands
+ opnd
;
3285 err
= (*op
->insert
) (op
, val
, (ia64_insn
*)& insn
);
3287 return bfd_reloc_overflow
;
3289 dword
&= ~(0x1ffffffffffLL
<< shift
);
3290 dword
|= (insn
<< shift
);
3291 bfd_put_64 (abfd
, dword
, hit_addr
);
3295 /* A data relocation. */
3298 bfd_putb32 (val
, hit_addr
);
3300 bfd_putb64 (val
, hit_addr
);
3303 bfd_putl32 (val
, hit_addr
);
3305 bfd_putl64 (val
, hit_addr
);
3309 return bfd_reloc_ok
;
3313 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
3316 struct bfd_link_info
*info
;
3324 Elf_Internal_Rela outrel
;
3327 BFD_ASSERT (dynindx
!= -1);
3328 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3329 outrel
.r_addend
= addend
;
3330 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3331 if (outrel
.r_offset
>= (bfd_vma
) -2)
3333 /* Run for the hills. We shouldn't be outputting a relocation
3334 for this. So do what everyone else does and output a no-op. */
3335 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3336 outrel
.r_addend
= 0;
3337 outrel
.r_offset
= 0;
3340 outrel
.r_offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3342 loc
= srel
->contents
;
3343 loc
+= srel
->reloc_count
++ * sizeof (ElfNN_External_Rela
);
3344 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
3345 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3346 <= srel
->_cooked_size
);
3349 /* Store an entry for target address TARGET_ADDR in the linkage table
3350 and return the gp-relative address of the linkage table entry. */
3353 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3355 struct bfd_link_info
*info
;
3356 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3360 unsigned int dyn_r_type
;
3362 struct elfNN_ia64_link_hash_table
*ia64_info
;
3367 ia64_info
= elfNN_ia64_hash_table (info
);
3368 got_sec
= ia64_info
->got_sec
;
3372 case R_IA64_TPREL64LSB
:
3373 done
= dyn_i
->tprel_done
;
3374 dyn_i
->tprel_done
= TRUE
;
3375 got_offset
= dyn_i
->tprel_offset
;
3377 case R_IA64_DTPMOD64LSB
:
3378 if (dyn_i
->dtpmod_offset
!= ia64_info
->self_dtpmod_offset
)
3380 done
= dyn_i
->dtpmod_done
;
3381 dyn_i
->dtpmod_done
= TRUE
;
3385 done
= ia64_info
->self_dtpmod_done
;
3386 ia64_info
->self_dtpmod_done
= TRUE
;
3389 got_offset
= dyn_i
->dtpmod_offset
;
3391 case R_IA64_DTPREL64LSB
:
3392 done
= dyn_i
->dtprel_done
;
3393 dyn_i
->dtprel_done
= TRUE
;
3394 got_offset
= dyn_i
->dtprel_offset
;
3397 done
= dyn_i
->got_done
;
3398 dyn_i
->got_done
= TRUE
;
3399 got_offset
= dyn_i
->got_offset
;
3403 BFD_ASSERT ((got_offset
& 7) == 0);
3407 /* Store the target address in the linkage table entry. */
3408 bfd_put_64 (abfd
, value
, got_sec
->contents
+ got_offset
);
3410 /* Install a dynamic relocation if needed. */
3411 if ((info
->shared
&& dyn_r_type
!= R_IA64_DTPREL64LSB
)
3412 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3413 || elfNN_ia64_aix_vec (abfd
->xvec
)
3414 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3417 && dyn_r_type
!= R_IA64_TPREL64LSB
3418 && dyn_r_type
!= R_IA64_DTPMOD64LSB
3419 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
3421 dyn_r_type
= R_IA64_REL64LSB
;
3426 if (bfd_big_endian (abfd
))
3430 case R_IA64_REL64LSB
:
3431 dyn_r_type
= R_IA64_REL64MSB
;
3433 case R_IA64_DIR64LSB
:
3434 dyn_r_type
= R_IA64_DIR64MSB
;
3436 case R_IA64_FPTR64LSB
:
3437 dyn_r_type
= R_IA64_FPTR64MSB
;
3439 case R_IA64_TPREL64LSB
:
3440 dyn_r_type
= R_IA64_TPREL64MSB
;
3442 case R_IA64_DTPMOD64LSB
:
3443 dyn_r_type
= R_IA64_DTPMOD64MSB
;
3445 case R_IA64_DTPREL64LSB
:
3446 dyn_r_type
= R_IA64_DTPREL64MSB
;
3454 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3455 ia64_info
->rel_got_sec
,
3456 got_offset
, dyn_r_type
,
3461 /* Return the address of the linkage table entry. */
3462 value
= (got_sec
->output_section
->vma
3463 + got_sec
->output_offset
3469 /* Fill in a function descriptor consisting of the function's code
3470 address and its global pointer. Return the descriptor's address. */
3473 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3475 struct bfd_link_info
*info
;
3476 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3479 struct elfNN_ia64_link_hash_table
*ia64_info
;
3482 ia64_info
= elfNN_ia64_hash_table (info
);
3483 fptr_sec
= ia64_info
->fptr_sec
;
3485 if (!dyn_i
->fptr_done
)
3487 dyn_i
->fptr_done
= 1;
3489 /* Fill in the function descriptor. */
3490 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3491 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3492 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3495 /* Return the descriptor's address. */
3496 value
= (fptr_sec
->output_section
->vma
3497 + fptr_sec
->output_offset
3498 + dyn_i
->fptr_offset
);
3503 /* Fill in a PLTOFF entry consisting of the function's code address
3504 and its global pointer. Return the descriptor's address. */
3507 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3509 struct bfd_link_info
*info
;
3510 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3514 struct elfNN_ia64_link_hash_table
*ia64_info
;
3515 asection
*pltoff_sec
;
3517 ia64_info
= elfNN_ia64_hash_table (info
);
3518 pltoff_sec
= ia64_info
->pltoff_sec
;
3520 /* Don't do anything if this symbol uses a real PLT entry. In
3521 that case, we'll fill this in during finish_dynamic_symbol. */
3522 if ((! dyn_i
->want_plt
|| is_plt
)
3523 && !dyn_i
->pltoff_done
)
3525 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3527 /* Fill in the function descriptor. */
3528 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3529 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3531 /* Install dynamic relocations if needed. */
3532 if (!is_plt
&& info
->shared
)
3534 unsigned int dyn_r_type
;
3536 if (bfd_big_endian (abfd
))
3537 dyn_r_type
= R_IA64_REL64MSB
;
3539 dyn_r_type
= R_IA64_REL64LSB
;
3541 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3542 ia64_info
->rel_pltoff_sec
,
3543 dyn_i
->pltoff_offset
,
3544 dyn_r_type
, 0, value
);
3545 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3546 ia64_info
->rel_pltoff_sec
,
3547 dyn_i
->pltoff_offset
+ 8,
3551 dyn_i
->pltoff_done
= 1;
3554 /* Return the descriptor's address. */
3555 value
= (pltoff_sec
->output_section
->vma
3556 + pltoff_sec
->output_offset
3557 + dyn_i
->pltoff_offset
);
3562 /* Return the base VMA address which should be subtracted from real addresses
3563 when resolving @tprel() relocation.
3564 Main program TLS (whose template starts at PT_TLS p_vaddr)
3565 is assigned offset round(16, PT_TLS p_align). */
3568 elfNN_ia64_tprel_base (info
)
3569 struct bfd_link_info
*info
;
3571 struct elf_link_tls_segment
*tls_segment
3572 = elf_hash_table (info
)->tls_segment
;
3574 BFD_ASSERT (tls_segment
!= NULL
);
3575 return (tls_segment
->start
3576 - align_power ((bfd_vma
) 16, tls_segment
->align
));
3579 /* Return the base VMA address which should be subtracted from real addresses
3580 when resolving @dtprel() relocation.
3581 This is PT_TLS segment p_vaddr. */
3584 elfNN_ia64_dtprel_base (info
)
3585 struct bfd_link_info
*info
;
3587 BFD_ASSERT (elf_hash_table (info
)->tls_segment
!= NULL
);
3588 return elf_hash_table (info
)->tls_segment
->start
;
3591 /* Called through qsort to sort the .IA_64.unwind section during a
3592 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3593 to the output bfd so we can do proper endianness frobbing. */
3595 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3598 elfNN_ia64_unwind_entry_compare (a
, b
)
3604 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3605 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3607 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3610 /* Make sure we've got ourselves a nice fat __gp value. */
3612 elfNN_ia64_choose_gp (abfd
, info
)
3614 struct bfd_link_info
*info
;
3616 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3617 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3618 struct elf_link_hash_entry
*gp
;
3621 struct elfNN_ia64_link_hash_table
*ia64_info
;
3623 ia64_info
= elfNN_ia64_hash_table (info
);
3625 /* Find the min and max vma of all sections marked short. Also collect
3626 min and max vma of any type, for use in selecting a nice gp. */
3627 for (os
= abfd
->sections
; os
; os
= os
->next
)
3631 if ((os
->flags
& SEC_ALLOC
) == 0)
3635 hi
= os
->vma
+ os
->_raw_size
;
3643 if (os
->flags
& SEC_SMALL_DATA
)
3645 if (min_short_vma
> lo
)
3647 if (max_short_vma
< hi
)
3652 /* See if the user wants to force a value. */
3653 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
3657 && (gp
->root
.type
== bfd_link_hash_defined
3658 || gp
->root
.type
== bfd_link_hash_defweak
))
3660 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3661 gp_val
= (gp
->root
.u
.def
.value
3662 + gp_sec
->output_section
->vma
3663 + gp_sec
->output_offset
);
3667 /* Pick a sensible value. */
3669 asection
*got_sec
= ia64_info
->got_sec
;
3671 /* Start with just the address of the .got. */
3673 gp_val
= got_sec
->output_section
->vma
;
3674 else if (max_short_vma
!= 0)
3675 gp_val
= min_short_vma
;
3679 /* If it is possible to address the entire image, but we
3680 don't with the choice above, adjust. */
3681 if (max_vma
- min_vma
< 0x400000
3682 && max_vma
- gp_val
<= 0x200000
3683 && gp_val
- min_vma
> 0x200000)
3684 gp_val
= min_vma
+ 0x200000;
3685 else if (max_short_vma
!= 0)
3687 /* If we don't cover all the short data, adjust. */
3688 if (max_short_vma
- gp_val
>= 0x200000)
3689 gp_val
= min_short_vma
+ 0x200000;
3691 /* If we're addressing stuff past the end, adjust back. */
3692 if (gp_val
> max_vma
)
3693 gp_val
= max_vma
- 0x200000 + 8;
3697 /* Validate whether all SHF_IA_64_SHORT sections are within
3698 range of the chosen GP. */
3700 if (max_short_vma
!= 0)
3702 if (max_short_vma
- min_short_vma
>= 0x400000)
3704 (*_bfd_error_handler
)
3705 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3706 bfd_get_filename (abfd
),
3707 (unsigned long) (max_short_vma
- min_short_vma
));
3710 else if ((gp_val
> min_short_vma
3711 && gp_val
- min_short_vma
> 0x200000)
3712 || (gp_val
< max_short_vma
3713 && max_short_vma
- gp_val
>= 0x200000))
3715 (*_bfd_error_handler
)
3716 (_("%s: __gp does not cover short data segment"),
3717 bfd_get_filename (abfd
));
3722 _bfd_set_gp_value (abfd
, gp_val
);
3728 elfNN_ia64_final_link (abfd
, info
)
3730 struct bfd_link_info
*info
;
3732 struct elfNN_ia64_link_hash_table
*ia64_info
;
3733 asection
*unwind_output_sec
;
3735 ia64_info
= elfNN_ia64_hash_table (info
);
3737 /* Make sure we've got ourselves a nice fat __gp value. */
3738 if (!info
->relocateable
)
3740 bfd_vma gp_val
= _bfd_get_gp_value (abfd
);
3741 struct elf_link_hash_entry
*gp
;
3745 if (! elfNN_ia64_choose_gp (abfd
, info
))
3747 gp_val
= _bfd_get_gp_value (abfd
);
3750 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
3754 gp
->root
.type
= bfd_link_hash_defined
;
3755 gp
->root
.u
.def
.value
= gp_val
;
3756 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3760 /* If we're producing a final executable, we need to sort the contents
3761 of the .IA_64.unwind section. Force this section to be relocated
3762 into memory rather than written immediately to the output file. */
3763 unwind_output_sec
= NULL
;
3764 if (!info
->relocateable
)
3766 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3769 unwind_output_sec
= s
->output_section
;
3770 unwind_output_sec
->contents
3771 = bfd_malloc (unwind_output_sec
->_raw_size
);
3772 if (unwind_output_sec
->contents
== NULL
)
3777 /* Invoke the regular ELF backend linker to do all the work. */
3778 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3781 if (unwind_output_sec
)
3783 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3784 qsort (unwind_output_sec
->contents
,
3785 (size_t) (unwind_output_sec
->_raw_size
/ 24),
3787 elfNN_ia64_unwind_entry_compare
);
3789 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3790 unwind_output_sec
->contents
, (bfd_vma
) 0,
3791 unwind_output_sec
->_raw_size
))
3799 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3800 contents
, relocs
, local_syms
, local_sections
)
3802 struct bfd_link_info
*info
;
3804 asection
*input_section
;
3806 Elf_Internal_Rela
*relocs
;
3807 Elf_Internal_Sym
*local_syms
;
3808 asection
**local_sections
;
3810 struct elfNN_ia64_link_hash_table
*ia64_info
;
3811 Elf_Internal_Shdr
*symtab_hdr
;
3812 Elf_Internal_Rela
*rel
;
3813 Elf_Internal_Rela
*relend
;
3815 bfd_boolean ret_val
= TRUE
; /* for non-fatal errors */
3818 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3819 ia64_info
= elfNN_ia64_hash_table (info
);
3821 /* Infect various flags from the input section to the output section. */
3822 if (info
->relocateable
)
3826 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3827 flags
&= SHF_IA_64_NORECOV
;
3829 elf_section_data(input_section
->output_section
)
3830 ->this_hdr
.sh_flags
|= flags
;
3834 gp_val
= _bfd_get_gp_value (output_bfd
);
3835 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, FALSE
);
3838 relend
= relocs
+ input_section
->reloc_count
;
3839 for (; rel
< relend
; ++rel
)
3841 struct elf_link_hash_entry
*h
;
3842 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3843 bfd_reloc_status_type r
;
3844 reloc_howto_type
*howto
;
3845 unsigned long r_symndx
;
3846 Elf_Internal_Sym
*sym
;
3847 unsigned int r_type
;
3851 bfd_boolean dynamic_symbol_p
;
3852 bfd_boolean undef_weak_ref
;
3854 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3855 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3857 (*_bfd_error_handler
)
3858 (_("%s: unknown relocation type %d"),
3859 bfd_archive_filename (input_bfd
), (int)r_type
);
3860 bfd_set_error (bfd_error_bad_value
);
3865 howto
= lookup_howto (r_type
);
3866 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3870 undef_weak_ref
= FALSE
;
3872 if (r_symndx
< symtab_hdr
->sh_info
)
3874 /* Reloc against local symbol. */
3875 sym
= local_syms
+ r_symndx
;
3876 sym_sec
= local_sections
[r_symndx
];
3877 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, sym_sec
, rel
);
3878 if ((sym_sec
->flags
& SEC_MERGE
)
3879 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
3880 && sym_sec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
3882 struct elfNN_ia64_local_hash_entry
*loc_h
;
3884 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, FALSE
);
3885 if (loc_h
&& ! loc_h
->sec_merge_done
)
3887 struct elfNN_ia64_dyn_sym_info
*dynent
;
3890 for (dynent
= loc_h
->info
; dynent
; dynent
= dynent
->next
)
3894 _bfd_merged_section_offset (output_bfd
, &msec
,
3895 elf_section_data (msec
)->
3900 dynent
->addend
-= sym
->st_value
;
3901 dynent
->addend
+= msec
->output_section
->vma
3902 + msec
->output_offset
3903 - sym_sec
->output_section
->vma
3904 - sym_sec
->output_offset
;
3906 loc_h
->sec_merge_done
= 1;
3914 /* Reloc against global symbol. */
3915 indx
= r_symndx
- symtab_hdr
->sh_info
;
3916 h
= elf_sym_hashes (input_bfd
)[indx
];
3917 while (h
->root
.type
== bfd_link_hash_indirect
3918 || h
->root
.type
== bfd_link_hash_warning
)
3919 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3922 if (h
->root
.type
== bfd_link_hash_defined
3923 || h
->root
.type
== bfd_link_hash_defweak
)
3925 sym_sec
= h
->root
.u
.def
.section
;
3927 /* Detect the cases that sym_sec->output_section is
3928 expected to be NULL -- all cases in which the symbol
3929 is defined in another shared module. This includes
3930 PLT relocs for which we've created a PLT entry and
3931 other relocs for which we're prepared to create
3932 dynamic relocations. */
3933 /* ??? Just accept it NULL and continue. */
3935 if (sym_sec
->output_section
!= NULL
)
3937 value
= (h
->root
.u
.def
.value
3938 + sym_sec
->output_section
->vma
3939 + sym_sec
->output_offset
);
3942 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3943 undef_weak_ref
= TRUE
;
3944 else if (info
->shared
3945 && !info
->no_undefined
3946 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3950 if (! ((*info
->callbacks
->undefined_symbol
)
3951 (info
, h
->root
.root
.string
, input_bfd
,
3952 input_section
, rel
->r_offset
,
3953 (!info
->shared
|| info
->no_undefined
3954 || ELF_ST_VISIBILITY (h
->other
)))))
3961 hit_addr
= contents
+ rel
->r_offset
;
3962 value
+= rel
->r_addend
;
3963 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3974 case R_IA64_DIR32MSB
:
3975 case R_IA64_DIR32LSB
:
3976 case R_IA64_DIR64MSB
:
3977 case R_IA64_DIR64LSB
:
3978 /* Install a dynamic relocation for this reloc. */
3979 if ((dynamic_symbol_p
|| info
->shared
3980 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
3981 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3982 && (!h
|| strcmp (h
->root
.root
.string
,
3983 "__GLOB_DATA_PTR") != 0)))
3985 && (input_section
->flags
& SEC_ALLOC
) != 0)
3987 unsigned int dyn_r_type
;
3991 BFD_ASSERT (srel
!= NULL
);
3993 /* If we don't need dynamic symbol lookup, find a
3994 matching RELATIVE relocation. */
3995 dyn_r_type
= r_type
;
3996 if (dynamic_symbol_p
)
3998 dynindx
= h
->dynindx
;
3999 addend
= rel
->r_addend
;
4006 case R_IA64_DIR32MSB
:
4007 dyn_r_type
= R_IA64_REL32MSB
;
4009 case R_IA64_DIR32LSB
:
4010 dyn_r_type
= R_IA64_REL32LSB
;
4012 case R_IA64_DIR64MSB
:
4013 dyn_r_type
= R_IA64_REL64MSB
;
4015 case R_IA64_DIR64LSB
:
4016 dyn_r_type
= R_IA64_REL64LSB
;
4020 /* We can't represent this without a dynamic symbol.
4021 Adjust the relocation to be against an output
4022 section symbol, which are always present in the
4023 dynamic symbol table. */
4024 /* ??? People shouldn't be doing non-pic code in
4025 shared libraries. Hork. */
4026 (*_bfd_error_handler
)
4027 (_("%s: linking non-pic code in a shared library"),
4028 bfd_archive_filename (input_bfd
));
4036 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
4037 rel
->r_addend
= value
;
4038 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4039 srel
, rel
->r_offset
, dyn_r_type
,
4044 case R_IA64_LTV32MSB
:
4045 case R_IA64_LTV32LSB
:
4046 case R_IA64_LTV64MSB
:
4047 case R_IA64_LTV64LSB
:
4048 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4051 case R_IA64_GPREL22
:
4052 case R_IA64_GPREL64I
:
4053 case R_IA64_GPREL32MSB
:
4054 case R_IA64_GPREL32LSB
:
4055 case R_IA64_GPREL64MSB
:
4056 case R_IA64_GPREL64LSB
:
4057 if (dynamic_symbol_p
)
4059 (*_bfd_error_handler
)
4060 (_("%s: @gprel relocation against dynamic symbol %s"),
4061 bfd_archive_filename (input_bfd
), h
->root
.root
.string
);
4066 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4069 case R_IA64_LTOFF22
:
4070 case R_IA64_LTOFF22X
:
4071 case R_IA64_LTOFF64I
:
4072 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4073 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
4074 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
4076 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4079 case R_IA64_PLTOFF22
:
4080 case R_IA64_PLTOFF64I
:
4081 case R_IA64_PLTOFF64MSB
:
4082 case R_IA64_PLTOFF64LSB
:
4083 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4084 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, FALSE
);
4086 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4089 case R_IA64_FPTR64I
:
4090 case R_IA64_FPTR32MSB
:
4091 case R_IA64_FPTR32LSB
:
4092 case R_IA64_FPTR64MSB
:
4093 case R_IA64_FPTR64LSB
:
4094 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4095 if (dyn_i
->want_fptr
)
4097 if (!undef_weak_ref
)
4098 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4104 /* Otherwise, we expect the dynamic linker to create
4109 if (h
->dynindx
!= -1)
4110 dynindx
= h
->dynindx
;
4112 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4113 (info
, h
->root
.u
.def
.section
->owner
,
4114 global_sym_index (h
)));
4118 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4119 (info
, input_bfd
, (long) r_symndx
));
4122 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4123 srel
, rel
->r_offset
, r_type
,
4124 dynindx
, rel
->r_addend
);
4128 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4131 case R_IA64_LTOFF_FPTR22
:
4132 case R_IA64_LTOFF_FPTR64I
:
4133 case R_IA64_LTOFF_FPTR32MSB
:
4134 case R_IA64_LTOFF_FPTR32LSB
:
4135 case R_IA64_LTOFF_FPTR64MSB
:
4136 case R_IA64_LTOFF_FPTR64LSB
:
4140 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4141 if (dyn_i
->want_fptr
)
4143 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
4144 if (!undef_weak_ref
)
4145 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4150 /* Otherwise, we expect the dynamic linker to create
4154 if (h
->dynindx
!= -1)
4155 dynindx
= h
->dynindx
;
4157 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4158 (info
, h
->root
.u
.def
.section
->owner
,
4159 global_sym_index (h
)));
4162 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4163 (info
, input_bfd
, (long) r_symndx
));
4167 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
4168 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
4170 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4174 case R_IA64_PCREL32MSB
:
4175 case R_IA64_PCREL32LSB
:
4176 case R_IA64_PCREL64MSB
:
4177 case R_IA64_PCREL64LSB
:
4178 /* Install a dynamic relocation for this reloc. */
4179 if ((dynamic_symbol_p
4180 || elfNN_ia64_aix_vec (info
->hash
->creator
))
4183 BFD_ASSERT (srel
!= NULL
);
4185 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4186 srel
, rel
->r_offset
, r_type
,
4187 h
->dynindx
, rel
->r_addend
);
4191 case R_IA64_PCREL21B
:
4192 case R_IA64_PCREL60B
:
4193 /* We should have created a PLT entry for any dynamic symbol. */
4196 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4198 if (dyn_i
&& dyn_i
->want_plt2
)
4200 /* Should have caught this earlier. */
4201 BFD_ASSERT (rel
->r_addend
== 0);
4203 value
= (ia64_info
->plt_sec
->output_section
->vma
4204 + ia64_info
->plt_sec
->output_offset
4205 + dyn_i
->plt2_offset
);
4209 /* Since there's no PLT entry, Validate that this is
4211 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
4213 /* If the symbol is undef_weak, we shouldn't be trying
4214 to call it. There's every chance that we'd wind up
4215 with an out-of-range fixup here. Don't bother setting
4216 any value at all. */
4222 case R_IA64_PCREL21BI
:
4223 case R_IA64_PCREL21F
:
4224 case R_IA64_PCREL21M
:
4225 case R_IA64_PCREL22
:
4226 case R_IA64_PCREL64I
:
4227 /* The PCREL21BI reloc is specifically not intended for use with
4228 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4229 fixup code, and thus probably ought not be dynamic. The
4230 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4231 if (dynamic_symbol_p
)
4235 if (r_type
== R_IA64_PCREL21BI
)
4236 msg
= _("%s: @internal branch to dynamic symbol %s");
4237 else if (r_type
== R_IA64_PCREL21F
|| r_type
== R_IA64_PCREL21M
)
4238 msg
= _("%s: speculation fixup to dynamic symbol %s");
4240 msg
= _("%s: @pcrel relocation against dynamic symbol %s");
4241 (*_bfd_error_handler
) (msg
, bfd_archive_filename (input_bfd
),
4242 h
->root
.root
.string
);
4249 /* Make pc-relative. */
4250 value
-= (input_section
->output_section
->vma
4251 + input_section
->output_offset
4252 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
4253 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4256 case R_IA64_SEGREL32MSB
:
4257 case R_IA64_SEGREL32LSB
:
4258 case R_IA64_SEGREL64MSB
:
4259 case R_IA64_SEGREL64LSB
:
4262 /* If the input section was discarded from the output, then
4268 struct elf_segment_map
*m
;
4269 Elf_Internal_Phdr
*p
;
4271 /* Find the segment that contains the output_section. */
4272 for (m
= elf_tdata (output_bfd
)->segment_map
,
4273 p
= elf_tdata (output_bfd
)->phdr
;
4278 for (i
= m
->count
- 1; i
>= 0; i
--)
4279 if (m
->sections
[i
] == sym_sec
->output_section
)
4287 r
= bfd_reloc_notsupported
;
4291 /* The VMA of the segment is the vaddr of the associated
4293 if (value
> p
->p_vaddr
)
4294 value
-= p
->p_vaddr
;
4297 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
4303 case R_IA64_SECREL32MSB
:
4304 case R_IA64_SECREL32LSB
:
4305 case R_IA64_SECREL64MSB
:
4306 case R_IA64_SECREL64LSB
:
4307 /* Make output-section relative. */
4308 if (value
> input_section
->output_section
->vma
)
4309 value
-= input_section
->output_section
->vma
;
4312 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4315 case R_IA64_IPLTMSB
:
4316 case R_IA64_IPLTLSB
:
4317 /* Install a dynamic relocation for this reloc. */
4318 if ((dynamic_symbol_p
|| info
->shared
)
4319 && (input_section
->flags
& SEC_ALLOC
) != 0)
4321 BFD_ASSERT (srel
!= NULL
);
4323 /* If we don't need dynamic symbol lookup, install two
4324 RELATIVE relocations. */
4325 if (! dynamic_symbol_p
)
4327 unsigned int dyn_r_type
;
4329 if (r_type
== R_IA64_IPLTMSB
)
4330 dyn_r_type
= R_IA64_REL64MSB
;
4332 dyn_r_type
= R_IA64_REL64LSB
;
4334 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4336 srel
, rel
->r_offset
,
4337 dyn_r_type
, 0, value
);
4338 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4340 srel
, rel
->r_offset
+ 8,
4341 dyn_r_type
, 0, gp_val
);
4344 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4345 srel
, rel
->r_offset
, r_type
,
4346 h
->dynindx
, rel
->r_addend
);
4349 if (r_type
== R_IA64_IPLTMSB
)
4350 r_type
= R_IA64_DIR64MSB
;
4352 r_type
= R_IA64_DIR64LSB
;
4353 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4354 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
4358 case R_IA64_TPREL14
:
4359 case R_IA64_TPREL22
:
4360 case R_IA64_TPREL64I
:
4361 value
-= elfNN_ia64_tprel_base (info
);
4362 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4365 case R_IA64_DTPREL14
:
4366 case R_IA64_DTPREL22
:
4367 case R_IA64_DTPREL64I
:
4368 case R_IA64_DTPREL64LSB
:
4369 case R_IA64_DTPREL64MSB
:
4370 value
-= elfNN_ia64_dtprel_base (info
);
4371 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4374 case R_IA64_LTOFF_TPREL22
:
4375 case R_IA64_LTOFF_DTPMOD22
:
4376 case R_IA64_LTOFF_DTPREL22
:
4379 long dynindx
= h
? h
->dynindx
: -1;
4380 bfd_vma r_addend
= rel
->r_addend
;
4385 case R_IA64_LTOFF_TPREL22
:
4386 if (!dynamic_symbol_p
)
4389 value
-= elfNN_ia64_tprel_base (info
);
4392 r_addend
+= value
- elfNN_ia64_dtprel_base (info
);
4396 got_r_type
= R_IA64_TPREL64LSB
;
4398 case R_IA64_LTOFF_DTPMOD22
:
4399 if (!dynamic_symbol_p
&& !info
->shared
)
4401 got_r_type
= R_IA64_DTPMOD64LSB
;
4403 case R_IA64_LTOFF_DTPREL22
:
4404 if (!dynamic_symbol_p
)
4405 value
-= elfNN_ia64_dtprel_base (info
);
4406 got_r_type
= R_IA64_DTPREL64LSB
;
4409 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4410 value
= set_got_entry (input_bfd
, info
, dyn_i
, dynindx
, r_addend
,
4413 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
4419 r
= bfd_reloc_notsupported
;
4428 case bfd_reloc_undefined
:
4429 /* This can happen for global table relative relocs if
4430 __gp is undefined. This is a panic situation so we
4431 don't try to continue. */
4432 (*info
->callbacks
->undefined_symbol
)
4433 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
4436 case bfd_reloc_notsupported
:
4441 name
= h
->root
.root
.string
;
4444 name
= bfd_elf_string_from_elf_section (input_bfd
,
4445 symtab_hdr
->sh_link
,
4450 name
= bfd_section_name (input_bfd
, input_section
);
4452 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
4454 input_section
, rel
->r_offset
))
4460 case bfd_reloc_dangerous
:
4461 case bfd_reloc_outofrange
:
4462 case bfd_reloc_overflow
:
4468 name
= h
->root
.root
.string
;
4471 name
= bfd_elf_string_from_elf_section (input_bfd
,
4472 symtab_hdr
->sh_link
,
4477 name
= bfd_section_name (input_bfd
, input_section
);
4479 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
4496 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
4498 struct bfd_link_info
*info
;
4499 struct elf_link_hash_entry
*h
;
4500 Elf_Internal_Sym
*sym
;
4502 struct elfNN_ia64_link_hash_table
*ia64_info
;
4503 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4505 ia64_info
= elfNN_ia64_hash_table (info
);
4506 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4508 /* Fill in the PLT data, if required. */
4509 if (dyn_i
&& dyn_i
->want_plt
)
4511 Elf_Internal_Rela outrel
;
4514 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
4516 gp_val
= _bfd_get_gp_value (output_bfd
);
4518 /* Initialize the minimal PLT entry. */
4520 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4521 plt_sec
= ia64_info
->plt_sec
;
4522 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4524 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4525 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4526 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4529 plt_addr
= (plt_sec
->output_section
->vma
4530 + plt_sec
->output_offset
4531 + dyn_i
->plt_offset
);
4532 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, TRUE
);
4534 /* Initialize the FULL PLT entry, if needed. */
4535 if (dyn_i
->want_plt2
)
4537 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4539 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4540 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4543 /* Mark the symbol as undefined, rather than as defined in the
4544 plt section. Leave the value alone. */
4545 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4546 first place. But perhaps elflink.h did some for us. */
4547 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4548 sym
->st_shndx
= SHN_UNDEF
;
4551 /* Create the dynamic relocation. */
4552 outrel
.r_offset
= pltoff_addr
;
4553 if (bfd_little_endian (output_bfd
))
4554 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4556 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4557 outrel
.r_addend
= 0;
4559 /* This is fun. In the .IA_64.pltoff section, we've got entries
4560 that correspond both to real PLT entries, and those that
4561 happened to resolve to local symbols but need to be created
4562 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4563 relocations for the real PLT should come at the end of the
4564 section, so that they can be indexed by plt entry at runtime.
4566 We emitted all of the relocations for the non-PLT @pltoff
4567 entries during relocate_section. So we can consider the
4568 existing sec->reloc_count to be the base of the array of
4571 loc
= ia64_info
->rel_pltoff_sec
->contents
;
4572 loc
+= ((ia64_info
->rel_pltoff_sec
->reloc_count
+ index
)
4573 * sizeof (Elf64_External_Rela
));
4574 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
4577 /* Mark some specially defined symbols as absolute. */
4578 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4579 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4580 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4581 sym
->st_shndx
= SHN_ABS
;
4587 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4589 struct bfd_link_info
*info
;
4591 struct elfNN_ia64_link_hash_table
*ia64_info
;
4594 ia64_info
= elfNN_ia64_hash_table (info
);
4595 dynobj
= ia64_info
->root
.dynobj
;
4597 if (elf_hash_table (info
)->dynamic_sections_created
)
4599 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4600 asection
*sdyn
, *sgotplt
;
4603 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4604 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4605 BFD_ASSERT (sdyn
!= NULL
);
4606 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4607 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4609 gp_val
= _bfd_get_gp_value (abfd
);
4611 for (; dyncon
< dynconend
; dyncon
++)
4613 Elf_Internal_Dyn dyn
;
4615 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4620 dyn
.d_un
.d_ptr
= gp_val
;
4624 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4625 * sizeof (ElfNN_External_Rela
));
4629 /* See the comment above in finish_dynamic_symbol. */
4630 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4631 + ia64_info
->rel_pltoff_sec
->output_offset
4632 + (ia64_info
->rel_pltoff_sec
->reloc_count
4633 * sizeof (ElfNN_External_Rela
)));
4636 case DT_IA_64_PLT_RESERVE
:
4637 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4638 + sgotplt
->output_offset
);
4642 /* Do not have RELASZ include JMPREL. This makes things
4643 easier on ld.so. This is not what the rest of BFD set up. */
4644 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4645 * sizeof (ElfNN_External_Rela
));
4649 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4652 /* Initialize the PLT0 entry. */
4653 if (ia64_info
->plt_sec
)
4655 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4658 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4660 pltres
= (sgotplt
->output_section
->vma
4661 + sgotplt
->output_offset
4664 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4671 /* ELF file flag handling: */
4673 /* Function to keep IA-64 specific file flags. */
4675 elfNN_ia64_set_private_flags (abfd
, flags
)
4679 BFD_ASSERT (!elf_flags_init (abfd
)
4680 || elf_elfheader (abfd
)->e_flags
== flags
);
4682 elf_elfheader (abfd
)->e_flags
= flags
;
4683 elf_flags_init (abfd
) = TRUE
;
4687 /* Merge backend specific data from an object file to the output
4688 object file when linking. */
4690 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4695 bfd_boolean ok
= TRUE
;
4697 /* Don't even pretend to support mixed-format linking. */
4698 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4699 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4702 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4703 out_flags
= elf_elfheader (obfd
)->e_flags
;
4705 if (! elf_flags_init (obfd
))
4707 elf_flags_init (obfd
) = TRUE
;
4708 elf_elfheader (obfd
)->e_flags
= in_flags
;
4710 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4711 && bfd_get_arch_info (obfd
)->the_default
)
4713 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4714 bfd_get_mach (ibfd
));
4720 /* Check flag compatibility. */
4721 if (in_flags
== out_flags
)
4724 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4725 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4726 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4728 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4730 (*_bfd_error_handler
)
4731 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4732 bfd_archive_filename (ibfd
));
4734 bfd_set_error (bfd_error_bad_value
);
4737 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4739 (*_bfd_error_handler
)
4740 (_("%s: linking big-endian files with little-endian files"),
4741 bfd_archive_filename (ibfd
));
4743 bfd_set_error (bfd_error_bad_value
);
4746 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4748 (*_bfd_error_handler
)
4749 (_("%s: linking 64-bit files with 32-bit files"),
4750 bfd_archive_filename (ibfd
));
4752 bfd_set_error (bfd_error_bad_value
);
4755 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4757 (*_bfd_error_handler
)
4758 (_("%s: linking constant-gp files with non-constant-gp files"),
4759 bfd_archive_filename (ibfd
));
4761 bfd_set_error (bfd_error_bad_value
);
4764 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4765 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4767 (*_bfd_error_handler
)
4768 (_("%s: linking auto-pic files with non-auto-pic files"),
4769 bfd_archive_filename (ibfd
));
4771 bfd_set_error (bfd_error_bad_value
);
4779 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4783 FILE *file
= (FILE *) ptr
;
4784 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4786 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4788 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4789 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4790 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4791 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4792 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4793 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4794 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4795 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4796 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4798 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4802 static enum elf_reloc_type_class
4803 elfNN_ia64_reloc_type_class (rela
)
4804 const Elf_Internal_Rela
*rela
;
4806 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
4808 case R_IA64_REL32MSB
:
4809 case R_IA64_REL32LSB
:
4810 case R_IA64_REL64MSB
:
4811 case R_IA64_REL64LSB
:
4812 return reloc_class_relative
;
4813 case R_IA64_IPLTMSB
:
4814 case R_IA64_IPLTLSB
:
4815 return reloc_class_plt
;
4817 return reloc_class_copy
;
4819 return reloc_class_normal
;
4824 elfNN_ia64_hpux_vec (const bfd_target
*vec
)
4826 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec
;
4827 return (vec
== & bfd_elfNN_ia64_hpux_big_vec
);
4831 elfNN_hpux_post_process_headers (abfd
, info
)
4833 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
4835 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
4837 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_HPUX
;
4838 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 1;
4842 elfNN_hpux_backend_section_from_bfd_section (abfd
, sec
, retval
)
4843 bfd
*abfd ATTRIBUTE_UNUSED
;
4847 if (bfd_is_com_section (sec
))
4849 *retval
= SHN_IA_64_ANSI_COMMON
;
4855 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4856 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4857 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4858 #define TARGET_BIG_NAME "elfNN-ia64-big"
4859 #define ELF_ARCH bfd_arch_ia64
4860 #define ELF_MACHINE_CODE EM_IA_64
4861 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4862 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4863 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4865 #define elf_backend_section_from_shdr \
4866 elfNN_ia64_section_from_shdr
4867 #define elf_backend_section_flags \
4868 elfNN_ia64_section_flags
4869 #define elf_backend_fake_sections \
4870 elfNN_ia64_fake_sections
4871 #define elf_backend_final_write_processing \
4872 elfNN_ia64_final_write_processing
4873 #define elf_backend_add_symbol_hook \
4874 elfNN_ia64_add_symbol_hook
4875 #define elf_backend_additional_program_headers \
4876 elfNN_ia64_additional_program_headers
4877 #define elf_backend_modify_segment_map \
4878 elfNN_ia64_modify_segment_map
4879 #define elf_info_to_howto \
4880 elfNN_ia64_info_to_howto
4882 #define bfd_elfNN_bfd_reloc_type_lookup \
4883 elfNN_ia64_reloc_type_lookup
4884 #define bfd_elfNN_bfd_is_local_label_name \
4885 elfNN_ia64_is_local_label_name
4886 #define bfd_elfNN_bfd_relax_section \
4887 elfNN_ia64_relax_section
4889 /* Stuff for the BFD linker: */
4890 #define bfd_elfNN_bfd_link_hash_table_create \
4891 elfNN_ia64_hash_table_create
4892 #define elf_backend_create_dynamic_sections \
4893 elfNN_ia64_create_dynamic_sections
4894 #define elf_backend_check_relocs \
4895 elfNN_ia64_check_relocs
4896 #define elf_backend_adjust_dynamic_symbol \
4897 elfNN_ia64_adjust_dynamic_symbol
4898 #define elf_backend_size_dynamic_sections \
4899 elfNN_ia64_size_dynamic_sections
4900 #define elf_backend_relocate_section \
4901 elfNN_ia64_relocate_section
4902 #define elf_backend_finish_dynamic_symbol \
4903 elfNN_ia64_finish_dynamic_symbol
4904 #define elf_backend_finish_dynamic_sections \
4905 elfNN_ia64_finish_dynamic_sections
4906 #define bfd_elfNN_bfd_final_link \
4907 elfNN_ia64_final_link
4909 #define bfd_elfNN_bfd_merge_private_bfd_data \
4910 elfNN_ia64_merge_private_bfd_data
4911 #define bfd_elfNN_bfd_set_private_flags \
4912 elfNN_ia64_set_private_flags
4913 #define bfd_elfNN_bfd_print_private_bfd_data \
4914 elfNN_ia64_print_private_bfd_data
4916 #define elf_backend_plt_readonly 1
4917 #define elf_backend_want_plt_sym 0
4918 #define elf_backend_plt_alignment 5
4919 #define elf_backend_got_header_size 0
4920 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4921 #define elf_backend_want_got_plt 1
4922 #define elf_backend_may_use_rel_p 1
4923 #define elf_backend_may_use_rela_p 1
4924 #define elf_backend_default_use_rela_p 1
4925 #define elf_backend_want_dynbss 0
4926 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4927 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4928 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4929 #define elf_backend_rela_normal 1
4931 #include "elfNN-target.h"
4933 /* AIX-specific vectors. */
4935 #undef TARGET_LITTLE_SYM
4936 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4937 #undef TARGET_LITTLE_NAME
4938 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4939 #undef TARGET_BIG_SYM
4940 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4941 #undef TARGET_BIG_NAME
4942 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4944 #undef elf_backend_add_symbol_hook
4945 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4947 #undef bfd_elfNN_bfd_link_add_symbols
4948 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4950 #define elfNN_bed elfNN_ia64_aix_bed
4952 #include "elfNN-target.h"
4954 /* HPUX-specific vectors. */
4956 #undef TARGET_LITTLE_SYM
4957 #undef TARGET_LITTLE_NAME
4958 #undef TARGET_BIG_SYM
4959 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4960 #undef TARGET_BIG_NAME
4961 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4963 /* We need to undo the AIX specific functions. */
4965 #undef elf_backend_add_symbol_hook
4966 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
4968 #undef bfd_elfNN_bfd_link_add_symbols
4969 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
4971 /* These are HP-UX specific functions. */
4973 #undef elf_backend_post_process_headers
4974 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4976 #undef elf_backend_section_from_bfd_section
4977 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4979 #undef elf_backend_want_p_paddr_set_to_zero
4980 #define elf_backend_want_p_paddr_set_to_zero 1
4982 #undef ELF_MAXPAGESIZE
4983 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4986 #define elfNN_bed elfNN_ia64_hpux_bed
4988 #include "elfNN-target.h"
4990 #undef elf_backend_want_p_paddr_set_to_zero