1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #include "opcode/ia64.h"
29 * THE RULES for all the stuff the linker creates --
31 * GOT Entries created in response to LTOFF or LTOFF_FPTR
32 * relocations. Dynamic relocs created for dynamic
33 * symbols in an application; REL relocs for locals
34 * in a shared library.
36 * FPTR The canonical function descriptor. Created for local
37 * symbols in applications. Descriptors for dynamic symbols
38 * and local symbols in shared libraries are created by
39 * ld.so. Thus there are no dynamic relocs against these
40 * objects. The FPTR relocs for such _are_ passed through
41 * to the dynamic relocation tables.
43 * FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
44 * Requires the creation of a PLTOFF entry. This does not
45 * require any dynamic relocations.
47 * PLTOFF Created by PLTOFF relocations. For local symbols, this
48 * is an alternate function descriptor, and in shared libraries
49 * requires two REL relocations. Note that this cannot be
50 * transformed into an FPTR relocation, since it must be in
51 * range of the GP. For dynamic symbols, this is a function
52 * descriptor for a MIN_PLT entry, and requires one IPLT reloc.
54 * MIN_PLT Created by PLTOFF entries against dynamic symbols. This
55 * does not reqire dynamic relocations.
58 #define USE_RELA /* we want RELA relocs, not REL */
60 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
62 typedef struct bfd_hash_entry
*(*new_hash_entry_func
)
63 PARAMS ((struct bfd_hash_entry
*, struct bfd_hash_table
*, const char *));
65 /* In dynamically (linker-) created sections, we generally need to keep track
66 of the place a symbol or expression got allocated to. This is done via hash
67 tables that store entries of the following type. */
69 struct elfNN_ia64_dyn_sym_info
71 /* The addend for which this entry is relevant. */
74 /* Next addend in the list. */
75 struct elfNN_ia64_dyn_sym_info
*next
;
79 bfd_vma pltoff_offset
;
83 /* The symbol table entry, if any, that this was derrived from. */
84 struct elf_link_hash_entry
*h
;
86 /* Used to count non-got, non-plt relocations for delayed sizing
87 of relocation sections. */
88 struct elfNN_ia64_dyn_reloc_entry
90 struct elfNN_ia64_dyn_reloc_entry
*next
;
96 /* True when the section contents have been updated. */
97 unsigned got_done
: 1;
98 unsigned fptr_done
: 1;
99 unsigned pltoff_done
: 1;
101 /* True for the different kinds of linker data we want created. */
102 unsigned want_got
: 1;
103 unsigned want_fptr
: 1;
104 unsigned want_ltoff_fptr
: 1;
105 unsigned want_plt
: 1;
106 unsigned want_plt2
: 1;
107 unsigned want_pltoff
: 1;
110 struct elfNN_ia64_local_hash_entry
112 struct bfd_hash_entry root
;
113 struct elfNN_ia64_dyn_sym_info
*info
;
116 struct elfNN_ia64_local_hash_table
118 struct bfd_hash_table root
;
119 /* No additional fields for now. */
122 struct elfNN_ia64_link_hash_entry
124 struct elf_link_hash_entry root
;
125 struct elfNN_ia64_dyn_sym_info
*info
;
128 struct elfNN_ia64_link_hash_table
130 /* The main hash table */
131 struct elf_link_hash_table root
;
133 asection
*got_sec
; /* the linkage table section (or NULL) */
134 asection
*rel_got_sec
; /* dynamic relocation section for same */
135 asection
*fptr_sec
; /* function descriptor table (or NULL) */
136 asection
*plt_sec
; /* the primary plt section (or NULL) */
137 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
138 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
140 bfd_size_type minplt_entries
; /* number of minplt entries */
142 struct elfNN_ia64_local_hash_table loc_hash_table
;
145 #define elfNN_ia64_hash_table(p) \
146 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
148 static bfd_reloc_status_type elfNN_ia64_reloc
149 PARAMS ((bfd
*abfd
, arelent
*reloc
, asymbol
*sym
, PTR data
,
150 asection
*input_section
, bfd
*output_bfd
, char **error_message
));
151 static reloc_howto_type
* lookup_howto
152 PARAMS ((unsigned int rtype
));
153 static reloc_howto_type
*elfNN_ia64_reloc_type_lookup
154 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type bfd_code
));
155 static void elfNN_ia64_info_to_howto
156 PARAMS ((bfd
*abfd
, arelent
*bfd_reloc
, ElfNN_Internal_Rela
*elf_reloc
));
157 static boolean elfNN_ia64_relax_section
158 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
160 static boolean elfNN_ia64_section_from_shdr
161 PARAMS ((bfd
*, ElfNN_Internal_Shdr
*, char *));
162 static boolean elfNN_ia64_fake_sections
163 PARAMS ((bfd
*abfd
, ElfNN_Internal_Shdr
*hdr
, asection
*sec
));
164 static boolean elfNN_ia64_add_symbol_hook
165 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
166 const char **namep
, flagword
*flagsp
, asection
**secp
,
168 static int elfNN_ia64_additional_program_headers
169 PARAMS ((bfd
*abfd
));
170 static boolean elfNN_ia64_is_local_label_name
171 PARAMS ((bfd
*abfd
, const char *name
));
172 static boolean elfNN_ia64_dynamic_symbol_p
173 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
));
174 static boolean elfNN_ia64_local_hash_table_init
175 PARAMS ((struct elfNN_ia64_local_hash_table
*ht
, bfd
*abfd
,
176 new_hash_entry_func
new));
177 static struct bfd_hash_entry
*elfNN_ia64_new_loc_hash_entry
178 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
179 const char *string
));
180 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
181 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
182 const char *string
));
183 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
184 PARAMS ((bfd
*abfd
));
185 static struct elfNN_ia64_local_hash_entry
*elfNN_ia64_local_hash_lookup
186 PARAMS ((struct elfNN_ia64_local_hash_table
*table
, const char *string
,
187 boolean create
, boolean copy
));
188 static void elfNN_ia64_dyn_sym_traverse
189 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
190 boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
192 static boolean elfNN_ia64_create_dynamic_sections
193 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
194 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
195 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
196 struct elf_link_hash_entry
*h
,
197 bfd
*abfd
, const Elf_Internal_Rela
*rel
, boolean create
));
198 static asection
*get_got
199 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
200 struct elfNN_ia64_link_hash_table
*ia64_info
));
201 static asection
*get_fptr
202 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
203 struct elfNN_ia64_link_hash_table
*ia64_info
));
204 static asection
*get_pltoff
205 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
206 struct elfNN_ia64_link_hash_table
*ia64_info
));
207 static asection
*get_reloc_section
208 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
209 asection
*sec
, boolean create
));
210 static boolean count_dyn_reloc
211 PARAMS ((bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
212 asection
*srel
, int type
));
213 static boolean elfNN_ia64_check_relocs
214 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
215 const Elf_Internal_Rela
*relocs
));
216 static boolean elfNN_ia64_adjust_dynamic_symbol
217 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
218 static unsigned long global_sym_index
219 PARAMS ((struct elf_link_hash_entry
*h
));
220 static boolean allocate_fptr
221 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
222 static boolean allocate_global_data_got
223 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
224 static boolean allocate_global_fptr_got
225 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
226 static boolean allocate_local_got
227 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
228 static boolean allocate_pltoff_entries
229 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
230 static boolean allocate_plt_entries
231 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
232 static boolean allocate_plt2_entries
233 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
234 static boolean allocate_dynrel_entries
235 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
236 static boolean elfNN_ia64_size_dynamic_sections
237 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
238 static bfd_reloc_status_type elfNN_ia64_install_value
239 PARAMS ((bfd
*abfd
, bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
240 static void elfNN_ia64_install_dyn_reloc
241 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
242 asection
*srel
, bfd_vma offset
, unsigned int type
,
243 long dynindx
, bfd_vma addend
));
244 static bfd_vma set_got_entry
245 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
246 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
247 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
248 static bfd_vma set_fptr_entry
249 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
250 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
252 static bfd_vma set_pltoff_entry
253 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
254 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
255 bfd_vma value
, boolean
));
256 static boolean elfNN_ia64_final_link
257 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
258 static boolean elfNN_ia64_relocate_section
259 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
260 asection
*input_section
, bfd_byte
*contents
,
261 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
262 asection
**local_sections
));
263 static boolean elfNN_ia64_finish_dynamic_symbol
264 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
265 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
266 static boolean elfNN_ia64_finish_dynamic_sections
267 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
268 static boolean elfNN_ia64_set_private_flags
269 PARAMS ((bfd
*abfd
, flagword flags
));
270 static boolean elfNN_ia64_copy_private_bfd_data
271 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
272 static boolean elfNN_ia64_merge_private_bfd_data
273 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
274 static boolean elfNN_ia64_print_private_bfd_data
275 PARAMS ((bfd
*abfd
, PTR ptr
));
277 /* ia64-specific relocation */
279 /* Perform a relocation. Not much to do here as all the hard work is
280 done in elfNN_ia64_final_link_relocate. */
281 static bfd_reloc_status_type
282 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
283 output_bfd
, error_message
)
284 bfd
*abfd ATTRIBUTE_UNUSED
;
286 asymbol
*sym ATTRIBUTE_UNUSED
;
287 PTR data ATTRIBUTE_UNUSED
;
288 asection
*input_section
;
290 char **error_message
;
294 reloc
->address
+= input_section
->output_offset
;
297 *error_message
= "Unsupported call to elfNN_ia64_reloc";
298 return bfd_reloc_notsupported
;
301 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
302 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
303 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
305 /* This table has to be sorted according to increasing number of the
307 static reloc_howto_type ia64_howto_table
[] =
309 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, false, true),
311 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, false, true),
312 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, false, true),
313 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, false, true),
314 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, false, true),
315 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, false, true),
316 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, false, true),
317 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, false, true),
319 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, false, true),
320 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, false, true),
321 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, false, true),
322 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, false, true),
323 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, false, true),
324 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, false, true),
326 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, false, true),
327 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, false, true),
329 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, false, true),
330 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, false, true),
331 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, false, true),
332 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, false, true),
334 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, false, true),
335 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, false, true),
336 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, false, true),
337 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, false, true),
338 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, false, true),
340 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, true, true),
341 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, true, true),
342 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, true, true),
343 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, true, true),
344 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, true, true),
345 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, true, true),
346 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, true, true),
347 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, true, true),
349 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, false, true),
350 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, false, true),
351 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, false, true),
352 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, false, true),
354 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, false, true),
355 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, false, true),
356 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, false, true),
357 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, false, true),
359 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, false, true),
360 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, false, true),
361 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, false, true),
362 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, false, true),
364 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, false, true),
365 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, false, true),
366 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, false, true),
367 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, false, true),
369 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, false, true),
370 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, false, true),
371 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, false, true),
372 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, false, true),
374 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, true, true),
375 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, true, true),
376 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, true, true),
378 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, false, true),
379 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, false, true),
380 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, false, true),
381 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, false, true),
382 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, false, true),
384 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, false, false),
385 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, false, false),
386 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, false, false),
387 IA64_HOWTO (R_IA64_LTOFF_TP22
, "LTOFF_TP22", 0, false, false),
390 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
392 /* Given a BFD reloc type, return the matching HOWTO structure. */
394 static reloc_howto_type
*
398 static int inited
= 0;
405 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
406 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
407 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
410 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
411 i
= elf_code_to_howto_index
[rtype
];
412 if (i
>= NELEMS (ia64_howto_table
))
414 return ia64_howto_table
+ i
;
417 static reloc_howto_type
*
418 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
419 bfd
*abfd ATTRIBUTE_UNUSED
;
420 bfd_reloc_code_real_type bfd_code
;
426 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
428 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
429 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
430 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
432 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
433 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
434 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
435 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
437 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
438 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
439 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
440 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
441 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
442 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
444 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
445 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
447 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
448 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
449 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
450 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
451 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
452 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
453 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
454 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
455 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
457 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
458 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
459 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
460 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
461 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
462 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
463 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
464 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
465 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
466 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
467 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
469 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
470 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
471 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
472 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
474 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
475 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
476 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
477 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
479 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
480 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
481 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
482 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
484 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
485 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
486 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
487 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
489 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
490 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
491 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
492 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
494 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
495 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
496 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
497 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
498 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
500 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
501 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
502 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
503 case BFD_RELOC_IA64_LTOFF_TP22
: rtype
= R_IA64_LTOFF_TP22
; break;
507 return lookup_howto (rtype
);
510 /* Given a ELF reloc, return the matching HOWTO structure. */
513 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
514 bfd
*abfd ATTRIBUTE_UNUSED
;
516 ElfNN_Internal_Rela
*elf_reloc
;
518 bfd_reloc
->howto
= lookup_howto (ELFNN_R_TYPE (elf_reloc
->r_info
));
521 #define PLT_HEADER_SIZE (3 * 16)
522 #define PLT_MIN_ENTRY_SIZE (1 * 16)
523 #define PLT_FULL_ENTRY_SIZE (2 * 16)
524 #define PLT_RESERVED_WORDS 3
526 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
528 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
529 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
530 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
531 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
532 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
533 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
534 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
535 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
536 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
539 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
541 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
542 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
543 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
546 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
548 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
549 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
550 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
551 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
552 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
553 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
556 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
558 /* Select out of range branch fixup type. Note that Itanium does
559 not support brl, and so it gets emulated by the kernel. */
562 static const bfd_byte oor_brl
[16] =
564 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
566 0x00, 0x00, 0x00, 0xc0
569 static const bfd_byte oor_ip
[48] =
571 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
572 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
573 0x01, 0x00, 0x00, 0x60,
574 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
575 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
576 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
577 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
578 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
579 0x60, 0x00, 0x80, 0x00 /* br b6;; */
582 /* These functions do relaxation for IA-64 ELF.
584 This is primarily to support branches to targets out of range;
585 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
588 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
591 struct bfd_link_info
*link_info
;
596 struct one_fixup
*next
;
602 Elf_Internal_Shdr
*symtab_hdr
;
603 Elf_Internal_Rela
*internal_relocs
;
604 Elf_Internal_Rela
*free_relocs
= NULL
;
605 Elf_Internal_Rela
*irel
, *irelend
;
607 bfd_byte
*free_contents
= NULL
;
608 ElfNN_External_Sym
*extsyms
;
609 ElfNN_External_Sym
*free_extsyms
= NULL
;
610 struct elfNN_ia64_link_hash_table
*ia64_info
;
611 struct one_fixup
*fixups
= NULL
;
612 boolean changed_contents
= false;
613 boolean changed_relocs
= false;
615 /* Assume we're not going to change any sizes, and we'll only need
619 /* Nothing to do if there are no relocations. */
620 if ((sec
->flags
& SEC_RELOC
) == 0
621 || sec
->reloc_count
== 0)
624 /* If this is the first time we have been called for this section,
625 initialize the cooked size. */
626 if (sec
->_cooked_size
== 0)
627 sec
->_cooked_size
= sec
->_raw_size
;
629 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
631 /* Load the relocations for this section. */
632 internal_relocs
= (_bfd_elfNN_link_read_relocs
633 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
634 link_info
->keep_memory
));
635 if (internal_relocs
== NULL
)
638 if (! link_info
->keep_memory
)
639 free_relocs
= internal_relocs
;
641 ia64_info
= elfNN_ia64_hash_table (link_info
);
642 irelend
= internal_relocs
+ sec
->reloc_count
;
644 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
645 if (ELFNN_R_TYPE (irel
->r_info
) == (int) R_IA64_PCREL21B
)
648 /* No branch-type relocations. */
651 if (free_relocs
!= NULL
)
656 /* Get the section contents. */
657 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
658 contents
= elf_section_data (sec
)->this_hdr
.contents
;
661 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
662 if (contents
== NULL
)
664 free_contents
= contents
;
666 if (! bfd_get_section_contents (abfd
, sec
, contents
,
667 (file_ptr
) 0, sec
->_raw_size
))
671 /* Read this BFD's symbols. */
672 if (symtab_hdr
->contents
!= NULL
)
673 extsyms
= (ElfNN_External_Sym
*) symtab_hdr
->contents
;
676 extsyms
= (ElfNN_External_Sym
*) bfd_malloc (symtab_hdr
->sh_size
);
679 free_extsyms
= extsyms
;
680 if (bfd_seek (abfd
, symtab_hdr
->sh_offset
, SEEK_SET
) != 0
681 || (bfd_read (extsyms
, 1, symtab_hdr
->sh_size
, abfd
)
682 != symtab_hdr
->sh_size
))
686 for (; irel
< irelend
; irel
++)
688 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
689 Elf_Internal_Sym isym
;
693 if (ELFNN_R_TYPE (irel
->r_info
) != (int) R_IA64_PCREL21B
)
696 /* Get the value of the symbol referred to by the reloc. */
697 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
699 /* A local symbol. */
700 bfd_elfNN_swap_symbol_in (abfd
,
701 extsyms
+ ELFNN_R_SYM (irel
->r_info
),
703 if (isym
.st_shndx
== SHN_UNDEF
)
704 continue; /* We can't do anthing with undefined symbols. */
705 else if (isym
.st_shndx
== SHN_ABS
)
706 tsec
= bfd_abs_section_ptr
;
707 else if (isym
.st_shndx
== SHN_COMMON
)
708 tsec
= bfd_com_section_ptr
;
709 else if (isym
.st_shndx
> 0 && isym
.st_shndx
< SHN_LORESERVE
)
710 tsec
= bfd_section_from_elf_index (abfd
, isym
.st_shndx
);
712 continue; /* who knows. */
714 toff
= isym
.st_value
;
719 struct elf_link_hash_entry
*h
;
720 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
722 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
723 h
= elf_sym_hashes (abfd
)[indx
];
724 BFD_ASSERT (h
!= NULL
);
726 while (h
->root
.type
== bfd_link_hash_indirect
727 || h
->root
.type
== bfd_link_hash_warning
)
728 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
730 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, false);
732 /* For branches to dynamic symbols, we're interested instead
733 in a branch to the PLT entry. */
734 if (dyn_i
&& dyn_i
->want_plt2
)
736 tsec
= ia64_info
->plt_sec
;
737 toff
= dyn_i
->plt2_offset
;
741 /* We can't do anthing with undefined symbols. */
742 if (h
->root
.type
== bfd_link_hash_undefined
743 || h
->root
.type
== bfd_link_hash_undefweak
)
746 tsec
= h
->root
.u
.def
.section
;
747 toff
= h
->root
.u
.def
.value
;
751 symaddr
= (tsec
->output_section
->vma
752 + tsec
->output_offset
756 roff
= irel
->r_offset
;
757 reladdr
= (sec
->output_section
->vma
761 /* If the branch is in range, no need to do anything. */
762 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
763 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
766 /* If the branch and target are in the same section, you've
767 got one honking big section and we can't help you. You'll
768 get an error message later. */
772 /* Look for an existing fixup to this address. */
773 for (f
= fixups
; f
; f
= f
->next
)
774 if (f
->tsec
== tsec
&& f
->toff
== toff
)
779 /* Two alternatives: If it's a branch to a PLT entry, we can
780 make a copy of the FULL_PLT entry. Otherwise, we'll have
781 to use a `brl' insn to get where we're going. */
785 if (tsec
== ia64_info
->plt_sec
)
786 size
= sizeof (plt_full_entry
);
790 size
= sizeof (oor_brl
);
792 size
= sizeof (oor_ip
);
796 /* Resize the current section to make room for the new branch. */
797 trampoff
= (sec
->_cooked_size
+ 15) & -16;
798 contents
= (bfd_byte
*) bfd_realloc (contents
, trampoff
+ size
);
799 if (contents
== NULL
)
801 sec
->_cooked_size
= trampoff
+ size
;
803 if (tsec
== ia64_info
->plt_sec
)
805 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
807 /* Hijack the old relocation for use as the PLTOFF reloc. */
808 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
810 irel
->r_offset
= trampoff
;
815 memcpy (contents
+ trampoff
, oor_brl
, size
);
816 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
818 irel
->r_offset
= trampoff
+ 2;
820 memcpy (contents
+ trampoff
, oor_ip
, size
);
821 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
823 irel
->r_addend
-= 16;
824 irel
->r_offset
= trampoff
+ 2;
828 /* Record the fixup so we don't do it again this section. */
829 f
= (struct one_fixup
*) bfd_malloc (sizeof (*f
));
833 f
->trampoff
= trampoff
;
838 /* Nop out the reloc, since we're finalizing things here. */
839 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
842 /* Fix up the existing branch to hit the trampoline. Hope like
843 hell this doesn't overflow too. */
844 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
845 f
->trampoff
- (roff
& -4),
846 R_IA64_PCREL21B
) != bfd_reloc_ok
)
849 changed_contents
= true;
850 changed_relocs
= true;
853 /* Clean up and go home. */
856 struct one_fixup
*f
= fixups
;
857 fixups
= fixups
->next
;
862 elf_section_data (sec
)->relocs
= internal_relocs
;
863 else if (free_relocs
!= NULL
)
866 if (changed_contents
)
867 elf_section_data (sec
)->this_hdr
.contents
= contents
;
868 else if (free_contents
!= NULL
)
870 if (! link_info
->keep_memory
)
871 free (free_contents
);
874 /* Cache the section contents for elf_link_input_bfd. */
875 elf_section_data (sec
)->this_hdr
.contents
= contents
;
879 if (free_extsyms
!= NULL
)
881 if (! link_info
->keep_memory
)
885 /* Cache the symbols for elf_link_input_bfd. */
886 symtab_hdr
->contents
= extsyms
;
890 *again
= changed_contents
|| changed_relocs
;
894 if (free_relocs
!= NULL
)
896 if (free_contents
!= NULL
)
897 free (free_contents
);
898 if (free_extsyms
!= NULL
)
903 /* Handle an IA-64 specific section when reading an object file. This
904 is called when elfcode.h finds a section with an unknown type. */
907 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
909 ElfNN_Internal_Shdr
*hdr
;
914 /* There ought to be a place to keep ELF backend specific flags, but
915 at the moment there isn't one. We just keep track of the
916 sections by their name, instead. Fortunately, the ABI gives
917 suggested names for all the MIPS specific sections, so we will
918 probably get away with this. */
919 switch (hdr
->sh_type
)
921 case SHT_IA_64_UNWIND
:
922 if (strcmp (name
, ELF_STRING_ia64_unwind
) != 0)
927 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
935 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
937 newsect
= hdr
->bfd_section
;
942 /* Convert IA-64 specific section flags to bfd internal section flags. */
944 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
948 elfNN_ia64_section_flags (flags
, hdr
)
950 ElfNN_Internal_Shdr
*hdr
;
952 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
953 *flags
|= SEC_SMALL_DATA
;
958 /* Set the correct type for an IA-64 ELF section. We do this by the
959 section name, which is a hack, but ought to work. */
962 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
963 bfd
*abfd ATTRIBUTE_UNUSED
;
964 ElfNN_Internal_Shdr
*hdr
;
967 register const char *name
;
969 name
= bfd_get_section_name (abfd
, sec
);
971 if (strcmp (name
, ELF_STRING_ia64_unwind
) == 0)
972 hdr
->sh_type
= SHT_IA_64_UNWIND
;
973 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
974 hdr
->sh_type
= SHT_IA_64_EXT
;
975 else if (strcmp (name
, ".reloc") == 0)
977 * This is an ugly, but unfortunately necessary hack that is
978 * needed when producing EFI binaries on IA-64. It tells
979 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
980 * containing ELF relocation info. We need this hack in order to
981 * be able to generate ELF binaries that can be translated into
982 * EFI applications (which are essentially COFF objects). Those
983 * files contain a COFF ".reloc" section inside an ELFNN object,
984 * which would normally cause BFD to segfault because it would
985 * attempt to interpret this section as containing relocation
986 * entries for section "oc". With this hack enabled, ".reloc"
987 * will be treated as a normal data section, which will avoid the
988 * segfault. However, you won't be able to create an ELFNN binary
989 * with a section named "oc" that needs relocations, but that's
990 * the kind of ugly side-effects you get when detecting section
991 * types based on their names... In practice, this limitation is
994 hdr
->sh_type
= SHT_PROGBITS
;
996 if (sec
->flags
& SEC_SMALL_DATA
)
997 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1002 /* Hook called by the linker routine which adds symbols from an object
1003 file. We use it to put .comm items in .sbss, and not .bss. */
1006 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1008 struct bfd_link_info
*info
;
1009 const Elf_Internal_Sym
*sym
;
1010 const char **namep ATTRIBUTE_UNUSED
;
1011 flagword
*flagsp ATTRIBUTE_UNUSED
;
1015 if (sym
->st_shndx
== SHN_COMMON
1016 && !info
->relocateable
1017 && sym
->st_size
<= (unsigned) bfd_get_gp_size (abfd
))
1019 /* Common symbols less than or equal to -G nn bytes are
1020 automatically put into .sbss. */
1022 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1026 scomm
= bfd_make_section (abfd
, ".scommon");
1028 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1030 | SEC_LINKER_CREATED
)))
1035 *valp
= sym
->st_size
;
1041 /* Return the number of additional phdrs we will need. */
1044 elfNN_ia64_additional_program_headers (abfd
)
1050 /* See if we need a PT_IA_64_ARCHEXT segment. */
1051 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1052 if (s
&& (s
->flags
& SEC_LOAD
))
1055 /* See if we need a PT_IA_64_UNWIND segment. */
1056 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
1057 if (s
&& (s
->flags
& SEC_LOAD
))
1064 elfNN_ia64_modify_segment_map (abfd
)
1067 struct elf_segment_map
*m
, **pm
;
1070 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1071 all PT_LOAD segments. */
1072 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1073 if (s
&& (s
->flags
& SEC_LOAD
))
1075 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1076 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1080 m
= (struct elf_segment_map
*) bfd_zalloc (abfd
, sizeof *m
);
1084 m
->p_type
= PT_IA_64_ARCHEXT
;
1088 /* We want to put it after the PHDR and INTERP segments. */
1089 pm
= &elf_tdata (abfd
)->segment_map
;
1091 && ((*pm
)->p_type
== PT_PHDR
1092 || (*pm
)->p_type
== PT_INTERP
))
1100 /* Install the PT_IA_64_UNWIND segment, if needed. */
1101 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
1102 if (s
&& (s
->flags
& SEC_LOAD
))
1104 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1105 if (m
->p_type
== PT_IA_64_UNWIND
)
1109 m
= (struct elf_segment_map
*) bfd_zalloc (abfd
, sizeof *m
);
1113 m
->p_type
= PT_IA_64_UNWIND
;
1118 /* We want to put it last. */
1119 pm
= &elf_tdata (abfd
)->segment_map
;
1126 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1127 the input sections for each output section in the segment and testing
1128 for SHF_IA_64_NORECOV on each. */
1129 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1130 if (m
->p_type
== PT_LOAD
)
1133 for (i
= m
->count
- 1; i
>= 0; --i
)
1135 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1138 if (order
->type
== bfd_indirect_link_order
)
1140 asection
*is
= order
->u
.indirect
.section
;
1141 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1142 if (flags
& SHF_IA_64_NORECOV
)
1144 m
->p_flags
|= PF_IA_64_NORECOV
;
1148 order
= order
->next
;
1157 /* According to the Tahoe assembler spec, all labels starting with a
1161 elfNN_ia64_is_local_label_name (abfd
, name
)
1162 bfd
*abfd ATTRIBUTE_UNUSED
;
1165 return name
[0] == '.';
1168 /* Should we do dynamic things to this symbol? */
1171 elfNN_ia64_dynamic_symbol_p (h
, info
)
1172 struct elf_link_hash_entry
*h
;
1173 struct bfd_link_info
*info
;
1178 while (h
->root
.type
== bfd_link_hash_indirect
1179 || h
->root
.type
== bfd_link_hash_warning
)
1180 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1182 if (h
->dynindx
== -1)
1185 if (h
->root
.type
== bfd_link_hash_undefweak
1186 || h
->root
.type
== bfd_link_hash_defweak
)
1189 if ((info
->shared
&& !info
->symbolic
)
1190 || ((h
->elf_link_hash_flags
1191 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1192 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1199 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1200 struct elfNN_ia64_local_hash_table
*ht
;
1201 bfd
*abfd ATTRIBUTE_UNUSED
;
1202 new_hash_entry_func
new;
1204 memset (ht
, 0, sizeof (*ht
));
1205 return bfd_hash_table_init (&ht
->root
, new);
1208 static struct bfd_hash_entry
*
1209 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1210 struct bfd_hash_entry
*entry
;
1211 struct bfd_hash_table
*table
;
1214 struct elfNN_ia64_local_hash_entry
*ret
;
1215 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1217 /* Allocate the structure if it has not already been allocated by a
1220 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1225 /* Initialize our local data. All zeros, and definitely easier
1226 than setting a handful of bit fields. */
1227 memset (ret
, 0, sizeof (*ret
));
1229 /* Call the allocation method of the superclass. */
1230 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1231 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1233 return (struct bfd_hash_entry
*) ret
;
1236 static struct bfd_hash_entry
*
1237 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1238 struct bfd_hash_entry
*entry
;
1239 struct bfd_hash_table
*table
;
1242 struct elfNN_ia64_link_hash_entry
*ret
;
1243 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1245 /* Allocate the structure if it has not already been allocated by a
1248 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1253 /* Initialize our local data. All zeros, and definitely easier
1254 than setting a handful of bit fields. */
1255 memset (ret
, 0, sizeof (*ret
));
1257 /* Call the allocation method of the superclass. */
1258 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1259 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1262 return (struct bfd_hash_entry
*) ret
;
1266 elfNN_ia64_hash_copy_indirect (xdir
, xind
)
1267 struct elf_link_hash_entry
*xdir
, *xind
;
1269 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1271 dir
= (struct elfNN_ia64_link_hash_entry
*)xdir
;
1272 ind
= (struct elfNN_ia64_link_hash_entry
*)xind
;
1274 /* Copy down any references that we may have already seen to the
1275 symbol which just became indirect. */
1277 dir
->root
.elf_link_hash_flags
|=
1278 (ind
->root
.elf_link_hash_flags
1279 & (ELF_LINK_HASH_REF_DYNAMIC
1280 | ELF_LINK_HASH_REF_REGULAR
1281 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1283 /* Copy over the got and plt data. This would have been done
1286 if (dir
->info
== NULL
)
1288 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1290 dir
->info
= dyn_i
= ind
->info
;
1293 /* Fix up the dyn_sym_info pointers to the global symbol. */
1294 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1295 dyn_i
->h
= &dir
->root
;
1297 BFD_ASSERT (ind
->info
== NULL
);
1299 /* Copy over the dynindx. */
1301 if (dir
->root
.dynindx
== -1)
1303 dir
->root
.dynindx
= ind
->root
.dynindx
;
1304 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1305 ind
->root
.dynindx
= -1;
1306 ind
->root
.dynstr_index
= 0;
1308 BFD_ASSERT (ind
->root
.dynindx
== -1);
1312 elfNN_ia64_hash_hide_symbol (info
, xh
)
1313 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1314 struct elf_link_hash_entry
*xh
;
1316 struct elfNN_ia64_link_hash_entry
*h
;
1317 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1319 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1321 h
->root
.elf_link_hash_flags
&= ~ELF_LINK_HASH_NEEDS_PLT
;
1322 h
->root
.dynindx
= -1;
1324 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1325 dyn_i
->want_plt2
= 0;
1328 /* Create the derived linker hash table. The IA-64 ELF port uses this
1329 derived hash table to keep information specific to the IA-64 ElF
1330 linker (without using static variables). */
1332 static struct bfd_link_hash_table
*
1333 elfNN_ia64_hash_table_create (abfd
)
1336 struct elfNN_ia64_link_hash_table
*ret
;
1338 ret
= bfd_alloc (abfd
, sizeof (*ret
));
1341 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1342 elfNN_ia64_new_elf_hash_entry
))
1344 bfd_release (abfd
, ret
);
1348 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1349 elfNN_ia64_new_loc_hash_entry
))
1351 return &ret
->root
.root
;
1354 /* Look up an entry in a Alpha ELF linker hash table. */
1356 static INLINE
struct elfNN_ia64_local_hash_entry
*
1357 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1358 struct elfNN_ia64_local_hash_table
*table
;
1360 boolean create
, copy
;
1362 return ((struct elfNN_ia64_local_hash_entry
*)
1363 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1366 /* Traverse both local and global hash tables. */
1368 struct elfNN_ia64_dyn_sym_traverse_data
1370 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1375 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1376 struct bfd_hash_entry
*xentry
;
1379 struct elfNN_ia64_link_hash_entry
*entry
1380 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1381 struct elfNN_ia64_dyn_sym_traverse_data
*data
1382 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1383 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1385 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1386 if (! (*data
->func
) (dyn_i
, data
->data
))
1392 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1393 struct bfd_hash_entry
*xentry
;
1396 struct elfNN_ia64_local_hash_entry
*entry
1397 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1398 struct elfNN_ia64_dyn_sym_traverse_data
*data
1399 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1400 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1402 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1403 if (! (*data
->func
) (dyn_i
, data
->data
))
1409 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1410 struct elfNN_ia64_link_hash_table
*ia64_info
;
1411 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1414 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1419 elf_link_hash_traverse (&ia64_info
->root
,
1420 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1421 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1422 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1426 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1428 struct bfd_link_info
*info
;
1430 struct elfNN_ia64_link_hash_table
*ia64_info
;
1433 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1436 ia64_info
= elfNN_ia64_hash_table (info
);
1438 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1439 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1442 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1443 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1446 if (!get_pltoff (abfd
, info
, ia64_info
))
1449 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1451 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1454 | SEC_LINKER_CREATED
1456 || !bfd_set_section_alignment (abfd
, s
, 3))
1458 ia64_info
->rel_pltoff_sec
= s
;
1460 s
= bfd_make_section(abfd
, ".rela.got");
1462 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1465 | SEC_LINKER_CREATED
1467 || !bfd_set_section_alignment (abfd
, s
, 3))
1469 ia64_info
->rel_got_sec
= s
;
1474 /* Find and/or create a descriptor for dynamic symbol info. This will
1475 vary based on global or local symbol, and the addend to the reloc. */
1477 static struct elfNN_ia64_dyn_sym_info
*
1478 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1479 struct elfNN_ia64_link_hash_table
*ia64_info
;
1480 struct elf_link_hash_entry
*h
;
1482 const Elf_Internal_Rela
*rel
;
1485 struct elfNN_ia64_dyn_sym_info
**pp
;
1486 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1487 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1490 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1493 struct elfNN_ia64_local_hash_entry
*loc_h
;
1497 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1498 The name describes what was once anonymous memory. */
1500 len
= sizeof (void*)*2 + 1 + sizeof (bfd_vma
)*4 + 1 + 1;
1501 len
+= 10; /* %p slop */
1503 addr_name
= alloca (len
);
1504 sprintf (addr_name
, "%p:%lx", (void *) abfd
, ELFNN_R_SYM (rel
->r_info
));
1506 /* Collect the canonical entry data for this address. */
1507 loc_h
= elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1508 addr_name
, create
, create
);
1514 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
1517 if (dyn_i
== NULL
&& create
)
1519 dyn_i
= (struct elfNN_ia64_dyn_sym_info
*)
1520 bfd_zalloc (abfd
, sizeof *dyn_i
);
1522 dyn_i
->addend
= addend
;
1529 get_got (abfd
, info
, ia64_info
)
1531 struct bfd_link_info
*info
;
1532 struct elfNN_ia64_link_hash_table
*ia64_info
;
1537 got
= ia64_info
->got_sec
;
1542 dynobj
= ia64_info
->root
.dynobj
;
1544 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1545 if (!_bfd_elf_create_got_section (dynobj
, info
))
1548 got
= bfd_get_section_by_name (dynobj
, ".got");
1550 ia64_info
->got_sec
= got
;
1552 flags
= bfd_get_section_flags (abfd
, got
);
1553 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
1559 /* Create function descriptor section (.opd). This section is called .opd
1560 because it contains "official prodecure descriptors". The "official"
1561 refers to the fact that these descriptors are used when taking the address
1562 of a procedure, thus ensuring a unique address for each procedure. */
1565 get_fptr (abfd
, info
, ia64_info
)
1567 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1568 struct elfNN_ia64_link_hash_table
*ia64_info
;
1573 fptr
= ia64_info
->fptr_sec
;
1576 dynobj
= ia64_info
->root
.dynobj
;
1578 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1580 fptr
= bfd_make_section (dynobj
, ".opd");
1582 || !bfd_set_section_flags (dynobj
, fptr
,
1588 | SEC_LINKER_CREATED
))
1589 || !bfd_set_section_alignment (abfd
, fptr
, 4))
1595 ia64_info
->fptr_sec
= fptr
;
1602 get_pltoff (abfd
, info
, ia64_info
)
1604 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1605 struct elfNN_ia64_link_hash_table
*ia64_info
;
1610 pltoff
= ia64_info
->pltoff_sec
;
1613 dynobj
= ia64_info
->root
.dynobj
;
1615 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1617 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
1619 || !bfd_set_section_flags (dynobj
, pltoff
,
1625 | SEC_LINKER_CREATED
))
1626 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
1632 ia64_info
->pltoff_sec
= pltoff
;
1639 get_reloc_section (abfd
, ia64_info
, sec
, create
)
1641 struct elfNN_ia64_link_hash_table
*ia64_info
;
1645 const char *srel_name
;
1649 srel_name
= (bfd_elf_string_from_elf_section
1650 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
1651 elf_section_data(sec
)->rel_hdr
.sh_name
));
1652 if (srel_name
== NULL
)
1655 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
1656 && strcmp (bfd_get_section_name (abfd
, sec
),
1658 || (strncmp (srel_name
, ".rel", 4) == 0
1659 && strcmp (bfd_get_section_name (abfd
, sec
),
1660 srel_name
+4) == 0));
1662 dynobj
= ia64_info
->root
.dynobj
;
1664 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1666 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
1667 if (srel
== NULL
&& create
)
1669 srel
= bfd_make_section (dynobj
, srel_name
);
1671 || !bfd_set_section_flags (dynobj
, srel
,
1676 | SEC_LINKER_CREATED
1678 || !bfd_set_section_alignment (dynobj
, srel
, 3))
1686 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
1688 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1692 struct elfNN_ia64_dyn_reloc_entry
*rent
;
1694 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
1695 if (rent
->srel
== srel
&& rent
->type
== type
)
1700 rent
= (struct elfNN_ia64_dyn_reloc_entry
*)
1701 bfd_alloc (abfd
, sizeof (*rent
));
1705 rent
->next
= dyn_i
->reloc_entries
;
1709 dyn_i
->reloc_entries
= rent
;
1717 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
1719 struct bfd_link_info
*info
;
1721 const Elf_Internal_Rela
*relocs
;
1723 struct elfNN_ia64_link_hash_table
*ia64_info
;
1724 const Elf_Internal_Rela
*relend
;
1725 Elf_Internal_Shdr
*symtab_hdr
;
1726 const Elf_Internal_Rela
*rel
;
1727 asection
*got
, *fptr
, *srel
;
1729 if (info
->relocateable
)
1732 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1733 ia64_info
= elfNN_ia64_hash_table (info
);
1735 got
= fptr
= srel
= NULL
;
1737 relend
= relocs
+ sec
->reloc_count
;
1738 for (rel
= relocs
; rel
< relend
; ++rel
)
1747 NEED_LTOFF_FPTR
= 64,
1750 struct elf_link_hash_entry
*h
= NULL
;
1751 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
1752 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1754 boolean maybe_dynamic
;
1755 int dynrel_type
= R_IA64_NONE
;
1757 if (r_symndx
>= symtab_hdr
->sh_info
)
1759 /* We're dealing with a global symbol -- find its hash entry
1760 and mark it as being referenced. */
1761 long indx
= r_symndx
- symtab_hdr
->sh_info
;
1762 h
= elf_sym_hashes (abfd
)[indx
];
1763 while (h
->root
.type
== bfd_link_hash_indirect
1764 || h
->root
.type
== bfd_link_hash_warning
)
1765 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1767 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
1770 /* We can only get preliminary data on whether a symbol is
1771 locally or externally defined, as not all of the input files
1772 have yet been processed. Do something with what we know, as
1773 this may help reduce memory usage and processing time later. */
1774 maybe_dynamic
= false;
1775 if (h
&& ((info
->shared
&& ! info
->symbolic
)
1776 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
1777 || h
->root
.type
== bfd_link_hash_defweak
))
1778 maybe_dynamic
= true;
1781 switch (ELFNN_R_TYPE (rel
->r_info
))
1783 case R_IA64_TPREL22
:
1784 case R_IA64_TPREL64MSB
:
1785 case R_IA64_TPREL64LSB
:
1786 case R_IA64_LTOFF_TP22
:
1789 case R_IA64_LTOFF_FPTR22
:
1790 case R_IA64_LTOFF_FPTR64I
:
1791 case R_IA64_LTOFF_FPTR64MSB
:
1792 case R_IA64_LTOFF_FPTR64LSB
:
1793 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
1796 case R_IA64_FPTR64I
:
1797 case R_IA64_FPTR32MSB
:
1798 case R_IA64_FPTR32LSB
:
1799 case R_IA64_FPTR64MSB
:
1800 case R_IA64_FPTR64LSB
:
1801 if (info
->shared
|| h
)
1802 need_entry
= NEED_FPTR
| NEED_DYNREL
;
1804 need_entry
= NEED_FPTR
;
1805 dynrel_type
= R_IA64_FPTR64LSB
;
1808 case R_IA64_LTOFF22
:
1809 case R_IA64_LTOFF22X
:
1810 case R_IA64_LTOFF64I
:
1811 need_entry
= NEED_GOT
;
1814 case R_IA64_PLTOFF22
:
1815 case R_IA64_PLTOFF64I
:
1816 case R_IA64_PLTOFF64MSB
:
1817 case R_IA64_PLTOFF64LSB
:
1818 need_entry
= NEED_PLTOFF
;
1822 need_entry
|= NEED_MIN_PLT
;
1826 (*info
->callbacks
->warning
)
1827 (info
, _("@pltoff reloc against local symbol"), 0,
1832 case R_IA64_PCREL21B
:
1833 case R_IA64_PCREL60B
:
1834 /* Depending on where this symbol is defined, we may or may not
1835 need a full plt entry. Only skip if we know we'll not need
1836 the entry -- static or symbolic, and the symbol definition
1837 has already been seen. */
1838 if (maybe_dynamic
&& rel
->r_addend
== 0)
1839 need_entry
= NEED_FULL_PLT
;
1845 case R_IA64_DIR32MSB
:
1846 case R_IA64_DIR32LSB
:
1847 case R_IA64_DIR64MSB
:
1848 case R_IA64_DIR64LSB
:
1849 /* Shared objects will always need at least a REL relocation. */
1850 if (info
->shared
|| maybe_dynamic
)
1851 need_entry
= NEED_DYNREL
;
1852 dynrel_type
= R_IA64_DIR64LSB
;
1855 case R_IA64_IPLTMSB
:
1856 case R_IA64_IPLTLSB
:
1857 /* Shared objects will always need at least a REL relocation. */
1858 if (info
->shared
|| maybe_dynamic
)
1859 need_entry
= NEED_DYNREL
;
1860 dynrel_type
= R_IA64_IPLTLSB
;
1863 case R_IA64_PCREL22
:
1864 case R_IA64_PCREL64I
:
1865 case R_IA64_PCREL32MSB
:
1866 case R_IA64_PCREL32LSB
:
1867 case R_IA64_PCREL64MSB
:
1868 case R_IA64_PCREL64LSB
:
1870 need_entry
= NEED_DYNREL
;
1871 dynrel_type
= R_IA64_PCREL64LSB
;
1878 if ((need_entry
& NEED_FPTR
) != 0
1881 (*info
->callbacks
->warning
)
1882 (info
, _("non-zero addend in @fptr reloc"), 0,
1886 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, true);
1888 /* Record whether or not this is a local symbol. */
1891 /* Create what's needed. */
1892 if (need_entry
& NEED_GOT
)
1896 got
= get_got (abfd
, info
, ia64_info
);
1900 dyn_i
->want_got
= 1;
1902 if (need_entry
& NEED_FPTR
)
1906 fptr
= get_fptr (abfd
, info
, ia64_info
);
1911 /* FPTRs for shared libraries are allocated by the dynamic
1912 linker. Make sure this local symbol will appear in the
1913 dynamic symbol table. */
1914 if (!h
&& info
->shared
)
1916 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
1917 (info
, abfd
, r_symndx
)))
1921 dyn_i
->want_fptr
= 1;
1923 if (need_entry
& NEED_LTOFF_FPTR
)
1924 dyn_i
->want_ltoff_fptr
= 1;
1925 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
1927 if (!ia64_info
->root
.dynobj
)
1928 ia64_info
->root
.dynobj
= abfd
;
1929 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
1930 dyn_i
->want_plt
= 1;
1932 if (need_entry
& NEED_FULL_PLT
)
1933 dyn_i
->want_plt2
= 1;
1934 if (need_entry
& NEED_PLTOFF
)
1935 dyn_i
->want_pltoff
= 1;
1936 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
1940 srel
= get_reloc_section (abfd
, ia64_info
, sec
, true);
1944 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
1952 struct elfNN_ia64_allocate_data
1954 struct bfd_link_info
*info
;
1958 /* For cleanliness, and potentially faster dynamic loading, allocate
1959 external GOT entries first. */
1962 allocate_global_data_got (dyn_i
, data
)
1963 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1966 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
1969 && ! dyn_i
->want_fptr
1970 && elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
))
1972 dyn_i
->got_offset
= x
->ofs
;
1978 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
1981 allocate_global_fptr_got (dyn_i
, data
)
1982 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1985 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
1989 && elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
))
1991 dyn_i
->got_offset
= x
->ofs
;
1997 /* Lastly, allocate all the GOT entries for local data. */
2000 allocate_local_got (dyn_i
, data
)
2001 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2004 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2007 && ! elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
))
2009 dyn_i
->got_offset
= x
->ofs
;
2015 /* Search for the index of a global symbol in it's defining object file. */
2017 static unsigned long
2018 global_sym_index (h
)
2019 struct elf_link_hash_entry
*h
;
2021 struct elf_link_hash_entry
**p
;
2024 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2025 || h
->root
.type
== bfd_link_hash_defweak
);
2027 obj
= h
->root
.u
.def
.section
->owner
;
2028 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2031 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2034 /* Allocate function descriptors. We can do these for every function
2035 in a main executable that is not exported. */
2038 allocate_fptr (dyn_i
, data
)
2039 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2042 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2044 if (dyn_i
->want_fptr
)
2046 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2049 while (h
->root
.type
== bfd_link_hash_indirect
2050 || h
->root
.type
== bfd_link_hash_warning
)
2051 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2053 if (x
->info
->shared
)
2055 if (h
&& h
->dynindx
== -1)
2057 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2058 || (h
->root
.type
== bfd_link_hash_defweak
));
2060 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2061 (x
->info
, h
->root
.u
.def
.section
->owner
,
2062 global_sym_index (h
)))
2066 dyn_i
->want_fptr
= 0;
2068 else if (h
== NULL
|| h
->dynindx
== -1)
2070 dyn_i
->fptr_offset
= x
->ofs
;
2074 dyn_i
->want_fptr
= 0;
2079 /* Allocate all the minimal PLT entries. */
2082 allocate_plt_entries (dyn_i
, data
)
2083 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2086 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2088 if (dyn_i
->want_plt
)
2090 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2093 while (h
->root
.type
== bfd_link_hash_indirect
2094 || h
->root
.type
== bfd_link_hash_warning
)
2095 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2097 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2098 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2100 bfd_size_type offset
= x
->ofs
;
2102 offset
= PLT_HEADER_SIZE
;
2103 dyn_i
->plt_offset
= offset
;
2104 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2106 dyn_i
->want_pltoff
= 1;
2110 dyn_i
->want_plt
= 0;
2111 dyn_i
->want_plt2
= 0;
2117 /* Allocate all the full PLT entries. */
2120 allocate_plt2_entries (dyn_i
, data
)
2121 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2124 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2126 if (dyn_i
->want_plt2
)
2128 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2129 bfd_size_type ofs
= x
->ofs
;
2131 dyn_i
->plt2_offset
= ofs
;
2132 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2134 while (h
->root
.type
== bfd_link_hash_indirect
2135 || h
->root
.type
== bfd_link_hash_warning
)
2136 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2137 dyn_i
->h
->plt
.offset
= ofs
;
2142 /* Allocate all the PLTOFF entries requested by relocations and
2143 plt entries. We can't share space with allocated FPTR entries,
2144 because the latter are not necessarily addressable by the GP.
2145 ??? Relaxation might be able to determine that they are. */
2148 allocate_pltoff_entries (dyn_i
, data
)
2149 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2152 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2154 if (dyn_i
->want_pltoff
)
2156 dyn_i
->pltoff_offset
= x
->ofs
;
2162 /* Allocate dynamic relocations for those symbols that turned out
2166 allocate_dynrel_entries (dyn_i
, data
)
2167 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2170 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2171 struct elfNN_ia64_link_hash_table
*ia64_info
;
2172 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2173 boolean dynamic_symbol
, shared
;
2175 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2176 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
);
2177 shared
= x
->info
->shared
;
2179 /* Take care of the normal data relocations. */
2181 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2183 int count
= rent
->count
;
2187 case R_IA64_FPTR64LSB
:
2188 /* Allocate one iff !want_fptr, which by this point will
2189 be true only if we're actually allocating one statically
2190 in the main executable. */
2191 if (dyn_i
->want_fptr
)
2194 case R_IA64_PCREL64LSB
:
2195 if (!dynamic_symbol
)
2198 case R_IA64_DIR64LSB
:
2199 if (!dynamic_symbol
&& !shared
)
2202 case R_IA64_IPLTLSB
:
2203 if (!dynamic_symbol
&& !shared
)
2205 /* Use two REL relocations for IPLT relocations
2206 against local symbols. */
2207 if (!dynamic_symbol
)
2213 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2216 /* Take care of the GOT and PLT relocations. */
2218 if (((dynamic_symbol
|| shared
) && dyn_i
->want_got
)
2219 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2220 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2222 if (dyn_i
->want_pltoff
)
2224 bfd_size_type t
= 0;
2226 /* Dynamic symbols get one IPLT relocation. Local symbols in
2227 shared libraries get two REL relocations. Local symbols in
2228 main applications get nothing. */
2230 t
= sizeof (ElfNN_External_Rela
);
2232 t
= 2 * sizeof (ElfNN_External_Rela
);
2234 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2241 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2242 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2243 struct elf_link_hash_entry
*h
;
2245 /* ??? Undefined symbols with PLT entries should be re-defined
2246 to be the PLT entry. */
2248 /* If this is a weak symbol, and there is a real definition, the
2249 processor independent code will have arranged for us to see the
2250 real definition first, and we can just use the same value. */
2251 if (h
->weakdef
!= NULL
)
2253 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2254 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2255 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2256 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2260 /* If this is a reference to a symbol defined by a dynamic object which
2261 is not a function, we might allocate the symbol in our .dynbss section
2262 and allocate a COPY dynamic relocation.
2264 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2271 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2273 struct bfd_link_info
*info
;
2275 struct elfNN_ia64_allocate_data data
;
2276 struct elfNN_ia64_link_hash_table
*ia64_info
;
2279 boolean reltext
= false;
2280 boolean relplt
= false;
2282 dynobj
= elf_hash_table(info
)->dynobj
;
2283 ia64_info
= elfNN_ia64_hash_table (info
);
2284 BFD_ASSERT(dynobj
!= NULL
);
2287 /* Set the contents of the .interp section to the interpreter. */
2288 if (ia64_info
->root
.dynamic_sections_created
2291 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2292 BFD_ASSERT (sec
!= NULL
);
2293 sec
->contents
= (bfd_byte
*) ELF_DYNAMIC_INTERPRETER
;
2294 sec
->_raw_size
= strlen (ELF_DYNAMIC_INTERPRETER
) + 1;
2297 /* Allocate the GOT entries. */
2299 if (ia64_info
->got_sec
)
2302 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2303 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2304 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2305 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2308 /* Allocate the FPTR entries. */
2310 if (ia64_info
->fptr_sec
)
2313 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2314 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2317 /* Now that we've seen all of the input files, we can decide which
2318 symbols need plt entries. Allocate the minimal PLT entries first.
2319 We do this even though dynamic_sections_created may be false, because
2320 this has the side-effect of clearing want_plt and want_plt2. */
2323 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2325 ia64_info
->minplt_entries
= 0;
2328 ia64_info
->minplt_entries
2329 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2332 /* Align the pointer for the plt2 entries. */
2333 data
.ofs
= (data
.ofs
+ 31) & -32;
2335 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2338 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2340 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2342 /* If we've got a .plt, we need some extra memory for the dynamic
2343 linker. We stuff these in .got.plt. */
2344 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2345 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2348 /* Allocate the PLTOFF entries. */
2350 if (ia64_info
->pltoff_sec
)
2353 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2354 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2357 if (ia64_info
->root
.dynamic_sections_created
)
2359 /* Allocate space for the dynamic relocations that turned out to be
2362 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2365 /* We have now determined the sizes of the various dynamic sections.
2366 Allocate memory for them. */
2367 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2371 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2374 /* If we don't need this section, strip it from the output file.
2375 There were several sections primarily related to dynamic
2376 linking that must be create before the linker maps input
2377 sections to output sections. The linker does that before
2378 bfd_elf_size_dynamic_sections is called, and it is that
2379 function which decides whether anything needs to go into
2382 strip
= (sec
->_raw_size
== 0);
2384 if (sec
== ia64_info
->got_sec
)
2386 else if (sec
== ia64_info
->rel_got_sec
)
2389 ia64_info
->rel_got_sec
= NULL
;
2391 /* We use the reloc_count field as a counter if we need to
2392 copy relocs into the output file. */
2393 sec
->reloc_count
= 0;
2395 else if (sec
== ia64_info
->fptr_sec
)
2398 ia64_info
->fptr_sec
= NULL
;
2400 else if (sec
== ia64_info
->plt_sec
)
2403 ia64_info
->plt_sec
= NULL
;
2405 else if (sec
== ia64_info
->pltoff_sec
)
2408 ia64_info
->pltoff_sec
= NULL
;
2410 else if (sec
== ia64_info
->rel_pltoff_sec
)
2413 ia64_info
->rel_pltoff_sec
= NULL
;
2417 /* We use the reloc_count field as a counter if we need to
2418 copy relocs into the output file. */
2419 sec
->reloc_count
= 0;
2426 /* It's OK to base decisions on the section name, because none
2427 of the dynobj section names depend upon the input files. */
2428 name
= bfd_get_section_name (dynobj
, sec
);
2430 if (strcmp (name
, ".got.plt") == 0)
2432 else if (strncmp (name
, ".rel", 4) == 0)
2436 const char *outname
;
2439 /* If this relocation section applies to a read only
2440 section, then we probably need a DT_TEXTREL entry. */
2441 outname
= bfd_get_section_name (output_bfd
,
2442 sec
->output_section
);
2443 if (outname
[4] == 'a')
2448 target
= bfd_get_section_by_name (output_bfd
, outname
);
2450 && (target
->flags
& SEC_READONLY
) != 0
2451 && (target
->flags
& SEC_ALLOC
) != 0)
2454 /* We use the reloc_count field as a counter if we need to
2455 copy relocs into the output file. */
2456 sec
->reloc_count
= 0;
2464 _bfd_strip_section_from_output (info
, sec
);
2467 /* Allocate memory for the section contents. */
2468 sec
->contents
= (bfd_byte
*) bfd_zalloc(dynobj
, sec
->_raw_size
);
2469 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
2474 if (elf_hash_table (info
)->dynamic_sections_created
)
2476 /* Add some entries to the .dynamic section. We fill in the values
2477 later (in finish_dynamic_sections) but we must add the entries now
2478 so that we get the correct size for the .dynamic section. */
2482 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2484 if (!bfd_elfNN_add_dynamic_entry (info
, DT_DEBUG
, 0))
2488 if (! bfd_elfNN_add_dynamic_entry (info
, DT_IA_64_PLT_RESERVE
, 0))
2490 if (! bfd_elfNN_add_dynamic_entry (info
, DT_PLTGOT
, 0))
2495 if (! bfd_elfNN_add_dynamic_entry (info
, DT_PLTRELSZ
, 0)
2496 || ! bfd_elfNN_add_dynamic_entry (info
, DT_PLTREL
, DT_RELA
)
2497 || ! bfd_elfNN_add_dynamic_entry (info
, DT_JMPREL
, 0))
2501 if (! bfd_elfNN_add_dynamic_entry (info
, DT_RELA
, 0)
2502 || ! bfd_elfNN_add_dynamic_entry (info
, DT_RELASZ
, 0)
2503 || ! bfd_elfNN_add_dynamic_entry (info
, DT_RELAENT
,
2504 sizeof (ElfNN_External_Rela
)))
2509 if (! bfd_elfNN_add_dynamic_entry (info
, DT_TEXTREL
, 0))
2511 info
->flags
|= DF_TEXTREL
;
2515 /* ??? Perhaps force __gp local. */
2520 static bfd_reloc_status_type
2521 elfNN_ia64_install_value (abfd
, hit_addr
, val
, r_type
)
2525 unsigned int r_type
;
2527 const struct ia64_operand
*op
;
2528 int bigendian
= 0, shift
= 0;
2529 bfd_vma t0
, t1
, insn
, dword
;
2530 enum ia64_opnd opnd
;
2534 opnd
= IA64_OPND_NIL
;
2539 return bfd_reloc_ok
;
2541 /* Instruction relocations. */
2543 case R_IA64_IMM14
: opnd
= IA64_OPND_IMM14
; break;
2545 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
2546 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
2547 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
2548 case R_IA64_PCREL21B
:
2549 case R_IA64_PCREL21BI
:
2550 opnd
= IA64_OPND_TGT25c
;
2554 case R_IA64_GPREL22
:
2555 case R_IA64_LTOFF22
:
2556 case R_IA64_LTOFF22X
:
2557 case R_IA64_PLTOFF22
:
2558 case R_IA64_PCREL22
:
2559 case R_IA64_LTOFF_FPTR22
:
2560 opnd
= IA64_OPND_IMM22
;
2564 case R_IA64_GPREL64I
:
2565 case R_IA64_LTOFF64I
:
2566 case R_IA64_PLTOFF64I
:
2567 case R_IA64_PCREL64I
:
2568 case R_IA64_FPTR64I
:
2569 case R_IA64_LTOFF_FPTR64I
:
2570 opnd
= IA64_OPND_IMMU64
;
2573 /* Data relocations. */
2575 case R_IA64_DIR32MSB
:
2576 case R_IA64_GPREL32MSB
:
2577 case R_IA64_FPTR32MSB
:
2578 case R_IA64_PCREL32MSB
:
2579 case R_IA64_SEGREL32MSB
:
2580 case R_IA64_SECREL32MSB
:
2581 case R_IA64_LTV32MSB
:
2582 size
= 4; bigendian
= 1;
2585 case R_IA64_DIR32LSB
:
2586 case R_IA64_GPREL32LSB
:
2587 case R_IA64_FPTR32LSB
:
2588 case R_IA64_PCREL32LSB
:
2589 case R_IA64_SEGREL32LSB
:
2590 case R_IA64_SECREL32LSB
:
2591 case R_IA64_LTV32LSB
:
2592 size
= 4; bigendian
= 0;
2595 case R_IA64_DIR64MSB
:
2596 case R_IA64_GPREL64MSB
:
2597 case R_IA64_PLTOFF64MSB
:
2598 case R_IA64_FPTR64MSB
:
2599 case R_IA64_PCREL64MSB
:
2600 case R_IA64_LTOFF_FPTR64MSB
:
2601 case R_IA64_SEGREL64MSB
:
2602 case R_IA64_SECREL64MSB
:
2603 case R_IA64_LTV64MSB
:
2604 size
= 8; bigendian
= 1;
2607 case R_IA64_DIR64LSB
:
2608 case R_IA64_GPREL64LSB
:
2609 case R_IA64_PLTOFF64LSB
:
2610 case R_IA64_FPTR64LSB
:
2611 case R_IA64_PCREL64LSB
:
2612 case R_IA64_LTOFF_FPTR64LSB
:
2613 case R_IA64_SEGREL64LSB
:
2614 case R_IA64_SECREL64LSB
:
2615 case R_IA64_LTV64LSB
:
2616 size
= 8; bigendian
= 0;
2619 /* Unsupported / Dynamic relocations. */
2621 return bfd_reloc_notsupported
;
2626 case IA64_OPND_IMMU64
:
2627 hit_addr
-= (long) hit_addr
& 0x3;
2628 t0
= bfd_get_64 (abfd
, hit_addr
);
2629 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2631 /* tmpl/s: bits 0.. 5 in t0
2632 slot 0: bits 5..45 in t0
2633 slot 1: bits 46..63 in t0, bits 0..22 in t1
2634 slot 2: bits 23..63 in t1 */
2636 /* First, clear the bits that form the 64 bit constant. */
2637 t0
&= ~(0x3ffffLL
<< 46);
2639 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
2640 | (0x01fLL
<< 22) | (0x001LL
<< 21)
2641 | (0x001LL
<< 36)) << 23));
2643 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
2644 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
2645 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
2646 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
2647 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
2648 | (((val
>> 21) & 0x001) << 21) /* ic */
2649 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
2651 bfd_put_64 (abfd
, t0
, hit_addr
);
2652 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2655 case IA64_OPND_TGT64
:
2656 hit_addr
-= (long) hit_addr
& 0x3;
2657 t0
= bfd_get_64 (abfd
, hit_addr
);
2658 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2660 /* tmpl/s: bits 0.. 5 in t0
2661 slot 0: bits 5..45 in t0
2662 slot 1: bits 46..63 in t0, bits 0..22 in t1
2663 slot 2: bits 23..63 in t1 */
2665 /* First, clear the bits that form the 64 bit constant. */
2666 t0
&= ~(0x3ffffLL
<< 46);
2668 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
2671 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
2672 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
2673 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
2674 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
2676 bfd_put_64 (abfd
, t0
, hit_addr
);
2677 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2681 switch ((long) hit_addr
& 0x3)
2683 case 0: shift
= 5; break;
2684 case 1: shift
= 14; hit_addr
+= 3; break;
2685 case 2: shift
= 23; hit_addr
+= 6; break;
2686 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
2688 dword
= bfd_get_64 (abfd
, hit_addr
);
2689 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
2691 op
= elf64_ia64_operands
+ opnd
;
2692 err
= (*op
->insert
) (op
, val
, &insn
);
2694 return bfd_reloc_overflow
;
2696 dword
&= ~(0x1ffffffffffLL
<< shift
);
2697 dword
|= (insn
<< shift
);
2698 bfd_put_64 (abfd
, dword
, hit_addr
);
2702 /* A data relocation. */
2705 bfd_putb32 (val
, hit_addr
);
2707 bfd_putb64 (val
, hit_addr
);
2710 bfd_putl32 (val
, hit_addr
);
2712 bfd_putl64 (val
, hit_addr
);
2716 return bfd_reloc_ok
;
2720 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
2723 struct bfd_link_info
*info
;
2731 Elf_Internal_Rela outrel
;
2733 outrel
.r_offset
= (sec
->output_section
->vma
2734 + sec
->output_offset
2737 BFD_ASSERT (dynindx
!= -1);
2738 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
2739 outrel
.r_addend
= addend
;
2741 if (elf_section_data (sec
)->stab_info
!= NULL
)
2743 /* This may be NULL for linker-generated relocations, as it is
2744 inconvenient to pass all the bits around. And this shouldn't
2746 BFD_ASSERT (info
!= NULL
);
2748 offset
= (_bfd_stab_section_offset
2749 (abfd
, &elf_hash_table (info
)->stab_info
, sec
,
2750 &elf_section_data (sec
)->stab_info
, offset
));
2751 if (offset
== (bfd_vma
) -1)
2753 /* Run for the hills. We shouldn't be outputting a relocation
2754 for this. So do what everyone else does and output a no-op. */
2755 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
2756 outrel
.r_addend
= 0;
2759 outrel
.r_offset
= offset
;
2762 bfd_elfNN_swap_reloca_out (abfd
, &outrel
,
2763 ((ElfNN_External_Rela
*) srel
->contents
2764 + srel
->reloc_count
++));
2765 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
2766 <= srel
->_cooked_size
);
2769 /* Store an entry for target address TARGET_ADDR in the linkage table
2770 and return the gp-relative address of the linkage table entry. */
2773 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
2775 struct bfd_link_info
*info
;
2776 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2780 unsigned int dyn_r_type
;
2782 struct elfNN_ia64_link_hash_table
*ia64_info
;
2785 ia64_info
= elfNN_ia64_hash_table (info
);
2786 got_sec
= ia64_info
->got_sec
;
2788 BFD_ASSERT ((dyn_i
->got_offset
& 7) == 0);
2790 if (! dyn_i
->got_done
)
2792 dyn_i
->got_done
= true;
2794 /* Store the target address in the linkage table entry. */
2795 bfd_put_64 (abfd
, value
, got_sec
->contents
+ dyn_i
->got_offset
);
2797 /* Install a dynamic relocation if needed. */
2799 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
2800 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
2804 dyn_r_type
= R_IA64_REL64LSB
;
2809 if (bfd_big_endian (abfd
))
2813 case R_IA64_REL64LSB
:
2814 dyn_r_type
= R_IA64_REL64MSB
;
2816 case R_IA64_DIR64LSB
:
2817 dyn_r_type
= R_IA64_DIR64MSB
;
2819 case R_IA64_FPTR64LSB
:
2820 dyn_r_type
= R_IA64_FPTR64MSB
;
2828 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
2829 ia64_info
->rel_got_sec
,
2830 dyn_i
->got_offset
, dyn_r_type
,
2835 /* Return the address of the linkage table entry. */
2836 value
= (got_sec
->output_section
->vma
2837 + got_sec
->output_offset
2838 + dyn_i
->got_offset
);
2843 /* Fill in a function descriptor consisting of the function's code
2844 address and its global pointer. Return the descriptor's address. */
2847 set_fptr_entry (abfd
, info
, dyn_i
, value
)
2849 struct bfd_link_info
*info
;
2850 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2853 struct elfNN_ia64_link_hash_table
*ia64_info
;
2856 ia64_info
= elfNN_ia64_hash_table (info
);
2857 fptr_sec
= ia64_info
->fptr_sec
;
2859 if (!dyn_i
->fptr_done
)
2861 dyn_i
->fptr_done
= 1;
2863 /* Fill in the function descriptor. */
2864 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
2865 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
2866 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
2869 /* Return the descriptor's address. */
2870 value
= (fptr_sec
->output_section
->vma
2871 + fptr_sec
->output_offset
2872 + dyn_i
->fptr_offset
);
2877 /* Fill in a PLTOFF entry consisting of the function's code address
2878 and its global pointer. Return the descriptor's address. */
2881 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
2883 struct bfd_link_info
*info
;
2884 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2888 struct elfNN_ia64_link_hash_table
*ia64_info
;
2889 asection
*pltoff_sec
;
2891 ia64_info
= elfNN_ia64_hash_table (info
);
2892 pltoff_sec
= ia64_info
->pltoff_sec
;
2894 /* Don't do anything if this symbol uses a real PLT entry. In
2895 that case, we'll fill this in during finish_dynamic_symbol. */
2896 if ((! dyn_i
->want_plt
|| is_plt
)
2897 && !dyn_i
->pltoff_done
)
2899 bfd_vma gp
= _bfd_get_gp_value (abfd
);
2901 /* Fill in the function descriptor. */
2902 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
2903 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
2905 /* Install dynamic relocations if needed. */
2906 if (!is_plt
&& info
->shared
)
2908 unsigned int dyn_r_type
;
2910 if (bfd_big_endian (abfd
))
2911 dyn_r_type
= R_IA64_REL64MSB
;
2913 dyn_r_type
= R_IA64_REL64LSB
;
2915 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
2916 ia64_info
->rel_pltoff_sec
,
2917 dyn_i
->pltoff_offset
,
2918 dyn_r_type
, 0, value
);
2919 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
2920 ia64_info
->rel_pltoff_sec
,
2921 dyn_i
->pltoff_offset
+ 8,
2925 dyn_i
->pltoff_done
= 1;
2928 /* Return the descriptor's address. */
2929 value
= (pltoff_sec
->output_section
->vma
2930 + pltoff_sec
->output_offset
2931 + dyn_i
->pltoff_offset
);
2936 /* Called through qsort to sort the .IA_64.unwind section during a
2937 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
2938 to the output bfd so we can do proper endianness frobbing. */
2940 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
2943 elfNN_ia64_unwind_entry_compare (a
, b
)
2949 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
2950 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
2952 return (av
< bv
? -1 : av
> bv
? 1 : 0);
2956 elfNN_ia64_final_link (abfd
, info
)
2958 struct bfd_link_info
*info
;
2960 struct elfNN_ia64_link_hash_table
*ia64_info
;
2961 asection
*unwind_output_sec
;
2963 ia64_info
= elfNN_ia64_hash_table (info
);
2965 /* Make sure we've got ourselves a nice fat __gp value. */
2966 if (!info
->relocateable
)
2968 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
2969 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
2970 struct elf_link_hash_entry
*gp
;
2974 /* Find the min and max vma of all sections marked short. Also
2975 collect min and max vma of any type, for use in selecting a
2977 for (os
= abfd
->sections
; os
; os
= os
->next
)
2981 if ((os
->flags
& SEC_ALLOC
) == 0)
2985 hi
= os
->vma
+ os
->_raw_size
;
2993 if (os
->flags
& SEC_SMALL_DATA
)
2995 if (min_short_vma
> lo
)
2997 if (max_short_vma
< hi
)
3002 /* See if the user wants to force a value. */
3003 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", false,
3007 && (gp
->root
.type
== bfd_link_hash_defined
3008 || gp
->root
.type
== bfd_link_hash_defweak
))
3010 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3011 gp_val
= (gp
->root
.u
.def
.value
3012 + gp_sec
->output_section
->vma
3013 + gp_sec
->output_offset
);
3017 /* Pick a sensible value. */
3019 asection
*got_sec
= ia64_info
->got_sec
;
3021 /* Start with just the address of the .got. */
3023 gp_val
= got_sec
->output_section
->vma
;
3024 else if (max_short_vma
!= 0)
3025 gp_val
= min_short_vma
;
3029 /* If it is possible to address the entire image, but we
3030 don't with the choice above, adjust. */
3031 if (max_vma
- min_vma
< 0x400000
3032 && max_vma
- gp_val
<= 0x200000
3033 && gp_val
- min_vma
> 0x200000)
3034 gp_val
= min_vma
+ 0x200000;
3035 else if (max_short_vma
!= 0)
3037 /* If we don't cover all the short data, adjust. */
3038 if (max_short_vma
- gp_val
>= 0x200000)
3039 gp_val
= min_short_vma
+ 0x200000;
3041 /* If we're addressing stuff past the end, adjust back. */
3042 if (gp_val
> max_vma
)
3043 gp_val
= max_vma
- 0x200000 + 8;
3047 /* Validate whether all SHF_IA_64_SHORT sections are within
3048 range of the chosen GP. */
3050 if (max_short_vma
!= 0)
3052 if (max_short_vma
- min_short_vma
>= 0x400000)
3054 (*_bfd_error_handler
)
3055 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3056 bfd_get_filename (abfd
),
3057 (unsigned long) (max_short_vma
- min_short_vma
));
3060 else if ((gp_val
> min_short_vma
3061 && gp_val
- min_short_vma
> 0x200000)
3062 || (gp_val
< max_short_vma
3063 && max_short_vma
- gp_val
>= 0x200000))
3065 (*_bfd_error_handler
)
3066 (_("%s: __gp does not cover short data segment"),
3067 bfd_get_filename (abfd
));
3072 _bfd_set_gp_value (abfd
, gp_val
);
3075 /* If we're producing a final executable, we need to sort the contents
3076 of the .IA_64.unwind section. Force this section to be relocated
3077 into memory rather than written immediately to the output file. */
3078 unwind_output_sec
= NULL
;
3079 if (!info
->relocateable
)
3081 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3084 unwind_output_sec
= s
->output_section
;
3085 unwind_output_sec
->contents
3086 = bfd_malloc (unwind_output_sec
->_raw_size
);
3087 if (unwind_output_sec
->contents
== NULL
)
3092 /* Invoke the regular ELF backend linker to do all the work. */
3093 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3096 if (unwind_output_sec
)
3098 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3099 qsort (unwind_output_sec
->contents
, unwind_output_sec
->_raw_size
/ 24,
3100 24, elfNN_ia64_unwind_entry_compare
);
3102 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3103 unwind_output_sec
->contents
, 0,
3104 unwind_output_sec
->_raw_size
))
3112 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3113 contents
, relocs
, local_syms
, local_sections
)
3115 struct bfd_link_info
*info
;
3117 asection
*input_section
;
3119 Elf_Internal_Rela
*relocs
;
3120 Elf_Internal_Sym
*local_syms
;
3121 asection
**local_sections
;
3123 struct elfNN_ia64_link_hash_table
*ia64_info
;
3124 Elf_Internal_Shdr
*symtab_hdr
;
3125 Elf_Internal_Rela
*rel
;
3126 Elf_Internal_Rela
*relend
;
3128 boolean ret_val
= true; /* for non-fatal errors */
3131 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3132 ia64_info
= elfNN_ia64_hash_table (info
);
3134 /* Infect various flags from the input section to the output section. */
3135 if (info
->relocateable
)
3139 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3140 flags
&= SHF_IA_64_NORECOV
;
3142 elf_section_data(input_section
->output_section
)
3143 ->this_hdr
.sh_flags
|= flags
;
3146 gp_val
= _bfd_get_gp_value (output_bfd
);
3147 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, false);
3150 relend
= relocs
+ input_section
->reloc_count
;
3151 for (; rel
< relend
; ++rel
)
3153 struct elf_link_hash_entry
*h
;
3154 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3155 bfd_reloc_status_type r
;
3156 reloc_howto_type
*howto
;
3157 unsigned long r_symndx
;
3158 Elf_Internal_Sym
*sym
;
3159 unsigned int r_type
;
3163 boolean dynamic_symbol_p
;
3164 boolean undef_weak_ref
;
3166 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3167 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3169 (*_bfd_error_handler
)
3170 (_("%s: unknown relocation type %d"),
3171 bfd_get_filename (input_bfd
), (int)r_type
);
3172 bfd_set_error (bfd_error_bad_value
);
3176 howto
= lookup_howto (r_type
);
3177 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3179 if (info
->relocateable
)
3181 /* This is a relocateable link. We don't have to change
3182 anything, unless the reloc is against a section symbol,
3183 in which case we have to adjust according to where the
3184 section symbol winds up in the output section. */
3185 if (r_symndx
< symtab_hdr
->sh_info
)
3187 sym
= local_syms
+ r_symndx
;
3188 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
3190 sym_sec
= local_sections
[r_symndx
];
3191 rel
->r_addend
+= sym_sec
->output_offset
;
3197 /* This is a final link. */
3202 undef_weak_ref
= false;
3204 if (r_symndx
< symtab_hdr
->sh_info
)
3206 /* Reloc against local symbol. */
3207 sym
= local_syms
+ r_symndx
;
3208 sym_sec
= local_sections
[r_symndx
];
3209 value
= (sym_sec
->output_section
->vma
3210 + sym_sec
->output_offset
3217 /* Reloc against global symbol. */
3218 indx
= r_symndx
- symtab_hdr
->sh_info
;
3219 h
= elf_sym_hashes (input_bfd
)[indx
];
3220 while (h
->root
.type
== bfd_link_hash_indirect
3221 || h
->root
.type
== bfd_link_hash_warning
)
3222 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3225 if (h
->root
.type
== bfd_link_hash_defined
3226 || h
->root
.type
== bfd_link_hash_defweak
)
3228 sym_sec
= h
->root
.u
.def
.section
;
3230 /* Detect the cases that sym_sec->output_section is
3231 expected to be NULL -- all cases in which the symbol
3232 is defined in another shared module. This includes
3233 PLT relocs for which we've created a PLT entry and
3234 other relocs for which we're prepared to create
3235 dynamic relocations. */
3236 /* ??? Just accept it NULL and continue. */
3238 if (sym_sec
->output_section
!= NULL
)
3240 value
= (h
->root
.u
.def
.value
3241 + sym_sec
->output_section
->vma
3242 + sym_sec
->output_offset
);
3245 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3246 undef_weak_ref
= true;
3247 else if (info
->shared
&& !info
->symbolic
3248 && !info
->no_undefined
3249 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3253 if (! ((*info
->callbacks
->undefined_symbol
)
3254 (info
, h
->root
.root
.string
, input_bfd
,
3255 input_section
, rel
->r_offset
,
3256 (!info
->shared
|| info
->no_undefined
3257 || ELF_ST_VISIBILITY (h
->other
)))))
3264 hit_addr
= contents
+ rel
->r_offset
;
3265 value
+= rel
->r_addend
;
3266 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3277 case R_IA64_DIR32MSB
:
3278 case R_IA64_DIR32LSB
:
3279 case R_IA64_DIR64MSB
:
3280 case R_IA64_DIR64LSB
:
3281 /* Install a dynamic relocation for this reloc. */
3282 if ((dynamic_symbol_p
|| info
->shared
)
3283 && (input_section
->flags
& SEC_ALLOC
) != 0)
3285 unsigned int dyn_r_type
;
3289 BFD_ASSERT (srel
!= NULL
);
3291 /* If we don't need dynamic symbol lookup, find a
3292 matching RELATIVE relocation. */
3293 dyn_r_type
= r_type
;
3294 if (dynamic_symbol_p
)
3296 dynindx
= h
->dynindx
;
3297 addend
= rel
->r_addend
;
3304 case R_IA64_DIR32MSB
:
3305 dyn_r_type
= R_IA64_REL32MSB
;
3307 case R_IA64_DIR32LSB
:
3308 dyn_r_type
= R_IA64_REL32LSB
;
3310 case R_IA64_DIR64MSB
:
3311 dyn_r_type
= R_IA64_REL64MSB
;
3313 case R_IA64_DIR64LSB
:
3314 dyn_r_type
= R_IA64_REL64LSB
;
3318 /* We can't represent this without a dynamic symbol.
3319 Adjust the relocation to be against an output
3320 section symbol, which are always present in the
3321 dynamic symbol table. */
3322 /* ??? People shouldn't be doing non-pic code in
3323 shared libraries. Hork. */
3324 (*_bfd_error_handler
)
3325 (_("%s: linking non-pic code in a shared library"),
3326 bfd_get_filename (input_bfd
));
3334 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3335 srel
, rel
->r_offset
, dyn_r_type
,
3340 case R_IA64_LTV32MSB
:
3341 case R_IA64_LTV32LSB
:
3342 case R_IA64_LTV64MSB
:
3343 case R_IA64_LTV64LSB
:
3344 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3347 case R_IA64_GPREL22
:
3348 case R_IA64_GPREL64I
:
3349 case R_IA64_GPREL32MSB
:
3350 case R_IA64_GPREL32LSB
:
3351 case R_IA64_GPREL64MSB
:
3352 case R_IA64_GPREL64LSB
:
3353 if (dynamic_symbol_p
)
3355 (*_bfd_error_handler
)
3356 (_("%s: @gprel relocation against dynamic symbol %s"),
3357 bfd_get_filename (input_bfd
), h
->root
.root
.string
);
3362 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3365 case R_IA64_LTOFF22
:
3366 case R_IA64_LTOFF22X
:
3367 case R_IA64_LTOFF64I
:
3368 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3369 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
3370 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
3372 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3375 case R_IA64_PLTOFF22
:
3376 case R_IA64_PLTOFF64I
:
3377 case R_IA64_PLTOFF64MSB
:
3378 case R_IA64_PLTOFF64LSB
:
3379 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3380 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, false);
3382 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3385 case R_IA64_FPTR64I
:
3386 case R_IA64_FPTR32MSB
:
3387 case R_IA64_FPTR32LSB
:
3388 case R_IA64_FPTR64MSB
:
3389 case R_IA64_FPTR64LSB
:
3390 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3391 if (dyn_i
->want_fptr
)
3393 if (!undef_weak_ref
)
3394 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3400 /* Otherwise, we expect the dynamic linker to create
3405 if (h
->dynindx
!= -1)
3406 dynindx
= h
->dynindx
;
3408 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3409 (info
, h
->root
.u
.def
.section
->owner
,
3410 global_sym_index (h
)));
3414 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3415 (info
, input_bfd
, r_symndx
));
3418 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3419 srel
, rel
->r_offset
, r_type
,
3420 dynindx
, rel
->r_addend
);
3424 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3427 case R_IA64_LTOFF_FPTR22
:
3428 case R_IA64_LTOFF_FPTR64I
:
3429 case R_IA64_LTOFF_FPTR64MSB
:
3430 case R_IA64_LTOFF_FPTR64LSB
:
3434 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3435 if (dyn_i
->want_fptr
)
3437 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
3438 if (!undef_weak_ref
)
3439 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3444 /* Otherwise, we expect the dynamic linker to create
3448 if (h
->dynindx
!= -1)
3449 dynindx
= h
->dynindx
;
3451 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3452 (info
, h
->root
.u
.def
.section
->owner
,
3453 global_sym_index (h
)));
3456 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3457 (info
, input_bfd
, r_symndx
));
3461 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
3462 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
3464 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3468 case R_IA64_PCREL32MSB
:
3469 case R_IA64_PCREL32LSB
:
3470 case R_IA64_PCREL64MSB
:
3471 case R_IA64_PCREL64LSB
:
3472 /* Install a dynamic relocation for this reloc. */
3473 if (dynamic_symbol_p
)
3475 BFD_ASSERT (srel
!= NULL
);
3477 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3478 srel
, rel
->r_offset
, r_type
,
3479 h
->dynindx
, rel
->r_addend
);
3483 case R_IA64_PCREL21BI
:
3484 case R_IA64_PCREL21F
:
3485 case R_IA64_PCREL21M
:
3486 /* ??? These two are only used for speculation fixup code.
3487 They should never be dynamic. */
3488 if (dynamic_symbol_p
)
3490 (*_bfd_error_handler
)
3491 (_("%s: dynamic relocation against speculation fixup"),
3492 bfd_get_filename (input_bfd
));
3498 (*_bfd_error_handler
)
3499 (_("%s: speculation fixup against undefined weak symbol"),
3500 bfd_get_filename (input_bfd
));
3506 case R_IA64_PCREL21B
:
3507 case R_IA64_PCREL60B
:
3508 /* We should have created a PLT entry for any dynamic symbol. */
3511 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
3513 if (dyn_i
&& dyn_i
->want_plt2
)
3515 /* Should have caught this earlier. */
3516 BFD_ASSERT (rel
->r_addend
== 0);
3518 value
= (ia64_info
->plt_sec
->output_section
->vma
3519 + ia64_info
->plt_sec
->output_offset
3520 + dyn_i
->plt2_offset
);
3524 /* Since there's no PLT entry, Validate that this is
3526 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
3528 /* If the symbol is undef_weak, we shouldn't be trying
3529 to call it. There's every chance that we'd wind up
3530 with an out-of-range fixup here. Don't bother setting
3531 any value at all. */
3537 case R_IA64_PCREL22
:
3538 case R_IA64_PCREL64I
:
3540 /* Make pc-relative. */
3541 value
-= (input_section
->output_section
->vma
3542 + input_section
->output_offset
3543 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
3544 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3547 case R_IA64_SEGREL32MSB
:
3548 case R_IA64_SEGREL32LSB
:
3549 case R_IA64_SEGREL64MSB
:
3550 case R_IA64_SEGREL64LSB
:
3552 struct elf_segment_map
*m
;
3553 Elf_Internal_Phdr
*p
;
3555 /* Find the segment that contains the output_section. */
3556 for (m
= elf_tdata (output_bfd
)->segment_map
,
3557 p
= elf_tdata (output_bfd
)->phdr
;
3562 for (i
= m
->count
- 1; i
>= 0; i
--)
3563 if (m
->sections
[i
] == sym_sec
->output_section
)
3571 /* If the input section was discarded from the output, then
3574 if (bfd_is_abs_section (sym_sec
->output_section
))
3577 r
= bfd_reloc_notsupported
;
3581 /* The VMA of the segment is the vaddr of the associated
3583 if (value
> p
->p_vaddr
)
3584 value
-= p
->p_vaddr
;
3587 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
3593 case R_IA64_SECREL32MSB
:
3594 case R_IA64_SECREL32LSB
:
3595 case R_IA64_SECREL64MSB
:
3596 case R_IA64_SECREL64LSB
:
3597 /* Make output-section relative. */
3598 if (value
> input_section
->output_section
->vma
)
3599 value
-= input_section
->output_section
->vma
;
3602 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3605 case R_IA64_IPLTMSB
:
3606 case R_IA64_IPLTLSB
:
3607 /* Install a dynamic relocation for this reloc. */
3608 if ((dynamic_symbol_p
|| info
->shared
)
3609 && (input_section
->flags
& SEC_ALLOC
) != 0)
3611 BFD_ASSERT (srel
!= NULL
);
3613 /* If we don't need dynamic symbol lookup, install two
3614 RELATIVE relocations. */
3615 if (! dynamic_symbol_p
)
3617 unsigned int dyn_r_type
;
3619 if (r_type
== R_IA64_IPLTMSB
)
3620 dyn_r_type
= R_IA64_REL64MSB
;
3622 dyn_r_type
= R_IA64_REL64LSB
;
3624 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3626 srel
, rel
->r_offset
,
3627 dyn_r_type
, 0, value
);
3628 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3630 srel
, rel
->r_offset
+ 8,
3631 dyn_r_type
, 0, gp_val
);
3634 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3635 srel
, rel
->r_offset
, r_type
,
3636 h
->dynindx
, rel
->r_addend
);
3639 if (r_type
== R_IA64_IPLTMSB
)
3640 r_type
= R_IA64_DIR64MSB
;
3642 r_type
= R_IA64_DIR64LSB
;
3643 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3644 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
3649 r
= bfd_reloc_notsupported
;
3658 case bfd_reloc_undefined
:
3659 /* This can happen for global table relative relocs if
3660 __gp is undefined. This is a panic situation so we
3661 don't try to continue. */
3662 (*info
->callbacks
->undefined_symbol
)
3663 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
3666 case bfd_reloc_notsupported
:
3671 name
= h
->root
.root
.string
;
3674 name
= bfd_elf_string_from_elf_section (input_bfd
,
3675 symtab_hdr
->sh_link
,
3680 name
= bfd_section_name (input_bfd
, input_section
);
3682 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
3684 input_section
, rel
->r_offset
))
3690 case bfd_reloc_dangerous
:
3691 case bfd_reloc_outofrange
:
3692 case bfd_reloc_overflow
:
3698 name
= h
->root
.root
.string
;
3701 name
= bfd_elf_string_from_elf_section (input_bfd
,
3702 symtab_hdr
->sh_link
,
3707 name
= bfd_section_name (input_bfd
, input_section
);
3709 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
3725 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
3727 struct bfd_link_info
*info
;
3728 struct elf_link_hash_entry
*h
;
3729 Elf_Internal_Sym
*sym
;
3731 struct elfNN_ia64_link_hash_table
*ia64_info
;
3732 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3734 ia64_info
= elfNN_ia64_hash_table (info
);
3735 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
3737 /* Fill in the PLT data, if required. */
3738 if (dyn_i
&& dyn_i
->want_plt
)
3740 Elf_Internal_Rela outrel
;
3743 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
3744 ElfNN_External_Rela
*rel
;
3746 gp_val
= _bfd_get_gp_value (output_bfd
);
3748 /* Initialize the minimal PLT entry. */
3750 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
3751 plt_sec
= ia64_info
->plt_sec
;
3752 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
3754 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
3755 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
3756 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
3759 plt_addr
= (plt_sec
->output_section
->vma
3760 + plt_sec
->output_offset
3761 + dyn_i
->plt_offset
);
3762 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, true);
3764 /* Initialize the FULL PLT entry, if needed. */
3765 if (dyn_i
->want_plt2
)
3767 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
3769 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
3770 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
3773 /* Mark the symbol as undefined, rather than as defined in the
3774 plt section. Leave the value alone. */
3775 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
3776 first place. But perhaps elflink.h did some for us. */
3777 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
3778 sym
->st_shndx
= SHN_UNDEF
;
3781 /* Create the dynamic relocation. */
3782 outrel
.r_offset
= pltoff_addr
;
3783 if (bfd_little_endian (output_bfd
))
3784 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
3786 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
3787 outrel
.r_addend
= 0;
3789 /* This is fun. In the .IA_64.pltoff section, we've got entries
3790 that correspond both to real PLT entries, and those that
3791 happened to resolve to local symbols but need to be created
3792 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
3793 relocations for the real PLT should come at the end of the
3794 section, so that they can be indexed by plt entry at runtime.
3796 We emitted all of the relocations for the non-PLT @pltoff
3797 entries during relocate_section. So we can consider the
3798 existing sec->reloc_count to be the base of the array of
3801 rel
= (ElfNN_External_Rela
*)ia64_info
->rel_pltoff_sec
->contents
;
3802 rel
+= ia64_info
->rel_pltoff_sec
->reloc_count
;
3804 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, rel
+ index
);
3807 /* Mark some specially defined symbols as absolute. */
3808 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
3809 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
3810 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
3811 sym
->st_shndx
= SHN_ABS
;
3817 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
3819 struct bfd_link_info
*info
;
3821 struct elfNN_ia64_link_hash_table
*ia64_info
;
3824 ia64_info
= elfNN_ia64_hash_table (info
);
3825 dynobj
= ia64_info
->root
.dynobj
;
3827 if (elf_hash_table (info
)->dynamic_sections_created
)
3829 ElfNN_External_Dyn
*dyncon
, *dynconend
;
3830 asection
*sdyn
, *sgotplt
;
3833 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
3834 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
3835 BFD_ASSERT (sdyn
!= NULL
);
3836 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
3837 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
3839 gp_val
= _bfd_get_gp_value (abfd
);
3841 for (; dyncon
< dynconend
; dyncon
++)
3843 Elf_Internal_Dyn dyn
;
3845 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
3850 dyn
.d_un
.d_ptr
= gp_val
;
3854 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
3855 * sizeof (ElfNN_External_Rela
));
3859 /* See the comment above in finish_dynamic_symbol. */
3860 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
3861 + ia64_info
->rel_pltoff_sec
->output_offset
3862 + (ia64_info
->rel_pltoff_sec
->reloc_count
3863 * sizeof (ElfNN_External_Rela
)));
3866 case DT_IA_64_PLT_RESERVE
:
3867 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
3868 + sgotplt
->output_offset
);
3872 /* Do not have RELASZ include JMPREL. This makes things
3873 easier on ld.so. This is not what the rest of BFD set up. */
3874 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
3875 * sizeof (ElfNN_External_Rela
));
3879 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
3882 /* Initialize the PLT0 entry */
3883 if (ia64_info
->plt_sec
)
3885 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
3888 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
3890 pltres
= (sgotplt
->output_section
->vma
3891 + sgotplt
->output_offset
3894 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
3901 /* ELF file flag handling: */
3903 /* Function to keep IA-64 specific file flags. */
3905 elfNN_ia64_set_private_flags (abfd
, flags
)
3909 BFD_ASSERT (!elf_flags_init (abfd
)
3910 || elf_elfheader (abfd
)->e_flags
== flags
);
3912 elf_elfheader (abfd
)->e_flags
= flags
;
3913 elf_flags_init (abfd
) = true;
3917 /* Copy backend specific data from one object module to another */
3919 elfNN_ia64_copy_private_bfd_data (ibfd
, obfd
)
3922 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
3923 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
3926 BFD_ASSERT (!elf_flags_init (obfd
)
3927 || (elf_elfheader (obfd
)->e_flags
3928 == elf_elfheader (ibfd
)->e_flags
));
3930 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
3931 elf_flags_init (obfd
) = true;
3935 /* Merge backend specific data from an object file to the output
3936 object file when linking. */
3938 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
3945 /* Don't even pretend to support mixed-format linking. */
3946 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
3947 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
3950 in_flags
= elf_elfheader (ibfd
)->e_flags
;
3951 out_flags
= elf_elfheader (obfd
)->e_flags
;
3953 if (! elf_flags_init (obfd
))
3955 elf_flags_init (obfd
) = true;
3956 elf_elfheader (obfd
)->e_flags
= in_flags
;
3958 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
3959 && bfd_get_arch_info (obfd
)->the_default
)
3961 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
3962 bfd_get_mach (ibfd
));
3968 /* Check flag compatibility. */
3969 if (in_flags
== out_flags
)
3972 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
3973 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
3974 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
3976 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
3978 (*_bfd_error_handler
)
3979 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
3980 bfd_get_filename (ibfd
));
3982 bfd_set_error (bfd_error_bad_value
);
3985 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
3987 (*_bfd_error_handler
)
3988 (_("%s: linking big-endian files with little-endian files"),
3989 bfd_get_filename (ibfd
));
3991 bfd_set_error (bfd_error_bad_value
);
3994 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
3996 (*_bfd_error_handler
)
3997 (_("%s: linking 64-bit files with 32-bit files"),
3998 bfd_get_filename (ibfd
));
4000 bfd_set_error (bfd_error_bad_value
);
4003 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4005 (*_bfd_error_handler
)
4006 (_("%s: linking constant-gp files with non-constant-gp files"),
4007 bfd_get_filename (ibfd
));
4009 bfd_set_error (bfd_error_bad_value
);
4012 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4013 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4015 (*_bfd_error_handler
)
4016 (_("%s: linking auto-pic files with non-auto-pic files"),
4017 bfd_get_filename (ibfd
));
4019 bfd_set_error (bfd_error_bad_value
);
4027 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4031 FILE *file
= (FILE *) ptr
;
4032 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4034 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4036 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4037 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4038 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4039 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4040 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4041 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4042 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4043 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4044 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4046 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4050 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4051 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4052 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4053 #define TARGET_BIG_NAME "elfNN-ia64-big"
4054 #define ELF_ARCH bfd_arch_ia64
4055 #define ELF_MACHINE_CODE EM_IA_64
4056 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4057 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4058 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4060 #define elf_backend_section_from_shdr \
4061 elfNN_ia64_section_from_shdr
4062 #define elf_backend_section_flags \
4063 elfNN_ia64_section_flags
4064 #define elf_backend_fake_sections \
4065 elfNN_ia64_fake_sections
4066 #define elf_backend_add_symbol_hook \
4067 elfNN_ia64_add_symbol_hook
4068 #define elf_backend_additional_program_headers \
4069 elfNN_ia64_additional_program_headers
4070 #define elf_backend_modify_segment_map \
4071 elfNN_ia64_modify_segment_map
4072 #define elf_info_to_howto \
4073 elfNN_ia64_info_to_howto
4075 #define bfd_elfNN_bfd_reloc_type_lookup \
4076 elfNN_ia64_reloc_type_lookup
4077 #define bfd_elfNN_bfd_is_local_label_name \
4078 elfNN_ia64_is_local_label_name
4079 #define bfd_elfNN_bfd_relax_section \
4080 elfNN_ia64_relax_section
4082 /* Stuff for the BFD linker: */
4083 #define bfd_elfNN_bfd_link_hash_table_create \
4084 elfNN_ia64_hash_table_create
4085 #define elf_backend_create_dynamic_sections \
4086 elfNN_ia64_create_dynamic_sections
4087 #define elf_backend_check_relocs \
4088 elfNN_ia64_check_relocs
4089 #define elf_backend_adjust_dynamic_symbol \
4090 elfNN_ia64_adjust_dynamic_symbol
4091 #define elf_backend_size_dynamic_sections \
4092 elfNN_ia64_size_dynamic_sections
4093 #define elf_backend_relocate_section \
4094 elfNN_ia64_relocate_section
4095 #define elf_backend_finish_dynamic_symbol \
4096 elfNN_ia64_finish_dynamic_symbol
4097 #define elf_backend_finish_dynamic_sections \
4098 elfNN_ia64_finish_dynamic_sections
4099 #define bfd_elfNN_bfd_final_link \
4100 elfNN_ia64_final_link
4102 #define bfd_elfNN_bfd_copy_private_bfd_data \
4103 elfNN_ia64_copy_private_bfd_data
4104 #define bfd_elfNN_bfd_merge_private_bfd_data \
4105 elfNN_ia64_merge_private_bfd_data
4106 #define bfd_elfNN_bfd_set_private_flags \
4107 elfNN_ia64_set_private_flags
4108 #define bfd_elfNN_bfd_print_private_bfd_data \
4109 elfNN_ia64_print_private_bfd_data
4111 #define elf_backend_plt_readonly 1
4112 #define elf_backend_want_plt_sym 0
4113 #define elf_backend_plt_alignment 5
4114 #define elf_backend_got_header_size 0
4115 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4116 #define elf_backend_want_got_plt 1
4117 #define elf_backend_may_use_rel_p 1
4118 #define elf_backend_may_use_rela_p 1
4119 #define elf_backend_default_use_rela_p 1
4120 #define elf_backend_want_dynbss 0
4121 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4122 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4124 #include "elfNN-target.h"