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
*rel_fptr_sec
; /* dynamic relocation section for same */
147 asection
*plt_sec
; /* the primary plt section (or NULL) */
148 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
149 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
151 bfd_size_type minplt_entries
; /* number of minplt entries */
152 unsigned reltext
: 1; /* are there relocs against readonly sections? */
153 unsigned self_dtpmod_done
: 1;/* has self DTPMOD entry been finished? */
154 bfd_vma self_dtpmod_offset
; /* .got offset to self DTPMOD entry */
156 struct elfNN_ia64_local_hash_table loc_hash_table
;
159 struct elfNN_ia64_allocate_data
161 struct bfd_link_info
*info
;
165 #define elfNN_ia64_hash_table(p) \
166 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
168 static bfd_reloc_status_type elfNN_ia64_reloc
169 PARAMS ((bfd
*abfd
, arelent
*reloc
, asymbol
*sym
, PTR data
,
170 asection
*input_section
, bfd
*output_bfd
, char **error_message
));
171 static reloc_howto_type
* lookup_howto
172 PARAMS ((unsigned int rtype
));
173 static reloc_howto_type
*elfNN_ia64_reloc_type_lookup
174 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type bfd_code
));
175 static void elfNN_ia64_info_to_howto
176 PARAMS ((bfd
*abfd
, arelent
*bfd_reloc
, Elf_Internal_Rela
*elf_reloc
));
177 static bfd_boolean elfNN_ia64_relax_section
178 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
179 bfd_boolean
*again
));
180 static void elfNN_ia64_relax_ldxmov
181 PARAMS((bfd
*abfd
, bfd_byte
*contents
, bfd_vma off
));
182 static bfd_boolean is_unwind_section_name
183 PARAMS ((bfd
*abfd
, const char *));
184 static bfd_boolean elfNN_ia64_section_from_shdr
185 PARAMS ((bfd
*, Elf_Internal_Shdr
*, const char *));
186 static bfd_boolean elfNN_ia64_section_flags
187 PARAMS ((flagword
*, Elf_Internal_Shdr
*));
188 static bfd_boolean elfNN_ia64_fake_sections
189 PARAMS ((bfd
*abfd
, Elf_Internal_Shdr
*hdr
, asection
*sec
));
190 static void elfNN_ia64_final_write_processing
191 PARAMS ((bfd
*abfd
, bfd_boolean linker
));
192 static bfd_boolean elfNN_ia64_add_symbol_hook
193 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
194 const char **namep
, flagword
*flagsp
, asection
**secp
,
196 static bfd_boolean elfNN_ia64_aix_vec
197 PARAMS ((const bfd_target
*vec
));
198 static bfd_boolean elfNN_ia64_aix_add_symbol_hook
199 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
200 const char **namep
, flagword
*flagsp
, asection
**secp
,
202 static bfd_boolean elfNN_ia64_aix_link_add_symbols
203 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
204 static int elfNN_ia64_additional_program_headers
205 PARAMS ((bfd
*abfd
));
206 static bfd_boolean elfNN_ia64_modify_segment_map
208 static bfd_boolean elfNN_ia64_is_local_label_name
209 PARAMS ((bfd
*abfd
, const char *name
));
210 static bfd_boolean elfNN_ia64_dynamic_symbol_p
211 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
));
212 static bfd_boolean elfNN_ia64_local_hash_table_init
213 PARAMS ((struct elfNN_ia64_local_hash_table
*ht
, bfd
*abfd
,
214 new_hash_entry_func
new));
215 static struct bfd_hash_entry
*elfNN_ia64_new_loc_hash_entry
216 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
217 const char *string
));
218 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
219 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
220 const char *string
));
221 static void elfNN_ia64_hash_copy_indirect
222 PARAMS ((struct elf_backend_data
*, struct elf_link_hash_entry
*,
223 struct elf_link_hash_entry
*));
224 static void elfNN_ia64_hash_hide_symbol
225 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*, bfd_boolean
));
226 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
227 PARAMS ((bfd
*abfd
));
228 static struct elfNN_ia64_local_hash_entry
*elfNN_ia64_local_hash_lookup
229 PARAMS ((struct elfNN_ia64_local_hash_table
*table
, const char *string
,
230 bfd_boolean create
, bfd_boolean copy
));
231 static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
232 PARAMS ((struct bfd_hash_entry
*, PTR
));
233 static bfd_boolean elfNN_ia64_local_dyn_sym_thunk
234 PARAMS ((struct bfd_hash_entry
*, PTR
));
235 static void elfNN_ia64_dyn_sym_traverse
236 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
237 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
239 static bfd_boolean elfNN_ia64_create_dynamic_sections
240 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
241 static struct elfNN_ia64_local_hash_entry
* get_local_sym_hash
242 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
243 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
));
244 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
245 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
246 struct elf_link_hash_entry
*h
,
247 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
));
248 static asection
*get_got
249 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
250 struct elfNN_ia64_link_hash_table
*ia64_info
));
251 static asection
*get_fptr
252 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
253 struct elfNN_ia64_link_hash_table
*ia64_info
));
254 static asection
*get_pltoff
255 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
256 struct elfNN_ia64_link_hash_table
*ia64_info
));
257 static asection
*get_reloc_section
258 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
259 asection
*sec
, bfd_boolean create
));
260 static bfd_boolean count_dyn_reloc
261 PARAMS ((bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
262 asection
*srel
, int type
));
263 static bfd_boolean elfNN_ia64_check_relocs
264 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
265 const Elf_Internal_Rela
*relocs
));
266 static bfd_boolean elfNN_ia64_adjust_dynamic_symbol
267 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
268 static long global_sym_index
269 PARAMS ((struct elf_link_hash_entry
*h
));
270 static bfd_boolean allocate_fptr
271 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
272 static bfd_boolean allocate_global_data_got
273 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
274 static bfd_boolean allocate_global_fptr_got
275 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
276 static bfd_boolean allocate_local_got
277 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
278 static bfd_boolean allocate_pltoff_entries
279 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
280 static bfd_boolean allocate_plt_entries
281 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
282 static bfd_boolean allocate_plt2_entries
283 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
284 static bfd_boolean allocate_dynrel_entries
285 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
286 static bfd_boolean elfNN_ia64_size_dynamic_sections
287 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
288 static bfd_reloc_status_type elfNN_ia64_install_value
289 PARAMS ((bfd
*abfd
, bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
290 static void elfNN_ia64_install_dyn_reloc
291 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
292 asection
*srel
, bfd_vma offset
, unsigned int type
,
293 long dynindx
, bfd_vma addend
));
294 static bfd_vma set_got_entry
295 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
296 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
297 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
298 static bfd_vma set_fptr_entry
299 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
300 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
302 static bfd_vma set_pltoff_entry
303 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
304 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
305 bfd_vma value
, bfd_boolean
));
306 static bfd_vma elfNN_ia64_tprel_base
307 PARAMS ((struct bfd_link_info
*info
));
308 static bfd_vma elfNN_ia64_dtprel_base
309 PARAMS ((struct bfd_link_info
*info
));
310 static int elfNN_ia64_unwind_entry_compare
311 PARAMS ((const PTR
, const PTR
));
312 static bfd_boolean elfNN_ia64_choose_gp
313 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
314 static bfd_boolean elfNN_ia64_final_link
315 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
316 static bfd_boolean elfNN_ia64_relocate_section
317 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
318 asection
*input_section
, bfd_byte
*contents
,
319 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
320 asection
**local_sections
));
321 static bfd_boolean elfNN_ia64_finish_dynamic_symbol
322 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
323 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
324 static bfd_boolean elfNN_ia64_finish_dynamic_sections
325 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
326 static bfd_boolean elfNN_ia64_set_private_flags
327 PARAMS ((bfd
*abfd
, flagword flags
));
328 static bfd_boolean elfNN_ia64_merge_private_bfd_data
329 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
330 static bfd_boolean elfNN_ia64_print_private_bfd_data
331 PARAMS ((bfd
*abfd
, PTR ptr
));
332 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
333 PARAMS ((const Elf_Internal_Rela
*));
334 static bfd_boolean elfNN_ia64_hpux_vec
335 PARAMS ((const bfd_target
*vec
));
336 static void elfNN_hpux_post_process_headers
337 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
338 bfd_boolean elfNN_hpux_backend_section_from_bfd_section
339 PARAMS ((bfd
*abfd
, asection
*sec
, int *retval
));
341 /* ia64-specific relocation. */
343 /* Perform a relocation. Not much to do here as all the hard work is
344 done in elfNN_ia64_final_link_relocate. */
345 static bfd_reloc_status_type
346 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
347 output_bfd
, error_message
)
348 bfd
*abfd ATTRIBUTE_UNUSED
;
350 asymbol
*sym ATTRIBUTE_UNUSED
;
351 PTR data ATTRIBUTE_UNUSED
;
352 asection
*input_section
;
354 char **error_message
;
358 reloc
->address
+= input_section
->output_offset
;
362 if (input_section
->flags
& SEC_DEBUGGING
)
363 return bfd_reloc_continue
;
365 *error_message
= "Unsupported call to elfNN_ia64_reloc";
366 return bfd_reloc_notsupported
;
369 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
370 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
371 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
373 /* This table has to be sorted according to increasing number of the
375 static reloc_howto_type ia64_howto_table
[] =
377 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, FALSE
, TRUE
),
379 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, FALSE
, TRUE
),
380 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, FALSE
, TRUE
),
381 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, FALSE
, TRUE
),
382 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, FALSE
, TRUE
),
383 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, FALSE
, TRUE
),
384 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, FALSE
, TRUE
),
385 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, FALSE
, TRUE
),
387 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, FALSE
, TRUE
),
388 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, FALSE
, TRUE
),
389 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, FALSE
, TRUE
),
390 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, FALSE
, TRUE
),
391 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, FALSE
, TRUE
),
392 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, FALSE
, TRUE
),
394 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, FALSE
, TRUE
),
395 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, FALSE
, TRUE
),
397 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, FALSE
, TRUE
),
398 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, FALSE
, TRUE
),
399 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, FALSE
, TRUE
),
400 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, FALSE
, TRUE
),
402 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, FALSE
, TRUE
),
403 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, FALSE
, TRUE
),
404 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, FALSE
, TRUE
),
405 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, FALSE
, TRUE
),
406 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, FALSE
, TRUE
),
408 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, TRUE
, TRUE
),
409 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, TRUE
, TRUE
),
410 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, TRUE
, TRUE
),
411 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, TRUE
, TRUE
),
412 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, TRUE
, TRUE
),
413 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, TRUE
, TRUE
),
414 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, TRUE
, TRUE
),
415 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, TRUE
, TRUE
),
417 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, FALSE
, TRUE
),
418 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, FALSE
, TRUE
),
419 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, FALSE
, TRUE
),
420 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, FALSE
, TRUE
),
421 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, FALSE
, TRUE
),
422 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, FALSE
, TRUE
),
424 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, FALSE
, TRUE
),
425 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, FALSE
, TRUE
),
426 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, FALSE
, TRUE
),
427 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, FALSE
, TRUE
),
429 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, FALSE
, TRUE
),
430 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, FALSE
, TRUE
),
431 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, FALSE
, TRUE
),
432 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, FALSE
, TRUE
),
434 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, FALSE
, TRUE
),
435 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, FALSE
, TRUE
),
436 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, FALSE
, TRUE
),
437 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, FALSE
, TRUE
),
439 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, FALSE
, TRUE
),
440 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, FALSE
, TRUE
),
441 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, FALSE
, TRUE
),
442 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, FALSE
, TRUE
),
444 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, TRUE
, TRUE
),
445 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, TRUE
, TRUE
),
446 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, TRUE
, TRUE
),
448 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, FALSE
, TRUE
),
449 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, FALSE
, TRUE
),
450 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, FALSE
, TRUE
),
451 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, FALSE
, TRUE
),
452 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, FALSE
, TRUE
),
454 IA64_HOWTO (R_IA64_TPREL14
, "TPREL14", 0, FALSE
, FALSE
),
455 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, FALSE
, FALSE
),
456 IA64_HOWTO (R_IA64_TPREL64I
, "TPREL64I", 0, FALSE
, FALSE
),
457 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, FALSE
, FALSE
),
458 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, FALSE
, FALSE
),
459 IA64_HOWTO (R_IA64_LTOFF_TPREL22
, "LTOFF_TPREL22", 0, FALSE
, FALSE
),
461 IA64_HOWTO (R_IA64_DTPMOD64MSB
, "TPREL64MSB", 8, FALSE
, FALSE
),
462 IA64_HOWTO (R_IA64_DTPMOD64LSB
, "TPREL64LSB", 8, FALSE
, FALSE
),
463 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22
, "LTOFF_DTPMOD22", 0, FALSE
, FALSE
),
465 IA64_HOWTO (R_IA64_DTPREL14
, "DTPREL14", 0, FALSE
, FALSE
),
466 IA64_HOWTO (R_IA64_DTPREL22
, "DTPREL22", 0, FALSE
, FALSE
),
467 IA64_HOWTO (R_IA64_DTPREL64I
, "DTPREL64I", 0, FALSE
, FALSE
),
468 IA64_HOWTO (R_IA64_DTPREL32MSB
, "DTPREL32MSB", 4, FALSE
, FALSE
),
469 IA64_HOWTO (R_IA64_DTPREL32LSB
, "DTPREL32LSB", 4, FALSE
, FALSE
),
470 IA64_HOWTO (R_IA64_DTPREL64MSB
, "DTPREL64MSB", 8, FALSE
, FALSE
),
471 IA64_HOWTO (R_IA64_DTPREL64LSB
, "DTPREL64LSB", 8, FALSE
, FALSE
),
472 IA64_HOWTO (R_IA64_LTOFF_DTPREL22
, "LTOFF_DTPREL22", 0, FALSE
, FALSE
),
475 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
477 /* Given a BFD reloc type, return the matching HOWTO structure. */
479 static reloc_howto_type
*
483 static int inited
= 0;
490 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
491 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
492 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
495 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
496 i
= elf_code_to_howto_index
[rtype
];
497 if (i
>= NELEMS (ia64_howto_table
))
499 return ia64_howto_table
+ i
;
502 static reloc_howto_type
*
503 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
504 bfd
*abfd ATTRIBUTE_UNUSED
;
505 bfd_reloc_code_real_type bfd_code
;
511 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
513 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
514 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
515 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
517 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
518 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
519 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
520 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
522 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
523 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
524 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
525 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
526 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
527 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
529 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
530 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
532 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
533 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
534 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
535 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
536 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
537 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
538 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
539 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
540 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
542 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
543 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
544 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
545 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
546 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
547 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
548 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
549 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
550 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
551 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
552 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
554 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
555 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
556 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
557 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
558 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
559 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
561 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
562 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
563 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
564 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
566 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
567 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
568 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
569 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
571 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
572 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
573 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
574 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
576 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
577 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
578 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
579 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
581 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
582 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
583 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
584 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
585 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
587 case BFD_RELOC_IA64_TPREL14
: rtype
= R_IA64_TPREL14
; break;
588 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
589 case BFD_RELOC_IA64_TPREL64I
: rtype
= R_IA64_TPREL64I
; break;
590 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
591 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
592 case BFD_RELOC_IA64_LTOFF_TPREL22
: rtype
= R_IA64_LTOFF_TPREL22
; break;
594 case BFD_RELOC_IA64_DTPMOD64MSB
: rtype
= R_IA64_DTPMOD64MSB
; break;
595 case BFD_RELOC_IA64_DTPMOD64LSB
: rtype
= R_IA64_DTPMOD64LSB
; break;
596 case BFD_RELOC_IA64_LTOFF_DTPMOD22
: rtype
= R_IA64_LTOFF_DTPMOD22
; break;
598 case BFD_RELOC_IA64_DTPREL14
: rtype
= R_IA64_DTPREL14
; break;
599 case BFD_RELOC_IA64_DTPREL22
: rtype
= R_IA64_DTPREL22
; break;
600 case BFD_RELOC_IA64_DTPREL64I
: rtype
= R_IA64_DTPREL64I
; break;
601 case BFD_RELOC_IA64_DTPREL32MSB
: rtype
= R_IA64_DTPREL32MSB
; break;
602 case BFD_RELOC_IA64_DTPREL32LSB
: rtype
= R_IA64_DTPREL32LSB
; break;
603 case BFD_RELOC_IA64_DTPREL64MSB
: rtype
= R_IA64_DTPREL64MSB
; break;
604 case BFD_RELOC_IA64_DTPREL64LSB
: rtype
= R_IA64_DTPREL64LSB
; break;
605 case BFD_RELOC_IA64_LTOFF_DTPREL22
: rtype
= R_IA64_LTOFF_DTPREL22
; break;
609 return lookup_howto (rtype
);
612 /* Given a ELF reloc, return the matching HOWTO structure. */
615 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
616 bfd
*abfd ATTRIBUTE_UNUSED
;
618 Elf_Internal_Rela
*elf_reloc
;
621 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
624 #define PLT_HEADER_SIZE (3 * 16)
625 #define PLT_MIN_ENTRY_SIZE (1 * 16)
626 #define PLT_FULL_ENTRY_SIZE (2 * 16)
627 #define PLT_RESERVED_WORDS 3
629 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
631 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
632 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
633 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
634 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
635 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
636 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
637 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
638 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
639 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
642 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
644 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
645 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
646 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
649 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
651 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
652 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
653 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
654 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
655 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
656 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
659 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
660 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
661 #define DYNAMIC_INTERPRETER(abfd) \
662 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
664 static const bfd_byte oor_brl
[16] =
666 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
668 0x00, 0x00, 0x00, 0xc0
671 /* These functions do relaxation for IA-64 ELF. */
674 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
677 struct bfd_link_info
*link_info
;
682 struct one_fixup
*next
;
688 Elf_Internal_Shdr
*symtab_hdr
;
689 Elf_Internal_Rela
*internal_relocs
;
690 Elf_Internal_Rela
*irel
, *irelend
;
692 Elf_Internal_Sym
*isymbuf
= NULL
;
693 struct elfNN_ia64_link_hash_table
*ia64_info
;
694 struct one_fixup
*fixups
= NULL
;
695 bfd_boolean changed_contents
= FALSE
;
696 bfd_boolean changed_relocs
= FALSE
;
697 bfd_boolean changed_got
= FALSE
;
700 /* Assume we're not going to change any sizes, and we'll only need
704 /* Don't even try to relax for non-ELF outputs. */
705 if (link_info
->hash
->creator
->flavour
!= bfd_target_elf_flavour
)
708 /* Nothing to do if there are no relocations or there is no need for
709 the relax finalize pass. */
710 if ((sec
->flags
& SEC_RELOC
) == 0
711 || sec
->reloc_count
== 0
712 || (link_info
->relax_finalizing
713 && sec
->need_finalize_relax
== 0))
716 /* If this is the first time we have been called for this section,
717 initialize the cooked size. */
718 if (sec
->_cooked_size
== 0)
719 sec
->_cooked_size
= sec
->_raw_size
;
721 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
723 /* Load the relocations for this section. */
724 internal_relocs
= (_bfd_elf_link_read_relocs
725 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
726 link_info
->keep_memory
));
727 if (internal_relocs
== NULL
)
730 ia64_info
= elfNN_ia64_hash_table (link_info
);
731 irelend
= internal_relocs
+ sec
->reloc_count
;
733 /* Get the section contents. */
734 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
735 contents
= elf_section_data (sec
)->this_hdr
.contents
;
738 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
739 if (contents
== NULL
)
742 if (! bfd_get_section_contents (abfd
, sec
, contents
,
743 (file_ptr
) 0, sec
->_raw_size
))
747 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
749 unsigned long r_type
= ELFNN_R_TYPE (irel
->r_info
);
750 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
754 bfd_boolean is_branch
;
755 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
759 case R_IA64_PCREL21B
:
760 case R_IA64_PCREL21BI
:
761 case R_IA64_PCREL21M
:
762 case R_IA64_PCREL21F
:
763 if (link_info
->relax_finalizing
)
768 case R_IA64_LTOFF22X
:
770 if (!link_info
->relax_finalizing
)
772 sec
->need_finalize_relax
= 1;
782 /* Get the value of the symbol referred to by the reloc. */
783 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
785 /* A local symbol. */
786 Elf_Internal_Sym
*isym
;
788 /* Read this BFD's local symbols. */
791 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
793 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
794 symtab_hdr
->sh_info
, 0,
800 isym
= isymbuf
+ ELFNN_R_SYM (irel
->r_info
);
801 if (isym
->st_shndx
== SHN_UNDEF
)
802 continue; /* We can't do anthing with undefined symbols. */
803 else if (isym
->st_shndx
== SHN_ABS
)
804 tsec
= bfd_abs_section_ptr
;
805 else if (isym
->st_shndx
== SHN_COMMON
)
806 tsec
= bfd_com_section_ptr
;
807 else if (isym
->st_shndx
== SHN_IA_64_ANSI_COMMON
)
808 tsec
= bfd_com_section_ptr
;
810 tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
812 toff
= isym
->st_value
;
813 dyn_i
= get_dyn_sym_info (ia64_info
, NULL
, abfd
, irel
, FALSE
);
818 struct elf_link_hash_entry
*h
;
820 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
821 h
= elf_sym_hashes (abfd
)[indx
];
822 BFD_ASSERT (h
!= NULL
);
824 while (h
->root
.type
== bfd_link_hash_indirect
825 || h
->root
.type
== bfd_link_hash_warning
)
826 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
828 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, FALSE
);
830 /* For branches to dynamic symbols, we're interested instead
831 in a branch to the PLT entry. */
832 if (is_branch
&& dyn_i
&& dyn_i
->want_plt2
)
834 /* Internal branches shouldn't be sent to the PLT.
835 Leave this for now and we'll give an error later. */
836 if (r_type
!= R_IA64_PCREL21B
)
839 tsec
= ia64_info
->plt_sec
;
840 toff
= dyn_i
->plt2_offset
;
841 BFD_ASSERT (irel
->r_addend
== 0);
844 /* Can't do anything else with dynamic symbols. */
845 else if (elfNN_ia64_dynamic_symbol_p (h
, link_info
))
850 /* We can't do anthing with undefined symbols. */
851 if (h
->root
.type
== bfd_link_hash_undefined
852 || h
->root
.type
== bfd_link_hash_undefweak
)
855 tsec
= h
->root
.u
.def
.section
;
856 toff
= h
->root
.u
.def
.value
;
860 if (tsec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
861 toff
= _bfd_merged_section_offset (abfd
, &tsec
,
862 elf_section_data (tsec
)->sec_info
,
863 toff
+ irel
->r_addend
,
866 toff
+= irel
->r_addend
;
868 symaddr
= tsec
->output_section
->vma
+ tsec
->output_offset
+ toff
;
870 roff
= irel
->r_offset
;
874 reladdr
= (sec
->output_section
->vma
876 + roff
) & (bfd_vma
) -4;
878 /* If the branch is in range, no need to do anything. */
879 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
880 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
883 /* If the branch and target are in the same section, you've
884 got one honking big section and we can't help you. You'll
885 get an error message later. */
889 /* Look for an existing fixup to this address. */
890 for (f
= fixups
; f
; f
= f
->next
)
891 if (f
->tsec
== tsec
&& f
->toff
== toff
)
896 /* Two alternatives: If it's a branch to a PLT entry, we can
897 make a copy of the FULL_PLT entry. Otherwise, we'll have
898 to use a `brl' insn to get where we're going. */
902 if (tsec
== ia64_info
->plt_sec
)
903 size
= sizeof (plt_full_entry
);
906 size
= sizeof (oor_brl
);
909 /* Resize the current section to make room for the new branch. */
910 trampoff
= (sec
->_cooked_size
+ 15) & (bfd_vma
) -16;
911 amt
= trampoff
+ size
;
912 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
913 if (contents
== NULL
)
915 sec
->_cooked_size
= amt
;
917 if (tsec
== ia64_info
->plt_sec
)
919 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
921 /* Hijack the old relocation for use as the PLTOFF reloc. */
922 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
924 irel
->r_offset
= trampoff
;
928 memcpy (contents
+ trampoff
, oor_brl
, size
);
929 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
931 irel
->r_offset
= trampoff
+ 2;
934 /* Record the fixup so we don't do it again this section. */
935 f
= (struct one_fixup
*)
936 bfd_malloc ((bfd_size_type
) sizeof (*f
));
940 f
->trampoff
= trampoff
;
945 /* Nop out the reloc, since we're finalizing things here. */
946 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
949 /* Fix up the existing branch to hit the trampoline. Hope like
950 hell this doesn't overflow too. */
951 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
952 f
->trampoff
- (roff
& (bfd_vma
) -4),
953 r_type
) != bfd_reloc_ok
)
956 changed_contents
= TRUE
;
957 changed_relocs
= TRUE
;
964 bfd
*obfd
= sec
->output_section
->owner
;
965 gp
= _bfd_get_gp_value (obfd
);
968 if (!elfNN_ia64_choose_gp (obfd
, link_info
))
970 gp
= _bfd_get_gp_value (obfd
);
974 /* If the data is out of range, do nothing. */
975 if ((bfd_signed_vma
) (symaddr
- gp
) >= 0x200000
976 ||(bfd_signed_vma
) (symaddr
- gp
) < -0x200000)
979 if (r_type
== R_IA64_LTOFF22X
)
981 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
983 changed_relocs
= TRUE
;
984 if (dyn_i
->want_gotx
)
986 dyn_i
->want_gotx
= 0;
987 changed_got
|= !dyn_i
->want_got
;
992 elfNN_ia64_relax_ldxmov (abfd
, contents
, roff
);
993 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
994 changed_contents
= TRUE
;
995 changed_relocs
= TRUE
;
1000 /* ??? If we created fixups, this may push the code segment large
1001 enough that the data segment moves, which will change the GP.
1002 Reset the GP so that we re-calculate next round. We need to
1003 do this at the _beginning_ of the next round; now will not do. */
1005 /* Clean up and go home. */
1008 struct one_fixup
*f
= fixups
;
1009 fixups
= fixups
->next
;
1014 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1016 if (! link_info
->keep_memory
)
1020 /* Cache the symbols for elf_link_input_bfd. */
1021 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1025 if (contents
!= NULL
1026 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1028 if (!changed_contents
&& !link_info
->keep_memory
)
1032 /* Cache the section contents for elf_link_input_bfd. */
1033 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1037 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
1039 if (!changed_relocs
)
1040 free (internal_relocs
);
1042 elf_section_data (sec
)->relocs
= internal_relocs
;
1047 struct elfNN_ia64_allocate_data data
;
1048 data
.info
= link_info
;
1050 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
1052 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
1053 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
1054 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
1055 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
1056 ia64_info
->got_sec
->_cooked_size
= data
.ofs
;
1058 /* ??? Resize .rela.got too. */
1061 if (link_info
->relax_finalizing
)
1062 sec
->need_finalize_relax
= 0;
1064 *again
= changed_contents
|| changed_relocs
;
1068 if (isymbuf
!= NULL
&& (unsigned char *) isymbuf
!= symtab_hdr
->contents
)
1070 if (contents
!= NULL
1071 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1073 if (internal_relocs
!= NULL
1074 && elf_section_data (sec
)->relocs
!= internal_relocs
)
1075 free (internal_relocs
);
1080 elfNN_ia64_relax_ldxmov (abfd
, contents
, off
)
1086 bfd_vma dword
, insn
;
1088 switch ((int)off
& 0x3)
1090 case 0: shift
= 5; break;
1091 case 1: shift
= 14; off
+= 3; break;
1092 case 2: shift
= 23; off
+= 6; break;
1097 dword
= bfd_get_64 (abfd
, contents
+ off
);
1098 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
1100 r1
= (insn
>> 6) & 127;
1101 r3
= (insn
>> 20) & 127;
1103 insn
= 0x8000000; /* nop */
1105 insn
= (insn
& 0x7f01fff) | 0x10800000000LL
; /* (qp) mov r1 = r3 */
1107 dword
&= ~(0x1ffffffffffLL
<< shift
);
1108 dword
|= (insn
<< shift
);
1109 bfd_put_64 (abfd
, dword
, contents
+ off
);
1112 /* Return TRUE if NAME is an unwind table section name. */
1114 static inline bfd_boolean
1115 is_unwind_section_name (abfd
, name
)
1119 size_t len1
, len2
, len3
;
1121 if (elfNN_ia64_hpux_vec (abfd
->xvec
)
1122 && !strcmp (name
, ELF_STRING_ia64_unwind_hdr
))
1125 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1126 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
1127 len3
= sizeof (ELF_STRING_ia64_unwind_once
) - 1;
1128 return ((strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
1129 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0)
1130 || strncmp (name
, ELF_STRING_ia64_unwind_once
, len3
) == 0);
1133 /* Handle an IA-64 specific section when reading an object file. This
1134 is called when elfcode.h finds a section with an unknown type. */
1137 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
1139 Elf_Internal_Shdr
*hdr
;
1144 /* There ought to be a place to keep ELF backend specific flags, but
1145 at the moment there isn't one. We just keep track of the
1146 sections by their name, instead. Fortunately, the ABI gives
1147 suggested names for all the MIPS specific sections, so we will
1148 probably get away with this. */
1149 switch (hdr
->sh_type
)
1151 case SHT_IA_64_UNWIND
:
1152 case SHT_IA_64_HP_OPT_ANOT
:
1156 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1164 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
1166 newsect
= hdr
->bfd_section
;
1171 /* Convert IA-64 specific section flags to bfd internal section flags. */
1173 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1177 elfNN_ia64_section_flags (flags
, hdr
)
1179 Elf_Internal_Shdr
*hdr
;
1181 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1182 *flags
|= SEC_SMALL_DATA
;
1187 /* Set the correct type for an IA-64 ELF section. We do this by the
1188 section name, which is a hack, but ought to work. */
1191 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1192 bfd
*abfd ATTRIBUTE_UNUSED
;
1193 Elf_Internal_Shdr
*hdr
;
1196 register const char *name
;
1198 name
= bfd_get_section_name (abfd
, sec
);
1200 if (is_unwind_section_name (abfd
, name
))
1202 /* We don't have the sections numbered at this point, so sh_info
1203 is set later, in elfNN_ia64_final_write_processing. */
1204 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1205 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1207 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1208 hdr
->sh_type
= SHT_IA_64_EXT
;
1209 else if (strcmp (name
, ".HP.opt_annot") == 0)
1210 hdr
->sh_type
= SHT_IA_64_HP_OPT_ANOT
;
1211 else if (strcmp (name
, ".reloc") == 0)
1212 /* This is an ugly, but unfortunately necessary hack that is
1213 needed when producing EFI binaries on IA-64. It tells
1214 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1215 containing ELF relocation info. We need this hack in order to
1216 be able to generate ELF binaries that can be translated into
1217 EFI applications (which are essentially COFF objects). Those
1218 files contain a COFF ".reloc" section inside an ELFNN object,
1219 which would normally cause BFD to segfault because it would
1220 attempt to interpret this section as containing relocation
1221 entries for section "oc". With this hack enabled, ".reloc"
1222 will be treated as a normal data section, which will avoid the
1223 segfault. However, you won't be able to create an ELFNN binary
1224 with a section named "oc" that needs relocations, but that's
1225 the kind of ugly side-effects you get when detecting section
1226 types based on their names... In practice, this limitation is
1227 unlikely to bite. */
1228 hdr
->sh_type
= SHT_PROGBITS
;
1230 if (sec
->flags
& SEC_SMALL_DATA
)
1231 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1236 /* The final processing done just before writing out an IA-64 ELF
1240 elfNN_ia64_final_write_processing (abfd
, linker
)
1242 bfd_boolean linker ATTRIBUTE_UNUSED
;
1244 Elf_Internal_Shdr
*hdr
;
1246 asection
*text_sect
, *s
;
1249 for (s
= abfd
->sections
; s
; s
= s
->next
)
1251 hdr
= &elf_section_data (s
)->this_hdr
;
1252 switch (hdr
->sh_type
)
1254 case SHT_IA_64_UNWIND
:
1255 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1257 sname
= bfd_get_section_name (abfd
, s
);
1258 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1259 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1263 if (sname
[0] == '\0')
1264 /* .IA_64.unwind -> .text */
1265 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1267 /* .IA_64.unwindFOO -> FOO */
1268 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1271 && (len
= sizeof (ELF_STRING_ia64_unwind_once
) - 1,
1272 strncmp (sname
, ELF_STRING_ia64_unwind_once
, len
)) == 0)
1274 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1275 size_t len2
= sizeof (".gnu.linkonce.t.") - 1;
1276 char *once_name
= bfd_malloc (len2
+ strlen (sname
+ len
) + 1);
1278 if (once_name
!= NULL
)
1280 memcpy (once_name
, ".gnu.linkonce.t.", len2
);
1281 strcpy (once_name
+ len2
, sname
+ len
);
1282 text_sect
= bfd_get_section_by_name (abfd
, once_name
);
1286 /* Should only happen if we run out of memory, in
1287 which case we're probably toast anyway. Try to
1288 cope by finding the section the slow way. */
1289 for (text_sect
= abfd
->sections
;
1291 text_sect
= text_sect
->next
)
1293 if (strncmp (bfd_section_name (abfd
, text_sect
),
1294 ".gnu.linkonce.t.", len2
) == 0
1295 && strcmp (bfd_section_name (abfd
, text_sect
) + len2
,
1301 /* last resort: fall back on .text */
1302 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1306 /* The IA-64 processor-specific ABI requires setting
1307 sh_link to the unwind section, whereas HP-UX requires
1308 sh_info to do so. For maximum compatibility, we'll
1309 set both for now... */
1310 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1311 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1317 if (! elf_flags_init (abfd
))
1319 unsigned long flags
= 0;
1321 if (abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
)
1322 flags
|= EF_IA_64_BE
;
1323 if (bfd_get_mach (abfd
) == bfd_mach_ia64_elf64
)
1324 flags
|= EF_IA_64_ABI64
;
1326 elf_elfheader(abfd
)->e_flags
= flags
;
1327 elf_flags_init (abfd
) = TRUE
;
1331 /* Hook called by the linker routine which adds symbols from an object
1332 file. We use it to put .comm items in .sbss, and not .bss. */
1335 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1337 struct bfd_link_info
*info
;
1338 const Elf_Internal_Sym
*sym
;
1339 const char **namep ATTRIBUTE_UNUSED
;
1340 flagword
*flagsp ATTRIBUTE_UNUSED
;
1344 if (sym
->st_shndx
== SHN_COMMON
1345 && !info
->relocatable
1346 && sym
->st_size
<= elf_gp_size (abfd
))
1348 /* Common symbols less than or equal to -G nn bytes are
1349 automatically put into .sbss. */
1351 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1355 scomm
= bfd_make_section (abfd
, ".scommon");
1357 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1359 | SEC_LINKER_CREATED
)))
1364 *valp
= sym
->st_size
;
1371 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1373 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1374 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1376 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1377 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1380 /* Hook called by the linker routine which adds symbols from an object
1381 file. We use it to handle OS-specific symbols. */
1384 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1386 struct bfd_link_info
*info
;
1387 const Elf_Internal_Sym
*sym
;
1393 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1395 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1396 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1397 no one else should use it b/c it is undocumented. */
1398 struct elf_link_hash_entry
*h
;
1400 h
= elf_link_hash_lookup (elf_hash_table (info
), *namep
,
1401 FALSE
, FALSE
, FALSE
);
1404 struct elf_backend_data
*bed
;
1405 struct elfNN_ia64_link_hash_table
*ia64_info
;
1406 struct bfd_link_hash_entry
*bh
= NULL
;
1408 bed
= get_elf_backend_data (abfd
);
1409 ia64_info
= elfNN_ia64_hash_table (info
);
1411 if (!(_bfd_generic_link_add_one_symbol
1412 (info
, abfd
, *namep
, BSF_GLOBAL
,
1413 bfd_get_section_by_name (abfd
, ".bss"),
1414 bed
->got_symbol_offset
, (const char *) NULL
, FALSE
,
1415 bed
->collect
, &bh
)))
1418 h
= (struct elf_link_hash_entry
*) bh
;
1419 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1420 h
->type
= STT_OBJECT
;
1422 if (! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1428 else if (sym
->st_shndx
== SHN_LOOS
)
1432 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1433 is only relevant when compiling code for extended system calls.
1434 Replace the "special" section with .text, if possible.
1435 Note that these symbols are always assumed to be in .text. */
1436 for (i
= 1; i
< elf_numsections (abfd
); i
++)
1438 asection
* sec
= bfd_section_from_elf_index (abfd
, i
);
1440 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1448 *secp
= bfd_abs_section_ptr
;
1450 *valp
= sym
->st_size
;
1456 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1457 namep
, flagsp
, secp
, valp
);
1462 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1464 struct bfd_link_info
*info
;
1466 /* Make sure dynamic sections are always created. */
1467 if (! elf_hash_table (info
)->dynamic_sections_created
1468 && abfd
->xvec
== info
->hash
->creator
)
1470 if (! _bfd_elf_link_create_dynamic_sections (abfd
, info
))
1474 /* Now do the standard call. */
1475 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1478 /* Return the number of additional phdrs we will need. */
1481 elfNN_ia64_additional_program_headers (abfd
)
1487 /* See if we need a PT_IA_64_ARCHEXT segment. */
1488 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1489 if (s
&& (s
->flags
& SEC_LOAD
))
1492 /* Count how many PT_IA_64_UNWIND segments we need. */
1493 for (s
= abfd
->sections
; s
; s
= s
->next
)
1494 if (is_unwind_section_name (abfd
, s
->name
) && (s
->flags
& SEC_LOAD
))
1501 elfNN_ia64_modify_segment_map (abfd
)
1504 struct elf_segment_map
*m
, **pm
;
1505 Elf_Internal_Shdr
*hdr
;
1508 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1509 all PT_LOAD segments. */
1510 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1511 if (s
&& (s
->flags
& SEC_LOAD
))
1513 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1514 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1518 m
= ((struct elf_segment_map
*)
1519 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1523 m
->p_type
= PT_IA_64_ARCHEXT
;
1527 /* We want to put it after the PHDR and INTERP segments. */
1528 pm
= &elf_tdata (abfd
)->segment_map
;
1530 && ((*pm
)->p_type
== PT_PHDR
1531 || (*pm
)->p_type
== PT_INTERP
))
1539 /* Install PT_IA_64_UNWIND segments, if needed. */
1540 for (s
= abfd
->sections
; s
; s
= s
->next
)
1542 hdr
= &elf_section_data (s
)->this_hdr
;
1543 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1546 if (s
&& (s
->flags
& SEC_LOAD
))
1548 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1549 if (m
->p_type
== PT_IA_64_UNWIND
)
1553 /* Look through all sections in the unwind segment
1554 for a match since there may be multiple sections
1556 for (i
= m
->count
- 1; i
>= 0; --i
)
1557 if (m
->sections
[i
] == s
)
1566 m
= ((struct elf_segment_map
*)
1567 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1571 m
->p_type
= PT_IA_64_UNWIND
;
1576 /* We want to put it last. */
1577 pm
= &elf_tdata (abfd
)->segment_map
;
1585 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1586 the input sections for each output section in the segment and testing
1587 for SHF_IA_64_NORECOV on each. */
1588 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1589 if (m
->p_type
== PT_LOAD
)
1592 for (i
= m
->count
- 1; i
>= 0; --i
)
1594 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1597 if (order
->type
== bfd_indirect_link_order
)
1599 asection
*is
= order
->u
.indirect
.section
;
1600 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1601 if (flags
& SHF_IA_64_NORECOV
)
1603 m
->p_flags
|= PF_IA_64_NORECOV
;
1607 order
= order
->next
;
1616 /* According to the Tahoe assembler spec, all labels starting with a
1620 elfNN_ia64_is_local_label_name (abfd
, name
)
1621 bfd
*abfd ATTRIBUTE_UNUSED
;
1624 return name
[0] == '.';
1627 /* Should we do dynamic things to this symbol? */
1630 elfNN_ia64_dynamic_symbol_p (h
, info
)
1631 struct elf_link_hash_entry
*h
;
1632 struct bfd_link_info
*info
;
1637 while (h
->root
.type
== bfd_link_hash_indirect
1638 || h
->root
.type
== bfd_link_hash_warning
)
1639 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1641 if (h
->dynindx
== -1)
1643 switch (ELF_ST_VISIBILITY (h
->other
))
1652 if (h
->root
.type
== bfd_link_hash_undefweak
1653 || h
->root
.type
== bfd_link_hash_defweak
)
1656 if ((!info
->executable
&& (!info
->symbolic
|| info
->allow_shlib_undefined
))
1657 || ((h
->elf_link_hash_flags
1658 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1659 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1666 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1667 struct elfNN_ia64_local_hash_table
*ht
;
1668 bfd
*abfd ATTRIBUTE_UNUSED
;
1669 new_hash_entry_func
new;
1671 memset (ht
, 0, sizeof (*ht
));
1672 return bfd_hash_table_init (&ht
->root
, new);
1675 static struct bfd_hash_entry
*
1676 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1677 struct bfd_hash_entry
*entry
;
1678 struct bfd_hash_table
*table
;
1681 struct elfNN_ia64_local_hash_entry
*ret
;
1682 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1684 /* Allocate the structure if it has not already been allocated by a
1687 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1692 /* Initialize our local data. All zeros, and definitely easier
1693 than setting a handful of bit fields. */
1694 memset (ret
, 0, sizeof (*ret
));
1696 /* Call the allocation method of the superclass. */
1697 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1698 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1700 return (struct bfd_hash_entry
*) ret
;
1703 static struct bfd_hash_entry
*
1704 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1705 struct bfd_hash_entry
*entry
;
1706 struct bfd_hash_table
*table
;
1709 struct elfNN_ia64_link_hash_entry
*ret
;
1710 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1712 /* Allocate the structure if it has not already been allocated by a
1715 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1720 /* Initialize our local data. All zeros, and definitely easier
1721 than setting a handful of bit fields. */
1722 memset (ret
, 0, sizeof (*ret
));
1724 /* Call the allocation method of the superclass. */
1725 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1726 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1729 return (struct bfd_hash_entry
*) ret
;
1733 elfNN_ia64_hash_copy_indirect (bed
, xdir
, xind
)
1734 struct elf_backend_data
*bed ATTRIBUTE_UNUSED
;
1735 struct elf_link_hash_entry
*xdir
, *xind
;
1737 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1739 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1740 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1742 /* Copy down any references that we may have already seen to the
1743 symbol which just became indirect. */
1745 dir
->root
.elf_link_hash_flags
|=
1746 (ind
->root
.elf_link_hash_flags
1747 & (ELF_LINK_HASH_REF_DYNAMIC
1748 | ELF_LINK_HASH_REF_REGULAR
1749 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1751 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1754 /* Copy over the got and plt data. This would have been done
1757 if (dir
->info
== NULL
)
1759 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1761 dir
->info
= dyn_i
= ind
->info
;
1764 /* Fix up the dyn_sym_info pointers to the global symbol. */
1765 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1766 dyn_i
->h
= &dir
->root
;
1768 BFD_ASSERT (ind
->info
== NULL
);
1770 /* Copy over the dynindx. */
1772 if (dir
->root
.dynindx
== -1)
1774 dir
->root
.dynindx
= ind
->root
.dynindx
;
1775 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1776 ind
->root
.dynindx
= -1;
1777 ind
->root
.dynstr_index
= 0;
1779 BFD_ASSERT (ind
->root
.dynindx
== -1);
1783 elfNN_ia64_hash_hide_symbol (info
, xh
, force_local
)
1784 struct bfd_link_info
*info
;
1785 struct elf_link_hash_entry
*xh
;
1786 bfd_boolean force_local
;
1788 struct elfNN_ia64_link_hash_entry
*h
;
1789 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1791 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1793 _bfd_elf_link_hash_hide_symbol (info
, &h
->root
, force_local
);
1795 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1797 dyn_i
->want_plt2
= 0;
1798 dyn_i
->want_plt
= 0;
1802 /* Create the derived linker hash table. The IA-64 ELF port uses this
1803 derived hash table to keep information specific to the IA-64 ElF
1804 linker (without using static variables). */
1806 static struct bfd_link_hash_table
*
1807 elfNN_ia64_hash_table_create (abfd
)
1810 struct elfNN_ia64_link_hash_table
*ret
;
1812 ret
= bfd_zmalloc ((bfd_size_type
) sizeof (*ret
));
1816 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1817 elfNN_ia64_new_elf_hash_entry
))
1823 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1824 elfNN_ia64_new_loc_hash_entry
))
1830 return &ret
->root
.root
;
1833 /* Look up an entry in a Alpha ELF linker hash table. */
1835 static INLINE
struct elfNN_ia64_local_hash_entry
*
1836 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1837 struct elfNN_ia64_local_hash_table
*table
;
1839 bfd_boolean create
, copy
;
1841 return ((struct elfNN_ia64_local_hash_entry
*)
1842 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1845 /* Traverse both local and global hash tables. */
1847 struct elfNN_ia64_dyn_sym_traverse_data
1849 bfd_boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1854 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1855 struct bfd_hash_entry
*xentry
;
1858 struct elfNN_ia64_link_hash_entry
*entry
1859 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1860 struct elfNN_ia64_dyn_sym_traverse_data
*data
1861 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1862 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1864 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
1865 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
1867 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1868 if (! (*data
->func
) (dyn_i
, data
->data
))
1874 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1875 struct bfd_hash_entry
*xentry
;
1878 struct elfNN_ia64_local_hash_entry
*entry
1879 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1880 struct elfNN_ia64_dyn_sym_traverse_data
*data
1881 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1882 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1884 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1885 if (! (*data
->func
) (dyn_i
, data
->data
))
1891 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1892 struct elfNN_ia64_link_hash_table
*ia64_info
;
1893 bfd_boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1896 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1901 elf_link_hash_traverse (&ia64_info
->root
,
1902 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1903 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1904 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1908 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1910 struct bfd_link_info
*info
;
1912 struct elfNN_ia64_link_hash_table
*ia64_info
;
1915 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1918 ia64_info
= elfNN_ia64_hash_table (info
);
1920 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1921 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1924 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1925 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1928 if (!get_pltoff (abfd
, info
, ia64_info
))
1931 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1933 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1936 | SEC_LINKER_CREATED
1938 || !bfd_set_section_alignment (abfd
, s
, 3))
1940 ia64_info
->rel_pltoff_sec
= s
;
1942 s
= bfd_make_section(abfd
, ".rela.got");
1944 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1947 | SEC_LINKER_CREATED
1949 || !bfd_set_section_alignment (abfd
, s
, 3))
1951 ia64_info
->rel_got_sec
= s
;
1956 /* Find and/or create a hash entry for local symbol. */
1957 static struct elfNN_ia64_local_hash_entry
*
1958 get_local_sym_hash (ia64_info
, abfd
, rel
, create
)
1959 struct elfNN_ia64_link_hash_table
*ia64_info
;
1961 const Elf_Internal_Rela
*rel
;
1964 struct elfNN_ia64_local_hash_entry
*ret
;
1965 asection
*sec
= abfd
->sections
;
1966 char addr_name
[34];
1968 BFD_ASSERT ((sizeof (sec
->id
)*2 + 1 + sizeof (unsigned long)*2 + 1) <= 34);
1971 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1972 name describes what was once anonymous memory. */
1974 sprintf (addr_name
, "%x:%lx",
1975 sec
->id
, (unsigned long) ELFNN_R_SYM (rel
->r_info
));
1977 /* Collect the canonical entry data for this address. */
1978 ret
= elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1979 addr_name
, create
, create
);
1983 /* Find and/or create a descriptor for dynamic symbol info. This will
1984 vary based on global or local symbol, and the addend to the reloc. */
1986 static struct elfNN_ia64_dyn_sym_info
*
1987 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1988 struct elfNN_ia64_link_hash_table
*ia64_info
;
1989 struct elf_link_hash_entry
*h
;
1991 const Elf_Internal_Rela
*rel
;
1994 struct elfNN_ia64_dyn_sym_info
**pp
;
1995 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1996 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1999 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
2002 struct elfNN_ia64_local_hash_entry
*loc_h
;
2004 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
2007 BFD_ASSERT (!create
);
2014 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
2017 if (dyn_i
== NULL
&& create
)
2019 dyn_i
= ((struct elfNN_ia64_dyn_sym_info
*)
2020 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *dyn_i
));
2022 dyn_i
->addend
= addend
;
2029 get_got (abfd
, info
, ia64_info
)
2031 struct bfd_link_info
*info
;
2032 struct elfNN_ia64_link_hash_table
*ia64_info
;
2037 got
= ia64_info
->got_sec
;
2042 dynobj
= ia64_info
->root
.dynobj
;
2044 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2045 if (!_bfd_elf_create_got_section (dynobj
, info
))
2048 got
= bfd_get_section_by_name (dynobj
, ".got");
2050 ia64_info
->got_sec
= got
;
2052 flags
= bfd_get_section_flags (abfd
, got
);
2053 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
2059 /* Create function descriptor section (.opd). This section is called .opd
2060 because it contains "official prodecure descriptors". The "official"
2061 refers to the fact that these descriptors are used when taking the address
2062 of a procedure, thus ensuring a unique address for each procedure. */
2065 get_fptr (abfd
, info
, ia64_info
)
2067 struct bfd_link_info
*info
;
2068 struct elfNN_ia64_link_hash_table
*ia64_info
;
2073 fptr
= ia64_info
->fptr_sec
;
2076 dynobj
= ia64_info
->root
.dynobj
;
2078 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2080 fptr
= bfd_make_section (dynobj
, ".opd");
2082 || !bfd_set_section_flags (dynobj
, fptr
,
2087 | (info
->pie
? 0 : SEC_READONLY
)
2088 | SEC_LINKER_CREATED
))
2089 || !bfd_set_section_alignment (abfd
, fptr
, 4))
2095 ia64_info
->fptr_sec
= fptr
;
2100 fptr_rel
= bfd_make_section(abfd
, ".rela.opd");
2101 if (fptr_rel
== NULL
2102 || !bfd_set_section_flags (abfd
, fptr_rel
,
2103 (SEC_ALLOC
| SEC_LOAD
2106 | SEC_LINKER_CREATED
2108 || !bfd_set_section_alignment (abfd
, fptr_rel
, 3))
2114 ia64_info
->rel_fptr_sec
= fptr_rel
;
2122 get_pltoff (abfd
, info
, ia64_info
)
2124 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2125 struct elfNN_ia64_link_hash_table
*ia64_info
;
2130 pltoff
= ia64_info
->pltoff_sec
;
2133 dynobj
= ia64_info
->root
.dynobj
;
2135 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2137 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
2139 || !bfd_set_section_flags (dynobj
, pltoff
,
2145 | SEC_LINKER_CREATED
))
2146 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
2152 ia64_info
->pltoff_sec
= pltoff
;
2159 get_reloc_section (abfd
, ia64_info
, sec
, create
)
2161 struct elfNN_ia64_link_hash_table
*ia64_info
;
2165 const char *srel_name
;
2169 srel_name
= (bfd_elf_string_from_elf_section
2170 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
2171 elf_section_data(sec
)->rel_hdr
.sh_name
));
2172 if (srel_name
== NULL
)
2175 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
2176 && strcmp (bfd_get_section_name (abfd
, sec
),
2178 || (strncmp (srel_name
, ".rel", 4) == 0
2179 && strcmp (bfd_get_section_name (abfd
, sec
),
2180 srel_name
+4) == 0));
2182 dynobj
= ia64_info
->root
.dynobj
;
2184 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2186 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
2187 if (srel
== NULL
&& create
)
2189 srel
= bfd_make_section (dynobj
, srel_name
);
2191 || !bfd_set_section_flags (dynobj
, srel
,
2196 | SEC_LINKER_CREATED
2198 || !bfd_set_section_alignment (dynobj
, srel
, 3))
2202 if (sec
->flags
& SEC_READONLY
)
2203 ia64_info
->reltext
= 1;
2209 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
2211 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2215 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2217 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2218 if (rent
->srel
== srel
&& rent
->type
== type
)
2223 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
2224 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
2228 rent
->next
= dyn_i
->reloc_entries
;
2232 dyn_i
->reloc_entries
= rent
;
2240 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
2242 struct bfd_link_info
*info
;
2244 const Elf_Internal_Rela
*relocs
;
2246 struct elfNN_ia64_link_hash_table
*ia64_info
;
2247 const Elf_Internal_Rela
*relend
;
2248 Elf_Internal_Shdr
*symtab_hdr
;
2249 const Elf_Internal_Rela
*rel
;
2250 asection
*got
, *fptr
, *srel
;
2252 if (info
->relocatable
)
2255 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2256 ia64_info
= elfNN_ia64_hash_table (info
);
2258 got
= fptr
= srel
= NULL
;
2260 relend
= relocs
+ sec
->reloc_count
;
2261 for (rel
= relocs
; rel
< relend
; ++rel
)
2271 NEED_LTOFF_FPTR
= 128,
2277 struct elf_link_hash_entry
*h
= NULL
;
2278 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2279 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2281 bfd_boolean maybe_dynamic
;
2282 int dynrel_type
= R_IA64_NONE
;
2284 if (r_symndx
>= symtab_hdr
->sh_info
)
2286 /* We're dealing with a global symbol -- find its hash entry
2287 and mark it as being referenced. */
2288 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2289 h
= elf_sym_hashes (abfd
)[indx
];
2290 while (h
->root
.type
== bfd_link_hash_indirect
2291 || h
->root
.type
== bfd_link_hash_warning
)
2292 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2294 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
2297 /* We can only get preliminary data on whether a symbol is
2298 locally or externally defined, as not all of the input files
2299 have yet been processed. Do something with what we know, as
2300 this may help reduce memory usage and processing time later. */
2301 maybe_dynamic
= FALSE
;
2302 if (h
&& ((!info
->executable
2303 && (!info
->symbolic
|| info
->allow_shlib_undefined
))
2304 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
2305 || h
->root
.type
== bfd_link_hash_defweak
2306 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2307 maybe_dynamic
= TRUE
;
2310 switch (ELFNN_R_TYPE (rel
->r_info
))
2312 case R_IA64_TPREL64MSB
:
2313 case R_IA64_TPREL64LSB
:
2314 if (info
->shared
|| maybe_dynamic
)
2315 need_entry
= NEED_DYNREL
;
2316 dynrel_type
= R_IA64_TPREL64LSB
;
2318 info
->flags
|= DF_STATIC_TLS
;
2321 case R_IA64_LTOFF_TPREL22
:
2322 need_entry
= NEED_TPREL
;
2324 info
->flags
|= DF_STATIC_TLS
;
2327 case R_IA64_DTPREL64MSB
:
2328 case R_IA64_DTPREL64LSB
:
2329 if (info
->shared
|| maybe_dynamic
)
2330 need_entry
= NEED_DYNREL
;
2331 dynrel_type
= R_IA64_DTPREL64LSB
;
2334 case R_IA64_LTOFF_DTPREL22
:
2335 need_entry
= NEED_DTPREL
;
2338 case R_IA64_DTPMOD64MSB
:
2339 case R_IA64_DTPMOD64LSB
:
2340 if (info
->shared
|| maybe_dynamic
)
2341 need_entry
= NEED_DYNREL
;
2342 dynrel_type
= R_IA64_DTPMOD64LSB
;
2345 case R_IA64_LTOFF_DTPMOD22
:
2346 need_entry
= NEED_DTPMOD
;
2349 case R_IA64_LTOFF_FPTR22
:
2350 case R_IA64_LTOFF_FPTR64I
:
2351 case R_IA64_LTOFF_FPTR32MSB
:
2352 case R_IA64_LTOFF_FPTR32LSB
:
2353 case R_IA64_LTOFF_FPTR64MSB
:
2354 case R_IA64_LTOFF_FPTR64LSB
:
2355 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2358 case R_IA64_FPTR64I
:
2359 case R_IA64_FPTR32MSB
:
2360 case R_IA64_FPTR32LSB
:
2361 case R_IA64_FPTR64MSB
:
2362 case R_IA64_FPTR64LSB
:
2363 if (info
->shared
|| h
|| elfNN_ia64_aix_vec (abfd
->xvec
))
2364 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2366 need_entry
= NEED_FPTR
;
2367 dynrel_type
= R_IA64_FPTR64LSB
;
2370 case R_IA64_LTOFF22
:
2371 case R_IA64_LTOFF64I
:
2372 need_entry
= NEED_GOT
;
2375 case R_IA64_LTOFF22X
:
2376 need_entry
= NEED_GOTX
;
2379 case R_IA64_PLTOFF22
:
2380 case R_IA64_PLTOFF64I
:
2381 case R_IA64_PLTOFF64MSB
:
2382 case R_IA64_PLTOFF64LSB
:
2383 need_entry
= NEED_PLTOFF
;
2387 need_entry
|= NEED_MIN_PLT
;
2391 (*info
->callbacks
->warning
)
2392 (info
, _("@pltoff reloc against local symbol"), 0,
2393 abfd
, 0, (bfd_vma
) 0);
2397 case R_IA64_PCREL21B
:
2398 case R_IA64_PCREL60B
:
2399 /* Depending on where this symbol is defined, we may or may not
2400 need a full plt entry. Only skip if we know we'll not need
2401 the entry -- static or symbolic, and the symbol definition
2402 has already been seen. */
2403 if (maybe_dynamic
&& rel
->r_addend
== 0)
2404 need_entry
= NEED_FULL_PLT
;
2410 case R_IA64_DIR32MSB
:
2411 case R_IA64_DIR32LSB
:
2412 case R_IA64_DIR64MSB
:
2413 case R_IA64_DIR64LSB
:
2414 /* Shared objects will always need at least a REL relocation. */
2415 if (info
->shared
|| maybe_dynamic
2416 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2417 && (!h
|| strcmp (h
->root
.root
.string
,
2418 "__GLOB_DATA_PTR") != 0)))
2419 need_entry
= NEED_DYNREL
;
2420 dynrel_type
= R_IA64_DIR64LSB
;
2423 case R_IA64_IPLTMSB
:
2424 case R_IA64_IPLTLSB
:
2425 /* Shared objects will always need at least a REL relocation. */
2426 if (info
->shared
|| maybe_dynamic
)
2427 need_entry
= NEED_DYNREL
;
2428 dynrel_type
= R_IA64_IPLTLSB
;
2431 case R_IA64_PCREL22
:
2432 case R_IA64_PCREL64I
:
2433 case R_IA64_PCREL32MSB
:
2434 case R_IA64_PCREL32LSB
:
2435 case R_IA64_PCREL64MSB
:
2436 case R_IA64_PCREL64LSB
:
2438 need_entry
= NEED_DYNREL
;
2439 dynrel_type
= R_IA64_PCREL64LSB
;
2446 if ((need_entry
& NEED_FPTR
) != 0
2449 (*info
->callbacks
->warning
)
2450 (info
, _("non-zero addend in @fptr reloc"), 0,
2451 abfd
, 0, (bfd_vma
) 0);
2454 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, TRUE
);
2456 /* Record whether or not this is a local symbol. */
2459 /* Create what's needed. */
2460 if (need_entry
& (NEED_GOT
| NEED_GOTX
| NEED_TPREL
2461 | NEED_DTPMOD
| NEED_DTPREL
))
2465 got
= get_got (abfd
, info
, ia64_info
);
2469 if (need_entry
& NEED_GOT
)
2470 dyn_i
->want_got
= 1;
2471 if (need_entry
& NEED_GOTX
)
2472 dyn_i
->want_gotx
= 1;
2473 if (need_entry
& NEED_TPREL
)
2474 dyn_i
->want_tprel
= 1;
2475 if (need_entry
& NEED_DTPMOD
)
2476 dyn_i
->want_dtpmod
= 1;
2477 if (need_entry
& NEED_DTPREL
)
2478 dyn_i
->want_dtprel
= 1;
2480 if (need_entry
& NEED_FPTR
)
2484 fptr
= get_fptr (abfd
, info
, ia64_info
);
2489 /* FPTRs for shared libraries are allocated by the dynamic
2490 linker. Make sure this local symbol will appear in the
2491 dynamic symbol table. */
2492 if (!h
&& (info
->shared
2493 /* AIX also needs one */
2494 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2496 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2497 (info
, abfd
, (long) r_symndx
)))
2501 dyn_i
->want_fptr
= 1;
2503 if (need_entry
& NEED_LTOFF_FPTR
)
2504 dyn_i
->want_ltoff_fptr
= 1;
2505 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2507 if (!ia64_info
->root
.dynobj
)
2508 ia64_info
->root
.dynobj
= abfd
;
2509 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2510 dyn_i
->want_plt
= 1;
2512 if (need_entry
& NEED_FULL_PLT
)
2513 dyn_i
->want_plt2
= 1;
2514 if (need_entry
& NEED_PLTOFF
)
2515 dyn_i
->want_pltoff
= 1;
2516 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2520 srel
= get_reloc_section (abfd
, ia64_info
, sec
, TRUE
);
2524 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2532 /* For cleanliness, and potentially faster dynamic loading, allocate
2533 external GOT entries first. */
2536 allocate_global_data_got (dyn_i
, data
)
2537 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2540 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2542 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
2543 && ! dyn_i
->want_fptr
2544 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2545 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2546 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2547 "__GLOB_DATA_PTR") != 0))))
2549 dyn_i
->got_offset
= x
->ofs
;
2552 if (dyn_i
->want_tprel
)
2554 dyn_i
->tprel_offset
= x
->ofs
;
2557 if (dyn_i
->want_dtpmod
)
2559 if (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
))
2561 dyn_i
->dtpmod_offset
= x
->ofs
;
2566 struct elfNN_ia64_link_hash_table
*ia64_info
;
2568 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2569 if (ia64_info
->self_dtpmod_offset
== (bfd_vma
) -1)
2571 ia64_info
->self_dtpmod_offset
= x
->ofs
;
2574 dyn_i
->dtpmod_offset
= ia64_info
->self_dtpmod_offset
;
2577 if (dyn_i
->want_dtprel
)
2579 dyn_i
->dtprel_offset
= x
->ofs
;
2585 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2588 allocate_global_fptr_got (dyn_i
, data
)
2589 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2592 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2596 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2597 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2599 dyn_i
->got_offset
= x
->ofs
;
2605 /* Lastly, allocate all the GOT entries for local data. */
2608 allocate_local_got (dyn_i
, data
)
2609 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2612 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2614 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
2615 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2616 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2618 dyn_i
->got_offset
= x
->ofs
;
2624 /* Search for the index of a global symbol in it's defining object file. */
2627 global_sym_index (h
)
2628 struct elf_link_hash_entry
*h
;
2630 struct elf_link_hash_entry
**p
;
2633 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2634 || h
->root
.type
== bfd_link_hash_defweak
);
2636 obj
= h
->root
.u
.def
.section
->owner
;
2637 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2640 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2643 /* Allocate function descriptors. We can do these for every function
2644 in a main executable that is not exported. */
2647 allocate_fptr (dyn_i
, data
)
2648 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2651 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2653 if (dyn_i
->want_fptr
)
2655 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2658 while (h
->root
.type
== bfd_link_hash_indirect
2659 || h
->root
.type
== bfd_link_hash_warning
)
2660 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2662 if ((!x
->info
->executable
2664 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
2665 || h
->root
.type
!= bfd_link_hash_undefweak
))
2666 /* AIX needs an FPTR in this case. */
2667 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2669 || h
->root
.type
== bfd_link_hash_defined
2670 || h
->root
.type
== bfd_link_hash_defweak
)))
2672 if (h
&& h
->dynindx
== -1)
2674 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2675 || (h
->root
.type
== bfd_link_hash_defweak
));
2677 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2678 (x
->info
, h
->root
.u
.def
.section
->owner
,
2679 global_sym_index (h
)))
2683 dyn_i
->want_fptr
= 0;
2685 else if (h
== NULL
|| h
->dynindx
== -1)
2687 dyn_i
->fptr_offset
= x
->ofs
;
2691 dyn_i
->want_fptr
= 0;
2696 /* Allocate all the minimal PLT entries. */
2699 allocate_plt_entries (dyn_i
, data
)
2700 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2703 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2705 if (dyn_i
->want_plt
)
2707 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2710 while (h
->root
.type
== bfd_link_hash_indirect
2711 || h
->root
.type
== bfd_link_hash_warning
)
2712 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2714 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2715 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2717 bfd_size_type offset
= x
->ofs
;
2719 offset
= PLT_HEADER_SIZE
;
2720 dyn_i
->plt_offset
= offset
;
2721 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2723 dyn_i
->want_pltoff
= 1;
2727 dyn_i
->want_plt
= 0;
2728 dyn_i
->want_plt2
= 0;
2734 /* Allocate all the full PLT entries. */
2737 allocate_plt2_entries (dyn_i
, data
)
2738 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2741 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2743 if (dyn_i
->want_plt2
)
2745 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2746 bfd_size_type ofs
= x
->ofs
;
2748 dyn_i
->plt2_offset
= ofs
;
2749 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2751 while (h
->root
.type
== bfd_link_hash_indirect
2752 || h
->root
.type
== bfd_link_hash_warning
)
2753 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2754 dyn_i
->h
->plt
.offset
= ofs
;
2759 /* Allocate all the PLTOFF entries requested by relocations and
2760 plt entries. We can't share space with allocated FPTR entries,
2761 because the latter are not necessarily addressable by the GP.
2762 ??? Relaxation might be able to determine that they are. */
2765 allocate_pltoff_entries (dyn_i
, data
)
2766 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2769 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2771 if (dyn_i
->want_pltoff
)
2773 dyn_i
->pltoff_offset
= x
->ofs
;
2779 /* Allocate dynamic relocations for those symbols that turned out
2783 allocate_dynrel_entries (dyn_i
, data
)
2784 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2787 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2788 struct elfNN_ia64_link_hash_table
*ia64_info
;
2789 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2790 bfd_boolean dynamic_symbol
, shared
, resolved_zero
;
2792 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2793 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2794 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2795 /* Don't allocate an entry for __GLOB_DATA_PTR */
2796 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2797 "__GLOB_DATA_PTR") != 0));
2798 shared
= x
->info
->shared
;
2799 resolved_zero
= (dyn_i
->h
2800 && ELF_ST_VISIBILITY (dyn_i
->h
->other
)
2801 && dyn_i
->h
->root
.type
== bfd_link_hash_undefweak
);
2803 /* Take care of the normal data relocations. */
2805 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2807 int count
= rent
->count
;
2811 case R_IA64_FPTR64LSB
:
2812 /* Allocate one iff !want_fptr and not PIE, which by this point
2813 will be true only if we're actually allocating one statically
2814 in the main executable. Position independent executables
2815 need a relative reloc. */
2816 if (dyn_i
->want_fptr
&& !x
->info
->pie
)
2819 case R_IA64_PCREL64LSB
:
2820 if (!dynamic_symbol
)
2823 case R_IA64_DIR64LSB
:
2824 if (!dynamic_symbol
&& !shared
)
2827 case R_IA64_IPLTLSB
:
2828 if (!dynamic_symbol
&& !shared
)
2830 /* Use two REL relocations for IPLT relocations
2831 against local symbols. */
2832 if (!dynamic_symbol
)
2835 case R_IA64_TPREL64LSB
:
2836 case R_IA64_DTPREL64LSB
:
2837 case R_IA64_DTPMOD64LSB
:
2842 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2845 /* Take care of the GOT and PLT relocations. */
2848 && (dynamic_symbol
|| shared
)
2849 && (dyn_i
->want_got
|| dyn_i
->want_gotx
))
2850 || (dyn_i
->want_ltoff_fptr
2852 && dyn_i
->h
->dynindx
!= -1))
2854 if (!dyn_i
->want_ltoff_fptr
2857 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
2858 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2860 if ((dynamic_symbol
|| shared
) && dyn_i
->want_tprel
)
2861 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2862 if (dynamic_symbol
&& dyn_i
->want_dtpmod
)
2863 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2864 if (dynamic_symbol
&& dyn_i
->want_dtprel
)
2865 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2866 if (ia64_info
->rel_fptr_sec
&& dyn_i
->want_fptr
)
2868 if (dyn_i
->h
== NULL
|| dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
2869 ia64_info
->rel_fptr_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2872 if (!resolved_zero
&& dyn_i
->want_pltoff
)
2874 bfd_size_type t
= 0;
2876 /* Dynamic symbols get one IPLT relocation. Local symbols in
2877 shared libraries get two REL relocations. Local symbols in
2878 main applications get nothing. */
2880 t
= sizeof (ElfNN_External_Rela
);
2882 t
= 2 * sizeof (ElfNN_External_Rela
);
2884 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2891 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2892 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2893 struct elf_link_hash_entry
*h
;
2895 /* ??? Undefined symbols with PLT entries should be re-defined
2896 to be the PLT entry. */
2898 /* If this is a weak symbol, and there is a real definition, the
2899 processor independent code will have arranged for us to see the
2900 real definition first, and we can just use the same value. */
2901 if (h
->weakdef
!= NULL
)
2903 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2904 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2905 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2906 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2910 /* If this is a reference to a symbol defined by a dynamic object which
2911 is not a function, we might allocate the symbol in our .dynbss section
2912 and allocate a COPY dynamic relocation.
2914 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2921 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2923 struct bfd_link_info
*info
;
2925 struct elfNN_ia64_allocate_data data
;
2926 struct elfNN_ia64_link_hash_table
*ia64_info
;
2929 bfd_boolean relplt
= FALSE
;
2931 dynobj
= elf_hash_table(info
)->dynobj
;
2932 ia64_info
= elfNN_ia64_hash_table (info
);
2933 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
2934 BFD_ASSERT(dynobj
!= NULL
);
2937 /* Set the contents of the .interp section to the interpreter. */
2938 if (ia64_info
->root
.dynamic_sections_created
2939 && info
->executable
)
2941 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2942 BFD_ASSERT (sec
!= NULL
);
2943 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2944 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2947 /* Allocate the GOT entries. */
2949 if (ia64_info
->got_sec
)
2952 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2953 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2954 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2955 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2958 /* Allocate the FPTR entries. */
2960 if (ia64_info
->fptr_sec
)
2963 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2964 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2967 /* Now that we've seen all of the input files, we can decide which
2968 symbols need plt entries. Allocate the minimal PLT entries first.
2969 We do this even though dynamic_sections_created may be FALSE, because
2970 this has the side-effect of clearing want_plt and want_plt2. */
2973 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2975 ia64_info
->minplt_entries
= 0;
2978 ia64_info
->minplt_entries
2979 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2982 /* Align the pointer for the plt2 entries. */
2983 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
2985 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2988 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2990 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2992 /* If we've got a .plt, we need some extra memory for the dynamic
2993 linker. We stuff these in .got.plt. */
2994 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2995 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2998 /* Allocate the PLTOFF entries. */
3000 if (ia64_info
->pltoff_sec
)
3003 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
3004 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
3007 if (ia64_info
->root
.dynamic_sections_created
)
3009 /* Allocate space for the dynamic relocations that turned out to be
3012 if (info
->shared
&& ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
3013 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
3014 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
3017 /* We have now determined the sizes of the various dynamic sections.
3018 Allocate memory for them. */
3019 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
3023 if (!(sec
->flags
& SEC_LINKER_CREATED
))
3026 /* If we don't need this section, strip it from the output file.
3027 There were several sections primarily related to dynamic
3028 linking that must be create before the linker maps input
3029 sections to output sections. The linker does that before
3030 bfd_elf_size_dynamic_sections is called, and it is that
3031 function which decides whether anything needs to go into
3034 strip
= (sec
->_raw_size
== 0);
3036 if (sec
== ia64_info
->got_sec
)
3038 else if (sec
== ia64_info
->rel_got_sec
)
3041 ia64_info
->rel_got_sec
= NULL
;
3043 /* We use the reloc_count field as a counter if we need to
3044 copy relocs into the output file. */
3045 sec
->reloc_count
= 0;
3047 else if (sec
== ia64_info
->fptr_sec
)
3050 ia64_info
->fptr_sec
= NULL
;
3052 else if (sec
== ia64_info
->plt_sec
)
3055 ia64_info
->plt_sec
= NULL
;
3057 else if (sec
== ia64_info
->pltoff_sec
)
3060 ia64_info
->pltoff_sec
= NULL
;
3062 else if (sec
== ia64_info
->rel_pltoff_sec
)
3065 ia64_info
->rel_pltoff_sec
= NULL
;
3069 /* We use the reloc_count field as a counter if we need to
3070 copy relocs into the output file. */
3071 sec
->reloc_count
= 0;
3078 /* It's OK to base decisions on the section name, because none
3079 of the dynobj section names depend upon the input files. */
3080 name
= bfd_get_section_name (dynobj
, sec
);
3082 if (strcmp (name
, ".got.plt") == 0)
3084 else if (strncmp (name
, ".rel", 4) == 0)
3088 /* We use the reloc_count field as a counter if we need to
3089 copy relocs into the output file. */
3090 sec
->reloc_count
= 0;
3098 _bfd_strip_section_from_output (info
, sec
);
3101 /* Allocate memory for the section contents. */
3102 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->_raw_size
);
3103 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
3108 if (elf_hash_table (info
)->dynamic_sections_created
)
3110 /* Add some entries to the .dynamic section. We fill in the values
3111 later (in finish_dynamic_sections) but we must add the entries now
3112 so that we get the correct size for the .dynamic section. */
3114 if (info
->executable
)
3116 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3118 #define add_dynamic_entry(TAG, VAL) \
3119 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
3121 if (!add_dynamic_entry (DT_DEBUG
, 0))
3125 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
3127 if (!add_dynamic_entry (DT_PLTGOT
, 0))
3132 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
3133 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
3134 || !add_dynamic_entry (DT_JMPREL
, 0))
3138 if (!add_dynamic_entry (DT_RELA
, 0)
3139 || !add_dynamic_entry (DT_RELASZ
, 0)
3140 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
3143 if (ia64_info
->reltext
)
3145 if (!add_dynamic_entry (DT_TEXTREL
, 0))
3147 info
->flags
|= DF_TEXTREL
;
3151 /* ??? Perhaps force __gp local. */
3156 static bfd_reloc_status_type
3157 elfNN_ia64_install_value (abfd
, hit_addr
, v
, r_type
)
3161 unsigned int r_type
;
3163 const struct ia64_operand
*op
;
3164 int bigendian
= 0, shift
= 0;
3165 bfd_vma t0
, t1
, insn
, dword
;
3166 enum ia64_opnd opnd
;
3169 #ifdef BFD_HOST_U_64_BIT
3170 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
3175 opnd
= IA64_OPND_NIL
;
3180 return bfd_reloc_ok
;
3182 /* Instruction relocations. */
3185 case R_IA64_TPREL14
:
3186 case R_IA64_DTPREL14
:
3187 opnd
= IA64_OPND_IMM14
;
3190 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
3191 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
3192 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
3193 case R_IA64_PCREL21B
:
3194 case R_IA64_PCREL21BI
:
3195 opnd
= IA64_OPND_TGT25c
;
3199 case R_IA64_GPREL22
:
3200 case R_IA64_LTOFF22
:
3201 case R_IA64_LTOFF22X
:
3202 case R_IA64_PLTOFF22
:
3203 case R_IA64_PCREL22
:
3204 case R_IA64_LTOFF_FPTR22
:
3205 case R_IA64_TPREL22
:
3206 case R_IA64_DTPREL22
:
3207 case R_IA64_LTOFF_TPREL22
:
3208 case R_IA64_LTOFF_DTPMOD22
:
3209 case R_IA64_LTOFF_DTPREL22
:
3210 opnd
= IA64_OPND_IMM22
;
3214 case R_IA64_GPREL64I
:
3215 case R_IA64_LTOFF64I
:
3216 case R_IA64_PLTOFF64I
:
3217 case R_IA64_PCREL64I
:
3218 case R_IA64_FPTR64I
:
3219 case R_IA64_LTOFF_FPTR64I
:
3220 case R_IA64_TPREL64I
:
3221 case R_IA64_DTPREL64I
:
3222 opnd
= IA64_OPND_IMMU64
;
3225 /* Data relocations. */
3227 case R_IA64_DIR32MSB
:
3228 case R_IA64_GPREL32MSB
:
3229 case R_IA64_FPTR32MSB
:
3230 case R_IA64_PCREL32MSB
:
3231 case R_IA64_LTOFF_FPTR32MSB
:
3232 case R_IA64_SEGREL32MSB
:
3233 case R_IA64_SECREL32MSB
:
3234 case R_IA64_LTV32MSB
:
3235 case R_IA64_DTPREL32MSB
:
3236 size
= 4; bigendian
= 1;
3239 case R_IA64_DIR32LSB
:
3240 case R_IA64_GPREL32LSB
:
3241 case R_IA64_FPTR32LSB
:
3242 case R_IA64_PCREL32LSB
:
3243 case R_IA64_LTOFF_FPTR32LSB
:
3244 case R_IA64_SEGREL32LSB
:
3245 case R_IA64_SECREL32LSB
:
3246 case R_IA64_LTV32LSB
:
3247 case R_IA64_DTPREL32LSB
:
3248 size
= 4; bigendian
= 0;
3251 case R_IA64_DIR64MSB
:
3252 case R_IA64_GPREL64MSB
:
3253 case R_IA64_PLTOFF64MSB
:
3254 case R_IA64_FPTR64MSB
:
3255 case R_IA64_PCREL64MSB
:
3256 case R_IA64_LTOFF_FPTR64MSB
:
3257 case R_IA64_SEGREL64MSB
:
3258 case R_IA64_SECREL64MSB
:
3259 case R_IA64_LTV64MSB
:
3260 case R_IA64_TPREL64MSB
:
3261 case R_IA64_DTPMOD64MSB
:
3262 case R_IA64_DTPREL64MSB
:
3263 size
= 8; bigendian
= 1;
3266 case R_IA64_DIR64LSB
:
3267 case R_IA64_GPREL64LSB
:
3268 case R_IA64_PLTOFF64LSB
:
3269 case R_IA64_FPTR64LSB
:
3270 case R_IA64_PCREL64LSB
:
3271 case R_IA64_LTOFF_FPTR64LSB
:
3272 case R_IA64_SEGREL64LSB
:
3273 case R_IA64_SECREL64LSB
:
3274 case R_IA64_LTV64LSB
:
3275 case R_IA64_TPREL64LSB
:
3276 case R_IA64_DTPMOD64LSB
:
3277 case R_IA64_DTPREL64LSB
:
3278 size
= 8; bigendian
= 0;
3281 /* Unsupported / Dynamic relocations. */
3283 return bfd_reloc_notsupported
;
3288 case IA64_OPND_IMMU64
:
3289 hit_addr
-= (long) hit_addr
& 0x3;
3290 t0
= bfd_get_64 (abfd
, hit_addr
);
3291 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
3293 /* tmpl/s: bits 0.. 5 in t0
3294 slot 0: bits 5..45 in t0
3295 slot 1: bits 46..63 in t0, bits 0..22 in t1
3296 slot 2: bits 23..63 in t1 */
3298 /* First, clear the bits that form the 64 bit constant. */
3299 t0
&= ~(0x3ffffLL
<< 46);
3301 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
3302 | (0x01fLL
<< 22) | (0x001LL
<< 21)
3303 | (0x001LL
<< 36)) << 23));
3305 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
3306 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
3307 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
3308 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
3309 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
3310 | (((val
>> 21) & 0x001) << 21) /* ic */
3311 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
3313 bfd_put_64 (abfd
, t0
, hit_addr
);
3314 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3317 case IA64_OPND_TGT64
:
3318 hit_addr
-= (long) hit_addr
& 0x3;
3319 t0
= bfd_get_64 (abfd
, hit_addr
);
3320 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
3322 /* tmpl/s: bits 0.. 5 in t0
3323 slot 0: bits 5..45 in t0
3324 slot 1: bits 46..63 in t0, bits 0..22 in t1
3325 slot 2: bits 23..63 in t1 */
3327 /* First, clear the bits that form the 64 bit constant. */
3328 t0
&= ~(0x3ffffLL
<< 46);
3330 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
3333 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
3334 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
3335 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
3336 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
3338 bfd_put_64 (abfd
, t0
, hit_addr
);
3339 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3343 switch ((long) hit_addr
& 0x3)
3345 case 0: shift
= 5; break;
3346 case 1: shift
= 14; hit_addr
+= 3; break;
3347 case 2: shift
= 23; hit_addr
+= 6; break;
3348 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
3350 dword
= bfd_get_64 (abfd
, hit_addr
);
3351 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
3353 op
= elf64_ia64_operands
+ opnd
;
3354 err
= (*op
->insert
) (op
, val
, (ia64_insn
*)& insn
);
3356 return bfd_reloc_overflow
;
3358 dword
&= ~(0x1ffffffffffLL
<< shift
);
3359 dword
|= (insn
<< shift
);
3360 bfd_put_64 (abfd
, dword
, hit_addr
);
3364 /* A data relocation. */
3367 bfd_putb32 (val
, hit_addr
);
3369 bfd_putb64 (val
, hit_addr
);
3372 bfd_putl32 (val
, hit_addr
);
3374 bfd_putl64 (val
, hit_addr
);
3378 return bfd_reloc_ok
;
3382 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
3385 struct bfd_link_info
*info
;
3393 Elf_Internal_Rela outrel
;
3396 BFD_ASSERT (dynindx
!= -1);
3397 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3398 outrel
.r_addend
= addend
;
3399 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3400 if (outrel
.r_offset
>= (bfd_vma
) -2)
3402 /* Run for the hills. We shouldn't be outputting a relocation
3403 for this. So do what everyone else does and output a no-op. */
3404 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3405 outrel
.r_addend
= 0;
3406 outrel
.r_offset
= 0;
3409 outrel
.r_offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3411 loc
= srel
->contents
;
3412 loc
+= srel
->reloc_count
++ * sizeof (ElfNN_External_Rela
);
3413 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
3414 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3415 <= srel
->_cooked_size
);
3418 /* Store an entry for target address TARGET_ADDR in the linkage table
3419 and return the gp-relative address of the linkage table entry. */
3422 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3424 struct bfd_link_info
*info
;
3425 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3429 unsigned int dyn_r_type
;
3431 struct elfNN_ia64_link_hash_table
*ia64_info
;
3436 ia64_info
= elfNN_ia64_hash_table (info
);
3437 got_sec
= ia64_info
->got_sec
;
3441 case R_IA64_TPREL64LSB
:
3442 done
= dyn_i
->tprel_done
;
3443 dyn_i
->tprel_done
= TRUE
;
3444 got_offset
= dyn_i
->tprel_offset
;
3446 case R_IA64_DTPMOD64LSB
:
3447 if (dyn_i
->dtpmod_offset
!= ia64_info
->self_dtpmod_offset
)
3449 done
= dyn_i
->dtpmod_done
;
3450 dyn_i
->dtpmod_done
= TRUE
;
3454 done
= ia64_info
->self_dtpmod_done
;
3455 ia64_info
->self_dtpmod_done
= TRUE
;
3458 got_offset
= dyn_i
->dtpmod_offset
;
3460 case R_IA64_DTPREL64LSB
:
3461 done
= dyn_i
->dtprel_done
;
3462 dyn_i
->dtprel_done
= TRUE
;
3463 got_offset
= dyn_i
->dtprel_offset
;
3466 done
= dyn_i
->got_done
;
3467 dyn_i
->got_done
= TRUE
;
3468 got_offset
= dyn_i
->got_offset
;
3472 BFD_ASSERT ((got_offset
& 7) == 0);
3476 /* Store the target address in the linkage table entry. */
3477 bfd_put_64 (abfd
, value
, got_sec
->contents
+ got_offset
);
3479 /* Install a dynamic relocation if needed. */
3482 || ELF_ST_VISIBILITY (dyn_i
->h
->other
) == STV_DEFAULT
3483 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
3484 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
3485 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3486 || elfNN_ia64_aix_vec (abfd
->xvec
)
3487 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3488 && (!dyn_i
->want_ltoff_fptr
3491 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
))
3494 && dyn_r_type
!= R_IA64_TPREL64LSB
3495 && dyn_r_type
!= R_IA64_DTPMOD64LSB
3496 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
3498 dyn_r_type
= R_IA64_REL64LSB
;
3503 if (bfd_big_endian (abfd
))
3507 case R_IA64_REL64LSB
:
3508 dyn_r_type
= R_IA64_REL64MSB
;
3510 case R_IA64_DIR64LSB
:
3511 dyn_r_type
= R_IA64_DIR64MSB
;
3513 case R_IA64_FPTR64LSB
:
3514 dyn_r_type
= R_IA64_FPTR64MSB
;
3516 case R_IA64_TPREL64LSB
:
3517 dyn_r_type
= R_IA64_TPREL64MSB
;
3519 case R_IA64_DTPMOD64LSB
:
3520 dyn_r_type
= R_IA64_DTPMOD64MSB
;
3522 case R_IA64_DTPREL64LSB
:
3523 dyn_r_type
= R_IA64_DTPREL64MSB
;
3531 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3532 ia64_info
->rel_got_sec
,
3533 got_offset
, dyn_r_type
,
3538 /* Return the address of the linkage table entry. */
3539 value
= (got_sec
->output_section
->vma
3540 + got_sec
->output_offset
3546 /* Fill in a function descriptor consisting of the function's code
3547 address and its global pointer. Return the descriptor's address. */
3550 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3552 struct bfd_link_info
*info
;
3553 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3556 struct elfNN_ia64_link_hash_table
*ia64_info
;
3559 ia64_info
= elfNN_ia64_hash_table (info
);
3560 fptr_sec
= ia64_info
->fptr_sec
;
3562 if (!dyn_i
->fptr_done
)
3564 dyn_i
->fptr_done
= 1;
3566 /* Fill in the function descriptor. */
3567 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3568 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3569 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3570 if (ia64_info
->rel_fptr_sec
)
3572 Elf_Internal_Rela outrel
;
3575 if (bfd_little_endian (abfd
))
3576 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_IPLTLSB
);
3578 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_IPLTMSB
);
3579 outrel
.r_addend
= value
;
3580 outrel
.r_offset
= (fptr_sec
->output_section
->vma
3581 + fptr_sec
->output_offset
3582 + dyn_i
->fptr_offset
);
3583 loc
= ia64_info
->rel_fptr_sec
->contents
;
3584 loc
+= ia64_info
->rel_fptr_sec
->reloc_count
++
3585 * sizeof (ElfNN_External_Rela
);
3586 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
3590 /* Return the descriptor's address. */
3591 value
= (fptr_sec
->output_section
->vma
3592 + fptr_sec
->output_offset
3593 + dyn_i
->fptr_offset
);
3598 /* Fill in a PLTOFF entry consisting of the function's code address
3599 and its global pointer. Return the descriptor's address. */
3602 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3604 struct bfd_link_info
*info
;
3605 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3609 struct elfNN_ia64_link_hash_table
*ia64_info
;
3610 asection
*pltoff_sec
;
3612 ia64_info
= elfNN_ia64_hash_table (info
);
3613 pltoff_sec
= ia64_info
->pltoff_sec
;
3615 /* Don't do anything if this symbol uses a real PLT entry. In
3616 that case, we'll fill this in during finish_dynamic_symbol. */
3617 if ((! dyn_i
->want_plt
|| is_plt
)
3618 && !dyn_i
->pltoff_done
)
3620 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3622 /* Fill in the function descriptor. */
3623 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3624 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3626 /* Install dynamic relocations if needed. */
3630 || ELF_ST_VISIBILITY (dyn_i
->h
->other
) == STV_DEFAULT
3631 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
))
3633 unsigned int dyn_r_type
;
3635 if (bfd_big_endian (abfd
))
3636 dyn_r_type
= R_IA64_REL64MSB
;
3638 dyn_r_type
= R_IA64_REL64LSB
;
3640 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3641 ia64_info
->rel_pltoff_sec
,
3642 dyn_i
->pltoff_offset
,
3643 dyn_r_type
, 0, value
);
3644 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3645 ia64_info
->rel_pltoff_sec
,
3646 dyn_i
->pltoff_offset
+ 8,
3650 dyn_i
->pltoff_done
= 1;
3653 /* Return the descriptor's address. */
3654 value
= (pltoff_sec
->output_section
->vma
3655 + pltoff_sec
->output_offset
3656 + dyn_i
->pltoff_offset
);
3661 /* Return the base VMA address which should be subtracted from real addresses
3662 when resolving @tprel() relocation.
3663 Main program TLS (whose template starts at PT_TLS p_vaddr)
3664 is assigned offset round(16, PT_TLS p_align). */
3667 elfNN_ia64_tprel_base (info
)
3668 struct bfd_link_info
*info
;
3670 struct elf_link_tls_segment
*tls_segment
3671 = elf_hash_table (info
)->tls_segment
;
3673 BFD_ASSERT (tls_segment
!= NULL
);
3674 return (tls_segment
->start
3675 - align_power ((bfd_vma
) 16, tls_segment
->align
));
3678 /* Return the base VMA address which should be subtracted from real addresses
3679 when resolving @dtprel() relocation.
3680 This is PT_TLS segment p_vaddr. */
3683 elfNN_ia64_dtprel_base (info
)
3684 struct bfd_link_info
*info
;
3686 BFD_ASSERT (elf_hash_table (info
)->tls_segment
!= NULL
);
3687 return elf_hash_table (info
)->tls_segment
->start
;
3690 /* Called through qsort to sort the .IA_64.unwind section during a
3691 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3692 to the output bfd so we can do proper endianness frobbing. */
3694 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3697 elfNN_ia64_unwind_entry_compare (a
, b
)
3703 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3704 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3706 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3709 /* Make sure we've got ourselves a nice fat __gp value. */
3711 elfNN_ia64_choose_gp (abfd
, info
)
3713 struct bfd_link_info
*info
;
3715 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3716 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3717 struct elf_link_hash_entry
*gp
;
3720 struct elfNN_ia64_link_hash_table
*ia64_info
;
3722 ia64_info
= elfNN_ia64_hash_table (info
);
3724 /* Find the min and max vma of all sections marked short. Also collect
3725 min and max vma of any type, for use in selecting a nice gp. */
3726 for (os
= abfd
->sections
; os
; os
= os
->next
)
3730 if ((os
->flags
& SEC_ALLOC
) == 0)
3734 hi
= os
->vma
+ os
->_raw_size
;
3742 if (os
->flags
& SEC_SMALL_DATA
)
3744 if (min_short_vma
> lo
)
3746 if (max_short_vma
< hi
)
3751 /* See if the user wants to force a value. */
3752 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
3756 && (gp
->root
.type
== bfd_link_hash_defined
3757 || gp
->root
.type
== bfd_link_hash_defweak
))
3759 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3760 gp_val
= (gp
->root
.u
.def
.value
3761 + gp_sec
->output_section
->vma
3762 + gp_sec
->output_offset
);
3766 /* Pick a sensible value. */
3768 asection
*got_sec
= ia64_info
->got_sec
;
3770 /* Start with just the address of the .got. */
3772 gp_val
= got_sec
->output_section
->vma
;
3773 else if (max_short_vma
!= 0)
3774 gp_val
= min_short_vma
;
3778 /* If it is possible to address the entire image, but we
3779 don't with the choice above, adjust. */
3780 if (max_vma
- min_vma
< 0x400000
3781 && max_vma
- gp_val
<= 0x200000
3782 && gp_val
- min_vma
> 0x200000)
3783 gp_val
= min_vma
+ 0x200000;
3784 else if (max_short_vma
!= 0)
3786 /* If we don't cover all the short data, adjust. */
3787 if (max_short_vma
- gp_val
>= 0x200000)
3788 gp_val
= min_short_vma
+ 0x200000;
3790 /* If we're addressing stuff past the end, adjust back. */
3791 if (gp_val
> max_vma
)
3792 gp_val
= max_vma
- 0x200000 + 8;
3796 /* Validate whether all SHF_IA_64_SHORT sections are within
3797 range of the chosen GP. */
3799 if (max_short_vma
!= 0)
3801 if (max_short_vma
- min_short_vma
>= 0x400000)
3803 (*_bfd_error_handler
)
3804 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3805 bfd_get_filename (abfd
),
3806 (unsigned long) (max_short_vma
- min_short_vma
));
3809 else if ((gp_val
> min_short_vma
3810 && gp_val
- min_short_vma
> 0x200000)
3811 || (gp_val
< max_short_vma
3812 && max_short_vma
- gp_val
>= 0x200000))
3814 (*_bfd_error_handler
)
3815 (_("%s: __gp does not cover short data segment"),
3816 bfd_get_filename (abfd
));
3821 _bfd_set_gp_value (abfd
, gp_val
);
3827 elfNN_ia64_final_link (abfd
, info
)
3829 struct bfd_link_info
*info
;
3831 struct elfNN_ia64_link_hash_table
*ia64_info
;
3832 asection
*unwind_output_sec
;
3834 ia64_info
= elfNN_ia64_hash_table (info
);
3836 /* Make sure we've got ourselves a nice fat __gp value. */
3837 if (!info
->relocatable
)
3839 bfd_vma gp_val
= _bfd_get_gp_value (abfd
);
3840 struct elf_link_hash_entry
*gp
;
3844 if (! elfNN_ia64_choose_gp (abfd
, info
))
3846 gp_val
= _bfd_get_gp_value (abfd
);
3849 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
3853 gp
->root
.type
= bfd_link_hash_defined
;
3854 gp
->root
.u
.def
.value
= gp_val
;
3855 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3859 /* If we're producing a final executable, we need to sort the contents
3860 of the .IA_64.unwind section. Force this section to be relocated
3861 into memory rather than written immediately to the output file. */
3862 unwind_output_sec
= NULL
;
3863 if (!info
->relocatable
)
3865 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3868 unwind_output_sec
= s
->output_section
;
3869 unwind_output_sec
->contents
3870 = bfd_malloc (unwind_output_sec
->_raw_size
);
3871 if (unwind_output_sec
->contents
== NULL
)
3876 /* Invoke the regular ELF backend linker to do all the work. */
3877 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3880 if (unwind_output_sec
)
3882 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3883 qsort (unwind_output_sec
->contents
,
3884 (size_t) (unwind_output_sec
->_raw_size
/ 24),
3886 elfNN_ia64_unwind_entry_compare
);
3888 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3889 unwind_output_sec
->contents
, (bfd_vma
) 0,
3890 unwind_output_sec
->_raw_size
))
3898 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3899 contents
, relocs
, local_syms
, local_sections
)
3901 struct bfd_link_info
*info
;
3903 asection
*input_section
;
3905 Elf_Internal_Rela
*relocs
;
3906 Elf_Internal_Sym
*local_syms
;
3907 asection
**local_sections
;
3909 struct elfNN_ia64_link_hash_table
*ia64_info
;
3910 Elf_Internal_Shdr
*symtab_hdr
;
3911 Elf_Internal_Rela
*rel
;
3912 Elf_Internal_Rela
*relend
;
3914 bfd_boolean ret_val
= TRUE
; /* for non-fatal errors */
3917 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3918 ia64_info
= elfNN_ia64_hash_table (info
);
3920 /* Infect various flags from the input section to the output section. */
3921 if (info
->relocatable
)
3925 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3926 flags
&= SHF_IA_64_NORECOV
;
3928 elf_section_data(input_section
->output_section
)
3929 ->this_hdr
.sh_flags
|= flags
;
3933 gp_val
= _bfd_get_gp_value (output_bfd
);
3934 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, FALSE
);
3937 relend
= relocs
+ input_section
->reloc_count
;
3938 for (; rel
< relend
; ++rel
)
3940 struct elf_link_hash_entry
*h
;
3941 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3942 bfd_reloc_status_type r
;
3943 reloc_howto_type
*howto
;
3944 unsigned long r_symndx
;
3945 Elf_Internal_Sym
*sym
;
3946 unsigned int r_type
;
3950 bfd_boolean dynamic_symbol_p
;
3951 bfd_boolean local_symbol_p
;
3952 bfd_boolean undef_weak_ref
;
3954 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3955 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3957 (*_bfd_error_handler
)
3958 (_("%s: unknown relocation type %d"),
3959 bfd_archive_filename (input_bfd
), (int)r_type
);
3960 bfd_set_error (bfd_error_bad_value
);
3965 howto
= lookup_howto (r_type
);
3966 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3970 undef_weak_ref
= FALSE
;
3972 if (r_symndx
< symtab_hdr
->sh_info
)
3974 /* Reloc against local symbol. */
3975 sym
= local_syms
+ r_symndx
;
3976 sym_sec
= local_sections
[r_symndx
];
3977 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, sym_sec
, rel
);
3978 if ((sym_sec
->flags
& SEC_MERGE
)
3979 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
3980 && sym_sec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
3982 struct elfNN_ia64_local_hash_entry
*loc_h
;
3984 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, FALSE
);
3985 if (loc_h
&& ! loc_h
->sec_merge_done
)
3987 struct elfNN_ia64_dyn_sym_info
*dynent
;
3990 for (dynent
= loc_h
->info
; dynent
; dynent
= dynent
->next
)
3994 _bfd_merged_section_offset (output_bfd
, &msec
,
3995 elf_section_data (msec
)->
4000 dynent
->addend
-= sym
->st_value
;
4001 dynent
->addend
+= msec
->output_section
->vma
4002 + msec
->output_offset
4003 - sym_sec
->output_section
->vma
4004 - sym_sec
->output_offset
;
4006 loc_h
->sec_merge_done
= 1;
4014 /* Reloc against global symbol. */
4015 indx
= r_symndx
- symtab_hdr
->sh_info
;
4016 h
= elf_sym_hashes (input_bfd
)[indx
];
4017 while (h
->root
.type
== bfd_link_hash_indirect
4018 || h
->root
.type
== bfd_link_hash_warning
)
4019 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
4022 if (h
->root
.type
== bfd_link_hash_defined
4023 || h
->root
.type
== bfd_link_hash_defweak
)
4025 sym_sec
= h
->root
.u
.def
.section
;
4027 /* Detect the cases that sym_sec->output_section is
4028 expected to be NULL -- all cases in which the symbol
4029 is defined in another shared module. This includes
4030 PLT relocs for which we've created a PLT entry and
4031 other relocs for which we're prepared to create
4032 dynamic relocations. */
4033 /* ??? Just accept it NULL and continue. */
4035 if (sym_sec
->output_section
!= NULL
)
4037 value
= (h
->root
.u
.def
.value
4038 + sym_sec
->output_section
->vma
4039 + sym_sec
->output_offset
);
4042 else if (h
->root
.type
== bfd_link_hash_undefweak
)
4043 undef_weak_ref
= TRUE
;
4044 else if (! info
->executable
4045 && !info
->no_undefined
4046 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
4050 if (! ((*info
->callbacks
->undefined_symbol
)
4051 (info
, h
->root
.root
.string
, input_bfd
,
4052 input_section
, rel
->r_offset
,
4053 (!info
->shared
|| info
->no_undefined
4054 || ELF_ST_VISIBILITY (h
->other
)))))
4060 hit_addr
= contents
+ rel
->r_offset
;
4061 value
+= rel
->r_addend
;
4062 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
4063 /* Is this symbol locally defined? A protected symbol is locallly
4064 defined. But its function descriptor may not. Use it with
4066 local_symbol_p
= (! dynamic_symbol_p
4067 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
);
4078 case R_IA64_DIR32MSB
:
4079 case R_IA64_DIR32LSB
:
4080 case R_IA64_DIR64MSB
:
4081 case R_IA64_DIR64LSB
:
4082 /* Install a dynamic relocation for this reloc. */
4083 if ((dynamic_symbol_p
|| info
->shared
4084 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
4085 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
4086 && (!h
|| strcmp (h
->root
.root
.string
,
4087 "__GLOB_DATA_PTR") != 0)))
4089 && (input_section
->flags
& SEC_ALLOC
) != 0)
4091 unsigned int dyn_r_type
;
4095 BFD_ASSERT (srel
!= NULL
);
4097 /* If we don't need dynamic symbol lookup, find a
4098 matching RELATIVE relocation. */
4099 dyn_r_type
= r_type
;
4100 if (! local_symbol_p
)
4102 dynindx
= h
->dynindx
;
4103 addend
= rel
->r_addend
;
4110 case R_IA64_DIR32MSB
:
4111 dyn_r_type
= R_IA64_REL32MSB
;
4113 case R_IA64_DIR32LSB
:
4114 dyn_r_type
= R_IA64_REL32LSB
;
4116 case R_IA64_DIR64MSB
:
4117 dyn_r_type
= R_IA64_REL64MSB
;
4119 case R_IA64_DIR64LSB
:
4120 dyn_r_type
= R_IA64_REL64LSB
;
4124 /* We can't represent this without a dynamic symbol.
4125 Adjust the relocation to be against an output
4126 section symbol, which are always present in the
4127 dynamic symbol table. */
4128 /* ??? People shouldn't be doing non-pic code in
4129 shared libraries. Hork. */
4130 (*_bfd_error_handler
)
4131 (_("%s: linking non-pic code in a shared library"),
4132 bfd_archive_filename (input_bfd
));
4140 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
4141 rel
->r_addend
= value
;
4142 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4143 srel
, rel
->r_offset
, dyn_r_type
,
4148 case R_IA64_LTV32MSB
:
4149 case R_IA64_LTV32LSB
:
4150 case R_IA64_LTV64MSB
:
4151 case R_IA64_LTV64LSB
:
4152 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4155 case R_IA64_GPREL22
:
4156 case R_IA64_GPREL64I
:
4157 case R_IA64_GPREL32MSB
:
4158 case R_IA64_GPREL32LSB
:
4159 case R_IA64_GPREL64MSB
:
4160 case R_IA64_GPREL64LSB
:
4161 if (dynamic_symbol_p
)
4163 (*_bfd_error_handler
)
4164 (_("%s: @gprel relocation against dynamic symbol %s"),
4165 bfd_archive_filename (input_bfd
), h
->root
.root
.string
);
4170 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4173 case R_IA64_LTOFF22
:
4174 case R_IA64_LTOFF22X
:
4175 case R_IA64_LTOFF64I
:
4176 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4177 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
4178 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
4180 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4183 case R_IA64_PLTOFF22
:
4184 case R_IA64_PLTOFF64I
:
4185 case R_IA64_PLTOFF64MSB
:
4186 case R_IA64_PLTOFF64LSB
:
4187 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4188 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, FALSE
);
4190 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4193 case R_IA64_FPTR64I
:
4194 case R_IA64_FPTR32MSB
:
4195 case R_IA64_FPTR32LSB
:
4196 case R_IA64_FPTR64MSB
:
4197 case R_IA64_FPTR64LSB
:
4198 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4199 if (dyn_i
->want_fptr
)
4201 if (!undef_weak_ref
)
4202 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4204 if (!dyn_i
->want_fptr
|| info
->pie
)
4207 unsigned int dyn_r_type
= r_type
;
4208 bfd_vma addend
= rel
->r_addend
;
4210 /* Otherwise, we expect the dynamic linker to create
4213 if (dyn_i
->want_fptr
)
4215 if (r_type
== R_IA64_FPTR64I
)
4217 /* We can't represent this without a dynamic symbol.
4218 Adjust the relocation to be against an output
4219 section symbol, which are always present in the
4220 dynamic symbol table. */
4221 /* ??? People shouldn't be doing non-pic code in
4222 shared libraries. Hork. */
4223 (*_bfd_error_handler
)
4224 (_("%s: linking non-pic code in a position independent executable"),
4225 bfd_archive_filename (input_bfd
));
4231 dyn_r_type
= r_type
+ R_IA64_REL64LSB
- R_IA64_FPTR64LSB
;
4235 if (h
->dynindx
!= -1)
4236 dynindx
= h
->dynindx
;
4238 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4239 (info
, h
->root
.u
.def
.section
->owner
,
4240 global_sym_index (h
)));
4245 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4246 (info
, input_bfd
, (long) r_symndx
));
4250 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4251 srel
, rel
->r_offset
, dyn_r_type
,
4255 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4258 case R_IA64_LTOFF_FPTR22
:
4259 case R_IA64_LTOFF_FPTR64I
:
4260 case R_IA64_LTOFF_FPTR32MSB
:
4261 case R_IA64_LTOFF_FPTR32LSB
:
4262 case R_IA64_LTOFF_FPTR64MSB
:
4263 case R_IA64_LTOFF_FPTR64LSB
:
4267 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4268 if (dyn_i
->want_fptr
)
4270 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
4271 if (!undef_weak_ref
)
4272 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4277 /* Otherwise, we expect the dynamic linker to create
4281 if (h
->dynindx
!= -1)
4282 dynindx
= h
->dynindx
;
4284 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4285 (info
, h
->root
.u
.def
.section
->owner
,
4286 global_sym_index (h
)));
4289 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4290 (info
, input_bfd
, (long) r_symndx
));
4294 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
4295 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
4297 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4301 case R_IA64_PCREL32MSB
:
4302 case R_IA64_PCREL32LSB
:
4303 case R_IA64_PCREL64MSB
:
4304 case R_IA64_PCREL64LSB
:
4305 /* Install a dynamic relocation for this reloc. */
4306 if ((dynamic_symbol_p
4307 || elfNN_ia64_aix_vec (info
->hash
->creator
))
4310 BFD_ASSERT (srel
!= NULL
);
4312 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4313 srel
, rel
->r_offset
, r_type
,
4314 h
->dynindx
, rel
->r_addend
);
4318 case R_IA64_PCREL21B
:
4319 case R_IA64_PCREL60B
:
4320 /* We should have created a PLT entry for any dynamic symbol. */
4323 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4325 if (dyn_i
&& dyn_i
->want_plt2
)
4327 /* Should have caught this earlier. */
4328 BFD_ASSERT (rel
->r_addend
== 0);
4330 value
= (ia64_info
->plt_sec
->output_section
->vma
4331 + ia64_info
->plt_sec
->output_offset
4332 + dyn_i
->plt2_offset
);
4336 /* Since there's no PLT entry, Validate that this is
4338 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
4340 /* If the symbol is undef_weak, we shouldn't be trying
4341 to call it. There's every chance that we'd wind up
4342 with an out-of-range fixup here. Don't bother setting
4343 any value at all. */
4349 case R_IA64_PCREL21BI
:
4350 case R_IA64_PCREL21F
:
4351 case R_IA64_PCREL21M
:
4352 case R_IA64_PCREL22
:
4353 case R_IA64_PCREL64I
:
4354 /* The PCREL21BI reloc is specifically not intended for use with
4355 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4356 fixup code, and thus probably ought not be dynamic. The
4357 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4358 if (dynamic_symbol_p
)
4362 if (r_type
== R_IA64_PCREL21BI
)
4363 msg
= _("%s: @internal branch to dynamic symbol %s");
4364 else if (r_type
== R_IA64_PCREL21F
|| r_type
== R_IA64_PCREL21M
)
4365 msg
= _("%s: speculation fixup to dynamic symbol %s");
4367 msg
= _("%s: @pcrel relocation against dynamic symbol %s");
4368 (*_bfd_error_handler
) (msg
, bfd_archive_filename (input_bfd
),
4369 h
->root
.root
.string
);
4376 /* Make pc-relative. */
4377 value
-= (input_section
->output_section
->vma
4378 + input_section
->output_offset
4379 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
4380 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4383 case R_IA64_SEGREL32MSB
:
4384 case R_IA64_SEGREL32LSB
:
4385 case R_IA64_SEGREL64MSB
:
4386 case R_IA64_SEGREL64LSB
:
4389 /* If the input section was discarded from the output, then
4395 struct elf_segment_map
*m
;
4396 Elf_Internal_Phdr
*p
;
4398 /* Find the segment that contains the output_section. */
4399 for (m
= elf_tdata (output_bfd
)->segment_map
,
4400 p
= elf_tdata (output_bfd
)->phdr
;
4405 for (i
= m
->count
- 1; i
>= 0; i
--)
4406 if (m
->sections
[i
] == input_section
->output_section
)
4414 r
= bfd_reloc_notsupported
;
4418 /* The VMA of the segment is the vaddr of the associated
4420 if (value
> p
->p_vaddr
)
4421 value
-= p
->p_vaddr
;
4424 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
4430 case R_IA64_SECREL32MSB
:
4431 case R_IA64_SECREL32LSB
:
4432 case R_IA64_SECREL64MSB
:
4433 case R_IA64_SECREL64LSB
:
4434 /* Make output-section relative. */
4435 if (value
> input_section
->output_section
->vma
)
4436 value
-= input_section
->output_section
->vma
;
4439 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4442 case R_IA64_IPLTMSB
:
4443 case R_IA64_IPLTLSB
:
4444 /* Install a dynamic relocation for this reloc. */
4445 if ((dynamic_symbol_p
|| info
->shared
)
4446 && (input_section
->flags
& SEC_ALLOC
) != 0)
4448 BFD_ASSERT (srel
!= NULL
);
4450 /* If we don't need dynamic symbol lookup, install two
4451 RELATIVE relocations. */
4454 unsigned int dyn_r_type
;
4456 if (r_type
== R_IA64_IPLTMSB
)
4457 dyn_r_type
= R_IA64_REL64MSB
;
4459 dyn_r_type
= R_IA64_REL64LSB
;
4461 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4463 srel
, rel
->r_offset
,
4464 dyn_r_type
, 0, value
);
4465 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4467 srel
, rel
->r_offset
+ 8,
4468 dyn_r_type
, 0, gp_val
);
4471 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4472 srel
, rel
->r_offset
, r_type
,
4473 h
->dynindx
, rel
->r_addend
);
4476 if (r_type
== R_IA64_IPLTMSB
)
4477 r_type
= R_IA64_DIR64MSB
;
4479 r_type
= R_IA64_DIR64LSB
;
4480 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4481 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
4485 case R_IA64_TPREL14
:
4486 case R_IA64_TPREL22
:
4487 case R_IA64_TPREL64I
:
4488 value
-= elfNN_ia64_tprel_base (info
);
4489 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4492 case R_IA64_DTPREL14
:
4493 case R_IA64_DTPREL22
:
4494 case R_IA64_DTPREL64I
:
4495 case R_IA64_DTPREL64LSB
:
4496 case R_IA64_DTPREL64MSB
:
4497 value
-= elfNN_ia64_dtprel_base (info
);
4498 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4501 case R_IA64_LTOFF_TPREL22
:
4502 case R_IA64_LTOFF_DTPMOD22
:
4503 case R_IA64_LTOFF_DTPREL22
:
4506 long dynindx
= h
? h
->dynindx
: -1;
4507 bfd_vma r_addend
= rel
->r_addend
;
4512 case R_IA64_LTOFF_TPREL22
:
4513 if (!dynamic_symbol_p
)
4516 value
-= elfNN_ia64_tprel_base (info
);
4519 r_addend
+= value
- elfNN_ia64_dtprel_base (info
);
4523 got_r_type
= R_IA64_TPREL64LSB
;
4525 case R_IA64_LTOFF_DTPMOD22
:
4526 if (!dynamic_symbol_p
&& !info
->shared
)
4528 got_r_type
= R_IA64_DTPMOD64LSB
;
4530 case R_IA64_LTOFF_DTPREL22
:
4531 if (!dynamic_symbol_p
)
4532 value
-= elfNN_ia64_dtprel_base (info
);
4533 got_r_type
= R_IA64_DTPREL64LSB
;
4536 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4537 value
= set_got_entry (input_bfd
, info
, dyn_i
, dynindx
, r_addend
,
4540 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
4546 r
= bfd_reloc_notsupported
;
4555 case bfd_reloc_undefined
:
4556 /* This can happen for global table relative relocs if
4557 __gp is undefined. This is a panic situation so we
4558 don't try to continue. */
4559 (*info
->callbacks
->undefined_symbol
)
4560 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
4563 case bfd_reloc_notsupported
:
4568 name
= h
->root
.root
.string
;
4571 name
= bfd_elf_string_from_elf_section (input_bfd
,
4572 symtab_hdr
->sh_link
,
4577 name
= bfd_section_name (input_bfd
, input_section
);
4579 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
4581 input_section
, rel
->r_offset
))
4587 case bfd_reloc_dangerous
:
4588 case bfd_reloc_outofrange
:
4589 case bfd_reloc_overflow
:
4595 name
= h
->root
.root
.string
;
4598 name
= bfd_elf_string_from_elf_section (input_bfd
,
4599 symtab_hdr
->sh_link
,
4604 name
= bfd_section_name (input_bfd
, input_section
);
4606 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
4623 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
4625 struct bfd_link_info
*info
;
4626 struct elf_link_hash_entry
*h
;
4627 Elf_Internal_Sym
*sym
;
4629 struct elfNN_ia64_link_hash_table
*ia64_info
;
4630 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4632 ia64_info
= elfNN_ia64_hash_table (info
);
4633 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4635 /* Fill in the PLT data, if required. */
4636 if (dyn_i
&& dyn_i
->want_plt
)
4638 Elf_Internal_Rela outrel
;
4641 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
4643 gp_val
= _bfd_get_gp_value (output_bfd
);
4645 /* Initialize the minimal PLT entry. */
4647 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4648 plt_sec
= ia64_info
->plt_sec
;
4649 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4651 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4652 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4653 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4656 plt_addr
= (plt_sec
->output_section
->vma
4657 + plt_sec
->output_offset
4658 + dyn_i
->plt_offset
);
4659 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, TRUE
);
4661 /* Initialize the FULL PLT entry, if needed. */
4662 if (dyn_i
->want_plt2
)
4664 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4666 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4667 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4670 /* Mark the symbol as undefined, rather than as defined in the
4671 plt section. Leave the value alone. */
4672 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4673 first place. But perhaps elflink.h did some for us. */
4674 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4675 sym
->st_shndx
= SHN_UNDEF
;
4678 /* Create the dynamic relocation. */
4679 outrel
.r_offset
= pltoff_addr
;
4680 if (bfd_little_endian (output_bfd
))
4681 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4683 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4684 outrel
.r_addend
= 0;
4686 /* This is fun. In the .IA_64.pltoff section, we've got entries
4687 that correspond both to real PLT entries, and those that
4688 happened to resolve to local symbols but need to be created
4689 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4690 relocations for the real PLT should come at the end of the
4691 section, so that they can be indexed by plt entry at runtime.
4693 We emitted all of the relocations for the non-PLT @pltoff
4694 entries during relocate_section. So we can consider the
4695 existing sec->reloc_count to be the base of the array of
4698 loc
= ia64_info
->rel_pltoff_sec
->contents
;
4699 loc
+= ((ia64_info
->rel_pltoff_sec
->reloc_count
+ index
)
4700 * sizeof (Elf64_External_Rela
));
4701 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
4704 /* Mark some specially defined symbols as absolute. */
4705 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4706 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4707 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4708 sym
->st_shndx
= SHN_ABS
;
4714 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4716 struct bfd_link_info
*info
;
4718 struct elfNN_ia64_link_hash_table
*ia64_info
;
4721 ia64_info
= elfNN_ia64_hash_table (info
);
4722 dynobj
= ia64_info
->root
.dynobj
;
4724 if (elf_hash_table (info
)->dynamic_sections_created
)
4726 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4727 asection
*sdyn
, *sgotplt
;
4730 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4731 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4732 BFD_ASSERT (sdyn
!= NULL
);
4733 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4734 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4736 gp_val
= _bfd_get_gp_value (abfd
);
4738 for (; dyncon
< dynconend
; dyncon
++)
4740 Elf_Internal_Dyn dyn
;
4742 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4747 dyn
.d_un
.d_ptr
= gp_val
;
4751 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4752 * sizeof (ElfNN_External_Rela
));
4756 /* See the comment above in finish_dynamic_symbol. */
4757 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4758 + ia64_info
->rel_pltoff_sec
->output_offset
4759 + (ia64_info
->rel_pltoff_sec
->reloc_count
4760 * sizeof (ElfNN_External_Rela
)));
4763 case DT_IA_64_PLT_RESERVE
:
4764 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4765 + sgotplt
->output_offset
);
4769 /* Do not have RELASZ include JMPREL. This makes things
4770 easier on ld.so. This is not what the rest of BFD set up. */
4771 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4772 * sizeof (ElfNN_External_Rela
));
4776 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4779 /* Initialize the PLT0 entry. */
4780 if (ia64_info
->plt_sec
)
4782 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4785 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4787 pltres
= (sgotplt
->output_section
->vma
4788 + sgotplt
->output_offset
4791 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4798 /* ELF file flag handling: */
4800 /* Function to keep IA-64 specific file flags. */
4802 elfNN_ia64_set_private_flags (abfd
, flags
)
4806 BFD_ASSERT (!elf_flags_init (abfd
)
4807 || elf_elfheader (abfd
)->e_flags
== flags
);
4809 elf_elfheader (abfd
)->e_flags
= flags
;
4810 elf_flags_init (abfd
) = TRUE
;
4814 /* Merge backend specific data from an object file to the output
4815 object file when linking. */
4817 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4822 bfd_boolean ok
= TRUE
;
4824 /* Don't even pretend to support mixed-format linking. */
4825 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4826 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4829 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4830 out_flags
= elf_elfheader (obfd
)->e_flags
;
4832 if (! elf_flags_init (obfd
))
4834 elf_flags_init (obfd
) = TRUE
;
4835 elf_elfheader (obfd
)->e_flags
= in_flags
;
4837 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4838 && bfd_get_arch_info (obfd
)->the_default
)
4840 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4841 bfd_get_mach (ibfd
));
4847 /* Check flag compatibility. */
4848 if (in_flags
== out_flags
)
4851 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4852 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4853 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4855 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4857 (*_bfd_error_handler
)
4858 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4859 bfd_archive_filename (ibfd
));
4861 bfd_set_error (bfd_error_bad_value
);
4864 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4866 (*_bfd_error_handler
)
4867 (_("%s: linking big-endian files with little-endian files"),
4868 bfd_archive_filename (ibfd
));
4870 bfd_set_error (bfd_error_bad_value
);
4873 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4875 (*_bfd_error_handler
)
4876 (_("%s: linking 64-bit files with 32-bit files"),
4877 bfd_archive_filename (ibfd
));
4879 bfd_set_error (bfd_error_bad_value
);
4882 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4884 (*_bfd_error_handler
)
4885 (_("%s: linking constant-gp files with non-constant-gp files"),
4886 bfd_archive_filename (ibfd
));
4888 bfd_set_error (bfd_error_bad_value
);
4891 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4892 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4894 (*_bfd_error_handler
)
4895 (_("%s: linking auto-pic files with non-auto-pic files"),
4896 bfd_archive_filename (ibfd
));
4898 bfd_set_error (bfd_error_bad_value
);
4906 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4910 FILE *file
= (FILE *) ptr
;
4911 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4913 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4915 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4916 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4917 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4918 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4919 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4920 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4921 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4922 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4923 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4925 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4929 static enum elf_reloc_type_class
4930 elfNN_ia64_reloc_type_class (rela
)
4931 const Elf_Internal_Rela
*rela
;
4933 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
4935 case R_IA64_REL32MSB
:
4936 case R_IA64_REL32LSB
:
4937 case R_IA64_REL64MSB
:
4938 case R_IA64_REL64LSB
:
4939 return reloc_class_relative
;
4940 case R_IA64_IPLTMSB
:
4941 case R_IA64_IPLTLSB
:
4942 return reloc_class_plt
;
4944 return reloc_class_copy
;
4946 return reloc_class_normal
;
4951 elfNN_ia64_hpux_vec (const bfd_target
*vec
)
4953 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec
;
4954 return (vec
== & bfd_elfNN_ia64_hpux_big_vec
);
4958 elfNN_hpux_post_process_headers (abfd
, info
)
4960 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
4962 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
4964 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_HPUX
;
4965 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 1;
4969 elfNN_hpux_backend_section_from_bfd_section (abfd
, sec
, retval
)
4970 bfd
*abfd ATTRIBUTE_UNUSED
;
4974 if (bfd_is_com_section (sec
))
4976 *retval
= SHN_IA_64_ANSI_COMMON
;
4982 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4983 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4984 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4985 #define TARGET_BIG_NAME "elfNN-ia64-big"
4986 #define ELF_ARCH bfd_arch_ia64
4987 #define ELF_MACHINE_CODE EM_IA_64
4988 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4989 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4990 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4992 #define elf_backend_section_from_shdr \
4993 elfNN_ia64_section_from_shdr
4994 #define elf_backend_section_flags \
4995 elfNN_ia64_section_flags
4996 #define elf_backend_fake_sections \
4997 elfNN_ia64_fake_sections
4998 #define elf_backend_final_write_processing \
4999 elfNN_ia64_final_write_processing
5000 #define elf_backend_add_symbol_hook \
5001 elfNN_ia64_add_symbol_hook
5002 #define elf_backend_additional_program_headers \
5003 elfNN_ia64_additional_program_headers
5004 #define elf_backend_modify_segment_map \
5005 elfNN_ia64_modify_segment_map
5006 #define elf_info_to_howto \
5007 elfNN_ia64_info_to_howto
5009 #define bfd_elfNN_bfd_reloc_type_lookup \
5010 elfNN_ia64_reloc_type_lookup
5011 #define bfd_elfNN_bfd_is_local_label_name \
5012 elfNN_ia64_is_local_label_name
5013 #define bfd_elfNN_bfd_relax_section \
5014 elfNN_ia64_relax_section
5016 /* Stuff for the BFD linker: */
5017 #define bfd_elfNN_bfd_link_hash_table_create \
5018 elfNN_ia64_hash_table_create
5019 #define elf_backend_create_dynamic_sections \
5020 elfNN_ia64_create_dynamic_sections
5021 #define elf_backend_check_relocs \
5022 elfNN_ia64_check_relocs
5023 #define elf_backend_adjust_dynamic_symbol \
5024 elfNN_ia64_adjust_dynamic_symbol
5025 #define elf_backend_size_dynamic_sections \
5026 elfNN_ia64_size_dynamic_sections
5027 #define elf_backend_relocate_section \
5028 elfNN_ia64_relocate_section
5029 #define elf_backend_finish_dynamic_symbol \
5030 elfNN_ia64_finish_dynamic_symbol
5031 #define elf_backend_finish_dynamic_sections \
5032 elfNN_ia64_finish_dynamic_sections
5033 #define bfd_elfNN_bfd_final_link \
5034 elfNN_ia64_final_link
5036 #define bfd_elfNN_bfd_merge_private_bfd_data \
5037 elfNN_ia64_merge_private_bfd_data
5038 #define bfd_elfNN_bfd_set_private_flags \
5039 elfNN_ia64_set_private_flags
5040 #define bfd_elfNN_bfd_print_private_bfd_data \
5041 elfNN_ia64_print_private_bfd_data
5043 #define elf_backend_plt_readonly 1
5044 #define elf_backend_want_plt_sym 0
5045 #define elf_backend_plt_alignment 5
5046 #define elf_backend_got_header_size 0
5047 #define elf_backend_plt_header_size PLT_HEADER_SIZE
5048 #define elf_backend_want_got_plt 1
5049 #define elf_backend_may_use_rel_p 1
5050 #define elf_backend_may_use_rela_p 1
5051 #define elf_backend_default_use_rela_p 1
5052 #define elf_backend_want_dynbss 0
5053 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5054 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
5055 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
5056 #define elf_backend_rela_normal 1
5058 #include "elfNN-target.h"
5060 /* AIX-specific vectors. */
5062 #undef TARGET_LITTLE_SYM
5063 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
5064 #undef TARGET_LITTLE_NAME
5065 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
5066 #undef TARGET_BIG_SYM
5067 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
5068 #undef TARGET_BIG_NAME
5069 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
5071 #undef elf_backend_add_symbol_hook
5072 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
5074 #undef bfd_elfNN_bfd_link_add_symbols
5075 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
5077 #define elfNN_bed elfNN_ia64_aix_bed
5079 #include "elfNN-target.h"
5081 /* HPUX-specific vectors. */
5083 #undef TARGET_LITTLE_SYM
5084 #undef TARGET_LITTLE_NAME
5085 #undef TARGET_BIG_SYM
5086 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
5087 #undef TARGET_BIG_NAME
5088 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
5090 /* We need to undo the AIX specific functions. */
5092 #undef elf_backend_add_symbol_hook
5093 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
5095 #undef bfd_elfNN_bfd_link_add_symbols
5096 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
5098 /* These are HP-UX specific functions. */
5100 #undef elf_backend_post_process_headers
5101 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5103 #undef elf_backend_section_from_bfd_section
5104 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5106 #undef elf_backend_want_p_paddr_set_to_zero
5107 #define elf_backend_want_p_paddr_set_to_zero 1
5109 #undef ELF_MAXPAGESIZE
5110 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
5113 #define elfNN_bed elfNN_ia64_hpux_bed
5115 #include "elfNN-target.h"
5117 #undef elf_backend_want_p_paddr_set_to_zero