1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #include "opcode/ia64.h"
28 /* THE RULES for all the stuff the linker creates --
30 GOT Entries created in response to LTOFF or LTOFF_FPTR
31 relocations. Dynamic relocs created for dynamic
32 symbols in an application; REL relocs for locals
35 FPTR The canonical function descriptor. Created for local
36 symbols in applications. Descriptors for dynamic symbols
37 and local symbols in shared libraries are created by
38 ld.so. Thus there are no dynamic relocs against these
39 objects. The FPTR relocs for such _are_ passed through
40 to the dynamic relocation tables.
42 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
43 Requires the creation of a PLTOFF entry. This does not
44 require any dynamic relocations.
46 PLTOFF Created by PLTOFF relocations. For local symbols, this
47 is an alternate function descriptor, and in shared libraries
48 requires two REL relocations. Note that this cannot be
49 transformed into an FPTR relocation, since it must be in
50 range of the GP. For dynamic symbols, this is a function
51 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
53 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
54 does not reqire dynamic relocations. */
56 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
58 typedef struct bfd_hash_entry
*(*new_hash_entry_func
)
59 PARAMS ((struct bfd_hash_entry
*, struct bfd_hash_table
*, const char *));
61 /* In dynamically (linker-) created sections, we generally need to keep track
62 of the place a symbol or expression got allocated to. This is done via hash
63 tables that store entries of the following type. */
65 struct elfNN_ia64_dyn_sym_info
67 /* The addend for which this entry is relevant. */
70 /* Next addend in the list. */
71 struct elfNN_ia64_dyn_sym_info
*next
;
75 bfd_vma pltoff_offset
;
79 bfd_vma dtpmod_offset
;
80 bfd_vma dtprel_offset
;
82 /* The symbol table entry, if any, that this was derrived from. */
83 struct elf_link_hash_entry
*h
;
85 /* Used to count non-got, non-plt relocations for delayed sizing
86 of relocation sections. */
87 struct elfNN_ia64_dyn_reloc_entry
89 struct elfNN_ia64_dyn_reloc_entry
*next
;
95 /* TRUE when the section contents have been updated. */
96 unsigned got_done
: 1;
97 unsigned fptr_done
: 1;
98 unsigned pltoff_done
: 1;
99 unsigned tprel_done
: 1;
100 unsigned dtpmod_done
: 1;
101 unsigned dtprel_done
: 1;
103 /* TRUE for the different kinds of linker data we want created. */
104 unsigned want_got
: 1;
105 unsigned want_gotx
: 1;
106 unsigned want_fptr
: 1;
107 unsigned want_ltoff_fptr
: 1;
108 unsigned want_plt
: 1;
109 unsigned want_plt2
: 1;
110 unsigned want_pltoff
: 1;
111 unsigned want_tprel
: 1;
112 unsigned want_dtpmod
: 1;
113 unsigned want_dtprel
: 1;
116 struct elfNN_ia64_local_hash_entry
118 struct bfd_hash_entry root
;
119 struct elfNN_ia64_dyn_sym_info
*info
;
121 /* TRUE if this hash entry's addends was translated for
122 SHF_MERGE optimization. */
123 unsigned sec_merge_done
: 1;
126 struct elfNN_ia64_local_hash_table
128 struct bfd_hash_table root
;
129 /* No additional fields for now. */
132 struct elfNN_ia64_link_hash_entry
134 struct elf_link_hash_entry root
;
135 struct elfNN_ia64_dyn_sym_info
*info
;
138 struct elfNN_ia64_link_hash_table
140 /* The main hash table. */
141 struct elf_link_hash_table root
;
143 asection
*got_sec
; /* the linkage table section (or NULL) */
144 asection
*rel_got_sec
; /* dynamic relocation section for same */
145 asection
*fptr_sec
; /* function descriptor table (or NULL) */
146 asection
*plt_sec
; /* the primary plt section (or NULL) */
147 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
148 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
150 bfd_size_type minplt_entries
; /* number of minplt entries */
151 unsigned reltext
: 1; /* are there relocs against readonly sections? */
152 unsigned self_dtpmod_done
: 1;/* has self DTPMOD entry been finished? */
153 bfd_vma self_dtpmod_offset
; /* .got offset to self DTPMOD entry */
155 struct elfNN_ia64_local_hash_table loc_hash_table
;
158 struct elfNN_ia64_allocate_data
160 struct bfd_link_info
*info
;
164 #define elfNN_ia64_hash_table(p) \
165 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
167 static bfd_reloc_status_type elfNN_ia64_reloc
168 PARAMS ((bfd
*abfd
, arelent
*reloc
, asymbol
*sym
, PTR data
,
169 asection
*input_section
, bfd
*output_bfd
, char **error_message
));
170 static reloc_howto_type
* lookup_howto
171 PARAMS ((unsigned int rtype
));
172 static reloc_howto_type
*elfNN_ia64_reloc_type_lookup
173 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type bfd_code
));
174 static void elfNN_ia64_info_to_howto
175 PARAMS ((bfd
*abfd
, arelent
*bfd_reloc
, Elf_Internal_Rela
*elf_reloc
));
176 static bfd_boolean elfNN_ia64_relax_section
177 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
178 bfd_boolean
*again
));
179 static void elfNN_ia64_relax_ldxmov
180 PARAMS((bfd
*abfd
, bfd_byte
*contents
, bfd_vma off
));
181 static bfd_boolean is_unwind_section_name
182 PARAMS ((bfd
*abfd
, const char *));
183 static bfd_boolean elfNN_ia64_section_from_shdr
184 PARAMS ((bfd
*, Elf_Internal_Shdr
*, const char *));
185 static bfd_boolean elfNN_ia64_section_flags
186 PARAMS ((flagword
*, Elf_Internal_Shdr
*));
187 static bfd_boolean elfNN_ia64_fake_sections
188 PARAMS ((bfd
*abfd
, Elf_Internal_Shdr
*hdr
, asection
*sec
));
189 static void elfNN_ia64_final_write_processing
190 PARAMS ((bfd
*abfd
, bfd_boolean linker
));
191 static bfd_boolean elfNN_ia64_add_symbol_hook
192 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
193 const char **namep
, flagword
*flagsp
, asection
**secp
,
195 static bfd_boolean elfNN_ia64_aix_vec
196 PARAMS ((const bfd_target
*vec
));
197 static bfd_boolean elfNN_ia64_aix_add_symbol_hook
198 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
199 const char **namep
, flagword
*flagsp
, asection
**secp
,
201 static bfd_boolean elfNN_ia64_aix_link_add_symbols
202 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
203 static int elfNN_ia64_additional_program_headers
204 PARAMS ((bfd
*abfd
));
205 static bfd_boolean elfNN_ia64_modify_segment_map
207 static bfd_boolean elfNN_ia64_is_local_label_name
208 PARAMS ((bfd
*abfd
, const char *name
));
209 static bfd_boolean elfNN_ia64_dynamic_symbol_p
210 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
));
211 static bfd_boolean elfNN_ia64_local_hash_table_init
212 PARAMS ((struct elfNN_ia64_local_hash_table
*ht
, bfd
*abfd
,
213 new_hash_entry_func
new));
214 static struct bfd_hash_entry
*elfNN_ia64_new_loc_hash_entry
215 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
216 const char *string
));
217 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
218 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
219 const char *string
));
220 static void elfNN_ia64_hash_copy_indirect
221 PARAMS ((struct elf_backend_data
*, struct elf_link_hash_entry
*,
222 struct elf_link_hash_entry
*));
223 static void elfNN_ia64_hash_hide_symbol
224 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*, bfd_boolean
));
225 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
226 PARAMS ((bfd
*abfd
));
227 static struct elfNN_ia64_local_hash_entry
*elfNN_ia64_local_hash_lookup
228 PARAMS ((struct elfNN_ia64_local_hash_table
*table
, const char *string
,
229 bfd_boolean create
, bfd_boolean copy
));
230 static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
231 PARAMS ((struct bfd_hash_entry
*, PTR
));
232 static bfd_boolean elfNN_ia64_local_dyn_sym_thunk
233 PARAMS ((struct bfd_hash_entry
*, PTR
));
234 static void elfNN_ia64_dyn_sym_traverse
235 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
236 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
238 static bfd_boolean elfNN_ia64_create_dynamic_sections
239 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
240 static struct elfNN_ia64_local_hash_entry
* get_local_sym_hash
241 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
242 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
));
243 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
244 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
245 struct elf_link_hash_entry
*h
,
246 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
));
247 static asection
*get_got
248 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
249 struct elfNN_ia64_link_hash_table
*ia64_info
));
250 static asection
*get_fptr
251 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
252 struct elfNN_ia64_link_hash_table
*ia64_info
));
253 static asection
*get_pltoff
254 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
255 struct elfNN_ia64_link_hash_table
*ia64_info
));
256 static asection
*get_reloc_section
257 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
258 asection
*sec
, bfd_boolean create
));
259 static bfd_boolean count_dyn_reloc
260 PARAMS ((bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
261 asection
*srel
, int type
));
262 static bfd_boolean elfNN_ia64_check_relocs
263 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
264 const Elf_Internal_Rela
*relocs
));
265 static bfd_boolean elfNN_ia64_adjust_dynamic_symbol
266 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
267 static long global_sym_index
268 PARAMS ((struct elf_link_hash_entry
*h
));
269 static bfd_boolean allocate_fptr
270 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
271 static bfd_boolean allocate_global_data_got
272 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
273 static bfd_boolean allocate_global_fptr_got
274 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
275 static bfd_boolean allocate_local_got
276 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
277 static bfd_boolean allocate_pltoff_entries
278 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
279 static bfd_boolean allocate_plt_entries
280 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
281 static bfd_boolean allocate_plt2_entries
282 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
283 static bfd_boolean allocate_dynrel_entries
284 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
285 static bfd_boolean elfNN_ia64_size_dynamic_sections
286 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
287 static bfd_reloc_status_type elfNN_ia64_install_value
288 PARAMS ((bfd
*abfd
, bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
289 static void elfNN_ia64_install_dyn_reloc
290 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
291 asection
*srel
, bfd_vma offset
, unsigned int type
,
292 long dynindx
, bfd_vma addend
));
293 static bfd_vma set_got_entry
294 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
295 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
296 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
297 static bfd_vma set_fptr_entry
298 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
299 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
301 static bfd_vma set_pltoff_entry
302 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
303 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
304 bfd_vma value
, bfd_boolean
));
305 static bfd_vma elfNN_ia64_tprel_base
306 PARAMS ((struct bfd_link_info
*info
));
307 static bfd_vma elfNN_ia64_dtprel_base
308 PARAMS ((struct bfd_link_info
*info
));
309 static int elfNN_ia64_unwind_entry_compare
310 PARAMS ((const PTR
, const PTR
));
311 static bfd_boolean elfNN_ia64_choose_gp
312 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
313 static bfd_boolean elfNN_ia64_final_link
314 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
315 static bfd_boolean elfNN_ia64_relocate_section
316 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
317 asection
*input_section
, bfd_byte
*contents
,
318 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
319 asection
**local_sections
));
320 static bfd_boolean elfNN_ia64_finish_dynamic_symbol
321 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
322 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
323 static bfd_boolean elfNN_ia64_finish_dynamic_sections
324 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
325 static bfd_boolean elfNN_ia64_set_private_flags
326 PARAMS ((bfd
*abfd
, flagword flags
));
327 static bfd_boolean elfNN_ia64_merge_private_bfd_data
328 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
329 static bfd_boolean elfNN_ia64_print_private_bfd_data
330 PARAMS ((bfd
*abfd
, PTR ptr
));
331 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
332 PARAMS ((const Elf_Internal_Rela
*));
333 static bfd_boolean elfNN_ia64_hpux_vec
334 PARAMS ((const bfd_target
*vec
));
335 static void elfNN_hpux_post_process_headers
336 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
337 bfd_boolean elfNN_hpux_backend_section_from_bfd_section
338 PARAMS ((bfd
*abfd
, asection
*sec
, int *retval
));
340 /* ia64-specific relocation. */
342 /* Perform a relocation. Not much to do here as all the hard work is
343 done in elfNN_ia64_final_link_relocate. */
344 static bfd_reloc_status_type
345 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
346 output_bfd
, error_message
)
347 bfd
*abfd ATTRIBUTE_UNUSED
;
349 asymbol
*sym ATTRIBUTE_UNUSED
;
350 PTR data ATTRIBUTE_UNUSED
;
351 asection
*input_section
;
353 char **error_message
;
357 reloc
->address
+= input_section
->output_offset
;
361 if (input_section
->flags
& SEC_DEBUGGING
)
362 return bfd_reloc_continue
;
364 *error_message
= "Unsupported call to elfNN_ia64_reloc";
365 return bfd_reloc_notsupported
;
368 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
369 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
370 elfNN_ia64_reloc, NAME, FALSE, 0, 0, IN)
372 /* This table has to be sorted according to increasing number of the
374 static reloc_howto_type ia64_howto_table
[] =
376 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, FALSE
, TRUE
),
378 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, FALSE
, TRUE
),
379 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, FALSE
, TRUE
),
380 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, FALSE
, TRUE
),
381 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, FALSE
, TRUE
),
382 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, FALSE
, TRUE
),
383 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, FALSE
, TRUE
),
384 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, FALSE
, TRUE
),
386 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, FALSE
, TRUE
),
387 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, FALSE
, TRUE
),
388 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, FALSE
, TRUE
),
389 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, FALSE
, TRUE
),
390 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, FALSE
, TRUE
),
391 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, FALSE
, TRUE
),
393 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, FALSE
, TRUE
),
394 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, FALSE
, TRUE
),
396 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, FALSE
, TRUE
),
397 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, FALSE
, TRUE
),
398 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, FALSE
, TRUE
),
399 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, FALSE
, TRUE
),
401 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, FALSE
, TRUE
),
402 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, FALSE
, TRUE
),
403 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, FALSE
, TRUE
),
404 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, FALSE
, TRUE
),
405 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, FALSE
, TRUE
),
407 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, TRUE
, TRUE
),
408 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, TRUE
, TRUE
),
409 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, TRUE
, TRUE
),
410 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, TRUE
, TRUE
),
411 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, TRUE
, TRUE
),
412 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, TRUE
, TRUE
),
413 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, TRUE
, TRUE
),
414 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, TRUE
, TRUE
),
416 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, FALSE
, TRUE
),
417 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, FALSE
, TRUE
),
418 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, FALSE
, TRUE
),
419 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, FALSE
, TRUE
),
420 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, FALSE
, TRUE
),
421 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, FALSE
, TRUE
),
423 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, FALSE
, TRUE
),
424 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, FALSE
, TRUE
),
425 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, FALSE
, TRUE
),
426 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, FALSE
, TRUE
),
428 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, FALSE
, TRUE
),
429 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, FALSE
, TRUE
),
430 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, FALSE
, TRUE
),
431 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, FALSE
, TRUE
),
433 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, FALSE
, TRUE
),
434 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, FALSE
, TRUE
),
435 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, FALSE
, TRUE
),
436 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, FALSE
, TRUE
),
438 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, FALSE
, TRUE
),
439 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, FALSE
, TRUE
),
440 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, FALSE
, TRUE
),
441 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, FALSE
, TRUE
),
443 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, TRUE
, TRUE
),
444 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, TRUE
, TRUE
),
445 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, TRUE
, TRUE
),
447 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, FALSE
, TRUE
),
448 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, FALSE
, TRUE
),
449 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, FALSE
, TRUE
),
450 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, FALSE
, TRUE
),
451 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, FALSE
, TRUE
),
453 IA64_HOWTO (R_IA64_TPREL14
, "TPREL14", 0, FALSE
, FALSE
),
454 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, FALSE
, FALSE
),
455 IA64_HOWTO (R_IA64_TPREL64I
, "TPREL64I", 0, FALSE
, FALSE
),
456 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, FALSE
, FALSE
),
457 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, FALSE
, FALSE
),
458 IA64_HOWTO (R_IA64_LTOFF_TPREL22
, "LTOFF_TPREL22", 0, FALSE
, FALSE
),
460 IA64_HOWTO (R_IA64_DTPMOD64MSB
, "TPREL64MSB", 8, FALSE
, FALSE
),
461 IA64_HOWTO (R_IA64_DTPMOD64LSB
, "TPREL64LSB", 8, FALSE
, FALSE
),
462 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22
, "LTOFF_DTPMOD22", 0, FALSE
, FALSE
),
464 IA64_HOWTO (R_IA64_DTPREL14
, "DTPREL14", 0, FALSE
, FALSE
),
465 IA64_HOWTO (R_IA64_DTPREL22
, "DTPREL22", 0, FALSE
, FALSE
),
466 IA64_HOWTO (R_IA64_DTPREL64I
, "DTPREL64I", 0, FALSE
, FALSE
),
467 IA64_HOWTO (R_IA64_DTPREL32MSB
, "DTPREL32MSB", 4, FALSE
, FALSE
),
468 IA64_HOWTO (R_IA64_DTPREL32LSB
, "DTPREL32LSB", 4, FALSE
, FALSE
),
469 IA64_HOWTO (R_IA64_DTPREL64MSB
, "DTPREL64MSB", 8, FALSE
, FALSE
),
470 IA64_HOWTO (R_IA64_DTPREL64LSB
, "DTPREL64LSB", 8, FALSE
, FALSE
),
471 IA64_HOWTO (R_IA64_LTOFF_DTPREL22
, "LTOFF_DTPREL22", 0, FALSE
, FALSE
),
474 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
476 /* Given a BFD reloc type, return the matching HOWTO structure. */
478 static reloc_howto_type
*
482 static int inited
= 0;
489 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
490 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
491 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
494 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
495 i
= elf_code_to_howto_index
[rtype
];
496 if (i
>= NELEMS (ia64_howto_table
))
498 return ia64_howto_table
+ i
;
501 static reloc_howto_type
*
502 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
503 bfd
*abfd ATTRIBUTE_UNUSED
;
504 bfd_reloc_code_real_type bfd_code
;
510 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
512 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
513 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
514 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
516 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
517 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
518 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
519 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
521 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
522 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
523 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
524 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
525 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
526 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
528 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
529 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
531 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
532 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
533 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
534 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
535 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
536 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
537 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
538 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
539 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
541 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
542 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
543 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
544 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
545 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
546 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
547 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
548 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
549 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
550 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
551 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
553 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
554 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
555 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
556 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
557 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
558 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
560 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
561 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
562 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
563 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
565 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
566 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
567 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
568 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
570 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
571 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
572 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
573 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
575 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
576 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
577 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
578 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
580 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
581 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
582 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
583 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
584 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
586 case BFD_RELOC_IA64_TPREL14
: rtype
= R_IA64_TPREL14
; break;
587 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
588 case BFD_RELOC_IA64_TPREL64I
: rtype
= R_IA64_TPREL64I
; break;
589 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
590 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
591 case BFD_RELOC_IA64_LTOFF_TPREL22
: rtype
= R_IA64_LTOFF_TPREL22
; break;
593 case BFD_RELOC_IA64_DTPMOD64MSB
: rtype
= R_IA64_DTPMOD64MSB
; break;
594 case BFD_RELOC_IA64_DTPMOD64LSB
: rtype
= R_IA64_DTPMOD64LSB
; break;
595 case BFD_RELOC_IA64_LTOFF_DTPMOD22
: rtype
= R_IA64_LTOFF_DTPMOD22
; break;
597 case BFD_RELOC_IA64_DTPREL14
: rtype
= R_IA64_DTPREL14
; break;
598 case BFD_RELOC_IA64_DTPREL22
: rtype
= R_IA64_DTPREL22
; break;
599 case BFD_RELOC_IA64_DTPREL64I
: rtype
= R_IA64_DTPREL64I
; break;
600 case BFD_RELOC_IA64_DTPREL32MSB
: rtype
= R_IA64_DTPREL32MSB
; break;
601 case BFD_RELOC_IA64_DTPREL32LSB
: rtype
= R_IA64_DTPREL32LSB
; break;
602 case BFD_RELOC_IA64_DTPREL64MSB
: rtype
= R_IA64_DTPREL64MSB
; break;
603 case BFD_RELOC_IA64_DTPREL64LSB
: rtype
= R_IA64_DTPREL64LSB
; break;
604 case BFD_RELOC_IA64_LTOFF_DTPREL22
: rtype
= R_IA64_LTOFF_DTPREL22
; break;
608 return lookup_howto (rtype
);
611 /* Given a ELF reloc, return the matching HOWTO structure. */
614 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
615 bfd
*abfd ATTRIBUTE_UNUSED
;
617 Elf_Internal_Rela
*elf_reloc
;
620 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
623 #define PLT_HEADER_SIZE (3 * 16)
624 #define PLT_MIN_ENTRY_SIZE (1 * 16)
625 #define PLT_FULL_ENTRY_SIZE (2 * 16)
626 #define PLT_RESERVED_WORDS 3
628 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
630 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
631 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
632 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
633 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
634 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
635 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
636 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
637 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
638 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
641 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
643 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
644 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
645 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
648 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
650 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
651 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
652 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
653 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
654 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
655 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
658 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
659 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
660 #define DYNAMIC_INTERPRETER(abfd) \
661 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
663 static const bfd_byte oor_brl
[16] =
665 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
667 0x00, 0x00, 0x00, 0xc0
670 /* These functions do relaxation for IA-64 ELF. */
673 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
676 struct bfd_link_info
*link_info
;
681 struct one_fixup
*next
;
687 Elf_Internal_Shdr
*symtab_hdr
;
688 Elf_Internal_Rela
*internal_relocs
;
689 Elf_Internal_Rela
*irel
, *irelend
;
691 Elf_Internal_Sym
*isymbuf
= NULL
;
692 struct elfNN_ia64_link_hash_table
*ia64_info
;
693 struct one_fixup
*fixups
= NULL
;
694 bfd_boolean changed_contents
= FALSE
;
695 bfd_boolean changed_relocs
= FALSE
;
696 bfd_boolean changed_got
= FALSE
;
699 /* Assume we're not going to change any sizes, and we'll only need
703 /* Don't even try to relax for non-ELF outputs. */
704 if (link_info
->hash
->creator
->flavour
!= bfd_target_elf_flavour
)
707 /* Nothing to do if there are no relocations. */
708 if ((sec
->flags
& SEC_RELOC
) == 0
709 || sec
->reloc_count
== 0)
712 /* If this is the first time we have been called for this section,
713 initialize the cooked size. */
714 if (sec
->_cooked_size
== 0)
715 sec
->_cooked_size
= sec
->_raw_size
;
717 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
719 /* Load the relocations for this section. */
720 internal_relocs
= (_bfd_elfNN_link_read_relocs
721 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
722 link_info
->keep_memory
));
723 if (internal_relocs
== NULL
)
726 ia64_info
= elfNN_ia64_hash_table (link_info
);
727 irelend
= internal_relocs
+ sec
->reloc_count
;
729 /* Get the section contents. */
730 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
731 contents
= elf_section_data (sec
)->this_hdr
.contents
;
734 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
735 if (contents
== NULL
)
738 if (! bfd_get_section_contents (abfd
, sec
, contents
,
739 (file_ptr
) 0, sec
->_raw_size
))
743 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
745 unsigned long r_type
= ELFNN_R_TYPE (irel
->r_info
);
746 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
750 bfd_boolean is_branch
;
751 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
755 case R_IA64_PCREL21B
:
756 case R_IA64_PCREL21BI
:
757 case R_IA64_PCREL21M
:
758 case R_IA64_PCREL21F
:
762 case R_IA64_LTOFF22X
:
771 /* Get the value of the symbol referred to by the reloc. */
772 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
774 /* A local symbol. */
775 Elf_Internal_Sym
*isym
;
777 /* Read this BFD's local symbols. */
780 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
782 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
783 symtab_hdr
->sh_info
, 0,
789 isym
= isymbuf
+ ELF64_R_SYM (irel
->r_info
);
790 if (isym
->st_shndx
== SHN_UNDEF
)
791 continue; /* We can't do anthing with undefined symbols. */
792 else if (isym
->st_shndx
== SHN_ABS
)
793 tsec
= bfd_abs_section_ptr
;
794 else if (isym
->st_shndx
== SHN_COMMON
)
795 tsec
= bfd_com_section_ptr
;
796 else if (isym
->st_shndx
== SHN_IA_64_ANSI_COMMON
)
797 tsec
= bfd_com_section_ptr
;
799 tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
801 toff
= isym
->st_value
;
802 dyn_i
= get_dyn_sym_info (ia64_info
, NULL
, abfd
, irel
, FALSE
);
807 struct elf_link_hash_entry
*h
;
809 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
810 h
= elf_sym_hashes (abfd
)[indx
];
811 BFD_ASSERT (h
!= NULL
);
813 while (h
->root
.type
== bfd_link_hash_indirect
814 || h
->root
.type
== bfd_link_hash_warning
)
815 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
817 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, FALSE
);
819 /* For branches to dynamic symbols, we're interested instead
820 in a branch to the PLT entry. */
821 if (is_branch
&& dyn_i
&& dyn_i
->want_plt2
)
823 /* Internal branches shouldn't be sent to the PLT.
824 Leave this for now and we'll give an error later. */
825 if (r_type
!= R_IA64_PCREL21B
)
828 tsec
= ia64_info
->plt_sec
;
829 toff
= dyn_i
->plt2_offset
;
830 BFD_ASSERT (irel
->r_addend
== 0);
833 /* Can't do anything else with dynamic symbols. */
834 else if (elfNN_ia64_dynamic_symbol_p (h
, link_info
))
839 /* We can't do anthing with undefined symbols. */
840 if (h
->root
.type
== bfd_link_hash_undefined
841 || h
->root
.type
== bfd_link_hash_undefweak
)
844 tsec
= h
->root
.u
.def
.section
;
845 toff
= h
->root
.u
.def
.value
;
849 if (tsec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
850 toff
= _bfd_merged_section_offset (abfd
, &tsec
,
851 elf_section_data (tsec
)->sec_info
,
852 toff
+ irel
->r_addend
,
855 toff
+= irel
->r_addend
;
857 symaddr
= tsec
->output_section
->vma
+ tsec
->output_offset
+ toff
;
859 roff
= irel
->r_offset
;
863 reladdr
= (sec
->output_section
->vma
865 + roff
) & (bfd_vma
) -4;
867 /* If the branch is in range, no need to do anything. */
868 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
869 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
872 /* If the branch and target are in the same section, you've
873 got one honking big section and we can't help you. You'll
874 get an error message later. */
878 /* Look for an existing fixup to this address. */
879 for (f
= fixups
; f
; f
= f
->next
)
880 if (f
->tsec
== tsec
&& f
->toff
== toff
)
885 /* Two alternatives: If it's a branch to a PLT entry, we can
886 make a copy of the FULL_PLT entry. Otherwise, we'll have
887 to use a `brl' insn to get where we're going. */
891 if (tsec
== ia64_info
->plt_sec
)
892 size
= sizeof (plt_full_entry
);
895 size
= sizeof (oor_brl
);
898 /* Resize the current section to make room for the new branch. */
899 trampoff
= (sec
->_cooked_size
+ 15) & (bfd_vma
) -16;
900 amt
= trampoff
+ size
;
901 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
902 if (contents
== NULL
)
904 sec
->_cooked_size
= amt
;
906 if (tsec
== ia64_info
->plt_sec
)
908 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
910 /* Hijack the old relocation for use as the PLTOFF reloc. */
911 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
913 irel
->r_offset
= trampoff
;
917 memcpy (contents
+ trampoff
, oor_brl
, size
);
918 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
920 irel
->r_offset
= trampoff
+ 2;
923 /* Record the fixup so we don't do it again this section. */
924 f
= (struct one_fixup
*)
925 bfd_malloc ((bfd_size_type
) sizeof (*f
));
929 f
->trampoff
= trampoff
;
934 /* Nop out the reloc, since we're finalizing things here. */
935 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
938 /* Fix up the existing branch to hit the trampoline. Hope like
939 hell this doesn't overflow too. */
940 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
941 f
->trampoff
- (roff
& (bfd_vma
) -4),
942 r_type
) != bfd_reloc_ok
)
945 changed_contents
= TRUE
;
946 changed_relocs
= TRUE
;
953 bfd
*obfd
= sec
->output_section
->owner
;
954 gp
= _bfd_get_gp_value (obfd
);
957 if (!elfNN_ia64_choose_gp (obfd
, link_info
))
959 gp
= _bfd_get_gp_value (obfd
);
963 /* If the data is out of range, do nothing. */
964 if ((bfd_signed_vma
) (symaddr
- gp
) >= 0x200000
965 ||(bfd_signed_vma
) (symaddr
- gp
) < -0x200000)
968 if (r_type
== R_IA64_LTOFF22X
)
970 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
972 changed_relocs
= TRUE
;
973 if (dyn_i
->want_gotx
)
975 dyn_i
->want_gotx
= 0;
976 changed_got
|= !dyn_i
->want_got
;
981 elfNN_ia64_relax_ldxmov (abfd
, contents
, roff
);
982 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
983 changed_contents
= TRUE
;
984 changed_relocs
= TRUE
;
989 /* ??? If we created fixups, this may push the code segment large
990 enough that the data segment moves, which will change the GP.
991 Reset the GP so that we re-calculate next round. We need to
992 do this at the _beginning_ of the next round; now will not do. */
994 /* Clean up and go home. */
997 struct one_fixup
*f
= fixups
;
998 fixups
= fixups
->next
;
1003 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1005 if (! link_info
->keep_memory
)
1009 /* Cache the symbols for elf_link_input_bfd. */
1010 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1014 if (contents
!= NULL
1015 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1017 if (!changed_contents
&& !link_info
->keep_memory
)
1021 /* Cache the section contents for elf_link_input_bfd. */
1022 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1026 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
1028 if (!changed_relocs
)
1029 free (internal_relocs
);
1031 elf_section_data (sec
)->relocs
= internal_relocs
;
1036 struct elfNN_ia64_allocate_data data
;
1037 data
.info
= link_info
;
1039 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
1041 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
1042 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
1043 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
1044 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
1045 ia64_info
->got_sec
->_cooked_size
= data
.ofs
;
1047 /* ??? Resize .rela.got too. */
1050 *again
= changed_contents
|| changed_relocs
;
1054 if (isymbuf
!= NULL
&& (unsigned char *) isymbuf
!= symtab_hdr
->contents
)
1056 if (contents
!= NULL
1057 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1059 if (internal_relocs
!= NULL
1060 && elf_section_data (sec
)->relocs
!= internal_relocs
)
1061 free (internal_relocs
);
1066 elfNN_ia64_relax_ldxmov (abfd
, contents
, off
)
1072 bfd_vma dword
, insn
;
1074 switch ((int)off
& 0x3)
1076 case 0: shift
= 5; break;
1077 case 1: shift
= 14; off
+= 3; break;
1078 case 2: shift
= 23; off
+= 6; break;
1083 dword
= bfd_get_64 (abfd
, contents
+ off
);
1084 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
1086 r1
= (insn
>> 6) & 127;
1087 r3
= (insn
>> 20) & 127;
1089 insn
= 0x8000000; /* nop */
1091 insn
= (insn
& 0x7f01fff) | 0x10800000000LL
; /* (qp) mov r1 = r3 */
1093 dword
&= ~(0x1ffffffffffLL
<< shift
);
1094 dword
|= (insn
<< shift
);
1095 bfd_put_64 (abfd
, dword
, contents
+ off
);
1098 /* Return TRUE if NAME is an unwind table section name. */
1100 static inline bfd_boolean
1101 is_unwind_section_name (abfd
, name
)
1105 size_t len1
, len2
, len3
;
1107 if (elfNN_ia64_hpux_vec (abfd
->xvec
)
1108 && !strcmp (name
, ELF_STRING_ia64_unwind_hdr
))
1111 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1112 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
1113 len3
= sizeof (ELF_STRING_ia64_unwind_once
) - 1;
1114 return ((strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
1115 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0)
1116 || strncmp (name
, ELF_STRING_ia64_unwind_once
, len3
) == 0);
1119 /* Handle an IA-64 specific section when reading an object file. This
1120 is called when elfcode.h finds a section with an unknown type. */
1123 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
1125 Elf_Internal_Shdr
*hdr
;
1130 /* There ought to be a place to keep ELF backend specific flags, but
1131 at the moment there isn't one. We just keep track of the
1132 sections by their name, instead. Fortunately, the ABI gives
1133 suggested names for all the MIPS specific sections, so we will
1134 probably get away with this. */
1135 switch (hdr
->sh_type
)
1137 case SHT_IA_64_UNWIND
:
1138 case SHT_IA_64_HP_OPT_ANOT
:
1142 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1150 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
1152 newsect
= hdr
->bfd_section
;
1157 /* Convert IA-64 specific section flags to bfd internal section flags. */
1159 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1163 elfNN_ia64_section_flags (flags
, hdr
)
1165 Elf_Internal_Shdr
*hdr
;
1167 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1168 *flags
|= SEC_SMALL_DATA
;
1173 /* Set the correct type for an IA-64 ELF section. We do this by the
1174 section name, which is a hack, but ought to work. */
1177 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1178 bfd
*abfd ATTRIBUTE_UNUSED
;
1179 Elf_Internal_Shdr
*hdr
;
1182 register const char *name
;
1184 name
= bfd_get_section_name (abfd
, sec
);
1186 if (is_unwind_section_name (abfd
, name
))
1188 /* We don't have the sections numbered at this point, so sh_info
1189 is set later, in elfNN_ia64_final_write_processing. */
1190 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1191 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1193 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1194 hdr
->sh_type
= SHT_IA_64_EXT
;
1195 else if (strcmp (name
, ".HP.opt_annot") == 0)
1196 hdr
->sh_type
= SHT_IA_64_HP_OPT_ANOT
;
1197 else if (strcmp (name
, ".reloc") == 0)
1198 /* This is an ugly, but unfortunately necessary hack that is
1199 needed when producing EFI binaries on IA-64. It tells
1200 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1201 containing ELF relocation info. We need this hack in order to
1202 be able to generate ELF binaries that can be translated into
1203 EFI applications (which are essentially COFF objects). Those
1204 files contain a COFF ".reloc" section inside an ELFNN object,
1205 which would normally cause BFD to segfault because it would
1206 attempt to interpret this section as containing relocation
1207 entries for section "oc". With this hack enabled, ".reloc"
1208 will be treated as a normal data section, which will avoid the
1209 segfault. However, you won't be able to create an ELFNN binary
1210 with a section named "oc" that needs relocations, but that's
1211 the kind of ugly side-effects you get when detecting section
1212 types based on their names... In practice, this limitation is
1213 unlikely to bite. */
1214 hdr
->sh_type
= SHT_PROGBITS
;
1216 if (sec
->flags
& SEC_SMALL_DATA
)
1217 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1222 /* The final processing done just before writing out an IA-64 ELF
1226 elfNN_ia64_final_write_processing (abfd
, linker
)
1228 bfd_boolean linker ATTRIBUTE_UNUSED
;
1230 Elf_Internal_Shdr
*hdr
;
1232 asection
*text_sect
, *s
;
1235 for (s
= abfd
->sections
; s
; s
= s
->next
)
1237 hdr
= &elf_section_data (s
)->this_hdr
;
1238 switch (hdr
->sh_type
)
1240 case SHT_IA_64_UNWIND
:
1241 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1243 sname
= bfd_get_section_name (abfd
, s
);
1244 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1245 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1249 if (sname
[0] == '\0')
1250 /* .IA_64.unwind -> .text */
1251 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1253 /* .IA_64.unwindFOO -> FOO */
1254 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1257 && (len
= sizeof (ELF_STRING_ia64_unwind_once
) - 1,
1258 strncmp (sname
, ELF_STRING_ia64_unwind_once
, len
)) == 0)
1260 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1261 size_t len2
= sizeof (".gnu.linkonce.t.") - 1;
1262 char *once_name
= bfd_malloc (len2
+ strlen (sname
+ len
) + 1);
1264 if (once_name
!= NULL
)
1266 memcpy (once_name
, ".gnu.linkonce.t.", len2
);
1267 strcpy (once_name
+ len2
, sname
+ len
);
1268 text_sect
= bfd_get_section_by_name (abfd
, once_name
);
1272 /* Should only happen if we run out of memory, in
1273 which case we're probably toast anyway. Try to
1274 cope by finding the section the slow way. */
1275 for (text_sect
= abfd
->sections
;
1277 text_sect
= text_sect
->next
)
1279 if (strncmp (bfd_section_name (abfd
, text_sect
),
1280 ".gnu.linkonce.t.", len2
) == 0
1281 && strcmp (bfd_section_name (abfd
, text_sect
) + len2
,
1287 /* last resort: fall back on .text */
1288 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1292 /* The IA-64 processor-specific ABI requires setting
1293 sh_link to the unwind section, whereas HP-UX requires
1294 sh_info to do so. For maximum compatibility, we'll
1295 set both for now... */
1296 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1297 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1303 if (! elf_flags_init (abfd
))
1305 unsigned long flags
= 0;
1307 if (abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
)
1308 flags
|= EF_IA_64_BE
;
1309 if (bfd_get_mach (abfd
) == bfd_mach_ia64_elf64
)
1310 flags
|= EF_IA_64_ABI64
;
1312 elf_elfheader(abfd
)->e_flags
= flags
;
1313 elf_flags_init (abfd
) = TRUE
;
1317 /* Hook called by the linker routine which adds symbols from an object
1318 file. We use it to put .comm items in .sbss, and not .bss. */
1321 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1323 struct bfd_link_info
*info
;
1324 const Elf_Internal_Sym
*sym
;
1325 const char **namep ATTRIBUTE_UNUSED
;
1326 flagword
*flagsp ATTRIBUTE_UNUSED
;
1330 if (sym
->st_shndx
== SHN_COMMON
1331 && !info
->relocateable
1332 && sym
->st_size
<= elf_gp_size (abfd
))
1334 /* Common symbols less than or equal to -G nn bytes are
1335 automatically put into .sbss. */
1337 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1341 scomm
= bfd_make_section (abfd
, ".scommon");
1343 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1345 | SEC_LINKER_CREATED
)))
1350 *valp
= sym
->st_size
;
1357 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1359 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1360 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1362 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1363 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1366 /* Hook called by the linker routine which adds symbols from an object
1367 file. We use it to handle OS-specific symbols. */
1370 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1372 struct bfd_link_info
*info
;
1373 const Elf_Internal_Sym
*sym
;
1379 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1381 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1382 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1383 no one else should use it b/c it is undocumented. */
1384 struct elf_link_hash_entry
*h
;
1386 h
= elf_link_hash_lookup (elf_hash_table (info
), *namep
,
1387 FALSE
, FALSE
, FALSE
);
1390 struct elf_backend_data
*bed
;
1391 struct elfNN_ia64_link_hash_table
*ia64_info
;
1392 struct bfd_link_hash_entry
*bh
= NULL
;
1394 bed
= get_elf_backend_data (abfd
);
1395 ia64_info
= elfNN_ia64_hash_table (info
);
1397 if (!(_bfd_generic_link_add_one_symbol
1398 (info
, abfd
, *namep
, BSF_GLOBAL
,
1399 bfd_get_section_by_name (abfd
, ".bss"),
1400 bed
->got_symbol_offset
, (const char *) NULL
, FALSE
,
1401 bed
->collect
, &bh
)))
1404 h
= (struct elf_link_hash_entry
*) bh
;
1405 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1406 h
->type
= STT_OBJECT
;
1408 if (! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1414 else if (sym
->st_shndx
== SHN_LOOS
)
1418 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1419 is only relevant when compiling code for extended system calls.
1420 Replace the "special" section with .text, if possible.
1421 Note that these symbols are always assumed to be in .text. */
1422 for (i
= 1; i
< elf_numsections (abfd
); i
++)
1424 asection
* sec
= bfd_section_from_elf_index (abfd
, i
);
1426 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1434 *secp
= bfd_abs_section_ptr
;
1436 *valp
= sym
->st_size
;
1442 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1443 namep
, flagsp
, secp
, valp
);
1448 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1450 struct bfd_link_info
*info
;
1452 /* Make sure dynamic sections are always created. */
1453 if (! elf_hash_table (info
)->dynamic_sections_created
1454 && abfd
->xvec
== info
->hash
->creator
)
1456 if (! bfd_elfNN_link_create_dynamic_sections (abfd
, info
))
1460 /* Now do the standard call. */
1461 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1464 /* Return the number of additional phdrs we will need. */
1467 elfNN_ia64_additional_program_headers (abfd
)
1473 /* See if we need a PT_IA_64_ARCHEXT segment. */
1474 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1475 if (s
&& (s
->flags
& SEC_LOAD
))
1478 /* Count how many PT_IA_64_UNWIND segments we need. */
1479 for (s
= abfd
->sections
; s
; s
= s
->next
)
1480 if (is_unwind_section_name (abfd
, s
->name
) && (s
->flags
& SEC_LOAD
))
1487 elfNN_ia64_modify_segment_map (abfd
)
1490 struct elf_segment_map
*m
, **pm
;
1491 Elf_Internal_Shdr
*hdr
;
1494 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1495 all PT_LOAD segments. */
1496 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1497 if (s
&& (s
->flags
& SEC_LOAD
))
1499 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1500 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1504 m
= ((struct elf_segment_map
*)
1505 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1509 m
->p_type
= PT_IA_64_ARCHEXT
;
1513 /* We want to put it after the PHDR and INTERP segments. */
1514 pm
= &elf_tdata (abfd
)->segment_map
;
1516 && ((*pm
)->p_type
== PT_PHDR
1517 || (*pm
)->p_type
== PT_INTERP
))
1525 /* Install PT_IA_64_UNWIND segments, if needed. */
1526 for (s
= abfd
->sections
; s
; s
= s
->next
)
1528 hdr
= &elf_section_data (s
)->this_hdr
;
1529 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1532 if (s
&& (s
->flags
& SEC_LOAD
))
1534 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1535 if (m
->p_type
== PT_IA_64_UNWIND
)
1539 /* Look through all sections in the unwind segment
1540 for a match since there may be multiple sections
1542 for (i
= m
->count
- 1; i
>= 0; --i
)
1543 if (m
->sections
[i
] == s
)
1552 m
= ((struct elf_segment_map
*)
1553 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1557 m
->p_type
= PT_IA_64_UNWIND
;
1562 /* We want to put it last. */
1563 pm
= &elf_tdata (abfd
)->segment_map
;
1571 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1572 the input sections for each output section in the segment and testing
1573 for SHF_IA_64_NORECOV on each. */
1574 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1575 if (m
->p_type
== PT_LOAD
)
1578 for (i
= m
->count
- 1; i
>= 0; --i
)
1580 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1583 if (order
->type
== bfd_indirect_link_order
)
1585 asection
*is
= order
->u
.indirect
.section
;
1586 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1587 if (flags
& SHF_IA_64_NORECOV
)
1589 m
->p_flags
|= PF_IA_64_NORECOV
;
1593 order
= order
->next
;
1602 /* According to the Tahoe assembler spec, all labels starting with a
1606 elfNN_ia64_is_local_label_name (abfd
, name
)
1607 bfd
*abfd ATTRIBUTE_UNUSED
;
1610 return name
[0] == '.';
1613 /* Should we do dynamic things to this symbol? */
1616 elfNN_ia64_dynamic_symbol_p (h
, info
)
1617 struct elf_link_hash_entry
*h
;
1618 struct bfd_link_info
*info
;
1623 while (h
->root
.type
== bfd_link_hash_indirect
1624 || h
->root
.type
== bfd_link_hash_warning
)
1625 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1627 if (h
->dynindx
== -1)
1629 switch (ELF_ST_VISIBILITY (h
->other
))
1638 if (h
->root
.type
== bfd_link_hash_undefweak
1639 || h
->root
.type
== bfd_link_hash_defweak
)
1642 if ((info
->shared
&& (!info
->symbolic
|| info
->allow_shlib_undefined
))
1643 || ((h
->elf_link_hash_flags
1644 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1645 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1652 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1653 struct elfNN_ia64_local_hash_table
*ht
;
1654 bfd
*abfd ATTRIBUTE_UNUSED
;
1655 new_hash_entry_func
new;
1657 memset (ht
, 0, sizeof (*ht
));
1658 return bfd_hash_table_init (&ht
->root
, new);
1661 static struct bfd_hash_entry
*
1662 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1663 struct bfd_hash_entry
*entry
;
1664 struct bfd_hash_table
*table
;
1667 struct elfNN_ia64_local_hash_entry
*ret
;
1668 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1670 /* Allocate the structure if it has not already been allocated by a
1673 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1678 /* Initialize our local data. All zeros, and definitely easier
1679 than setting a handful of bit fields. */
1680 memset (ret
, 0, sizeof (*ret
));
1682 /* Call the allocation method of the superclass. */
1683 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1684 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1686 return (struct bfd_hash_entry
*) ret
;
1689 static struct bfd_hash_entry
*
1690 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1691 struct bfd_hash_entry
*entry
;
1692 struct bfd_hash_table
*table
;
1695 struct elfNN_ia64_link_hash_entry
*ret
;
1696 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1698 /* Allocate the structure if it has not already been allocated by a
1701 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1706 /* Initialize our local data. All zeros, and definitely easier
1707 than setting a handful of bit fields. */
1708 memset (ret
, 0, sizeof (*ret
));
1710 /* Call the allocation method of the superclass. */
1711 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1712 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1715 return (struct bfd_hash_entry
*) ret
;
1719 elfNN_ia64_hash_copy_indirect (bed
, xdir
, xind
)
1720 struct elf_backend_data
*bed ATTRIBUTE_UNUSED
;
1721 struct elf_link_hash_entry
*xdir
, *xind
;
1723 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1725 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1726 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1728 /* Copy down any references that we may have already seen to the
1729 symbol which just became indirect. */
1731 dir
->root
.elf_link_hash_flags
|=
1732 (ind
->root
.elf_link_hash_flags
1733 & (ELF_LINK_HASH_REF_DYNAMIC
1734 | ELF_LINK_HASH_REF_REGULAR
1735 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1737 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1740 /* Copy over the got and plt data. This would have been done
1743 if (dir
->info
== NULL
)
1745 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1747 dir
->info
= dyn_i
= ind
->info
;
1750 /* Fix up the dyn_sym_info pointers to the global symbol. */
1751 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1752 dyn_i
->h
= &dir
->root
;
1754 BFD_ASSERT (ind
->info
== NULL
);
1756 /* Copy over the dynindx. */
1758 if (dir
->root
.dynindx
== -1)
1760 dir
->root
.dynindx
= ind
->root
.dynindx
;
1761 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1762 ind
->root
.dynindx
= -1;
1763 ind
->root
.dynstr_index
= 0;
1765 BFD_ASSERT (ind
->root
.dynindx
== -1);
1769 elfNN_ia64_hash_hide_symbol (info
, xh
, force_local
)
1770 struct bfd_link_info
*info
;
1771 struct elf_link_hash_entry
*xh
;
1772 bfd_boolean force_local
;
1774 struct elfNN_ia64_link_hash_entry
*h
;
1775 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1777 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1779 _bfd_elf_link_hash_hide_symbol (info
, &h
->root
, force_local
);
1781 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1782 dyn_i
->want_plt2
= 0;
1785 /* Create the derived linker hash table. The IA-64 ELF port uses this
1786 derived hash table to keep information specific to the IA-64 ElF
1787 linker (without using static variables). */
1789 static struct bfd_link_hash_table
*
1790 elfNN_ia64_hash_table_create (abfd
)
1793 struct elfNN_ia64_link_hash_table
*ret
;
1795 ret
= bfd_zmalloc ((bfd_size_type
) sizeof (*ret
));
1799 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1800 elfNN_ia64_new_elf_hash_entry
))
1806 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1807 elfNN_ia64_new_loc_hash_entry
))
1813 return &ret
->root
.root
;
1816 /* Look up an entry in a Alpha ELF linker hash table. */
1818 static INLINE
struct elfNN_ia64_local_hash_entry
*
1819 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1820 struct elfNN_ia64_local_hash_table
*table
;
1822 bfd_boolean create
, copy
;
1824 return ((struct elfNN_ia64_local_hash_entry
*)
1825 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1828 /* Traverse both local and global hash tables. */
1830 struct elfNN_ia64_dyn_sym_traverse_data
1832 bfd_boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1837 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1838 struct bfd_hash_entry
*xentry
;
1841 struct elfNN_ia64_link_hash_entry
*entry
1842 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1843 struct elfNN_ia64_dyn_sym_traverse_data
*data
1844 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1845 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1847 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
1848 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
1850 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1851 if (! (*data
->func
) (dyn_i
, data
->data
))
1857 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1858 struct bfd_hash_entry
*xentry
;
1861 struct elfNN_ia64_local_hash_entry
*entry
1862 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1863 struct elfNN_ia64_dyn_sym_traverse_data
*data
1864 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1865 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1867 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1868 if (! (*data
->func
) (dyn_i
, data
->data
))
1874 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1875 struct elfNN_ia64_link_hash_table
*ia64_info
;
1876 bfd_boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1879 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1884 elf_link_hash_traverse (&ia64_info
->root
,
1885 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1886 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1887 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1891 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1893 struct bfd_link_info
*info
;
1895 struct elfNN_ia64_link_hash_table
*ia64_info
;
1898 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1901 ia64_info
= elfNN_ia64_hash_table (info
);
1903 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1904 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1907 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1908 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1911 if (!get_pltoff (abfd
, info
, ia64_info
))
1914 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1916 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1919 | SEC_LINKER_CREATED
1921 || !bfd_set_section_alignment (abfd
, s
, 3))
1923 ia64_info
->rel_pltoff_sec
= s
;
1925 s
= bfd_make_section(abfd
, ".rela.got");
1927 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1930 | SEC_LINKER_CREATED
1932 || !bfd_set_section_alignment (abfd
, s
, 3))
1934 ia64_info
->rel_got_sec
= s
;
1939 /* Find and/or create a hash entry for local symbol. */
1940 static struct elfNN_ia64_local_hash_entry
*
1941 get_local_sym_hash (ia64_info
, abfd
, rel
, create
)
1942 struct elfNN_ia64_link_hash_table
*ia64_info
;
1944 const Elf_Internal_Rela
*rel
;
1947 struct elfNN_ia64_local_hash_entry
*ret
;
1948 asection
*sec
= abfd
->sections
;
1949 char addr_name
[34];
1951 BFD_ASSERT ((sizeof (sec
->id
)*2 + 1 + sizeof (unsigned long)*2 + 1) <= 34);
1954 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1955 name describes what was once anonymous memory. */
1957 sprintf (addr_name
, "%x:%lx",
1958 sec
->id
, (unsigned long) ELFNN_R_SYM (rel
->r_info
));
1960 /* Collect the canonical entry data for this address. */
1961 ret
= elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1962 addr_name
, create
, create
);
1966 /* Find and/or create a descriptor for dynamic symbol info. This will
1967 vary based on global or local symbol, and the addend to the reloc. */
1969 static struct elfNN_ia64_dyn_sym_info
*
1970 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1971 struct elfNN_ia64_link_hash_table
*ia64_info
;
1972 struct elf_link_hash_entry
*h
;
1974 const Elf_Internal_Rela
*rel
;
1977 struct elfNN_ia64_dyn_sym_info
**pp
;
1978 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1979 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1982 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1985 struct elfNN_ia64_local_hash_entry
*loc_h
;
1987 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
1990 BFD_ASSERT (!create
);
1997 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
2000 if (dyn_i
== NULL
&& create
)
2002 dyn_i
= ((struct elfNN_ia64_dyn_sym_info
*)
2003 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *dyn_i
));
2005 dyn_i
->addend
= addend
;
2012 get_got (abfd
, info
, ia64_info
)
2014 struct bfd_link_info
*info
;
2015 struct elfNN_ia64_link_hash_table
*ia64_info
;
2020 got
= ia64_info
->got_sec
;
2025 dynobj
= ia64_info
->root
.dynobj
;
2027 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2028 if (!_bfd_elf_create_got_section (dynobj
, info
))
2031 got
= bfd_get_section_by_name (dynobj
, ".got");
2033 ia64_info
->got_sec
= got
;
2035 flags
= bfd_get_section_flags (abfd
, got
);
2036 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
2042 /* Create function descriptor section (.opd). This section is called .opd
2043 because it contains "official prodecure descriptors". The "official"
2044 refers to the fact that these descriptors are used when taking the address
2045 of a procedure, thus ensuring a unique address for each procedure. */
2048 get_fptr (abfd
, info
, ia64_info
)
2050 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2051 struct elfNN_ia64_link_hash_table
*ia64_info
;
2056 fptr
= ia64_info
->fptr_sec
;
2059 dynobj
= ia64_info
->root
.dynobj
;
2061 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2063 fptr
= bfd_make_section (dynobj
, ".opd");
2065 || !bfd_set_section_flags (dynobj
, fptr
,
2071 | SEC_LINKER_CREATED
))
2072 || !bfd_set_section_alignment (abfd
, fptr
, 4))
2078 ia64_info
->fptr_sec
= fptr
;
2085 get_pltoff (abfd
, info
, ia64_info
)
2087 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2088 struct elfNN_ia64_link_hash_table
*ia64_info
;
2093 pltoff
= ia64_info
->pltoff_sec
;
2096 dynobj
= ia64_info
->root
.dynobj
;
2098 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2100 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
2102 || !bfd_set_section_flags (dynobj
, pltoff
,
2108 | SEC_LINKER_CREATED
))
2109 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
2115 ia64_info
->pltoff_sec
= pltoff
;
2122 get_reloc_section (abfd
, ia64_info
, sec
, create
)
2124 struct elfNN_ia64_link_hash_table
*ia64_info
;
2128 const char *srel_name
;
2132 srel_name
= (bfd_elf_string_from_elf_section
2133 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
2134 elf_section_data(sec
)->rel_hdr
.sh_name
));
2135 if (srel_name
== NULL
)
2138 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
2139 && strcmp (bfd_get_section_name (abfd
, sec
),
2141 || (strncmp (srel_name
, ".rel", 4) == 0
2142 && strcmp (bfd_get_section_name (abfd
, sec
),
2143 srel_name
+4) == 0));
2145 dynobj
= ia64_info
->root
.dynobj
;
2147 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2149 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
2150 if (srel
== NULL
&& create
)
2152 srel
= bfd_make_section (dynobj
, srel_name
);
2154 || !bfd_set_section_flags (dynobj
, srel
,
2159 | SEC_LINKER_CREATED
2161 || !bfd_set_section_alignment (dynobj
, srel
, 3))
2165 if (sec
->flags
& SEC_READONLY
)
2166 ia64_info
->reltext
= 1;
2172 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
2174 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2178 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2180 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2181 if (rent
->srel
== srel
&& rent
->type
== type
)
2186 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
2187 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
2191 rent
->next
= dyn_i
->reloc_entries
;
2195 dyn_i
->reloc_entries
= rent
;
2203 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
2205 struct bfd_link_info
*info
;
2207 const Elf_Internal_Rela
*relocs
;
2209 struct elfNN_ia64_link_hash_table
*ia64_info
;
2210 const Elf_Internal_Rela
*relend
;
2211 Elf_Internal_Shdr
*symtab_hdr
;
2212 const Elf_Internal_Rela
*rel
;
2213 asection
*got
, *fptr
, *srel
;
2215 if (info
->relocateable
)
2218 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2219 ia64_info
= elfNN_ia64_hash_table (info
);
2221 got
= fptr
= srel
= NULL
;
2223 relend
= relocs
+ sec
->reloc_count
;
2224 for (rel
= relocs
; rel
< relend
; ++rel
)
2234 NEED_LTOFF_FPTR
= 128,
2240 struct elf_link_hash_entry
*h
= NULL
;
2241 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2242 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2244 bfd_boolean maybe_dynamic
;
2245 int dynrel_type
= R_IA64_NONE
;
2247 if (r_symndx
>= symtab_hdr
->sh_info
)
2249 /* We're dealing with a global symbol -- find its hash entry
2250 and mark it as being referenced. */
2251 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2252 h
= elf_sym_hashes (abfd
)[indx
];
2253 while (h
->root
.type
== bfd_link_hash_indirect
2254 || h
->root
.type
== bfd_link_hash_warning
)
2255 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2257 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
2260 /* We can only get preliminary data on whether a symbol is
2261 locally or externally defined, as not all of the input files
2262 have yet been processed. Do something with what we know, as
2263 this may help reduce memory usage and processing time later. */
2264 maybe_dynamic
= FALSE
;
2265 if (h
&& ((info
->shared
2266 && (!info
->symbolic
|| info
->allow_shlib_undefined
))
2267 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
2268 || h
->root
.type
== bfd_link_hash_defweak
2269 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2270 maybe_dynamic
= TRUE
;
2273 switch (ELFNN_R_TYPE (rel
->r_info
))
2275 case R_IA64_TPREL64MSB
:
2276 case R_IA64_TPREL64LSB
:
2277 if (info
->shared
|| maybe_dynamic
)
2278 need_entry
= NEED_DYNREL
;
2279 dynrel_type
= R_IA64_TPREL64LSB
;
2281 info
->flags
|= DF_STATIC_TLS
;
2284 case R_IA64_LTOFF_TPREL22
:
2285 need_entry
= NEED_TPREL
;
2287 info
->flags
|= DF_STATIC_TLS
;
2290 case R_IA64_DTPREL64MSB
:
2291 case R_IA64_DTPREL64LSB
:
2292 if (info
->shared
|| maybe_dynamic
)
2293 need_entry
= NEED_DYNREL
;
2294 dynrel_type
= R_IA64_DTPREL64LSB
;
2297 case R_IA64_LTOFF_DTPREL22
:
2298 need_entry
= NEED_DTPREL
;
2301 case R_IA64_DTPMOD64MSB
:
2302 case R_IA64_DTPMOD64LSB
:
2303 if (info
->shared
|| maybe_dynamic
)
2304 need_entry
= NEED_DYNREL
;
2305 dynrel_type
= R_IA64_DTPMOD64LSB
;
2308 case R_IA64_LTOFF_DTPMOD22
:
2309 need_entry
= NEED_DTPMOD
;
2312 case R_IA64_LTOFF_FPTR22
:
2313 case R_IA64_LTOFF_FPTR64I
:
2314 case R_IA64_LTOFF_FPTR32MSB
:
2315 case R_IA64_LTOFF_FPTR32LSB
:
2316 case R_IA64_LTOFF_FPTR64MSB
:
2317 case R_IA64_LTOFF_FPTR64LSB
:
2318 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2321 case R_IA64_FPTR64I
:
2322 case R_IA64_FPTR32MSB
:
2323 case R_IA64_FPTR32LSB
:
2324 case R_IA64_FPTR64MSB
:
2325 case R_IA64_FPTR64LSB
:
2326 if (info
->shared
|| h
|| elfNN_ia64_aix_vec (abfd
->xvec
))
2327 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2329 need_entry
= NEED_FPTR
;
2330 dynrel_type
= R_IA64_FPTR64LSB
;
2333 case R_IA64_LTOFF22
:
2334 case R_IA64_LTOFF64I
:
2335 need_entry
= NEED_GOT
;
2338 case R_IA64_LTOFF22X
:
2339 need_entry
= NEED_GOTX
;
2342 case R_IA64_PLTOFF22
:
2343 case R_IA64_PLTOFF64I
:
2344 case R_IA64_PLTOFF64MSB
:
2345 case R_IA64_PLTOFF64LSB
:
2346 need_entry
= NEED_PLTOFF
;
2350 need_entry
|= NEED_MIN_PLT
;
2354 (*info
->callbacks
->warning
)
2355 (info
, _("@pltoff reloc against local symbol"), 0,
2356 abfd
, 0, (bfd_vma
) 0);
2360 case R_IA64_PCREL21B
:
2361 case R_IA64_PCREL60B
:
2362 /* Depending on where this symbol is defined, we may or may not
2363 need a full plt entry. Only skip if we know we'll not need
2364 the entry -- static or symbolic, and the symbol definition
2365 has already been seen. */
2366 if (maybe_dynamic
&& rel
->r_addend
== 0)
2367 need_entry
= NEED_FULL_PLT
;
2373 case R_IA64_DIR32MSB
:
2374 case R_IA64_DIR32LSB
:
2375 case R_IA64_DIR64MSB
:
2376 case R_IA64_DIR64LSB
:
2377 /* Shared objects will always need at least a REL relocation. */
2378 if (info
->shared
|| maybe_dynamic
2379 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2380 && (!h
|| strcmp (h
->root
.root
.string
,
2381 "__GLOB_DATA_PTR") != 0)))
2382 need_entry
= NEED_DYNREL
;
2383 dynrel_type
= R_IA64_DIR64LSB
;
2386 case R_IA64_IPLTMSB
:
2387 case R_IA64_IPLTLSB
:
2388 /* Shared objects will always need at least a REL relocation. */
2389 if (info
->shared
|| maybe_dynamic
)
2390 need_entry
= NEED_DYNREL
;
2391 dynrel_type
= R_IA64_IPLTLSB
;
2394 case R_IA64_PCREL22
:
2395 case R_IA64_PCREL64I
:
2396 case R_IA64_PCREL32MSB
:
2397 case R_IA64_PCREL32LSB
:
2398 case R_IA64_PCREL64MSB
:
2399 case R_IA64_PCREL64LSB
:
2401 need_entry
= NEED_DYNREL
;
2402 dynrel_type
= R_IA64_PCREL64LSB
;
2409 if ((need_entry
& NEED_FPTR
) != 0
2412 (*info
->callbacks
->warning
)
2413 (info
, _("non-zero addend in @fptr reloc"), 0,
2414 abfd
, 0, (bfd_vma
) 0);
2417 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, TRUE
);
2419 /* Record whether or not this is a local symbol. */
2422 /* Create what's needed. */
2423 if (need_entry
& (NEED_GOT
| NEED_GOTX
| NEED_TPREL
2424 | NEED_DTPMOD
| NEED_DTPREL
))
2428 got
= get_got (abfd
, info
, ia64_info
);
2432 if (need_entry
& NEED_GOT
)
2433 dyn_i
->want_got
= 1;
2434 if (need_entry
& NEED_GOTX
)
2435 dyn_i
->want_gotx
= 1;
2436 if (need_entry
& NEED_TPREL
)
2437 dyn_i
->want_tprel
= 1;
2438 if (need_entry
& NEED_DTPMOD
)
2439 dyn_i
->want_dtpmod
= 1;
2440 if (need_entry
& NEED_DTPREL
)
2441 dyn_i
->want_dtprel
= 1;
2443 if (need_entry
& NEED_FPTR
)
2447 fptr
= get_fptr (abfd
, info
, ia64_info
);
2452 /* FPTRs for shared libraries are allocated by the dynamic
2453 linker. Make sure this local symbol will appear in the
2454 dynamic symbol table. */
2455 if (!h
&& (info
->shared
2456 /* AIX also needs one */
2457 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2459 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2460 (info
, abfd
, (long) r_symndx
)))
2464 dyn_i
->want_fptr
= 1;
2466 if (need_entry
& NEED_LTOFF_FPTR
)
2467 dyn_i
->want_ltoff_fptr
= 1;
2468 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2470 if (!ia64_info
->root
.dynobj
)
2471 ia64_info
->root
.dynobj
= abfd
;
2472 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2473 dyn_i
->want_plt
= 1;
2475 if (need_entry
& NEED_FULL_PLT
)
2476 dyn_i
->want_plt2
= 1;
2477 if (need_entry
& NEED_PLTOFF
)
2478 dyn_i
->want_pltoff
= 1;
2479 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2483 srel
= get_reloc_section (abfd
, ia64_info
, sec
, TRUE
);
2487 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2495 /* For cleanliness, and potentially faster dynamic loading, allocate
2496 external GOT entries first. */
2499 allocate_global_data_got (dyn_i
, data
)
2500 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2503 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2505 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
2506 && ! dyn_i
->want_fptr
2507 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2508 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2509 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2510 "__GLOB_DATA_PTR") != 0))))
2512 dyn_i
->got_offset
= x
->ofs
;
2515 if (dyn_i
->want_tprel
)
2517 dyn_i
->tprel_offset
= x
->ofs
;
2520 if (dyn_i
->want_dtpmod
)
2522 if (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
))
2524 dyn_i
->dtpmod_offset
= x
->ofs
;
2529 struct elfNN_ia64_link_hash_table
*ia64_info
;
2531 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2532 if (ia64_info
->self_dtpmod_offset
== (bfd_vma
) -1)
2534 ia64_info
->self_dtpmod_offset
= x
->ofs
;
2537 dyn_i
->dtpmod_offset
= ia64_info
->self_dtpmod_offset
;
2540 if (dyn_i
->want_dtprel
)
2542 dyn_i
->dtprel_offset
= x
->ofs
;
2548 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2551 allocate_global_fptr_got (dyn_i
, data
)
2552 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2555 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2559 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2560 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2562 dyn_i
->got_offset
= x
->ofs
;
2568 /* Lastly, allocate all the GOT entries for local data. */
2571 allocate_local_got (dyn_i
, data
)
2572 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2575 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2577 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
2578 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2579 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2581 dyn_i
->got_offset
= x
->ofs
;
2587 /* Search for the index of a global symbol in it's defining object file. */
2590 global_sym_index (h
)
2591 struct elf_link_hash_entry
*h
;
2593 struct elf_link_hash_entry
**p
;
2596 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2597 || h
->root
.type
== bfd_link_hash_defweak
);
2599 obj
= h
->root
.u
.def
.section
->owner
;
2600 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2603 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2606 /* Allocate function descriptors. We can do these for every function
2607 in a main executable that is not exported. */
2610 allocate_fptr (dyn_i
, data
)
2611 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2614 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2616 if (dyn_i
->want_fptr
)
2618 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2621 while (h
->root
.type
== bfd_link_hash_indirect
2622 || h
->root
.type
== bfd_link_hash_warning
)
2623 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2626 /* AIX needs an FPTR in this case. */
2627 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2629 || h
->root
.type
== bfd_link_hash_defined
2630 || h
->root
.type
== bfd_link_hash_defweak
)))
2632 if (h
&& h
->dynindx
== -1)
2634 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2635 || (h
->root
.type
== bfd_link_hash_defweak
));
2637 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2638 (x
->info
, h
->root
.u
.def
.section
->owner
,
2639 global_sym_index (h
)))
2643 dyn_i
->want_fptr
= 0;
2645 else if (h
== NULL
|| h
->dynindx
== -1)
2647 dyn_i
->fptr_offset
= x
->ofs
;
2651 dyn_i
->want_fptr
= 0;
2656 /* Allocate all the minimal PLT entries. */
2659 allocate_plt_entries (dyn_i
, data
)
2660 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2663 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2665 if (dyn_i
->want_plt
)
2667 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2670 while (h
->root
.type
== bfd_link_hash_indirect
2671 || h
->root
.type
== bfd_link_hash_warning
)
2672 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2674 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2675 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2677 bfd_size_type offset
= x
->ofs
;
2679 offset
= PLT_HEADER_SIZE
;
2680 dyn_i
->plt_offset
= offset
;
2681 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2683 dyn_i
->want_pltoff
= 1;
2687 dyn_i
->want_plt
= 0;
2688 dyn_i
->want_plt2
= 0;
2694 /* Allocate all the full PLT entries. */
2697 allocate_plt2_entries (dyn_i
, data
)
2698 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2701 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2703 if (dyn_i
->want_plt2
)
2705 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2706 bfd_size_type ofs
= x
->ofs
;
2708 dyn_i
->plt2_offset
= ofs
;
2709 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2711 while (h
->root
.type
== bfd_link_hash_indirect
2712 || h
->root
.type
== bfd_link_hash_warning
)
2713 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2714 dyn_i
->h
->plt
.offset
= ofs
;
2719 /* Allocate all the PLTOFF entries requested by relocations and
2720 plt entries. We can't share space with allocated FPTR entries,
2721 because the latter are not necessarily addressable by the GP.
2722 ??? Relaxation might be able to determine that they are. */
2725 allocate_pltoff_entries (dyn_i
, data
)
2726 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2729 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2731 if (dyn_i
->want_pltoff
)
2733 dyn_i
->pltoff_offset
= x
->ofs
;
2739 /* Allocate dynamic relocations for those symbols that turned out
2743 allocate_dynrel_entries (dyn_i
, data
)
2744 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2747 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2748 struct elfNN_ia64_link_hash_table
*ia64_info
;
2749 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2750 bfd_boolean dynamic_symbol
, shared
;
2752 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2753 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2754 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2755 /* Don't allocate an entry for __GLOB_DATA_PTR */
2756 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2757 "__GLOB_DATA_PTR") != 0));
2758 shared
= x
->info
->shared
;
2760 /* Take care of the normal data relocations. */
2762 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2764 int count
= rent
->count
;
2768 case R_IA64_FPTR64LSB
:
2769 /* Allocate one iff !want_fptr, which by this point will
2770 be true only if we're actually allocating one statically
2771 in the main executable. */
2772 if (dyn_i
->want_fptr
)
2775 case R_IA64_PCREL64LSB
:
2776 if (!dynamic_symbol
)
2779 case R_IA64_DIR64LSB
:
2780 if (!dynamic_symbol
&& !shared
)
2783 case R_IA64_IPLTLSB
:
2784 if (!dynamic_symbol
&& !shared
)
2786 /* Use two REL relocations for IPLT relocations
2787 against local symbols. */
2788 if (!dynamic_symbol
)
2791 case R_IA64_TPREL64LSB
:
2792 case R_IA64_DTPREL64LSB
:
2793 case R_IA64_DTPMOD64LSB
:
2798 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2801 /* Take care of the GOT and PLT relocations. */
2803 if (((dynamic_symbol
|| shared
) && (dyn_i
->want_got
|| dyn_i
->want_gotx
))
2804 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2805 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2806 if ((dynamic_symbol
|| shared
) && dyn_i
->want_tprel
)
2807 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2808 if (dynamic_symbol
&& dyn_i
->want_dtpmod
)
2809 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2810 if (dynamic_symbol
&& dyn_i
->want_dtprel
)
2811 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2813 if (dyn_i
->want_pltoff
)
2815 bfd_size_type t
= 0;
2817 /* Dynamic symbols get one IPLT relocation. Local symbols in
2818 shared libraries get two REL relocations. Local symbols in
2819 main applications get nothing. */
2821 t
= sizeof (ElfNN_External_Rela
);
2823 t
= 2 * sizeof (ElfNN_External_Rela
);
2825 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2832 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2833 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2834 struct elf_link_hash_entry
*h
;
2836 /* ??? Undefined symbols with PLT entries should be re-defined
2837 to be the PLT entry. */
2839 /* If this is a weak symbol, and there is a real definition, the
2840 processor independent code will have arranged for us to see the
2841 real definition first, and we can just use the same value. */
2842 if (h
->weakdef
!= NULL
)
2844 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2845 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2846 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2847 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2851 /* If this is a reference to a symbol defined by a dynamic object which
2852 is not a function, we might allocate the symbol in our .dynbss section
2853 and allocate a COPY dynamic relocation.
2855 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2862 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2864 struct bfd_link_info
*info
;
2866 struct elfNN_ia64_allocate_data data
;
2867 struct elfNN_ia64_link_hash_table
*ia64_info
;
2870 bfd_boolean relplt
= FALSE
;
2872 dynobj
= elf_hash_table(info
)->dynobj
;
2873 ia64_info
= elfNN_ia64_hash_table (info
);
2874 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
2875 BFD_ASSERT(dynobj
!= NULL
);
2878 /* Set the contents of the .interp section to the interpreter. */
2879 if (ia64_info
->root
.dynamic_sections_created
2882 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2883 BFD_ASSERT (sec
!= NULL
);
2884 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2885 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2888 /* Allocate the GOT entries. */
2890 if (ia64_info
->got_sec
)
2893 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2894 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2895 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2896 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2899 /* Allocate the FPTR entries. */
2901 if (ia64_info
->fptr_sec
)
2904 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2905 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2908 /* Now that we've seen all of the input files, we can decide which
2909 symbols need plt entries. Allocate the minimal PLT entries first.
2910 We do this even though dynamic_sections_created may be FALSE, because
2911 this has the side-effect of clearing want_plt and want_plt2. */
2914 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2916 ia64_info
->minplt_entries
= 0;
2919 ia64_info
->minplt_entries
2920 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2923 /* Align the pointer for the plt2 entries. */
2924 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
2926 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2929 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2931 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2933 /* If we've got a .plt, we need some extra memory for the dynamic
2934 linker. We stuff these in .got.plt. */
2935 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2936 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2939 /* Allocate the PLTOFF entries. */
2941 if (ia64_info
->pltoff_sec
)
2944 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2945 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2948 if (ia64_info
->root
.dynamic_sections_created
)
2950 /* Allocate space for the dynamic relocations that turned out to be
2953 if (info
->shared
&& ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
2954 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2955 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2958 /* We have now determined the sizes of the various dynamic sections.
2959 Allocate memory for them. */
2960 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2964 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2967 /* If we don't need this section, strip it from the output file.
2968 There were several sections primarily related to dynamic
2969 linking that must be create before the linker maps input
2970 sections to output sections. The linker does that before
2971 bfd_elf_size_dynamic_sections is called, and it is that
2972 function which decides whether anything needs to go into
2975 strip
= (sec
->_raw_size
== 0);
2977 if (sec
== ia64_info
->got_sec
)
2979 else if (sec
== ia64_info
->rel_got_sec
)
2982 ia64_info
->rel_got_sec
= NULL
;
2984 /* We use the reloc_count field as a counter if we need to
2985 copy relocs into the output file. */
2986 sec
->reloc_count
= 0;
2988 else if (sec
== ia64_info
->fptr_sec
)
2991 ia64_info
->fptr_sec
= NULL
;
2993 else if (sec
== ia64_info
->plt_sec
)
2996 ia64_info
->plt_sec
= NULL
;
2998 else if (sec
== ia64_info
->pltoff_sec
)
3001 ia64_info
->pltoff_sec
= NULL
;
3003 else if (sec
== ia64_info
->rel_pltoff_sec
)
3006 ia64_info
->rel_pltoff_sec
= NULL
;
3010 /* We use the reloc_count field as a counter if we need to
3011 copy relocs into the output file. */
3012 sec
->reloc_count
= 0;
3019 /* It's OK to base decisions on the section name, because none
3020 of the dynobj section names depend upon the input files. */
3021 name
= bfd_get_section_name (dynobj
, sec
);
3023 if (strcmp (name
, ".got.plt") == 0)
3025 else if (strncmp (name
, ".rel", 4) == 0)
3029 /* We use the reloc_count field as a counter if we need to
3030 copy relocs into the output file. */
3031 sec
->reloc_count
= 0;
3039 _bfd_strip_section_from_output (info
, sec
);
3042 /* Allocate memory for the section contents. */
3043 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->_raw_size
);
3044 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
3049 if (elf_hash_table (info
)->dynamic_sections_created
)
3051 /* Add some entries to the .dynamic section. We fill in the values
3052 later (in finish_dynamic_sections) but we must add the entries now
3053 so that we get the correct size for the .dynamic section. */
3057 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3059 #define add_dynamic_entry(TAG, VAL) \
3060 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
3062 if (!add_dynamic_entry (DT_DEBUG
, 0))
3066 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
3068 if (!add_dynamic_entry (DT_PLTGOT
, 0))
3073 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
3074 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
3075 || !add_dynamic_entry (DT_JMPREL
, 0))
3079 if (!add_dynamic_entry (DT_RELA
, 0)
3080 || !add_dynamic_entry (DT_RELASZ
, 0)
3081 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
3084 if (ia64_info
->reltext
)
3086 if (!add_dynamic_entry (DT_TEXTREL
, 0))
3088 info
->flags
|= DF_TEXTREL
;
3092 /* ??? Perhaps force __gp local. */
3097 static bfd_reloc_status_type
3098 elfNN_ia64_install_value (abfd
, hit_addr
, v
, r_type
)
3102 unsigned int r_type
;
3104 const struct ia64_operand
*op
;
3105 int bigendian
= 0, shift
= 0;
3106 bfd_vma t0
, t1
, insn
, dword
;
3107 enum ia64_opnd opnd
;
3110 #ifdef BFD_HOST_U_64_BIT
3111 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
3116 opnd
= IA64_OPND_NIL
;
3121 return bfd_reloc_ok
;
3123 /* Instruction relocations. */
3126 case R_IA64_TPREL14
:
3127 case R_IA64_DTPREL14
:
3128 opnd
= IA64_OPND_IMM14
;
3131 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
3132 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
3133 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
3134 case R_IA64_PCREL21B
:
3135 case R_IA64_PCREL21BI
:
3136 opnd
= IA64_OPND_TGT25c
;
3140 case R_IA64_GPREL22
:
3141 case R_IA64_LTOFF22
:
3142 case R_IA64_LTOFF22X
:
3143 case R_IA64_PLTOFF22
:
3144 case R_IA64_PCREL22
:
3145 case R_IA64_LTOFF_FPTR22
:
3146 case R_IA64_TPREL22
:
3147 case R_IA64_DTPREL22
:
3148 case R_IA64_LTOFF_TPREL22
:
3149 case R_IA64_LTOFF_DTPMOD22
:
3150 case R_IA64_LTOFF_DTPREL22
:
3151 opnd
= IA64_OPND_IMM22
;
3155 case R_IA64_GPREL64I
:
3156 case R_IA64_LTOFF64I
:
3157 case R_IA64_PLTOFF64I
:
3158 case R_IA64_PCREL64I
:
3159 case R_IA64_FPTR64I
:
3160 case R_IA64_LTOFF_FPTR64I
:
3161 case R_IA64_TPREL64I
:
3162 case R_IA64_DTPREL64I
:
3163 opnd
= IA64_OPND_IMMU64
;
3166 /* Data relocations. */
3168 case R_IA64_DIR32MSB
:
3169 case R_IA64_GPREL32MSB
:
3170 case R_IA64_FPTR32MSB
:
3171 case R_IA64_PCREL32MSB
:
3172 case R_IA64_LTOFF_FPTR32MSB
:
3173 case R_IA64_SEGREL32MSB
:
3174 case R_IA64_SECREL32MSB
:
3175 case R_IA64_LTV32MSB
:
3176 case R_IA64_DTPREL32MSB
:
3177 size
= 4; bigendian
= 1;
3180 case R_IA64_DIR32LSB
:
3181 case R_IA64_GPREL32LSB
:
3182 case R_IA64_FPTR32LSB
:
3183 case R_IA64_PCREL32LSB
:
3184 case R_IA64_LTOFF_FPTR32LSB
:
3185 case R_IA64_SEGREL32LSB
:
3186 case R_IA64_SECREL32LSB
:
3187 case R_IA64_LTV32LSB
:
3188 case R_IA64_DTPREL32LSB
:
3189 size
= 4; bigendian
= 0;
3192 case R_IA64_DIR64MSB
:
3193 case R_IA64_GPREL64MSB
:
3194 case R_IA64_PLTOFF64MSB
:
3195 case R_IA64_FPTR64MSB
:
3196 case R_IA64_PCREL64MSB
:
3197 case R_IA64_LTOFF_FPTR64MSB
:
3198 case R_IA64_SEGREL64MSB
:
3199 case R_IA64_SECREL64MSB
:
3200 case R_IA64_LTV64MSB
:
3201 case R_IA64_TPREL64MSB
:
3202 case R_IA64_DTPMOD64MSB
:
3203 case R_IA64_DTPREL64MSB
:
3204 size
= 8; bigendian
= 1;
3207 case R_IA64_DIR64LSB
:
3208 case R_IA64_GPREL64LSB
:
3209 case R_IA64_PLTOFF64LSB
:
3210 case R_IA64_FPTR64LSB
:
3211 case R_IA64_PCREL64LSB
:
3212 case R_IA64_LTOFF_FPTR64LSB
:
3213 case R_IA64_SEGREL64LSB
:
3214 case R_IA64_SECREL64LSB
:
3215 case R_IA64_LTV64LSB
:
3216 case R_IA64_TPREL64LSB
:
3217 case R_IA64_DTPMOD64LSB
:
3218 case R_IA64_DTPREL64LSB
:
3219 size
= 8; bigendian
= 0;
3222 /* Unsupported / Dynamic relocations. */
3224 return bfd_reloc_notsupported
;
3229 case IA64_OPND_IMMU64
:
3230 hit_addr
-= (long) hit_addr
& 0x3;
3231 t0
= bfd_get_64 (abfd
, hit_addr
);
3232 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
3234 /* tmpl/s: bits 0.. 5 in t0
3235 slot 0: bits 5..45 in t0
3236 slot 1: bits 46..63 in t0, bits 0..22 in t1
3237 slot 2: bits 23..63 in t1 */
3239 /* First, clear the bits that form the 64 bit constant. */
3240 t0
&= ~(0x3ffffLL
<< 46);
3242 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
3243 | (0x01fLL
<< 22) | (0x001LL
<< 21)
3244 | (0x001LL
<< 36)) << 23));
3246 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
3247 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
3248 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
3249 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
3250 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
3251 | (((val
>> 21) & 0x001) << 21) /* ic */
3252 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
3254 bfd_put_64 (abfd
, t0
, hit_addr
);
3255 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3258 case IA64_OPND_TGT64
:
3259 hit_addr
-= (long) hit_addr
& 0x3;
3260 t0
= bfd_get_64 (abfd
, hit_addr
);
3261 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
3263 /* tmpl/s: bits 0.. 5 in t0
3264 slot 0: bits 5..45 in t0
3265 slot 1: bits 46..63 in t0, bits 0..22 in t1
3266 slot 2: bits 23..63 in t1 */
3268 /* First, clear the bits that form the 64 bit constant. */
3269 t0
&= ~(0x3ffffLL
<< 46);
3271 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
3274 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
3275 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
3276 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
3277 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
3279 bfd_put_64 (abfd
, t0
, hit_addr
);
3280 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
3284 switch ((long) hit_addr
& 0x3)
3286 case 0: shift
= 5; break;
3287 case 1: shift
= 14; hit_addr
+= 3; break;
3288 case 2: shift
= 23; hit_addr
+= 6; break;
3289 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
3291 dword
= bfd_get_64 (abfd
, hit_addr
);
3292 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
3294 op
= elf64_ia64_operands
+ opnd
;
3295 err
= (*op
->insert
) (op
, val
, (ia64_insn
*)& insn
);
3297 return bfd_reloc_overflow
;
3299 dword
&= ~(0x1ffffffffffLL
<< shift
);
3300 dword
|= (insn
<< shift
);
3301 bfd_put_64 (abfd
, dword
, hit_addr
);
3305 /* A data relocation. */
3308 bfd_putb32 (val
, hit_addr
);
3310 bfd_putb64 (val
, hit_addr
);
3313 bfd_putl32 (val
, hit_addr
);
3315 bfd_putl64 (val
, hit_addr
);
3319 return bfd_reloc_ok
;
3323 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
3326 struct bfd_link_info
*info
;
3334 Elf_Internal_Rela outrel
;
3337 BFD_ASSERT (dynindx
!= -1);
3338 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3339 outrel
.r_addend
= addend
;
3340 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3341 if (outrel
.r_offset
>= (bfd_vma
) -2)
3343 /* Run for the hills. We shouldn't be outputting a relocation
3344 for this. So do what everyone else does and output a no-op. */
3345 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3346 outrel
.r_addend
= 0;
3347 outrel
.r_offset
= 0;
3350 outrel
.r_offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3352 loc
= srel
->contents
;
3353 loc
+= srel
->reloc_count
++ * sizeof (ElfNN_External_Rela
);
3354 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
3355 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3356 <= srel
->_cooked_size
);
3359 /* Store an entry for target address TARGET_ADDR in the linkage table
3360 and return the gp-relative address of the linkage table entry. */
3363 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3365 struct bfd_link_info
*info
;
3366 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3370 unsigned int dyn_r_type
;
3372 struct elfNN_ia64_link_hash_table
*ia64_info
;
3377 ia64_info
= elfNN_ia64_hash_table (info
);
3378 got_sec
= ia64_info
->got_sec
;
3382 case R_IA64_TPREL64LSB
:
3383 done
= dyn_i
->tprel_done
;
3384 dyn_i
->tprel_done
= TRUE
;
3385 got_offset
= dyn_i
->tprel_offset
;
3387 case R_IA64_DTPMOD64LSB
:
3388 if (dyn_i
->dtpmod_offset
!= ia64_info
->self_dtpmod_offset
)
3390 done
= dyn_i
->dtpmod_done
;
3391 dyn_i
->dtpmod_done
= TRUE
;
3395 done
= ia64_info
->self_dtpmod_done
;
3396 ia64_info
->self_dtpmod_done
= TRUE
;
3399 got_offset
= dyn_i
->dtpmod_offset
;
3401 case R_IA64_DTPREL64LSB
:
3402 done
= dyn_i
->dtprel_done
;
3403 dyn_i
->dtprel_done
= TRUE
;
3404 got_offset
= dyn_i
->dtprel_offset
;
3407 done
= dyn_i
->got_done
;
3408 dyn_i
->got_done
= TRUE
;
3409 got_offset
= dyn_i
->got_offset
;
3413 BFD_ASSERT ((got_offset
& 7) == 0);
3417 /* Store the target address in the linkage table entry. */
3418 bfd_put_64 (abfd
, value
, got_sec
->contents
+ got_offset
);
3420 /* Install a dynamic relocation if needed. */
3421 if ((info
->shared
&& dyn_r_type
!= R_IA64_DTPREL64LSB
)
3422 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3423 || elfNN_ia64_aix_vec (abfd
->xvec
)
3424 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3427 && dyn_r_type
!= R_IA64_TPREL64LSB
3428 && dyn_r_type
!= R_IA64_DTPMOD64LSB
3429 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
3431 dyn_r_type
= R_IA64_REL64LSB
;
3436 if (bfd_big_endian (abfd
))
3440 case R_IA64_REL64LSB
:
3441 dyn_r_type
= R_IA64_REL64MSB
;
3443 case R_IA64_DIR64LSB
:
3444 dyn_r_type
= R_IA64_DIR64MSB
;
3446 case R_IA64_FPTR64LSB
:
3447 dyn_r_type
= R_IA64_FPTR64MSB
;
3449 case R_IA64_TPREL64LSB
:
3450 dyn_r_type
= R_IA64_TPREL64MSB
;
3452 case R_IA64_DTPMOD64LSB
:
3453 dyn_r_type
= R_IA64_DTPMOD64MSB
;
3455 case R_IA64_DTPREL64LSB
:
3456 dyn_r_type
= R_IA64_DTPREL64MSB
;
3464 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3465 ia64_info
->rel_got_sec
,
3466 got_offset
, dyn_r_type
,
3471 /* Return the address of the linkage table entry. */
3472 value
= (got_sec
->output_section
->vma
3473 + got_sec
->output_offset
3479 /* Fill in a function descriptor consisting of the function's code
3480 address and its global pointer. Return the descriptor's address. */
3483 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3485 struct bfd_link_info
*info
;
3486 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3489 struct elfNN_ia64_link_hash_table
*ia64_info
;
3492 ia64_info
= elfNN_ia64_hash_table (info
);
3493 fptr_sec
= ia64_info
->fptr_sec
;
3495 if (!dyn_i
->fptr_done
)
3497 dyn_i
->fptr_done
= 1;
3499 /* Fill in the function descriptor. */
3500 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3501 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3502 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3505 /* Return the descriptor's address. */
3506 value
= (fptr_sec
->output_section
->vma
3507 + fptr_sec
->output_offset
3508 + dyn_i
->fptr_offset
);
3513 /* Fill in a PLTOFF entry consisting of the function's code address
3514 and its global pointer. Return the descriptor's address. */
3517 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3519 struct bfd_link_info
*info
;
3520 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3524 struct elfNN_ia64_link_hash_table
*ia64_info
;
3525 asection
*pltoff_sec
;
3527 ia64_info
= elfNN_ia64_hash_table (info
);
3528 pltoff_sec
= ia64_info
->pltoff_sec
;
3530 /* Don't do anything if this symbol uses a real PLT entry. In
3531 that case, we'll fill this in during finish_dynamic_symbol. */
3532 if ((! dyn_i
->want_plt
|| is_plt
)
3533 && !dyn_i
->pltoff_done
)
3535 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3537 /* Fill in the function descriptor. */
3538 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3539 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3541 /* Install dynamic relocations if needed. */
3542 if (!is_plt
&& info
->shared
)
3544 unsigned int dyn_r_type
;
3546 if (bfd_big_endian (abfd
))
3547 dyn_r_type
= R_IA64_REL64MSB
;
3549 dyn_r_type
= R_IA64_REL64LSB
;
3551 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3552 ia64_info
->rel_pltoff_sec
,
3553 dyn_i
->pltoff_offset
,
3554 dyn_r_type
, 0, value
);
3555 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3556 ia64_info
->rel_pltoff_sec
,
3557 dyn_i
->pltoff_offset
+ 8,
3561 dyn_i
->pltoff_done
= 1;
3564 /* Return the descriptor's address. */
3565 value
= (pltoff_sec
->output_section
->vma
3566 + pltoff_sec
->output_offset
3567 + dyn_i
->pltoff_offset
);
3572 /* Return the base VMA address which should be subtracted from real addresses
3573 when resolving @tprel() relocation.
3574 Main program TLS (whose template starts at PT_TLS p_vaddr)
3575 is assigned offset round(16, PT_TLS p_align). */
3578 elfNN_ia64_tprel_base (info
)
3579 struct bfd_link_info
*info
;
3581 struct elf_link_tls_segment
*tls_segment
3582 = elf_hash_table (info
)->tls_segment
;
3584 BFD_ASSERT (tls_segment
!= NULL
);
3585 return (tls_segment
->start
3586 - align_power ((bfd_vma
) 16, tls_segment
->align
));
3589 /* Return the base VMA address which should be subtracted from real addresses
3590 when resolving @dtprel() relocation.
3591 This is PT_TLS segment p_vaddr. */
3594 elfNN_ia64_dtprel_base (info
)
3595 struct bfd_link_info
*info
;
3597 BFD_ASSERT (elf_hash_table (info
)->tls_segment
!= NULL
);
3598 return elf_hash_table (info
)->tls_segment
->start
;
3601 /* Called through qsort to sort the .IA_64.unwind section during a
3602 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3603 to the output bfd so we can do proper endianness frobbing. */
3605 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3608 elfNN_ia64_unwind_entry_compare (a
, b
)
3614 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3615 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3617 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3620 /* Make sure we've got ourselves a nice fat __gp value. */
3622 elfNN_ia64_choose_gp (abfd
, info
)
3624 struct bfd_link_info
*info
;
3626 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3627 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3628 struct elf_link_hash_entry
*gp
;
3631 struct elfNN_ia64_link_hash_table
*ia64_info
;
3633 ia64_info
= elfNN_ia64_hash_table (info
);
3635 /* Find the min and max vma of all sections marked short. Also collect
3636 min and max vma of any type, for use in selecting a nice gp. */
3637 for (os
= abfd
->sections
; os
; os
= os
->next
)
3641 if ((os
->flags
& SEC_ALLOC
) == 0)
3645 hi
= os
->vma
+ os
->_raw_size
;
3653 if (os
->flags
& SEC_SMALL_DATA
)
3655 if (min_short_vma
> lo
)
3657 if (max_short_vma
< hi
)
3662 /* See if the user wants to force a value. */
3663 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
3667 && (gp
->root
.type
== bfd_link_hash_defined
3668 || gp
->root
.type
== bfd_link_hash_defweak
))
3670 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3671 gp_val
= (gp
->root
.u
.def
.value
3672 + gp_sec
->output_section
->vma
3673 + gp_sec
->output_offset
);
3677 /* Pick a sensible value. */
3679 asection
*got_sec
= ia64_info
->got_sec
;
3681 /* Start with just the address of the .got. */
3683 gp_val
= got_sec
->output_section
->vma
;
3684 else if (max_short_vma
!= 0)
3685 gp_val
= min_short_vma
;
3689 /* If it is possible to address the entire image, but we
3690 don't with the choice above, adjust. */
3691 if (max_vma
- min_vma
< 0x400000
3692 && max_vma
- gp_val
<= 0x200000
3693 && gp_val
- min_vma
> 0x200000)
3694 gp_val
= min_vma
+ 0x200000;
3695 else if (max_short_vma
!= 0)
3697 /* If we don't cover all the short data, adjust. */
3698 if (max_short_vma
- gp_val
>= 0x200000)
3699 gp_val
= min_short_vma
+ 0x200000;
3701 /* If we're addressing stuff past the end, adjust back. */
3702 if (gp_val
> max_vma
)
3703 gp_val
= max_vma
- 0x200000 + 8;
3707 /* Validate whether all SHF_IA_64_SHORT sections are within
3708 range of the chosen GP. */
3710 if (max_short_vma
!= 0)
3712 if (max_short_vma
- min_short_vma
>= 0x400000)
3714 (*_bfd_error_handler
)
3715 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3716 bfd_get_filename (abfd
),
3717 (unsigned long) (max_short_vma
- min_short_vma
));
3720 else if ((gp_val
> min_short_vma
3721 && gp_val
- min_short_vma
> 0x200000)
3722 || (gp_val
< max_short_vma
3723 && max_short_vma
- gp_val
>= 0x200000))
3725 (*_bfd_error_handler
)
3726 (_("%s: __gp does not cover short data segment"),
3727 bfd_get_filename (abfd
));
3732 _bfd_set_gp_value (abfd
, gp_val
);
3738 elfNN_ia64_final_link (abfd
, info
)
3740 struct bfd_link_info
*info
;
3742 struct elfNN_ia64_link_hash_table
*ia64_info
;
3743 asection
*unwind_output_sec
;
3745 ia64_info
= elfNN_ia64_hash_table (info
);
3747 /* Make sure we've got ourselves a nice fat __gp value. */
3748 if (!info
->relocateable
)
3750 bfd_vma gp_val
= _bfd_get_gp_value (abfd
);
3751 struct elf_link_hash_entry
*gp
;
3755 if (! elfNN_ia64_choose_gp (abfd
, info
))
3757 gp_val
= _bfd_get_gp_value (abfd
);
3760 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
3764 gp
->root
.type
= bfd_link_hash_defined
;
3765 gp
->root
.u
.def
.value
= gp_val
;
3766 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3770 /* If we're producing a final executable, we need to sort the contents
3771 of the .IA_64.unwind section. Force this section to be relocated
3772 into memory rather than written immediately to the output file. */
3773 unwind_output_sec
= NULL
;
3774 if (!info
->relocateable
)
3776 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3779 unwind_output_sec
= s
->output_section
;
3780 unwind_output_sec
->contents
3781 = bfd_malloc (unwind_output_sec
->_raw_size
);
3782 if (unwind_output_sec
->contents
== NULL
)
3787 /* Invoke the regular ELF backend linker to do all the work. */
3788 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3791 if (unwind_output_sec
)
3793 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3794 qsort (unwind_output_sec
->contents
,
3795 (size_t) (unwind_output_sec
->_raw_size
/ 24),
3797 elfNN_ia64_unwind_entry_compare
);
3799 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3800 unwind_output_sec
->contents
, (bfd_vma
) 0,
3801 unwind_output_sec
->_raw_size
))
3809 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3810 contents
, relocs
, local_syms
, local_sections
)
3812 struct bfd_link_info
*info
;
3814 asection
*input_section
;
3816 Elf_Internal_Rela
*relocs
;
3817 Elf_Internal_Sym
*local_syms
;
3818 asection
**local_sections
;
3820 struct elfNN_ia64_link_hash_table
*ia64_info
;
3821 Elf_Internal_Shdr
*symtab_hdr
;
3822 Elf_Internal_Rela
*rel
;
3823 Elf_Internal_Rela
*relend
;
3825 bfd_boolean ret_val
= TRUE
; /* for non-fatal errors */
3828 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3829 ia64_info
= elfNN_ia64_hash_table (info
);
3831 /* Infect various flags from the input section to the output section. */
3832 if (info
->relocateable
)
3836 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3837 flags
&= SHF_IA_64_NORECOV
;
3839 elf_section_data(input_section
->output_section
)
3840 ->this_hdr
.sh_flags
|= flags
;
3844 gp_val
= _bfd_get_gp_value (output_bfd
);
3845 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, FALSE
);
3848 relend
= relocs
+ input_section
->reloc_count
;
3849 for (; rel
< relend
; ++rel
)
3851 struct elf_link_hash_entry
*h
;
3852 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3853 bfd_reloc_status_type r
;
3854 reloc_howto_type
*howto
;
3855 unsigned long r_symndx
;
3856 Elf_Internal_Sym
*sym
;
3857 unsigned int r_type
;
3861 bfd_boolean dynamic_symbol_p
;
3862 bfd_boolean undef_weak_ref
;
3864 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3865 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3867 (*_bfd_error_handler
)
3868 (_("%s: unknown relocation type %d"),
3869 bfd_archive_filename (input_bfd
), (int)r_type
);
3870 bfd_set_error (bfd_error_bad_value
);
3875 howto
= lookup_howto (r_type
);
3876 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3880 undef_weak_ref
= FALSE
;
3882 if (r_symndx
< symtab_hdr
->sh_info
)
3884 /* Reloc against local symbol. */
3885 sym
= local_syms
+ r_symndx
;
3886 sym_sec
= local_sections
[r_symndx
];
3887 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, sym_sec
, rel
);
3888 if ((sym_sec
->flags
& SEC_MERGE
)
3889 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
3890 && sym_sec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
3892 struct elfNN_ia64_local_hash_entry
*loc_h
;
3894 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, FALSE
);
3895 if (loc_h
&& ! loc_h
->sec_merge_done
)
3897 struct elfNN_ia64_dyn_sym_info
*dynent
;
3900 for (dynent
= loc_h
->info
; dynent
; dynent
= dynent
->next
)
3904 _bfd_merged_section_offset (output_bfd
, &msec
,
3905 elf_section_data (msec
)->
3910 dynent
->addend
-= sym
->st_value
;
3911 dynent
->addend
+= msec
->output_section
->vma
3912 + msec
->output_offset
3913 - sym_sec
->output_section
->vma
3914 - sym_sec
->output_offset
;
3916 loc_h
->sec_merge_done
= 1;
3924 /* Reloc against global symbol. */
3925 indx
= r_symndx
- symtab_hdr
->sh_info
;
3926 h
= elf_sym_hashes (input_bfd
)[indx
];
3927 while (h
->root
.type
== bfd_link_hash_indirect
3928 || h
->root
.type
== bfd_link_hash_warning
)
3929 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3932 if (h
->root
.type
== bfd_link_hash_defined
3933 || h
->root
.type
== bfd_link_hash_defweak
)
3935 sym_sec
= h
->root
.u
.def
.section
;
3937 /* Detect the cases that sym_sec->output_section is
3938 expected to be NULL -- all cases in which the symbol
3939 is defined in another shared module. This includes
3940 PLT relocs for which we've created a PLT entry and
3941 other relocs for which we're prepared to create
3942 dynamic relocations. */
3943 /* ??? Just accept it NULL and continue. */
3945 if (sym_sec
->output_section
!= NULL
)
3947 value
= (h
->root
.u
.def
.value
3948 + sym_sec
->output_section
->vma
3949 + sym_sec
->output_offset
);
3952 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3953 undef_weak_ref
= TRUE
;
3954 else if (info
->shared
3955 && !info
->no_undefined
3956 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3960 if (! ((*info
->callbacks
->undefined_symbol
)
3961 (info
, h
->root
.root
.string
, input_bfd
,
3962 input_section
, rel
->r_offset
,
3963 (!info
->shared
|| info
->no_undefined
3964 || ELF_ST_VISIBILITY (h
->other
)))))
3970 hit_addr
= contents
+ rel
->r_offset
;
3971 value
+= rel
->r_addend
;
3972 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3983 case R_IA64_DIR32MSB
:
3984 case R_IA64_DIR32LSB
:
3985 case R_IA64_DIR64MSB
:
3986 case R_IA64_DIR64LSB
:
3987 /* Install a dynamic relocation for this reloc. */
3988 if ((dynamic_symbol_p
|| info
->shared
3989 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
3990 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3991 && (!h
|| strcmp (h
->root
.root
.string
,
3992 "__GLOB_DATA_PTR") != 0)))
3994 && (input_section
->flags
& SEC_ALLOC
) != 0)
3996 unsigned int dyn_r_type
;
4000 BFD_ASSERT (srel
!= NULL
);
4002 /* If we don't need dynamic symbol lookup, find a
4003 matching RELATIVE relocation. */
4004 dyn_r_type
= r_type
;
4005 if (dynamic_symbol_p
)
4007 dynindx
= h
->dynindx
;
4008 addend
= rel
->r_addend
;
4015 case R_IA64_DIR32MSB
:
4016 dyn_r_type
= R_IA64_REL32MSB
;
4018 case R_IA64_DIR32LSB
:
4019 dyn_r_type
= R_IA64_REL32LSB
;
4021 case R_IA64_DIR64MSB
:
4022 dyn_r_type
= R_IA64_REL64MSB
;
4024 case R_IA64_DIR64LSB
:
4025 dyn_r_type
= R_IA64_REL64LSB
;
4029 /* We can't represent this without a dynamic symbol.
4030 Adjust the relocation to be against an output
4031 section symbol, which are always present in the
4032 dynamic symbol table. */
4033 /* ??? People shouldn't be doing non-pic code in
4034 shared libraries. Hork. */
4035 (*_bfd_error_handler
)
4036 (_("%s: linking non-pic code in a shared library"),
4037 bfd_archive_filename (input_bfd
));
4045 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
4046 rel
->r_addend
= value
;
4047 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4048 srel
, rel
->r_offset
, dyn_r_type
,
4053 case R_IA64_LTV32MSB
:
4054 case R_IA64_LTV32LSB
:
4055 case R_IA64_LTV64MSB
:
4056 case R_IA64_LTV64LSB
:
4057 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4060 case R_IA64_GPREL22
:
4061 case R_IA64_GPREL64I
:
4062 case R_IA64_GPREL32MSB
:
4063 case R_IA64_GPREL32LSB
:
4064 case R_IA64_GPREL64MSB
:
4065 case R_IA64_GPREL64LSB
:
4066 if (dynamic_symbol_p
)
4068 (*_bfd_error_handler
)
4069 (_("%s: @gprel relocation against dynamic symbol %s"),
4070 bfd_archive_filename (input_bfd
), h
->root
.root
.string
);
4075 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4078 case R_IA64_LTOFF22
:
4079 case R_IA64_LTOFF22X
:
4080 case R_IA64_LTOFF64I
:
4081 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4082 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
4083 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
4085 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4088 case R_IA64_PLTOFF22
:
4089 case R_IA64_PLTOFF64I
:
4090 case R_IA64_PLTOFF64MSB
:
4091 case R_IA64_PLTOFF64LSB
:
4092 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4093 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, FALSE
);
4095 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4098 case R_IA64_FPTR64I
:
4099 case R_IA64_FPTR32MSB
:
4100 case R_IA64_FPTR32LSB
:
4101 case R_IA64_FPTR64MSB
:
4102 case R_IA64_FPTR64LSB
:
4103 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4104 if (dyn_i
->want_fptr
)
4106 if (!undef_weak_ref
)
4107 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4113 /* Otherwise, we expect the dynamic linker to create
4118 if (h
->dynindx
!= -1)
4119 dynindx
= h
->dynindx
;
4121 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4122 (info
, h
->root
.u
.def
.section
->owner
,
4123 global_sym_index (h
)));
4127 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4128 (info
, input_bfd
, (long) r_symndx
));
4131 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4132 srel
, rel
->r_offset
, r_type
,
4133 dynindx
, rel
->r_addend
);
4137 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4140 case R_IA64_LTOFF_FPTR22
:
4141 case R_IA64_LTOFF_FPTR64I
:
4142 case R_IA64_LTOFF_FPTR32MSB
:
4143 case R_IA64_LTOFF_FPTR32LSB
:
4144 case R_IA64_LTOFF_FPTR64MSB
:
4145 case R_IA64_LTOFF_FPTR64LSB
:
4149 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4150 if (dyn_i
->want_fptr
)
4152 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
4153 if (!undef_weak_ref
)
4154 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4159 /* Otherwise, we expect the dynamic linker to create
4163 if (h
->dynindx
!= -1)
4164 dynindx
= h
->dynindx
;
4166 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4167 (info
, h
->root
.u
.def
.section
->owner
,
4168 global_sym_index (h
)));
4171 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4172 (info
, input_bfd
, (long) r_symndx
));
4176 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
4177 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
4179 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4183 case R_IA64_PCREL32MSB
:
4184 case R_IA64_PCREL32LSB
:
4185 case R_IA64_PCREL64MSB
:
4186 case R_IA64_PCREL64LSB
:
4187 /* Install a dynamic relocation for this reloc. */
4188 if ((dynamic_symbol_p
4189 || elfNN_ia64_aix_vec (info
->hash
->creator
))
4192 BFD_ASSERT (srel
!= NULL
);
4194 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4195 srel
, rel
->r_offset
, r_type
,
4196 h
->dynindx
, rel
->r_addend
);
4200 case R_IA64_PCREL21B
:
4201 case R_IA64_PCREL60B
:
4202 /* We should have created a PLT entry for any dynamic symbol. */
4205 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4207 if (dyn_i
&& dyn_i
->want_plt2
)
4209 /* Should have caught this earlier. */
4210 BFD_ASSERT (rel
->r_addend
== 0);
4212 value
= (ia64_info
->plt_sec
->output_section
->vma
4213 + ia64_info
->plt_sec
->output_offset
4214 + dyn_i
->plt2_offset
);
4218 /* Since there's no PLT entry, Validate that this is
4220 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
4222 /* If the symbol is undef_weak, we shouldn't be trying
4223 to call it. There's every chance that we'd wind up
4224 with an out-of-range fixup here. Don't bother setting
4225 any value at all. */
4231 case R_IA64_PCREL21BI
:
4232 case R_IA64_PCREL21F
:
4233 case R_IA64_PCREL21M
:
4234 case R_IA64_PCREL22
:
4235 case R_IA64_PCREL64I
:
4236 /* The PCREL21BI reloc is specifically not intended for use with
4237 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4238 fixup code, and thus probably ought not be dynamic. The
4239 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4240 if (dynamic_symbol_p
)
4244 if (r_type
== R_IA64_PCREL21BI
)
4245 msg
= _("%s: @internal branch to dynamic symbol %s");
4246 else if (r_type
== R_IA64_PCREL21F
|| r_type
== R_IA64_PCREL21M
)
4247 msg
= _("%s: speculation fixup to dynamic symbol %s");
4249 msg
= _("%s: @pcrel relocation against dynamic symbol %s");
4250 (*_bfd_error_handler
) (msg
, bfd_archive_filename (input_bfd
),
4251 h
->root
.root
.string
);
4258 /* Make pc-relative. */
4259 value
-= (input_section
->output_section
->vma
4260 + input_section
->output_offset
4261 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
4262 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4265 case R_IA64_SEGREL32MSB
:
4266 case R_IA64_SEGREL32LSB
:
4267 case R_IA64_SEGREL64MSB
:
4268 case R_IA64_SEGREL64LSB
:
4271 /* If the input section was discarded from the output, then
4277 struct elf_segment_map
*m
;
4278 Elf_Internal_Phdr
*p
;
4280 /* Find the segment that contains the output_section. */
4281 for (m
= elf_tdata (output_bfd
)->segment_map
,
4282 p
= elf_tdata (output_bfd
)->phdr
;
4287 for (i
= m
->count
- 1; i
>= 0; i
--)
4288 if (m
->sections
[i
] == sym_sec
->output_section
)
4296 r
= bfd_reloc_notsupported
;
4300 /* The VMA of the segment is the vaddr of the associated
4302 if (value
> p
->p_vaddr
)
4303 value
-= p
->p_vaddr
;
4306 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
4312 case R_IA64_SECREL32MSB
:
4313 case R_IA64_SECREL32LSB
:
4314 case R_IA64_SECREL64MSB
:
4315 case R_IA64_SECREL64LSB
:
4316 /* Make output-section relative. */
4317 if (value
> input_section
->output_section
->vma
)
4318 value
-= input_section
->output_section
->vma
;
4321 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4324 case R_IA64_IPLTMSB
:
4325 case R_IA64_IPLTLSB
:
4326 /* Install a dynamic relocation for this reloc. */
4327 if ((dynamic_symbol_p
|| info
->shared
)
4328 && (input_section
->flags
& SEC_ALLOC
) != 0)
4330 BFD_ASSERT (srel
!= NULL
);
4332 /* If we don't need dynamic symbol lookup, install two
4333 RELATIVE relocations. */
4334 if (! dynamic_symbol_p
)
4336 unsigned int dyn_r_type
;
4338 if (r_type
== R_IA64_IPLTMSB
)
4339 dyn_r_type
= R_IA64_REL64MSB
;
4341 dyn_r_type
= R_IA64_REL64LSB
;
4343 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4345 srel
, rel
->r_offset
,
4346 dyn_r_type
, 0, value
);
4347 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4349 srel
, rel
->r_offset
+ 8,
4350 dyn_r_type
, 0, gp_val
);
4353 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4354 srel
, rel
->r_offset
, r_type
,
4355 h
->dynindx
, rel
->r_addend
);
4358 if (r_type
== R_IA64_IPLTMSB
)
4359 r_type
= R_IA64_DIR64MSB
;
4361 r_type
= R_IA64_DIR64LSB
;
4362 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4363 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
4367 case R_IA64_TPREL14
:
4368 case R_IA64_TPREL22
:
4369 case R_IA64_TPREL64I
:
4370 value
-= elfNN_ia64_tprel_base (info
);
4371 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4374 case R_IA64_DTPREL14
:
4375 case R_IA64_DTPREL22
:
4376 case R_IA64_DTPREL64I
:
4377 case R_IA64_DTPREL64LSB
:
4378 case R_IA64_DTPREL64MSB
:
4379 value
-= elfNN_ia64_dtprel_base (info
);
4380 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
4383 case R_IA64_LTOFF_TPREL22
:
4384 case R_IA64_LTOFF_DTPMOD22
:
4385 case R_IA64_LTOFF_DTPREL22
:
4388 long dynindx
= h
? h
->dynindx
: -1;
4389 bfd_vma r_addend
= rel
->r_addend
;
4394 case R_IA64_LTOFF_TPREL22
:
4395 if (!dynamic_symbol_p
)
4398 value
-= elfNN_ia64_tprel_base (info
);
4401 r_addend
+= value
- elfNN_ia64_dtprel_base (info
);
4405 got_r_type
= R_IA64_TPREL64LSB
;
4407 case R_IA64_LTOFF_DTPMOD22
:
4408 if (!dynamic_symbol_p
&& !info
->shared
)
4410 got_r_type
= R_IA64_DTPMOD64LSB
;
4412 case R_IA64_LTOFF_DTPREL22
:
4413 if (!dynamic_symbol_p
)
4414 value
-= elfNN_ia64_dtprel_base (info
);
4415 got_r_type
= R_IA64_DTPREL64LSB
;
4418 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4419 value
= set_got_entry (input_bfd
, info
, dyn_i
, dynindx
, r_addend
,
4422 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
4428 r
= bfd_reloc_notsupported
;
4437 case bfd_reloc_undefined
:
4438 /* This can happen for global table relative relocs if
4439 __gp is undefined. This is a panic situation so we
4440 don't try to continue. */
4441 (*info
->callbacks
->undefined_symbol
)
4442 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
4445 case bfd_reloc_notsupported
:
4450 name
= h
->root
.root
.string
;
4453 name
= bfd_elf_string_from_elf_section (input_bfd
,
4454 symtab_hdr
->sh_link
,
4459 name
= bfd_section_name (input_bfd
, input_section
);
4461 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
4463 input_section
, rel
->r_offset
))
4469 case bfd_reloc_dangerous
:
4470 case bfd_reloc_outofrange
:
4471 case bfd_reloc_overflow
:
4477 name
= h
->root
.root
.string
;
4480 name
= bfd_elf_string_from_elf_section (input_bfd
,
4481 symtab_hdr
->sh_link
,
4486 name
= bfd_section_name (input_bfd
, input_section
);
4488 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
4505 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
4507 struct bfd_link_info
*info
;
4508 struct elf_link_hash_entry
*h
;
4509 Elf_Internal_Sym
*sym
;
4511 struct elfNN_ia64_link_hash_table
*ia64_info
;
4512 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4514 ia64_info
= elfNN_ia64_hash_table (info
);
4515 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4517 /* Fill in the PLT data, if required. */
4518 if (dyn_i
&& dyn_i
->want_plt
)
4520 Elf_Internal_Rela outrel
;
4523 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
4525 gp_val
= _bfd_get_gp_value (output_bfd
);
4527 /* Initialize the minimal PLT entry. */
4529 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4530 plt_sec
= ia64_info
->plt_sec
;
4531 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4533 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4534 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4535 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4538 plt_addr
= (plt_sec
->output_section
->vma
4539 + plt_sec
->output_offset
4540 + dyn_i
->plt_offset
);
4541 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, TRUE
);
4543 /* Initialize the FULL PLT entry, if needed. */
4544 if (dyn_i
->want_plt2
)
4546 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4548 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4549 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4552 /* Mark the symbol as undefined, rather than as defined in the
4553 plt section. Leave the value alone. */
4554 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4555 first place. But perhaps elflink.h did some for us. */
4556 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4557 sym
->st_shndx
= SHN_UNDEF
;
4560 /* Create the dynamic relocation. */
4561 outrel
.r_offset
= pltoff_addr
;
4562 if (bfd_little_endian (output_bfd
))
4563 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4565 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4566 outrel
.r_addend
= 0;
4568 /* This is fun. In the .IA_64.pltoff section, we've got entries
4569 that correspond both to real PLT entries, and those that
4570 happened to resolve to local symbols but need to be created
4571 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4572 relocations for the real PLT should come at the end of the
4573 section, so that they can be indexed by plt entry at runtime.
4575 We emitted all of the relocations for the non-PLT @pltoff
4576 entries during relocate_section. So we can consider the
4577 existing sec->reloc_count to be the base of the array of
4580 loc
= ia64_info
->rel_pltoff_sec
->contents
;
4581 loc
+= ((ia64_info
->rel_pltoff_sec
->reloc_count
+ index
)
4582 * sizeof (Elf64_External_Rela
));
4583 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
4586 /* Mark some specially defined symbols as absolute. */
4587 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4588 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4589 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4590 sym
->st_shndx
= SHN_ABS
;
4596 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4598 struct bfd_link_info
*info
;
4600 struct elfNN_ia64_link_hash_table
*ia64_info
;
4603 ia64_info
= elfNN_ia64_hash_table (info
);
4604 dynobj
= ia64_info
->root
.dynobj
;
4606 if (elf_hash_table (info
)->dynamic_sections_created
)
4608 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4609 asection
*sdyn
, *sgotplt
;
4612 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4613 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4614 BFD_ASSERT (sdyn
!= NULL
);
4615 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4616 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4618 gp_val
= _bfd_get_gp_value (abfd
);
4620 for (; dyncon
< dynconend
; dyncon
++)
4622 Elf_Internal_Dyn dyn
;
4624 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4629 dyn
.d_un
.d_ptr
= gp_val
;
4633 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4634 * sizeof (ElfNN_External_Rela
));
4638 /* See the comment above in finish_dynamic_symbol. */
4639 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4640 + ia64_info
->rel_pltoff_sec
->output_offset
4641 + (ia64_info
->rel_pltoff_sec
->reloc_count
4642 * sizeof (ElfNN_External_Rela
)));
4645 case DT_IA_64_PLT_RESERVE
:
4646 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4647 + sgotplt
->output_offset
);
4651 /* Do not have RELASZ include JMPREL. This makes things
4652 easier on ld.so. This is not what the rest of BFD set up. */
4653 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4654 * sizeof (ElfNN_External_Rela
));
4658 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4661 /* Initialize the PLT0 entry. */
4662 if (ia64_info
->plt_sec
)
4664 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4667 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4669 pltres
= (sgotplt
->output_section
->vma
4670 + sgotplt
->output_offset
4673 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4680 /* ELF file flag handling: */
4682 /* Function to keep IA-64 specific file flags. */
4684 elfNN_ia64_set_private_flags (abfd
, flags
)
4688 BFD_ASSERT (!elf_flags_init (abfd
)
4689 || elf_elfheader (abfd
)->e_flags
== flags
);
4691 elf_elfheader (abfd
)->e_flags
= flags
;
4692 elf_flags_init (abfd
) = TRUE
;
4696 /* Merge backend specific data from an object file to the output
4697 object file when linking. */
4699 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4704 bfd_boolean ok
= TRUE
;
4706 /* Don't even pretend to support mixed-format linking. */
4707 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4708 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4711 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4712 out_flags
= elf_elfheader (obfd
)->e_flags
;
4714 if (! elf_flags_init (obfd
))
4716 elf_flags_init (obfd
) = TRUE
;
4717 elf_elfheader (obfd
)->e_flags
= in_flags
;
4719 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4720 && bfd_get_arch_info (obfd
)->the_default
)
4722 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4723 bfd_get_mach (ibfd
));
4729 /* Check flag compatibility. */
4730 if (in_flags
== out_flags
)
4733 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4734 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4735 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4737 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4739 (*_bfd_error_handler
)
4740 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4741 bfd_archive_filename (ibfd
));
4743 bfd_set_error (bfd_error_bad_value
);
4746 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4748 (*_bfd_error_handler
)
4749 (_("%s: linking big-endian files with little-endian files"),
4750 bfd_archive_filename (ibfd
));
4752 bfd_set_error (bfd_error_bad_value
);
4755 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4757 (*_bfd_error_handler
)
4758 (_("%s: linking 64-bit files with 32-bit files"),
4759 bfd_archive_filename (ibfd
));
4761 bfd_set_error (bfd_error_bad_value
);
4764 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4766 (*_bfd_error_handler
)
4767 (_("%s: linking constant-gp files with non-constant-gp files"),
4768 bfd_archive_filename (ibfd
));
4770 bfd_set_error (bfd_error_bad_value
);
4773 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4774 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4776 (*_bfd_error_handler
)
4777 (_("%s: linking auto-pic files with non-auto-pic files"),
4778 bfd_archive_filename (ibfd
));
4780 bfd_set_error (bfd_error_bad_value
);
4788 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4792 FILE *file
= (FILE *) ptr
;
4793 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4795 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4797 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4798 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4799 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4800 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4801 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4802 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4803 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4804 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4805 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4807 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4811 static enum elf_reloc_type_class
4812 elfNN_ia64_reloc_type_class (rela
)
4813 const Elf_Internal_Rela
*rela
;
4815 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
4817 case R_IA64_REL32MSB
:
4818 case R_IA64_REL32LSB
:
4819 case R_IA64_REL64MSB
:
4820 case R_IA64_REL64LSB
:
4821 return reloc_class_relative
;
4822 case R_IA64_IPLTMSB
:
4823 case R_IA64_IPLTLSB
:
4824 return reloc_class_plt
;
4826 return reloc_class_copy
;
4828 return reloc_class_normal
;
4833 elfNN_ia64_hpux_vec (const bfd_target
*vec
)
4835 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec
;
4836 return (vec
== & bfd_elfNN_ia64_hpux_big_vec
);
4840 elfNN_hpux_post_process_headers (abfd
, info
)
4842 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
4844 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
4846 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_HPUX
;
4847 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 1;
4851 elfNN_hpux_backend_section_from_bfd_section (abfd
, sec
, retval
)
4852 bfd
*abfd ATTRIBUTE_UNUSED
;
4856 if (bfd_is_com_section (sec
))
4858 *retval
= SHN_IA_64_ANSI_COMMON
;
4864 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4865 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4866 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4867 #define TARGET_BIG_NAME "elfNN-ia64-big"
4868 #define ELF_ARCH bfd_arch_ia64
4869 #define ELF_MACHINE_CODE EM_IA_64
4870 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4871 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4872 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4874 #define elf_backend_section_from_shdr \
4875 elfNN_ia64_section_from_shdr
4876 #define elf_backend_section_flags \
4877 elfNN_ia64_section_flags
4878 #define elf_backend_fake_sections \
4879 elfNN_ia64_fake_sections
4880 #define elf_backend_final_write_processing \
4881 elfNN_ia64_final_write_processing
4882 #define elf_backend_add_symbol_hook \
4883 elfNN_ia64_add_symbol_hook
4884 #define elf_backend_additional_program_headers \
4885 elfNN_ia64_additional_program_headers
4886 #define elf_backend_modify_segment_map \
4887 elfNN_ia64_modify_segment_map
4888 #define elf_info_to_howto \
4889 elfNN_ia64_info_to_howto
4891 #define bfd_elfNN_bfd_reloc_type_lookup \
4892 elfNN_ia64_reloc_type_lookup
4893 #define bfd_elfNN_bfd_is_local_label_name \
4894 elfNN_ia64_is_local_label_name
4895 #define bfd_elfNN_bfd_relax_section \
4896 elfNN_ia64_relax_section
4898 /* Stuff for the BFD linker: */
4899 #define bfd_elfNN_bfd_link_hash_table_create \
4900 elfNN_ia64_hash_table_create
4901 #define elf_backend_create_dynamic_sections \
4902 elfNN_ia64_create_dynamic_sections
4903 #define elf_backend_check_relocs \
4904 elfNN_ia64_check_relocs
4905 #define elf_backend_adjust_dynamic_symbol \
4906 elfNN_ia64_adjust_dynamic_symbol
4907 #define elf_backend_size_dynamic_sections \
4908 elfNN_ia64_size_dynamic_sections
4909 #define elf_backend_relocate_section \
4910 elfNN_ia64_relocate_section
4911 #define elf_backend_finish_dynamic_symbol \
4912 elfNN_ia64_finish_dynamic_symbol
4913 #define elf_backend_finish_dynamic_sections \
4914 elfNN_ia64_finish_dynamic_sections
4915 #define bfd_elfNN_bfd_final_link \
4916 elfNN_ia64_final_link
4918 #define bfd_elfNN_bfd_merge_private_bfd_data \
4919 elfNN_ia64_merge_private_bfd_data
4920 #define bfd_elfNN_bfd_set_private_flags \
4921 elfNN_ia64_set_private_flags
4922 #define bfd_elfNN_bfd_print_private_bfd_data \
4923 elfNN_ia64_print_private_bfd_data
4925 #define elf_backend_plt_readonly 1
4926 #define elf_backend_want_plt_sym 0
4927 #define elf_backend_plt_alignment 5
4928 #define elf_backend_got_header_size 0
4929 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4930 #define elf_backend_want_got_plt 1
4931 #define elf_backend_may_use_rel_p 1
4932 #define elf_backend_may_use_rela_p 1
4933 #define elf_backend_default_use_rela_p 1
4934 #define elf_backend_want_dynbss 0
4935 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4936 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4937 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4938 #define elf_backend_rela_normal 1
4940 #include "elfNN-target.h"
4942 /* AIX-specific vectors. */
4944 #undef TARGET_LITTLE_SYM
4945 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4946 #undef TARGET_LITTLE_NAME
4947 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4948 #undef TARGET_BIG_SYM
4949 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4950 #undef TARGET_BIG_NAME
4951 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4953 #undef elf_backend_add_symbol_hook
4954 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4956 #undef bfd_elfNN_bfd_link_add_symbols
4957 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4959 #define elfNN_bed elfNN_ia64_aix_bed
4961 #include "elfNN-target.h"
4963 /* HPUX-specific vectors. */
4965 #undef TARGET_LITTLE_SYM
4966 #undef TARGET_LITTLE_NAME
4967 #undef TARGET_BIG_SYM
4968 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4969 #undef TARGET_BIG_NAME
4970 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4972 /* We need to undo the AIX specific functions. */
4974 #undef elf_backend_add_symbol_hook
4975 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
4977 #undef bfd_elfNN_bfd_link_add_symbols
4978 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
4980 /* These are HP-UX specific functions. */
4982 #undef elf_backend_post_process_headers
4983 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4985 #undef elf_backend_section_from_bfd_section
4986 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4988 #undef elf_backend_want_p_paddr_set_to_zero
4989 #define elf_backend_want_p_paddr_set_to_zero 1
4991 #undef ELF_MAXPAGESIZE
4992 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4995 #define elfNN_bed elfNN_ia64_hpux_bed
4997 #include "elfNN-target.h"
4999 #undef elf_backend_want_p_paddr_set_to_zero