1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001 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
;
115 /* True if this hash entry's addends was translated for
116 SHF_MERGE optimization. */
117 unsigned sec_merge_done
: 1;
120 struct elfNN_ia64_local_hash_table
122 struct bfd_hash_table root
;
123 /* No additional fields for now. */
126 struct elfNN_ia64_link_hash_entry
128 struct elf_link_hash_entry root
;
129 struct elfNN_ia64_dyn_sym_info
*info
;
132 struct elfNN_ia64_link_hash_table
134 /* The main hash table */
135 struct elf_link_hash_table root
;
137 asection
*got_sec
; /* the linkage table section (or NULL) */
138 asection
*rel_got_sec
; /* dynamic relocation section for same */
139 asection
*fptr_sec
; /* function descriptor table (or NULL) */
140 asection
*plt_sec
; /* the primary plt section (or NULL) */
141 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
142 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
144 bfd_size_type minplt_entries
; /* number of minplt entries */
145 unsigned reltext
: 1; /* are there relocs against readonly sections? */
147 struct elfNN_ia64_local_hash_table loc_hash_table
;
150 #define elfNN_ia64_hash_table(p) \
151 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
153 static bfd_reloc_status_type elfNN_ia64_reloc
154 PARAMS ((bfd
*abfd
, arelent
*reloc
, asymbol
*sym
, PTR data
,
155 asection
*input_section
, bfd
*output_bfd
, char **error_message
));
156 static reloc_howto_type
* lookup_howto
157 PARAMS ((unsigned int rtype
));
158 static reloc_howto_type
*elfNN_ia64_reloc_type_lookup
159 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type bfd_code
));
160 static void elfNN_ia64_info_to_howto
161 PARAMS ((bfd
*abfd
, arelent
*bfd_reloc
, ElfNN_Internal_Rela
*elf_reloc
));
162 static boolean elfNN_ia64_relax_section
163 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
165 static boolean is_unwind_section_name
166 PARAMS ((const char *));
167 static boolean elfNN_ia64_section_from_shdr
168 PARAMS ((bfd
*, ElfNN_Internal_Shdr
*, char *));
169 static boolean elfNN_ia64_section_flags
170 PARAMS ((flagword
*, ElfNN_Internal_Shdr
*));
171 static boolean elfNN_ia64_fake_sections
172 PARAMS ((bfd
*abfd
, ElfNN_Internal_Shdr
*hdr
, asection
*sec
));
173 static void elfNN_ia64_final_write_processing
174 PARAMS ((bfd
*abfd
, boolean linker
));
175 static boolean elfNN_ia64_add_symbol_hook
176 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
177 const char **namep
, flagword
*flagsp
, asection
**secp
,
179 static boolean elfNN_ia64_aix_vec
180 PARAMS ((const bfd_target
*vec
));
181 static boolean elfNN_ia64_aix_add_symbol_hook
182 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, const Elf_Internal_Sym
*sym
,
183 const char **namep
, flagword
*flagsp
, asection
**secp
,
185 static boolean elfNN_ia64_aix_link_add_symbols
186 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
187 static int elfNN_ia64_additional_program_headers
188 PARAMS ((bfd
*abfd
));
189 static boolean elfNN_ia64_modify_segment_map
191 static boolean elfNN_ia64_is_local_label_name
192 PARAMS ((bfd
*abfd
, const char *name
));
193 static boolean elfNN_ia64_dynamic_symbol_p
194 PARAMS ((struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
));
195 static boolean elfNN_ia64_local_hash_table_init
196 PARAMS ((struct elfNN_ia64_local_hash_table
*ht
, bfd
*abfd
,
197 new_hash_entry_func
new));
198 static struct bfd_hash_entry
*elfNN_ia64_new_loc_hash_entry
199 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
200 const char *string
));
201 static struct bfd_hash_entry
*elfNN_ia64_new_elf_hash_entry
202 PARAMS ((struct bfd_hash_entry
*entry
, struct bfd_hash_table
*table
,
203 const char *string
));
204 static void elfNN_ia64_hash_copy_indirect
205 PARAMS ((struct elf_link_hash_entry
*, struct elf_link_hash_entry
*));
206 static void elfNN_ia64_hash_hide_symbol
207 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*));
208 static struct bfd_link_hash_table
*elfNN_ia64_hash_table_create
209 PARAMS ((bfd
*abfd
));
210 static struct elfNN_ia64_local_hash_entry
*elfNN_ia64_local_hash_lookup
211 PARAMS ((struct elfNN_ia64_local_hash_table
*table
, const char *string
,
212 boolean create
, boolean copy
));
213 static boolean elfNN_ia64_global_dyn_sym_thunk
214 PARAMS ((struct bfd_hash_entry
*, PTR
));
215 static boolean elfNN_ia64_local_dyn_sym_thunk
216 PARAMS ((struct bfd_hash_entry
*, PTR
));
217 static void elfNN_ia64_dyn_sym_traverse
218 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
219 boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
221 static boolean elfNN_ia64_create_dynamic_sections
222 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
223 static struct elfNN_ia64_local_hash_entry
* get_local_sym_hash
224 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
225 bfd
*abfd
, const Elf_Internal_Rela
*rel
, boolean create
));
226 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
227 PARAMS ((struct elfNN_ia64_link_hash_table
*ia64_info
,
228 struct elf_link_hash_entry
*h
,
229 bfd
*abfd
, const Elf_Internal_Rela
*rel
, boolean create
));
230 static asection
*get_got
231 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
232 struct elfNN_ia64_link_hash_table
*ia64_info
));
233 static asection
*get_fptr
234 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
235 struct elfNN_ia64_link_hash_table
*ia64_info
));
236 static asection
*get_pltoff
237 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
238 struct elfNN_ia64_link_hash_table
*ia64_info
));
239 static asection
*get_reloc_section
240 PARAMS ((bfd
*abfd
, struct elfNN_ia64_link_hash_table
*ia64_info
,
241 asection
*sec
, boolean create
));
242 static boolean count_dyn_reloc
243 PARAMS ((bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
244 asection
*srel
, int type
));
245 static boolean elfNN_ia64_check_relocs
246 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
247 const Elf_Internal_Rela
*relocs
));
248 static boolean elfNN_ia64_adjust_dynamic_symbol
249 PARAMS ((struct bfd_link_info
*info
, struct elf_link_hash_entry
*h
));
250 static long global_sym_index
251 PARAMS ((struct elf_link_hash_entry
*h
));
252 static boolean allocate_fptr
253 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
254 static boolean allocate_global_data_got
255 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
256 static boolean allocate_global_fptr_got
257 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
258 static boolean allocate_local_got
259 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
260 static boolean allocate_pltoff_entries
261 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
262 static boolean allocate_plt_entries
263 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
264 static boolean allocate_plt2_entries
265 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
266 static boolean allocate_dynrel_entries
267 PARAMS ((struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
));
268 static boolean elfNN_ia64_size_dynamic_sections
269 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
));
270 static bfd_reloc_status_type elfNN_ia64_install_value
271 PARAMS ((bfd
*abfd
, bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
));
272 static void elfNN_ia64_install_dyn_reloc
273 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
, asection
*sec
,
274 asection
*srel
, bfd_vma offset
, unsigned int type
,
275 long dynindx
, bfd_vma addend
));
276 static bfd_vma set_got_entry
277 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
278 struct elfNN_ia64_dyn_sym_info
*dyn_i
, long dynindx
,
279 bfd_vma addend
, bfd_vma value
, unsigned int dyn_r_type
));
280 static bfd_vma set_fptr_entry
281 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
282 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
284 static bfd_vma set_pltoff_entry
285 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
,
286 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
287 bfd_vma value
, boolean
));
288 static int elfNN_ia64_unwind_entry_compare
289 PARAMS ((const PTR
, const PTR
));
290 static boolean elfNN_ia64_final_link
291 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
292 static boolean elfNN_ia64_relocate_section
293 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
, bfd
*input_bfd
,
294 asection
*input_section
, bfd_byte
*contents
,
295 Elf_Internal_Rela
*relocs
, Elf_Internal_Sym
*local_syms
,
296 asection
**local_sections
));
297 static boolean elfNN_ia64_finish_dynamic_symbol
298 PARAMS ((bfd
*output_bfd
, struct bfd_link_info
*info
,
299 struct elf_link_hash_entry
*h
, Elf_Internal_Sym
*sym
));
300 static boolean elfNN_ia64_finish_dynamic_sections
301 PARAMS ((bfd
*abfd
, struct bfd_link_info
*info
));
302 static boolean elfNN_ia64_set_private_flags
303 PARAMS ((bfd
*abfd
, flagword flags
));
304 static boolean elfNN_ia64_copy_private_bfd_data
305 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
306 static boolean elfNN_ia64_merge_private_bfd_data
307 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
308 static boolean elfNN_ia64_print_private_bfd_data
309 PARAMS ((bfd
*abfd
, PTR ptr
));
310 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
311 PARAMS ((const Elf_Internal_Rela
*));
313 /* ia64-specific relocation */
315 /* Perform a relocation. Not much to do here as all the hard work is
316 done in elfNN_ia64_final_link_relocate. */
317 static bfd_reloc_status_type
318 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
319 output_bfd
, error_message
)
320 bfd
*abfd ATTRIBUTE_UNUSED
;
322 asymbol
*sym ATTRIBUTE_UNUSED
;
323 PTR data ATTRIBUTE_UNUSED
;
324 asection
*input_section
;
326 char **error_message
;
330 reloc
->address
+= input_section
->output_offset
;
333 *error_message
= "Unsupported call to elfNN_ia64_reloc";
334 return bfd_reloc_notsupported
;
337 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
338 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
339 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
341 /* This table has to be sorted according to increasing number of the
343 static reloc_howto_type ia64_howto_table
[] =
345 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, false, true),
347 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, false, true),
348 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, false, true),
349 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, false, true),
350 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, false, true),
351 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, false, true),
352 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, false, true),
353 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, false, true),
355 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, false, true),
356 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, false, true),
357 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, false, true),
358 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, false, true),
359 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, false, true),
360 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, false, true),
362 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, false, true),
363 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, false, true),
365 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, false, true),
366 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, false, true),
367 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, false, true),
368 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, false, true),
370 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, false, true),
371 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, false, true),
372 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, false, true),
373 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, false, true),
374 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, false, true),
376 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, true, true),
377 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, true, true),
378 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, true, true),
379 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, true, true),
380 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, true, true),
381 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, true, true),
382 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, true, true),
383 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, true, true),
385 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, false, true),
386 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, false, true),
387 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, false, true),
388 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, false, true),
389 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, false, true),
390 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, false, true),
392 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, false, true),
393 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, false, true),
394 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, false, true),
395 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, false, true),
397 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, false, true),
398 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, false, true),
399 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, false, true),
400 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, false, true),
402 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, false, true),
403 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, false, true),
404 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, false, true),
405 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, false, true),
407 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, false, true),
408 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, false, true),
409 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, false, true),
410 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, false, true),
412 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, true, true),
413 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, true, true),
414 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, true, true),
416 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, false, true),
417 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, false, true),
418 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, false, true),
419 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, false, true),
420 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, false, true),
422 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, false, false),
423 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, false, false),
424 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, false, false),
425 IA64_HOWTO (R_IA64_LTOFF_TP22
, "LTOFF_TP22", 0, false, false),
428 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
430 /* Given a BFD reloc type, return the matching HOWTO structure. */
432 static reloc_howto_type
*
436 static int inited
= 0;
443 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
444 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
445 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
448 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
449 i
= elf_code_to_howto_index
[rtype
];
450 if (i
>= NELEMS (ia64_howto_table
))
452 return ia64_howto_table
+ i
;
455 static reloc_howto_type
*
456 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
457 bfd
*abfd ATTRIBUTE_UNUSED
;
458 bfd_reloc_code_real_type bfd_code
;
464 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
466 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
467 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
468 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
470 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
471 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
472 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
473 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
475 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
476 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
477 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
478 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
479 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
480 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
482 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
483 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
485 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
486 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
487 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
488 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
489 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
490 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
491 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
492 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
493 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
495 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
496 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
497 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
498 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
499 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
500 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
501 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
502 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
503 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
504 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
505 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
507 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
508 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
509 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
510 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
511 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
512 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
514 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
515 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
516 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
517 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
519 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
520 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
521 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
522 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
524 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
525 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
526 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
527 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
529 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
530 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
531 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
532 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
534 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
535 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
536 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
537 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
538 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
540 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
541 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
542 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
543 case BFD_RELOC_IA64_LTOFF_TP22
: rtype
= R_IA64_LTOFF_TP22
; break;
547 return lookup_howto (rtype
);
550 /* Given a ELF reloc, return the matching HOWTO structure. */
553 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
554 bfd
*abfd ATTRIBUTE_UNUSED
;
556 ElfNN_Internal_Rela
*elf_reloc
;
559 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
562 #define PLT_HEADER_SIZE (3 * 16)
563 #define PLT_MIN_ENTRY_SIZE (1 * 16)
564 #define PLT_FULL_ENTRY_SIZE (2 * 16)
565 #define PLT_RESERVED_WORDS 3
567 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
569 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
570 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
571 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
572 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
573 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
574 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
575 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
576 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
577 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
580 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
582 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
583 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
584 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
587 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
589 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
590 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
591 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
592 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
593 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
594 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
597 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
598 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
599 #define DYNAMIC_INTERPRETER(abfd) \
600 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
602 /* Select out of range branch fixup type. Note that Itanium does
603 not support brl, and so it gets emulated by the kernel. */
606 static const bfd_byte oor_brl
[16] =
608 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
610 0x00, 0x00, 0x00, 0xc0
613 static const bfd_byte oor_ip
[48] =
615 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
616 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
617 0x01, 0x00, 0x00, 0x60,
618 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
619 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
620 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
621 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
622 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
623 0x60, 0x00, 0x80, 0x00 /* br b6;; */
626 /* These functions do relaxation for IA-64 ELF.
628 This is primarily to support branches to targets out of range;
629 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
632 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
635 struct bfd_link_info
*link_info
;
640 struct one_fixup
*next
;
646 Elf_Internal_Shdr
*symtab_hdr
;
647 Elf_Internal_Rela
*internal_relocs
;
648 Elf_Internal_Rela
*free_relocs
= NULL
;
649 Elf_Internal_Rela
*irel
, *irelend
;
651 bfd_byte
*free_contents
= NULL
;
652 ElfNN_External_Sym
*extsyms
;
653 ElfNN_External_Sym
*free_extsyms
= NULL
;
654 struct elfNN_ia64_link_hash_table
*ia64_info
;
655 struct one_fixup
*fixups
= NULL
;
656 boolean changed_contents
= false;
657 boolean changed_relocs
= false;
659 /* Assume we're not going to change any sizes, and we'll only need
663 /* Nothing to do if there are no relocations. */
664 if ((sec
->flags
& SEC_RELOC
) == 0
665 || sec
->reloc_count
== 0)
668 /* If this is the first time we have been called for this section,
669 initialize the cooked size. */
670 if (sec
->_cooked_size
== 0)
671 sec
->_cooked_size
= sec
->_raw_size
;
673 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
675 /* Load the relocations for this section. */
676 internal_relocs
= (_bfd_elfNN_link_read_relocs
677 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
678 link_info
->keep_memory
));
679 if (internal_relocs
== NULL
)
682 if (! link_info
->keep_memory
)
683 free_relocs
= internal_relocs
;
685 ia64_info
= elfNN_ia64_hash_table (link_info
);
686 irelend
= internal_relocs
+ sec
->reloc_count
;
688 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
689 if (ELFNN_R_TYPE (irel
->r_info
) == (int) R_IA64_PCREL21B
)
692 /* No branch-type relocations. */
695 if (free_relocs
!= NULL
)
700 /* Get the section contents. */
701 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
702 contents
= elf_section_data (sec
)->this_hdr
.contents
;
705 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
706 if (contents
== NULL
)
708 free_contents
= contents
;
710 if (! bfd_get_section_contents (abfd
, sec
, contents
,
711 (file_ptr
) 0, sec
->_raw_size
))
715 /* Read this BFD's symbols. */
716 if (symtab_hdr
->contents
!= NULL
)
717 extsyms
= (ElfNN_External_Sym
*) symtab_hdr
->contents
;
720 extsyms
= (ElfNN_External_Sym
*) bfd_malloc (symtab_hdr
->sh_size
);
723 free_extsyms
= extsyms
;
724 if (bfd_seek (abfd
, symtab_hdr
->sh_offset
, SEEK_SET
) != 0
725 || (bfd_bread (extsyms
, symtab_hdr
->sh_size
, abfd
)
726 != symtab_hdr
->sh_size
))
730 for (; irel
< irelend
; irel
++)
732 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
733 Elf_Internal_Sym isym
;
738 if (ELFNN_R_TYPE (irel
->r_info
) != (int) R_IA64_PCREL21B
)
741 /* Get the value of the symbol referred to by the reloc. */
742 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
744 /* A local symbol. */
745 bfd_elfNN_swap_symbol_in (abfd
,
746 extsyms
+ ELFNN_R_SYM (irel
->r_info
),
748 if (isym
.st_shndx
== SHN_UNDEF
)
749 continue; /* We can't do anthing with undefined symbols. */
750 else if (isym
.st_shndx
== SHN_ABS
)
751 tsec
= bfd_abs_section_ptr
;
752 else if (isym
.st_shndx
== SHN_COMMON
)
753 tsec
= bfd_com_section_ptr
;
754 else if (isym
.st_shndx
> 0 && isym
.st_shndx
< SHN_LORESERVE
)
755 tsec
= bfd_section_from_elf_index (abfd
, isym
.st_shndx
);
757 continue; /* who knows. */
759 toff
= isym
.st_value
;
764 struct elf_link_hash_entry
*h
;
765 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
767 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
768 h
= elf_sym_hashes (abfd
)[indx
];
769 BFD_ASSERT (h
!= NULL
);
771 while (h
->root
.type
== bfd_link_hash_indirect
772 || h
->root
.type
== bfd_link_hash_warning
)
773 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
775 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, false);
777 /* For branches to dynamic symbols, we're interested instead
778 in a branch to the PLT entry. */
779 if (dyn_i
&& dyn_i
->want_plt2
)
781 tsec
= ia64_info
->plt_sec
;
782 toff
= dyn_i
->plt2_offset
;
786 /* We can't do anthing with undefined symbols. */
787 if (h
->root
.type
== bfd_link_hash_undefined
788 || h
->root
.type
== bfd_link_hash_undefweak
)
791 tsec
= h
->root
.u
.def
.section
;
792 toff
= h
->root
.u
.def
.value
;
796 symaddr
= (tsec
->output_section
->vma
797 + tsec
->output_offset
801 roff
= irel
->r_offset
;
802 reladdr
= (sec
->output_section
->vma
804 + roff
) & (bfd_vma
) -4;
806 /* If the branch is in range, no need to do anything. */
807 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
808 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
811 /* If the branch and target are in the same section, you've
812 got one honking big section and we can't help you. You'll
813 get an error message later. */
817 /* Look for an existing fixup to this address. */
818 for (f
= fixups
; f
; f
= f
->next
)
819 if (f
->tsec
== tsec
&& f
->toff
== toff
)
824 /* Two alternatives: If it's a branch to a PLT entry, we can
825 make a copy of the FULL_PLT entry. Otherwise, we'll have
826 to use a `brl' insn to get where we're going. */
830 if (tsec
== ia64_info
->plt_sec
)
831 size
= sizeof (plt_full_entry
);
835 size
= sizeof (oor_brl
);
837 size
= sizeof (oor_ip
);
841 /* Resize the current section to make room for the new branch. */
842 trampoff
= (sec
->_cooked_size
+ 15) & (bfd_vma
) -16;
843 amt
= trampoff
+ size
;
844 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
845 if (contents
== NULL
)
847 sec
->_cooked_size
= amt
;
849 if (tsec
== ia64_info
->plt_sec
)
851 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
853 /* Hijack the old relocation for use as the PLTOFF reloc. */
854 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
856 irel
->r_offset
= trampoff
;
861 memcpy (contents
+ trampoff
, oor_brl
, size
);
862 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
864 irel
->r_offset
= trampoff
+ 2;
866 memcpy (contents
+ trampoff
, oor_ip
, size
);
867 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
869 irel
->r_addend
-= 16;
870 irel
->r_offset
= trampoff
+ 2;
874 /* Record the fixup so we don't do it again this section. */
875 f
= (struct one_fixup
*) bfd_malloc ((bfd_size_type
) sizeof (*f
));
879 f
->trampoff
= trampoff
;
884 /* Nop out the reloc, since we're finalizing things here. */
885 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
888 /* Fix up the existing branch to hit the trampoline. Hope like
889 hell this doesn't overflow too. */
890 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
891 f
->trampoff
- (roff
& (bfd_vma
) -4),
892 R_IA64_PCREL21B
) != bfd_reloc_ok
)
895 changed_contents
= true;
896 changed_relocs
= true;
899 /* Clean up and go home. */
902 struct one_fixup
*f
= fixups
;
903 fixups
= fixups
->next
;
908 elf_section_data (sec
)->relocs
= internal_relocs
;
909 else if (free_relocs
!= NULL
)
912 if (changed_contents
)
913 elf_section_data (sec
)->this_hdr
.contents
= contents
;
914 else if (free_contents
!= NULL
)
916 if (! link_info
->keep_memory
)
917 free (free_contents
);
920 /* Cache the section contents for elf_link_input_bfd. */
921 elf_section_data (sec
)->this_hdr
.contents
= contents
;
925 if (free_extsyms
!= NULL
)
927 if (! link_info
->keep_memory
)
931 /* Cache the symbols for elf_link_input_bfd. */
932 symtab_hdr
->contents
= (unsigned char *) extsyms
;
936 *again
= changed_contents
|| changed_relocs
;
940 if (free_relocs
!= NULL
)
942 if (free_contents
!= NULL
)
943 free (free_contents
);
944 if (free_extsyms
!= NULL
)
949 /* Return true if NAME is an unwind table section name. */
951 static inline boolean
952 is_unwind_section_name (name
)
955 size_t len1
, len2
, len3
;
957 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
958 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
959 len3
= sizeof (ELF_STRING_ia64_unwind_once
) - 1;
960 return ((strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
961 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0)
962 || strncmp (name
, ELF_STRING_ia64_unwind_once
, len3
) == 0);
965 /* Handle an IA-64 specific section when reading an object file. This
966 is called when elfcode.h finds a section with an unknown type. */
969 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
971 ElfNN_Internal_Shdr
*hdr
;
976 /* There ought to be a place to keep ELF backend specific flags, but
977 at the moment there isn't one. We just keep track of the
978 sections by their name, instead. Fortunately, the ABI gives
979 suggested names for all the MIPS specific sections, so we will
980 probably get away with this. */
981 switch (hdr
->sh_type
)
983 case SHT_IA_64_UNWIND
:
987 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
995 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
997 newsect
= hdr
->bfd_section
;
1002 /* Convert IA-64 specific section flags to bfd internal section flags. */
1004 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1008 elfNN_ia64_section_flags (flags
, hdr
)
1010 ElfNN_Internal_Shdr
*hdr
;
1012 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1013 *flags
|= SEC_SMALL_DATA
;
1018 /* Set the correct type for an IA-64 ELF section. We do this by the
1019 section name, which is a hack, but ought to work. */
1022 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1023 bfd
*abfd ATTRIBUTE_UNUSED
;
1024 ElfNN_Internal_Shdr
*hdr
;
1027 register const char *name
;
1029 name
= bfd_get_section_name (abfd
, sec
);
1031 if (is_unwind_section_name (name
))
1033 /* We don't have the sections numbered at this point, so sh_info
1034 is set later, in elfNN_ia64_final_write_processing. */
1035 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1036 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1038 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1039 hdr
->sh_type
= SHT_IA_64_EXT
;
1040 else if (strcmp (name
, ".reloc") == 0)
1042 * This is an ugly, but unfortunately necessary hack that is
1043 * needed when producing EFI binaries on IA-64. It tells
1044 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1045 * containing ELF relocation info. We need this hack in order to
1046 * be able to generate ELF binaries that can be translated into
1047 * EFI applications (which are essentially COFF objects). Those
1048 * files contain a COFF ".reloc" section inside an ELFNN object,
1049 * which would normally cause BFD to segfault because it would
1050 * attempt to interpret this section as containing relocation
1051 * entries for section "oc". With this hack enabled, ".reloc"
1052 * will be treated as a normal data section, which will avoid the
1053 * segfault. However, you won't be able to create an ELFNN binary
1054 * with a section named "oc" that needs relocations, but that's
1055 * the kind of ugly side-effects you get when detecting section
1056 * types based on their names... In practice, this limitation is
1059 hdr
->sh_type
= SHT_PROGBITS
;
1061 if (sec
->flags
& SEC_SMALL_DATA
)
1062 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1067 /* The final processing done just before writing out an IA-64 ELF
1071 elfNN_ia64_final_write_processing (abfd
, linker
)
1073 boolean linker ATTRIBUTE_UNUSED
;
1075 Elf_Internal_Shdr
*hdr
;
1077 asection
*text_sect
, *s
;
1080 for (s
= abfd
->sections
; s
; s
= s
->next
)
1082 hdr
= &elf_section_data (s
)->this_hdr
;
1083 switch (hdr
->sh_type
)
1085 case SHT_IA_64_UNWIND
:
1086 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1088 sname
= bfd_get_section_name (abfd
, s
);
1089 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1090 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1094 if (sname
[0] == '\0')
1095 /* .IA_64.unwind -> .text */
1096 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1098 /* .IA_64.unwindFOO -> FOO */
1099 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1102 && (len
= sizeof (ELF_STRING_ia64_unwind_once
) - 1,
1103 strncmp (sname
, ELF_STRING_ia64_unwind_once
, len
)) == 0)
1105 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1106 size_t len2
= sizeof (".gnu.linkonce.t.") - 1;
1107 char *once_name
= alloca (len2
+ strlen (sname
) - len
+ 1);
1109 memcpy (once_name
, ".gnu.linkonce.t.", len2
);
1110 strcpy (once_name
+ len2
, sname
+ len
);
1111 text_sect
= bfd_get_section_by_name (abfd
, once_name
);
1114 /* last resort: fall back on .text */
1115 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1119 /* The IA-64 processor-specific ABI requires setting
1120 sh_link to the unwind section, whereas HP-UX requires
1121 sh_info to do so. For maximum compatibility, we'll
1122 set both for now... */
1123 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1124 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1131 /* Hook called by the linker routine which adds symbols from an object
1132 file. We use it to put .comm items in .sbss, and not .bss. */
1135 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1137 struct bfd_link_info
*info
;
1138 const Elf_Internal_Sym
*sym
;
1139 const char **namep ATTRIBUTE_UNUSED
;
1140 flagword
*flagsp ATTRIBUTE_UNUSED
;
1144 if (sym
->st_shndx
== SHN_COMMON
1145 && !info
->relocateable
1146 && sym
->st_size
<= elf_gp_size (abfd
))
1148 /* Common symbols less than or equal to -G nn bytes are
1149 automatically put into .sbss. */
1151 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1155 scomm
= bfd_make_section (abfd
, ".scommon");
1157 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1159 | SEC_LINKER_CREATED
)))
1164 *valp
= sym
->st_size
;
1171 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1173 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1174 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1176 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1177 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1180 /* Hook called by the linker routine which adds symbols from an object
1181 file. We use it to handle OS-specific symbols. */
1184 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1186 struct bfd_link_info
*info
;
1187 const Elf_Internal_Sym
*sym
;
1193 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1195 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1196 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1197 no one else should use it b/c it is undocumented. */
1198 struct elf_link_hash_entry
*h
;
1200 h
= elf_link_hash_lookup (elf_hash_table (info
), *namep
,
1201 false, false, false);
1204 struct elf_backend_data
*bed
;
1205 struct elfNN_ia64_link_hash_table
*ia64_info
;
1207 bed
= get_elf_backend_data (abfd
);
1208 ia64_info
= elfNN_ia64_hash_table (info
);
1210 if (!(_bfd_generic_link_add_one_symbol
1211 (info
, abfd
, *namep
, BSF_GLOBAL
,
1212 bfd_get_section_by_name (abfd
, ".bss"),
1213 bed
->got_symbol_offset
, (const char *) NULL
, false,
1214 bed
->collect
, (struct bfd_link_hash_entry
**) &h
)))
1217 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1218 h
->type
= STT_OBJECT
;
1220 if (! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1226 else if (sym
->st_shndx
== SHN_LOOS
)
1230 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1231 is only relevant when compiling code for extended system calls.
1232 Replace the "special" section with .text, if possible.
1233 Note that these symbols are always assumed to be in .text. */
1234 for (i
= 1; i
< elf_elfheader (abfd
)->e_shnum
; i
++)
1236 asection
* sec
= bfd_section_from_elf_index (abfd
, (unsigned) i
);
1238 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1246 *secp
= bfd_abs_section_ptr
;
1248 *valp
= sym
->st_size
;
1254 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1255 namep
, flagsp
, secp
, valp
);
1260 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1262 struct bfd_link_info
*info
;
1264 /* Make sure dynamic sections are always created. */
1265 if (! elf_hash_table (info
)->dynamic_sections_created
1266 && abfd
->xvec
== info
->hash
->creator
)
1268 if (! bfd_elfNN_link_create_dynamic_sections (abfd
, info
))
1272 /* Now do the standard call. */
1273 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1276 /* Return the number of additional phdrs we will need. */
1279 elfNN_ia64_additional_program_headers (abfd
)
1285 /* See if we need a PT_IA_64_ARCHEXT segment. */
1286 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1287 if (s
&& (s
->flags
& SEC_LOAD
))
1290 /* Count how many PT_IA_64_UNWIND segments we need. */
1291 for (s
= abfd
->sections
; s
; s
= s
->next
)
1292 if (is_unwind_section_name(s
->name
) && (s
->flags
& SEC_LOAD
))
1299 elfNN_ia64_modify_segment_map (abfd
)
1302 struct elf_segment_map
*m
, **pm
;
1303 Elf_Internal_Shdr
*hdr
;
1306 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1307 all PT_LOAD segments. */
1308 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1309 if (s
&& (s
->flags
& SEC_LOAD
))
1311 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1312 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1316 m
= ((struct elf_segment_map
*)
1317 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1321 m
->p_type
= PT_IA_64_ARCHEXT
;
1325 /* We want to put it after the PHDR and INTERP segments. */
1326 pm
= &elf_tdata (abfd
)->segment_map
;
1328 && ((*pm
)->p_type
== PT_PHDR
1329 || (*pm
)->p_type
== PT_INTERP
))
1337 /* Install PT_IA_64_UNWIND segments, if needed. */
1338 for (s
= abfd
->sections
; s
; s
= s
->next
)
1340 hdr
= &elf_section_data (s
)->this_hdr
;
1341 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1344 if (s
&& (s
->flags
& SEC_LOAD
))
1346 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1347 if (m
->p_type
== PT_IA_64_UNWIND
&& m
->sections
[0] == s
)
1352 m
= ((struct elf_segment_map
*)
1353 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1357 m
->p_type
= PT_IA_64_UNWIND
;
1362 /* We want to put it last. */
1363 pm
= &elf_tdata (abfd
)->segment_map
;
1371 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1372 the input sections for each output section in the segment and testing
1373 for SHF_IA_64_NORECOV on each. */
1374 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1375 if (m
->p_type
== PT_LOAD
)
1378 for (i
= m
->count
- 1; i
>= 0; --i
)
1380 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1383 if (order
->type
== bfd_indirect_link_order
)
1385 asection
*is
= order
->u
.indirect
.section
;
1386 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1387 if (flags
& SHF_IA_64_NORECOV
)
1389 m
->p_flags
|= PF_IA_64_NORECOV
;
1393 order
= order
->next
;
1402 /* According to the Tahoe assembler spec, all labels starting with a
1406 elfNN_ia64_is_local_label_name (abfd
, name
)
1407 bfd
*abfd ATTRIBUTE_UNUSED
;
1410 return name
[0] == '.';
1413 /* Should we do dynamic things to this symbol? */
1416 elfNN_ia64_dynamic_symbol_p (h
, info
)
1417 struct elf_link_hash_entry
*h
;
1418 struct bfd_link_info
*info
;
1423 while (h
->root
.type
== bfd_link_hash_indirect
1424 || h
->root
.type
== bfd_link_hash_warning
)
1425 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1427 if (h
->dynindx
== -1)
1429 switch (ELF_ST_VISIBILITY (h
->other
))
1436 if (h
->root
.type
== bfd_link_hash_undefweak
1437 || h
->root
.type
== bfd_link_hash_defweak
)
1440 if ((info
->shared
&& (!info
->symbolic
|| info
->allow_shlib_undefined
))
1441 || ((h
->elf_link_hash_flags
1442 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1443 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1450 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1451 struct elfNN_ia64_local_hash_table
*ht
;
1452 bfd
*abfd ATTRIBUTE_UNUSED
;
1453 new_hash_entry_func
new;
1455 memset (ht
, 0, sizeof (*ht
));
1456 return bfd_hash_table_init (&ht
->root
, new);
1459 static struct bfd_hash_entry
*
1460 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1461 struct bfd_hash_entry
*entry
;
1462 struct bfd_hash_table
*table
;
1465 struct elfNN_ia64_local_hash_entry
*ret
;
1466 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1468 /* Allocate the structure if it has not already been allocated by a
1471 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1476 /* Initialize our local data. All zeros, and definitely easier
1477 than setting a handful of bit fields. */
1478 memset (ret
, 0, sizeof (*ret
));
1480 /* Call the allocation method of the superclass. */
1481 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1482 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1484 return (struct bfd_hash_entry
*) ret
;
1487 static struct bfd_hash_entry
*
1488 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1489 struct bfd_hash_entry
*entry
;
1490 struct bfd_hash_table
*table
;
1493 struct elfNN_ia64_link_hash_entry
*ret
;
1494 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1496 /* Allocate the structure if it has not already been allocated by a
1499 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1504 /* Initialize our local data. All zeros, and definitely easier
1505 than setting a handful of bit fields. */
1506 memset (ret
, 0, sizeof (*ret
));
1508 /* Call the allocation method of the superclass. */
1509 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1510 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1513 return (struct bfd_hash_entry
*) ret
;
1517 elfNN_ia64_hash_copy_indirect (xdir
, xind
)
1518 struct elf_link_hash_entry
*xdir
, *xind
;
1520 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1522 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1523 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1525 /* Copy down any references that we may have already seen to the
1526 symbol which just became indirect. */
1528 dir
->root
.elf_link_hash_flags
|=
1529 (ind
->root
.elf_link_hash_flags
1530 & (ELF_LINK_HASH_REF_DYNAMIC
1531 | ELF_LINK_HASH_REF_REGULAR
1532 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1534 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1537 /* Copy over the got and plt data. This would have been done
1540 if (dir
->info
== NULL
)
1542 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1544 dir
->info
= dyn_i
= ind
->info
;
1547 /* Fix up the dyn_sym_info pointers to the global symbol. */
1548 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1549 dyn_i
->h
= &dir
->root
;
1551 BFD_ASSERT (ind
->info
== NULL
);
1553 /* Copy over the dynindx. */
1555 if (dir
->root
.dynindx
== -1)
1557 dir
->root
.dynindx
= ind
->root
.dynindx
;
1558 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1559 ind
->root
.dynindx
= -1;
1560 ind
->root
.dynstr_index
= 0;
1562 BFD_ASSERT (ind
->root
.dynindx
== -1);
1566 elfNN_ia64_hash_hide_symbol (info
, xh
)
1567 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1568 struct elf_link_hash_entry
*xh
;
1570 struct elfNN_ia64_link_hash_entry
*h
;
1571 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1573 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1575 h
->root
.elf_link_hash_flags
&= ~ELF_LINK_HASH_NEEDS_PLT
;
1576 if ((h
->root
.elf_link_hash_flags
& ELF_LINK_FORCED_LOCAL
) != 0)
1577 h
->root
.dynindx
= -1;
1579 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1580 dyn_i
->want_plt2
= 0;
1583 /* Create the derived linker hash table. The IA-64 ELF port uses this
1584 derived hash table to keep information specific to the IA-64 ElF
1585 linker (without using static variables). */
1587 static struct bfd_link_hash_table
*
1588 elfNN_ia64_hash_table_create (abfd
)
1591 struct elfNN_ia64_link_hash_table
*ret
;
1593 ret
= bfd_zalloc (abfd
, (bfd_size_type
) sizeof (*ret
));
1596 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1597 elfNN_ia64_new_elf_hash_entry
))
1599 bfd_release (abfd
, ret
);
1603 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1604 elfNN_ia64_new_loc_hash_entry
))
1606 return &ret
->root
.root
;
1609 /* Look up an entry in a Alpha ELF linker hash table. */
1611 static INLINE
struct elfNN_ia64_local_hash_entry
*
1612 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1613 struct elfNN_ia64_local_hash_table
*table
;
1615 boolean create
, copy
;
1617 return ((struct elfNN_ia64_local_hash_entry
*)
1618 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1621 /* Traverse both local and global hash tables. */
1623 struct elfNN_ia64_dyn_sym_traverse_data
1625 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1630 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1631 struct bfd_hash_entry
*xentry
;
1634 struct elfNN_ia64_link_hash_entry
*entry
1635 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1636 struct elfNN_ia64_dyn_sym_traverse_data
*data
1637 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1638 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1640 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1641 if (! (*data
->func
) (dyn_i
, data
->data
))
1647 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1648 struct bfd_hash_entry
*xentry
;
1651 struct elfNN_ia64_local_hash_entry
*entry
1652 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1653 struct elfNN_ia64_dyn_sym_traverse_data
*data
1654 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1655 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1657 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1658 if (! (*data
->func
) (dyn_i
, data
->data
))
1664 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1665 struct elfNN_ia64_link_hash_table
*ia64_info
;
1666 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1669 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1674 elf_link_hash_traverse (&ia64_info
->root
,
1675 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1676 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1677 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1681 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1683 struct bfd_link_info
*info
;
1685 struct elfNN_ia64_link_hash_table
*ia64_info
;
1688 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1691 ia64_info
= elfNN_ia64_hash_table (info
);
1693 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1694 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1697 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1698 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1701 if (!get_pltoff (abfd
, info
, ia64_info
))
1704 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1706 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1709 | SEC_LINKER_CREATED
1711 || !bfd_set_section_alignment (abfd
, s
, 3))
1713 ia64_info
->rel_pltoff_sec
= s
;
1715 s
= bfd_make_section(abfd
, ".rela.got");
1717 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1720 | SEC_LINKER_CREATED
1722 || !bfd_set_section_alignment (abfd
, s
, 3))
1724 ia64_info
->rel_got_sec
= s
;
1729 /* Find and/or create a hash entry for local symbol. */
1730 static struct elfNN_ia64_local_hash_entry
*
1731 get_local_sym_hash (ia64_info
, abfd
, rel
, create
)
1732 struct elfNN_ia64_link_hash_table
*ia64_info
;
1734 const Elf_Internal_Rela
*rel
;
1740 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1741 name describes what was once anonymous memory. */
1743 len
= sizeof (void*)*2 + 1 + sizeof (bfd_vma
)*4 + 1 + 1;
1744 len
+= 10; /* %p slop */
1746 addr_name
= alloca (len
);
1747 sprintf (addr_name
, "%p:%lx",
1748 (void *) abfd
, (unsigned long) ELFNN_R_SYM (rel
->r_info
));
1750 /* Collect the canonical entry data for this address. */
1751 return elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1752 addr_name
, create
, create
);
1755 /* Find and/or create a descriptor for dynamic symbol info. This will
1756 vary based on global or local symbol, and the addend to the reloc. */
1758 static struct elfNN_ia64_dyn_sym_info
*
1759 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1760 struct elfNN_ia64_link_hash_table
*ia64_info
;
1761 struct elf_link_hash_entry
*h
;
1763 const Elf_Internal_Rela
*rel
;
1766 struct elfNN_ia64_dyn_sym_info
**pp
;
1767 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1768 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1771 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1774 struct elfNN_ia64_local_hash_entry
*loc_h
;
1776 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
1782 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
1785 if (dyn_i
== NULL
&& create
)
1787 dyn_i
= ((struct elfNN_ia64_dyn_sym_info
*)
1788 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *dyn_i
));
1790 dyn_i
->addend
= addend
;
1797 get_got (abfd
, info
, ia64_info
)
1799 struct bfd_link_info
*info
;
1800 struct elfNN_ia64_link_hash_table
*ia64_info
;
1805 got
= ia64_info
->got_sec
;
1810 dynobj
= ia64_info
->root
.dynobj
;
1812 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1813 if (!_bfd_elf_create_got_section (dynobj
, info
))
1816 got
= bfd_get_section_by_name (dynobj
, ".got");
1818 ia64_info
->got_sec
= got
;
1820 flags
= bfd_get_section_flags (abfd
, got
);
1821 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
1827 /* Create function descriptor section (.opd). This section is called .opd
1828 because it contains "official prodecure descriptors". The "official"
1829 refers to the fact that these descriptors are used when taking the address
1830 of a procedure, thus ensuring a unique address for each procedure. */
1833 get_fptr (abfd
, info
, ia64_info
)
1835 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1836 struct elfNN_ia64_link_hash_table
*ia64_info
;
1841 fptr
= ia64_info
->fptr_sec
;
1844 dynobj
= ia64_info
->root
.dynobj
;
1846 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1848 fptr
= bfd_make_section (dynobj
, ".opd");
1850 || !bfd_set_section_flags (dynobj
, fptr
,
1856 | SEC_LINKER_CREATED
))
1857 || !bfd_set_section_alignment (abfd
, fptr
, 4))
1863 ia64_info
->fptr_sec
= fptr
;
1870 get_pltoff (abfd
, info
, ia64_info
)
1872 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1873 struct elfNN_ia64_link_hash_table
*ia64_info
;
1878 pltoff
= ia64_info
->pltoff_sec
;
1881 dynobj
= ia64_info
->root
.dynobj
;
1883 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1885 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
1887 || !bfd_set_section_flags (dynobj
, pltoff
,
1893 | SEC_LINKER_CREATED
))
1894 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
1900 ia64_info
->pltoff_sec
= pltoff
;
1907 get_reloc_section (abfd
, ia64_info
, sec
, create
)
1909 struct elfNN_ia64_link_hash_table
*ia64_info
;
1913 const char *srel_name
;
1917 srel_name
= (bfd_elf_string_from_elf_section
1918 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
1919 elf_section_data(sec
)->rel_hdr
.sh_name
));
1920 if (srel_name
== NULL
)
1923 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
1924 && strcmp (bfd_get_section_name (abfd
, sec
),
1926 || (strncmp (srel_name
, ".rel", 4) == 0
1927 && strcmp (bfd_get_section_name (abfd
, sec
),
1928 srel_name
+4) == 0));
1930 dynobj
= ia64_info
->root
.dynobj
;
1932 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1934 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
1935 if (srel
== NULL
&& create
)
1937 srel
= bfd_make_section (dynobj
, srel_name
);
1939 || !bfd_set_section_flags (dynobj
, srel
,
1944 | SEC_LINKER_CREATED
1946 || !bfd_set_section_alignment (dynobj
, srel
, 3))
1950 if (sec
->flags
& SEC_READONLY
)
1951 ia64_info
->reltext
= 1;
1957 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
1959 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1963 struct elfNN_ia64_dyn_reloc_entry
*rent
;
1965 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
1966 if (rent
->srel
== srel
&& rent
->type
== type
)
1971 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
1972 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
1976 rent
->next
= dyn_i
->reloc_entries
;
1980 dyn_i
->reloc_entries
= rent
;
1988 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
1990 struct bfd_link_info
*info
;
1992 const Elf_Internal_Rela
*relocs
;
1994 struct elfNN_ia64_link_hash_table
*ia64_info
;
1995 const Elf_Internal_Rela
*relend
;
1996 Elf_Internal_Shdr
*symtab_hdr
;
1997 const Elf_Internal_Rela
*rel
;
1998 asection
*got
, *fptr
, *srel
;
2000 if (info
->relocateable
)
2003 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2004 ia64_info
= elfNN_ia64_hash_table (info
);
2006 got
= fptr
= srel
= NULL
;
2008 relend
= relocs
+ sec
->reloc_count
;
2009 for (rel
= relocs
; rel
< relend
; ++rel
)
2018 NEED_LTOFF_FPTR
= 64,
2021 struct elf_link_hash_entry
*h
= NULL
;
2022 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2023 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2025 boolean maybe_dynamic
;
2026 int dynrel_type
= R_IA64_NONE
;
2028 if (r_symndx
>= symtab_hdr
->sh_info
)
2030 /* We're dealing with a global symbol -- find its hash entry
2031 and mark it as being referenced. */
2032 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2033 h
= elf_sym_hashes (abfd
)[indx
];
2034 while (h
->root
.type
== bfd_link_hash_indirect
2035 || h
->root
.type
== bfd_link_hash_warning
)
2036 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2038 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
2041 /* We can only get preliminary data on whether a symbol is
2042 locally or externally defined, as not all of the input files
2043 have yet been processed. Do something with what we know, as
2044 this may help reduce memory usage and processing time later. */
2045 maybe_dynamic
= false;
2046 if (h
&& ((info
->shared
2047 && (!info
->symbolic
|| info
->allow_shlib_undefined
))
2048 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
2049 || h
->root
.type
== bfd_link_hash_defweak
2050 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2051 maybe_dynamic
= true;
2054 switch (ELFNN_R_TYPE (rel
->r_info
))
2056 case R_IA64_TPREL22
:
2057 case R_IA64_TPREL64MSB
:
2058 case R_IA64_TPREL64LSB
:
2059 case R_IA64_LTOFF_TP22
:
2062 case R_IA64_LTOFF_FPTR22
:
2063 case R_IA64_LTOFF_FPTR64I
:
2064 case R_IA64_LTOFF_FPTR32MSB
:
2065 case R_IA64_LTOFF_FPTR32LSB
:
2066 case R_IA64_LTOFF_FPTR64MSB
:
2067 case R_IA64_LTOFF_FPTR64LSB
:
2068 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2071 case R_IA64_FPTR64I
:
2072 case R_IA64_FPTR32MSB
:
2073 case R_IA64_FPTR32LSB
:
2074 case R_IA64_FPTR64MSB
:
2075 case R_IA64_FPTR64LSB
:
2076 if (info
->shared
|| h
|| elfNN_ia64_aix_vec (abfd
->xvec
))
2077 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2079 need_entry
= NEED_FPTR
;
2080 dynrel_type
= R_IA64_FPTR64LSB
;
2083 case R_IA64_LTOFF22
:
2084 case R_IA64_LTOFF22X
:
2085 case R_IA64_LTOFF64I
:
2086 need_entry
= NEED_GOT
;
2089 case R_IA64_PLTOFF22
:
2090 case R_IA64_PLTOFF64I
:
2091 case R_IA64_PLTOFF64MSB
:
2092 case R_IA64_PLTOFF64LSB
:
2093 need_entry
= NEED_PLTOFF
;
2097 need_entry
|= NEED_MIN_PLT
;
2101 (*info
->callbacks
->warning
)
2102 (info
, _("@pltoff reloc against local symbol"), 0,
2103 abfd
, 0, (bfd_vma
) 0);
2107 case R_IA64_PCREL21B
:
2108 case R_IA64_PCREL60B
:
2109 /* Depending on where this symbol is defined, we may or may not
2110 need a full plt entry. Only skip if we know we'll not need
2111 the entry -- static or symbolic, and the symbol definition
2112 has already been seen. */
2113 if (maybe_dynamic
&& rel
->r_addend
== 0)
2114 need_entry
= NEED_FULL_PLT
;
2120 case R_IA64_DIR32MSB
:
2121 case R_IA64_DIR32LSB
:
2122 case R_IA64_DIR64MSB
:
2123 case R_IA64_DIR64LSB
:
2124 /* Shared objects will always need at least a REL relocation. */
2125 if (info
->shared
|| maybe_dynamic
2126 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2127 && (!h
|| strcmp (h
->root
.root
.string
,
2128 "__GLOB_DATA_PTR") != 0)))
2129 need_entry
= NEED_DYNREL
;
2130 dynrel_type
= R_IA64_DIR64LSB
;
2133 case R_IA64_IPLTMSB
:
2134 case R_IA64_IPLTLSB
:
2135 /* Shared objects will always need at least a REL relocation. */
2136 if (info
->shared
|| maybe_dynamic
)
2137 need_entry
= NEED_DYNREL
;
2138 dynrel_type
= R_IA64_IPLTLSB
;
2141 case R_IA64_PCREL22
:
2142 case R_IA64_PCREL64I
:
2143 case R_IA64_PCREL32MSB
:
2144 case R_IA64_PCREL32LSB
:
2145 case R_IA64_PCREL64MSB
:
2146 case R_IA64_PCREL64LSB
:
2148 need_entry
= NEED_DYNREL
;
2149 dynrel_type
= R_IA64_PCREL64LSB
;
2156 if ((need_entry
& NEED_FPTR
) != 0
2159 (*info
->callbacks
->warning
)
2160 (info
, _("non-zero addend in @fptr reloc"), 0,
2161 abfd
, 0, (bfd_vma
) 0);
2164 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, true);
2166 /* Record whether or not this is a local symbol. */
2169 /* Create what's needed. */
2170 if (need_entry
& NEED_GOT
)
2174 got
= get_got (abfd
, info
, ia64_info
);
2178 dyn_i
->want_got
= 1;
2180 if (need_entry
& NEED_FPTR
)
2184 fptr
= get_fptr (abfd
, info
, ia64_info
);
2189 /* FPTRs for shared libraries are allocated by the dynamic
2190 linker. Make sure this local symbol will appear in the
2191 dynamic symbol table. */
2192 if (!h
&& (info
->shared
2193 /* AIX also needs one */
2194 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2196 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2197 (info
, abfd
, (long) r_symndx
)))
2201 dyn_i
->want_fptr
= 1;
2203 if (need_entry
& NEED_LTOFF_FPTR
)
2204 dyn_i
->want_ltoff_fptr
= 1;
2205 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2207 if (!ia64_info
->root
.dynobj
)
2208 ia64_info
->root
.dynobj
= abfd
;
2209 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2210 dyn_i
->want_plt
= 1;
2212 if (need_entry
& NEED_FULL_PLT
)
2213 dyn_i
->want_plt2
= 1;
2214 if (need_entry
& NEED_PLTOFF
)
2215 dyn_i
->want_pltoff
= 1;
2216 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2220 srel
= get_reloc_section (abfd
, ia64_info
, sec
, true);
2224 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2232 struct elfNN_ia64_allocate_data
2234 struct bfd_link_info
*info
;
2238 /* For cleanliness, and potentially faster dynamic loading, allocate
2239 external GOT entries first. */
2242 allocate_global_data_got (dyn_i
, data
)
2243 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2246 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2249 && ! dyn_i
->want_fptr
2250 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2251 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2252 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2253 "__GLOB_DATA_PTR") != 0))))
2255 dyn_i
->got_offset
= x
->ofs
;
2261 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2264 allocate_global_fptr_got (dyn_i
, data
)
2265 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2268 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2272 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2273 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2275 dyn_i
->got_offset
= x
->ofs
;
2281 /* Lastly, allocate all the GOT entries for local data. */
2284 allocate_local_got (dyn_i
, data
)
2285 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2288 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2291 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2292 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2294 dyn_i
->got_offset
= x
->ofs
;
2300 /* Search for the index of a global symbol in it's defining object file. */
2303 global_sym_index (h
)
2304 struct elf_link_hash_entry
*h
;
2306 struct elf_link_hash_entry
**p
;
2309 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2310 || h
->root
.type
== bfd_link_hash_defweak
);
2312 obj
= h
->root
.u
.def
.section
->owner
;
2313 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2316 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2319 /* Allocate function descriptors. We can do these for every function
2320 in a main executable that is not exported. */
2323 allocate_fptr (dyn_i
, data
)
2324 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2327 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2329 if (dyn_i
->want_fptr
)
2331 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2334 while (h
->root
.type
== bfd_link_hash_indirect
2335 || h
->root
.type
== bfd_link_hash_warning
)
2336 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2339 /* AIX needs an FPTR in this case. */
2340 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2342 || h
->root
.type
== bfd_link_hash_defined
2343 || h
->root
.type
== bfd_link_hash_defweak
)))
2345 if (h
&& h
->dynindx
== -1)
2347 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2348 || (h
->root
.type
== bfd_link_hash_defweak
));
2350 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2351 (x
->info
, h
->root
.u
.def
.section
->owner
,
2352 global_sym_index (h
)))
2356 dyn_i
->want_fptr
= 0;
2358 else if (h
== NULL
|| h
->dynindx
== -1)
2360 dyn_i
->fptr_offset
= x
->ofs
;
2364 dyn_i
->want_fptr
= 0;
2369 /* Allocate all the minimal PLT entries. */
2372 allocate_plt_entries (dyn_i
, data
)
2373 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2376 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2378 if (dyn_i
->want_plt
)
2380 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2383 while (h
->root
.type
== bfd_link_hash_indirect
2384 || h
->root
.type
== bfd_link_hash_warning
)
2385 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2387 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2388 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2390 bfd_size_type offset
= x
->ofs
;
2392 offset
= PLT_HEADER_SIZE
;
2393 dyn_i
->plt_offset
= offset
;
2394 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2396 dyn_i
->want_pltoff
= 1;
2400 dyn_i
->want_plt
= 0;
2401 dyn_i
->want_plt2
= 0;
2407 /* Allocate all the full PLT entries. */
2410 allocate_plt2_entries (dyn_i
, data
)
2411 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2414 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2416 if (dyn_i
->want_plt2
)
2418 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2419 bfd_size_type ofs
= x
->ofs
;
2421 dyn_i
->plt2_offset
= ofs
;
2422 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2424 while (h
->root
.type
== bfd_link_hash_indirect
2425 || h
->root
.type
== bfd_link_hash_warning
)
2426 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2427 dyn_i
->h
->plt
.offset
= ofs
;
2432 /* Allocate all the PLTOFF entries requested by relocations and
2433 plt entries. We can't share space with allocated FPTR entries,
2434 because the latter are not necessarily addressable by the GP.
2435 ??? Relaxation might be able to determine that they are. */
2438 allocate_pltoff_entries (dyn_i
, data
)
2439 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2442 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2444 if (dyn_i
->want_pltoff
)
2446 dyn_i
->pltoff_offset
= x
->ofs
;
2452 /* Allocate dynamic relocations for those symbols that turned out
2456 allocate_dynrel_entries (dyn_i
, data
)
2457 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2460 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2461 struct elfNN_ia64_link_hash_table
*ia64_info
;
2462 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2463 boolean dynamic_symbol
, shared
;
2465 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2466 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2467 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2468 /* Don't allocate an entry for __GLOB_DATA_PTR */
2469 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2470 "__GLOB_DATA_PTR") != 0));
2471 shared
= x
->info
->shared
;
2473 /* Take care of the normal data relocations. */
2475 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2477 int count
= rent
->count
;
2481 case R_IA64_FPTR64LSB
:
2482 /* Allocate one iff !want_fptr, which by this point will
2483 be true only if we're actually allocating one statically
2484 in the main executable. */
2485 if (dyn_i
->want_fptr
)
2488 case R_IA64_PCREL64LSB
:
2489 if (!dynamic_symbol
)
2492 case R_IA64_DIR64LSB
:
2493 if (!dynamic_symbol
&& !shared
)
2496 case R_IA64_IPLTLSB
:
2497 if (!dynamic_symbol
&& !shared
)
2499 /* Use two REL relocations for IPLT relocations
2500 against local symbols. */
2501 if (!dynamic_symbol
)
2507 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2510 /* Take care of the GOT and PLT relocations. */
2512 if (((dynamic_symbol
|| shared
) && dyn_i
->want_got
)
2513 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2514 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2516 if (dyn_i
->want_pltoff
)
2518 bfd_size_type t
= 0;
2520 /* Dynamic symbols get one IPLT relocation. Local symbols in
2521 shared libraries get two REL relocations. Local symbols in
2522 main applications get nothing. */
2524 t
= sizeof (ElfNN_External_Rela
);
2526 t
= 2 * sizeof (ElfNN_External_Rela
);
2528 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2535 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2536 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2537 struct elf_link_hash_entry
*h
;
2539 /* ??? Undefined symbols with PLT entries should be re-defined
2540 to be the PLT entry. */
2542 /* If this is a weak symbol, and there is a real definition, the
2543 processor independent code will have arranged for us to see the
2544 real definition first, and we can just use the same value. */
2545 if (h
->weakdef
!= NULL
)
2547 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2548 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2549 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2550 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2554 /* If this is a reference to a symbol defined by a dynamic object which
2555 is not a function, we might allocate the symbol in our .dynbss section
2556 and allocate a COPY dynamic relocation.
2558 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2565 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2567 struct bfd_link_info
*info
;
2569 struct elfNN_ia64_allocate_data data
;
2570 struct elfNN_ia64_link_hash_table
*ia64_info
;
2573 boolean relplt
= false;
2575 dynobj
= elf_hash_table(info
)->dynobj
;
2576 ia64_info
= elfNN_ia64_hash_table (info
);
2577 BFD_ASSERT(dynobj
!= NULL
);
2580 /* Set the contents of the .interp section to the interpreter. */
2581 if (ia64_info
->root
.dynamic_sections_created
2584 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2585 BFD_ASSERT (sec
!= NULL
);
2586 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2587 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2590 /* Allocate the GOT entries. */
2592 if (ia64_info
->got_sec
)
2595 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2596 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2597 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2598 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2601 /* Allocate the FPTR entries. */
2603 if (ia64_info
->fptr_sec
)
2606 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2607 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2610 /* Now that we've seen all of the input files, we can decide which
2611 symbols need plt entries. Allocate the minimal PLT entries first.
2612 We do this even though dynamic_sections_created may be false, because
2613 this has the side-effect of clearing want_plt and want_plt2. */
2616 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2618 ia64_info
->minplt_entries
= 0;
2621 ia64_info
->minplt_entries
2622 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2625 /* Align the pointer for the plt2 entries. */
2626 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
2628 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2631 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2633 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2635 /* If we've got a .plt, we need some extra memory for the dynamic
2636 linker. We stuff these in .got.plt. */
2637 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2638 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2641 /* Allocate the PLTOFF entries. */
2643 if (ia64_info
->pltoff_sec
)
2646 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2647 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2650 if (ia64_info
->root
.dynamic_sections_created
)
2652 /* Allocate space for the dynamic relocations that turned out to be
2655 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2658 /* We have now determined the sizes of the various dynamic sections.
2659 Allocate memory for them. */
2660 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2664 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2667 /* If we don't need this section, strip it from the output file.
2668 There were several sections primarily related to dynamic
2669 linking that must be create before the linker maps input
2670 sections to output sections. The linker does that before
2671 bfd_elf_size_dynamic_sections is called, and it is that
2672 function which decides whether anything needs to go into
2675 strip
= (sec
->_raw_size
== 0);
2677 if (sec
== ia64_info
->got_sec
)
2679 else if (sec
== ia64_info
->rel_got_sec
)
2682 ia64_info
->rel_got_sec
= NULL
;
2684 /* We use the reloc_count field as a counter if we need to
2685 copy relocs into the output file. */
2686 sec
->reloc_count
= 0;
2688 else if (sec
== ia64_info
->fptr_sec
)
2691 ia64_info
->fptr_sec
= NULL
;
2693 else if (sec
== ia64_info
->plt_sec
)
2696 ia64_info
->plt_sec
= NULL
;
2698 else if (sec
== ia64_info
->pltoff_sec
)
2701 ia64_info
->pltoff_sec
= NULL
;
2703 else if (sec
== ia64_info
->rel_pltoff_sec
)
2706 ia64_info
->rel_pltoff_sec
= NULL
;
2710 /* We use the reloc_count field as a counter if we need to
2711 copy relocs into the output file. */
2712 sec
->reloc_count
= 0;
2719 /* It's OK to base decisions on the section name, because none
2720 of the dynobj section names depend upon the input files. */
2721 name
= bfd_get_section_name (dynobj
, sec
);
2723 if (strcmp (name
, ".got.plt") == 0)
2725 else if (strncmp (name
, ".rel", 4) == 0)
2729 /* We use the reloc_count field as a counter if we need to
2730 copy relocs into the output file. */
2731 sec
->reloc_count
= 0;
2739 _bfd_strip_section_from_output (info
, sec
);
2742 /* Allocate memory for the section contents. */
2743 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->_raw_size
);
2744 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
2749 if (elf_hash_table (info
)->dynamic_sections_created
)
2751 /* Add some entries to the .dynamic section. We fill in the values
2752 later (in finish_dynamic_sections) but we must add the entries now
2753 so that we get the correct size for the .dynamic section. */
2757 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2759 #define add_dynamic_entry(TAG, VAL) \
2760 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
2762 if (!add_dynamic_entry (DT_DEBUG
, 0))
2766 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
2768 if (!add_dynamic_entry (DT_PLTGOT
, 0))
2773 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
2774 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
2775 || !add_dynamic_entry (DT_JMPREL
, 0))
2779 if (!add_dynamic_entry (DT_RELA
, 0)
2780 || !add_dynamic_entry (DT_RELASZ
, 0)
2781 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
2784 if (ia64_info
->reltext
)
2786 if (!add_dynamic_entry (DT_TEXTREL
, 0))
2788 info
->flags
|= DF_TEXTREL
;
2792 /* ??? Perhaps force __gp local. */
2797 static bfd_reloc_status_type
2798 elfNN_ia64_install_value (abfd
, hit_addr
, v
, r_type
)
2802 unsigned int r_type
;
2804 const struct ia64_operand
*op
;
2805 int bigendian
= 0, shift
= 0;
2806 bfd_vma t0
, t1
, insn
, dword
;
2807 enum ia64_opnd opnd
;
2810 #ifdef BFD_HOST_U_64_BIT
2811 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
2816 opnd
= IA64_OPND_NIL
;
2821 return bfd_reloc_ok
;
2823 /* Instruction relocations. */
2825 case R_IA64_IMM14
: opnd
= IA64_OPND_IMM14
; break;
2827 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
2828 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
2829 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
2830 case R_IA64_PCREL21B
:
2831 case R_IA64_PCREL21BI
:
2832 opnd
= IA64_OPND_TGT25c
;
2836 case R_IA64_GPREL22
:
2837 case R_IA64_LTOFF22
:
2838 case R_IA64_LTOFF22X
:
2839 case R_IA64_PLTOFF22
:
2840 case R_IA64_PCREL22
:
2841 case R_IA64_LTOFF_FPTR22
:
2842 opnd
= IA64_OPND_IMM22
;
2846 case R_IA64_GPREL64I
:
2847 case R_IA64_LTOFF64I
:
2848 case R_IA64_PLTOFF64I
:
2849 case R_IA64_PCREL64I
:
2850 case R_IA64_FPTR64I
:
2851 case R_IA64_LTOFF_FPTR64I
:
2852 opnd
= IA64_OPND_IMMU64
;
2855 /* Data relocations. */
2857 case R_IA64_DIR32MSB
:
2858 case R_IA64_GPREL32MSB
:
2859 case R_IA64_FPTR32MSB
:
2860 case R_IA64_PCREL32MSB
:
2861 case R_IA64_LTOFF_FPTR32MSB
:
2862 case R_IA64_SEGREL32MSB
:
2863 case R_IA64_SECREL32MSB
:
2864 case R_IA64_LTV32MSB
:
2865 size
= 4; bigendian
= 1;
2868 case R_IA64_DIR32LSB
:
2869 case R_IA64_GPREL32LSB
:
2870 case R_IA64_FPTR32LSB
:
2871 case R_IA64_PCREL32LSB
:
2872 case R_IA64_LTOFF_FPTR32LSB
:
2873 case R_IA64_SEGREL32LSB
:
2874 case R_IA64_SECREL32LSB
:
2875 case R_IA64_LTV32LSB
:
2876 size
= 4; bigendian
= 0;
2879 case R_IA64_DIR64MSB
:
2880 case R_IA64_GPREL64MSB
:
2881 case R_IA64_PLTOFF64MSB
:
2882 case R_IA64_FPTR64MSB
:
2883 case R_IA64_PCREL64MSB
:
2884 case R_IA64_LTOFF_FPTR64MSB
:
2885 case R_IA64_SEGREL64MSB
:
2886 case R_IA64_SECREL64MSB
:
2887 case R_IA64_LTV64MSB
:
2888 size
= 8; bigendian
= 1;
2891 case R_IA64_DIR64LSB
:
2892 case R_IA64_GPREL64LSB
:
2893 case R_IA64_PLTOFF64LSB
:
2894 case R_IA64_FPTR64LSB
:
2895 case R_IA64_PCREL64LSB
:
2896 case R_IA64_LTOFF_FPTR64LSB
:
2897 case R_IA64_SEGREL64LSB
:
2898 case R_IA64_SECREL64LSB
:
2899 case R_IA64_LTV64LSB
:
2900 size
= 8; bigendian
= 0;
2903 /* Unsupported / Dynamic relocations. */
2905 return bfd_reloc_notsupported
;
2910 case IA64_OPND_IMMU64
:
2911 hit_addr
-= (long) hit_addr
& 0x3;
2912 t0
= bfd_get_64 (abfd
, hit_addr
);
2913 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2915 /* tmpl/s: bits 0.. 5 in t0
2916 slot 0: bits 5..45 in t0
2917 slot 1: bits 46..63 in t0, bits 0..22 in t1
2918 slot 2: bits 23..63 in t1 */
2920 /* First, clear the bits that form the 64 bit constant. */
2921 t0
&= ~(0x3ffffLL
<< 46);
2923 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
2924 | (0x01fLL
<< 22) | (0x001LL
<< 21)
2925 | (0x001LL
<< 36)) << 23));
2927 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
2928 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
2929 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
2930 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
2931 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
2932 | (((val
>> 21) & 0x001) << 21) /* ic */
2933 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
2935 bfd_put_64 (abfd
, t0
, hit_addr
);
2936 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2939 case IA64_OPND_TGT64
:
2940 hit_addr
-= (long) hit_addr
& 0x3;
2941 t0
= bfd_get_64 (abfd
, hit_addr
);
2942 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2944 /* tmpl/s: bits 0.. 5 in t0
2945 slot 0: bits 5..45 in t0
2946 slot 1: bits 46..63 in t0, bits 0..22 in t1
2947 slot 2: bits 23..63 in t1 */
2949 /* First, clear the bits that form the 64 bit constant. */
2950 t0
&= ~(0x3ffffLL
<< 46);
2952 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
2955 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
2956 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
2957 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
2958 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
2960 bfd_put_64 (abfd
, t0
, hit_addr
);
2961 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2965 switch ((long) hit_addr
& 0x3)
2967 case 0: shift
= 5; break;
2968 case 1: shift
= 14; hit_addr
+= 3; break;
2969 case 2: shift
= 23; hit_addr
+= 6; break;
2970 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
2972 dword
= bfd_get_64 (abfd
, hit_addr
);
2973 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
2975 op
= elf64_ia64_operands
+ opnd
;
2976 err
= (*op
->insert
) (op
, val
, (ia64_insn
*)& insn
);
2978 return bfd_reloc_overflow
;
2980 dword
&= ~(0x1ffffffffffLL
<< shift
);
2981 dword
|= (insn
<< shift
);
2982 bfd_put_64 (abfd
, dword
, hit_addr
);
2986 /* A data relocation. */
2989 bfd_putb32 (val
, hit_addr
);
2991 bfd_putb64 (val
, hit_addr
);
2994 bfd_putl32 (val
, hit_addr
);
2996 bfd_putl64 (val
, hit_addr
);
3000 return bfd_reloc_ok
;
3004 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
3007 struct bfd_link_info
*info
;
3015 Elf_Internal_Rela outrel
;
3017 offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3019 BFD_ASSERT (dynindx
!= -1);
3020 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3021 outrel
.r_addend
= addend
;
3022 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3023 if (outrel
.r_offset
== (bfd_vma
) -1)
3025 /* Run for the hills. We shouldn't be outputting a relocation
3026 for this. So do what everyone else does and output a no-op. */
3027 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3028 outrel
.r_addend
= 0;
3029 outrel
.r_offset
= 0;
3032 bfd_elfNN_swap_reloca_out (abfd
, &outrel
,
3033 ((ElfNN_External_Rela
*) srel
->contents
3034 + srel
->reloc_count
++));
3035 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3036 <= srel
->_cooked_size
);
3039 /* Store an entry for target address TARGET_ADDR in the linkage table
3040 and return the gp-relative address of the linkage table entry. */
3043 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3045 struct bfd_link_info
*info
;
3046 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3050 unsigned int dyn_r_type
;
3052 struct elfNN_ia64_link_hash_table
*ia64_info
;
3055 ia64_info
= elfNN_ia64_hash_table (info
);
3056 got_sec
= ia64_info
->got_sec
;
3058 BFD_ASSERT ((dyn_i
->got_offset
& 7) == 0);
3060 if (! dyn_i
->got_done
)
3062 dyn_i
->got_done
= true;
3064 /* Store the target address in the linkage table entry. */
3065 bfd_put_64 (abfd
, value
, got_sec
->contents
+ dyn_i
->got_offset
);
3067 /* Install a dynamic relocation if needed. */
3069 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3070 || elfNN_ia64_aix_vec (abfd
->xvec
)
3071 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3075 dyn_r_type
= R_IA64_REL64LSB
;
3080 if (bfd_big_endian (abfd
))
3084 case R_IA64_REL64LSB
:
3085 dyn_r_type
= R_IA64_REL64MSB
;
3087 case R_IA64_DIR64LSB
:
3088 dyn_r_type
= R_IA64_DIR64MSB
;
3090 case R_IA64_FPTR64LSB
:
3091 dyn_r_type
= R_IA64_FPTR64MSB
;
3099 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3100 ia64_info
->rel_got_sec
,
3101 dyn_i
->got_offset
, dyn_r_type
,
3106 /* Return the address of the linkage table entry. */
3107 value
= (got_sec
->output_section
->vma
3108 + got_sec
->output_offset
3109 + dyn_i
->got_offset
);
3114 /* Fill in a function descriptor consisting of the function's code
3115 address and its global pointer. Return the descriptor's address. */
3118 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3120 struct bfd_link_info
*info
;
3121 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3124 struct elfNN_ia64_link_hash_table
*ia64_info
;
3127 ia64_info
= elfNN_ia64_hash_table (info
);
3128 fptr_sec
= ia64_info
->fptr_sec
;
3130 if (!dyn_i
->fptr_done
)
3132 dyn_i
->fptr_done
= 1;
3134 /* Fill in the function descriptor. */
3135 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3136 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3137 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3140 /* Return the descriptor's address. */
3141 value
= (fptr_sec
->output_section
->vma
3142 + fptr_sec
->output_offset
3143 + dyn_i
->fptr_offset
);
3148 /* Fill in a PLTOFF entry consisting of the function's code address
3149 and its global pointer. Return the descriptor's address. */
3152 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3154 struct bfd_link_info
*info
;
3155 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3159 struct elfNN_ia64_link_hash_table
*ia64_info
;
3160 asection
*pltoff_sec
;
3162 ia64_info
= elfNN_ia64_hash_table (info
);
3163 pltoff_sec
= ia64_info
->pltoff_sec
;
3165 /* Don't do anything if this symbol uses a real PLT entry. In
3166 that case, we'll fill this in during finish_dynamic_symbol. */
3167 if ((! dyn_i
->want_plt
|| is_plt
)
3168 && !dyn_i
->pltoff_done
)
3170 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3172 /* Fill in the function descriptor. */
3173 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3174 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3176 /* Install dynamic relocations if needed. */
3177 if (!is_plt
&& info
->shared
)
3179 unsigned int dyn_r_type
;
3181 if (bfd_big_endian (abfd
))
3182 dyn_r_type
= R_IA64_REL64MSB
;
3184 dyn_r_type
= R_IA64_REL64LSB
;
3186 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3187 ia64_info
->rel_pltoff_sec
,
3188 dyn_i
->pltoff_offset
,
3189 dyn_r_type
, 0, value
);
3190 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3191 ia64_info
->rel_pltoff_sec
,
3192 dyn_i
->pltoff_offset
+ 8,
3196 dyn_i
->pltoff_done
= 1;
3199 /* Return the descriptor's address. */
3200 value
= (pltoff_sec
->output_section
->vma
3201 + pltoff_sec
->output_offset
3202 + dyn_i
->pltoff_offset
);
3207 /* Called through qsort to sort the .IA_64.unwind section during a
3208 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3209 to the output bfd so we can do proper endianness frobbing. */
3211 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3214 elfNN_ia64_unwind_entry_compare (a
, b
)
3220 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3221 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3223 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3227 elfNN_ia64_final_link (abfd
, info
)
3229 struct bfd_link_info
*info
;
3231 struct elfNN_ia64_link_hash_table
*ia64_info
;
3232 asection
*unwind_output_sec
;
3234 ia64_info
= elfNN_ia64_hash_table (info
);
3236 /* Make sure we've got ourselves a nice fat __gp value. */
3237 if (!info
->relocateable
)
3239 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3240 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3241 struct elf_link_hash_entry
*gp
;
3245 /* Find the min and max vma of all sections marked short. Also
3246 collect min and max vma of any type, for use in selecting a
3248 for (os
= abfd
->sections
; os
; os
= os
->next
)
3252 if ((os
->flags
& SEC_ALLOC
) == 0)
3256 hi
= os
->vma
+ os
->_raw_size
;
3264 if (os
->flags
& SEC_SMALL_DATA
)
3266 if (min_short_vma
> lo
)
3268 if (max_short_vma
< hi
)
3273 /* See if the user wants to force a value. */
3274 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", false,
3278 && (gp
->root
.type
== bfd_link_hash_defined
3279 || gp
->root
.type
== bfd_link_hash_defweak
))
3281 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3282 gp_val
= (gp
->root
.u
.def
.value
3283 + gp_sec
->output_section
->vma
3284 + gp_sec
->output_offset
);
3288 /* Pick a sensible value. */
3290 asection
*got_sec
= ia64_info
->got_sec
;
3292 /* Start with just the address of the .got. */
3294 gp_val
= got_sec
->output_section
->vma
;
3295 else if (max_short_vma
!= 0)
3296 gp_val
= min_short_vma
;
3300 /* If it is possible to address the entire image, but we
3301 don't with the choice above, adjust. */
3302 if (max_vma
- min_vma
< 0x400000
3303 && max_vma
- gp_val
<= 0x200000
3304 && gp_val
- min_vma
> 0x200000)
3305 gp_val
= min_vma
+ 0x200000;
3306 else if (max_short_vma
!= 0)
3308 /* If we don't cover all the short data, adjust. */
3309 if (max_short_vma
- gp_val
>= 0x200000)
3310 gp_val
= min_short_vma
+ 0x200000;
3312 /* If we're addressing stuff past the end, adjust back. */
3313 if (gp_val
> max_vma
)
3314 gp_val
= max_vma
- 0x200000 + 8;
3318 /* Validate whether all SHF_IA_64_SHORT sections are within
3319 range of the chosen GP. */
3321 if (max_short_vma
!= 0)
3323 if (max_short_vma
- min_short_vma
>= 0x400000)
3325 (*_bfd_error_handler
)
3326 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3327 bfd_get_filename (abfd
),
3328 (unsigned long) (max_short_vma
- min_short_vma
));
3331 else if ((gp_val
> min_short_vma
3332 && gp_val
- min_short_vma
> 0x200000)
3333 || (gp_val
< max_short_vma
3334 && max_short_vma
- gp_val
>= 0x200000))
3336 (*_bfd_error_handler
)
3337 (_("%s: __gp does not cover short data segment"),
3338 bfd_get_filename (abfd
));
3343 _bfd_set_gp_value (abfd
, gp_val
);
3347 gp
->root
.type
= bfd_link_hash_defined
;
3348 gp
->root
.u
.def
.value
= gp_val
;
3349 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3353 /* If we're producing a final executable, we need to sort the contents
3354 of the .IA_64.unwind section. Force this section to be relocated
3355 into memory rather than written immediately to the output file. */
3356 unwind_output_sec
= NULL
;
3357 if (!info
->relocateable
)
3359 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3362 unwind_output_sec
= s
->output_section
;
3363 unwind_output_sec
->contents
3364 = bfd_malloc (unwind_output_sec
->_raw_size
);
3365 if (unwind_output_sec
->contents
== NULL
)
3370 /* Invoke the regular ELF backend linker to do all the work. */
3371 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3374 if (unwind_output_sec
)
3376 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3377 qsort (unwind_output_sec
->contents
,
3378 (size_t) (unwind_output_sec
->_raw_size
/ 24),
3380 elfNN_ia64_unwind_entry_compare
);
3382 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3383 unwind_output_sec
->contents
, (bfd_vma
) 0,
3384 unwind_output_sec
->_raw_size
))
3392 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3393 contents
, relocs
, local_syms
, local_sections
)
3395 struct bfd_link_info
*info
;
3397 asection
*input_section
;
3399 Elf_Internal_Rela
*relocs
;
3400 Elf_Internal_Sym
*local_syms
;
3401 asection
**local_sections
;
3403 struct elfNN_ia64_link_hash_table
*ia64_info
;
3404 Elf_Internal_Shdr
*symtab_hdr
;
3405 Elf_Internal_Rela
*rel
;
3406 Elf_Internal_Rela
*relend
;
3408 boolean ret_val
= true; /* for non-fatal errors */
3411 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3412 ia64_info
= elfNN_ia64_hash_table (info
);
3414 /* Infect various flags from the input section to the output section. */
3415 if (info
->relocateable
)
3419 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3420 flags
&= SHF_IA_64_NORECOV
;
3422 elf_section_data(input_section
->output_section
)
3423 ->this_hdr
.sh_flags
|= flags
;
3426 gp_val
= _bfd_get_gp_value (output_bfd
);
3427 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, false);
3430 relend
= relocs
+ input_section
->reloc_count
;
3431 for (; rel
< relend
; ++rel
)
3433 struct elf_link_hash_entry
*h
;
3434 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3435 bfd_reloc_status_type r
;
3436 reloc_howto_type
*howto
;
3437 unsigned long r_symndx
;
3438 Elf_Internal_Sym
*sym
;
3439 unsigned int r_type
;
3443 boolean dynamic_symbol_p
;
3444 boolean undef_weak_ref
;
3446 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3447 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3449 (*_bfd_error_handler
)
3450 (_("%s: unknown relocation type %d"),
3451 bfd_archive_filename (input_bfd
), (int)r_type
);
3452 bfd_set_error (bfd_error_bad_value
);
3456 howto
= lookup_howto (r_type
);
3457 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3459 if (info
->relocateable
)
3461 /* This is a relocateable link. We don't have to change
3462 anything, unless the reloc is against a section symbol,
3463 in which case we have to adjust according to where the
3464 section symbol winds up in the output section. */
3465 if (r_symndx
< symtab_hdr
->sh_info
)
3467 sym
= local_syms
+ r_symndx
;
3468 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
3470 sym_sec
= local_sections
[r_symndx
];
3471 rel
->r_addend
+= sym_sec
->output_offset
;
3477 /* This is a final link. */
3482 undef_weak_ref
= false;
3484 if (r_symndx
< symtab_hdr
->sh_info
)
3486 /* Reloc against local symbol. */
3487 sym
= local_syms
+ r_symndx
;
3488 sym_sec
= local_sections
[r_symndx
];
3489 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, sym_sec
, rel
);
3490 if ((sym_sec
->flags
& SEC_MERGE
)
3491 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
3492 && elf_section_data (sym_sec
)->merge_info
)
3494 struct elfNN_ia64_local_hash_entry
*loc_h
;
3496 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, false);
3497 if (loc_h
&& ! loc_h
->sec_merge_done
)
3499 struct elfNN_ia64_dyn_sym_info
*dynent
;
3502 for (dynent
= loc_h
->info
; dynent
; dynent
= dynent
->next
)
3506 _bfd_merged_section_offset (output_bfd
, &msec
,
3507 elf_section_data (msec
)->
3512 dynent
->addend
-= sym
->st_value
;
3513 dynent
->addend
+= msec
->output_section
->vma
3514 + msec
->output_offset
3515 - sym_sec
->output_section
->vma
3516 - sym_sec
->output_offset
;
3518 loc_h
->sec_merge_done
= 1;
3526 /* Reloc against global symbol. */
3527 indx
= r_symndx
- symtab_hdr
->sh_info
;
3528 h
= elf_sym_hashes (input_bfd
)[indx
];
3529 while (h
->root
.type
== bfd_link_hash_indirect
3530 || h
->root
.type
== bfd_link_hash_warning
)
3531 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3534 if (h
->root
.type
== bfd_link_hash_defined
3535 || h
->root
.type
== bfd_link_hash_defweak
)
3537 sym_sec
= h
->root
.u
.def
.section
;
3539 /* Detect the cases that sym_sec->output_section is
3540 expected to be NULL -- all cases in which the symbol
3541 is defined in another shared module. This includes
3542 PLT relocs for which we've created a PLT entry and
3543 other relocs for which we're prepared to create
3544 dynamic relocations. */
3545 /* ??? Just accept it NULL and continue. */
3547 if (sym_sec
->output_section
!= NULL
)
3549 value
= (h
->root
.u
.def
.value
3550 + sym_sec
->output_section
->vma
3551 + sym_sec
->output_offset
);
3554 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3555 undef_weak_ref
= true;
3556 else if (info
->shared
3557 && (!info
->symbolic
|| info
->allow_shlib_undefined
)
3558 && !info
->no_undefined
3559 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3563 if (! ((*info
->callbacks
->undefined_symbol
)
3564 (info
, h
->root
.root
.string
, input_bfd
,
3565 input_section
, rel
->r_offset
,
3566 (!info
->shared
|| info
->no_undefined
3567 || ELF_ST_VISIBILITY (h
->other
)))))
3574 hit_addr
= contents
+ rel
->r_offset
;
3575 value
+= rel
->r_addend
;
3576 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3587 case R_IA64_DIR32MSB
:
3588 case R_IA64_DIR32LSB
:
3589 case R_IA64_DIR64MSB
:
3590 case R_IA64_DIR64LSB
:
3591 /* Install a dynamic relocation for this reloc. */
3592 if ((dynamic_symbol_p
|| info
->shared
3593 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
3594 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3595 && (!h
|| strcmp (h
->root
.root
.string
,
3596 "__GLOB_DATA_PTR") != 0)))
3598 && (input_section
->flags
& SEC_ALLOC
) != 0)
3600 unsigned int dyn_r_type
;
3604 BFD_ASSERT (srel
!= NULL
);
3606 /* If we don't need dynamic symbol lookup, find a
3607 matching RELATIVE relocation. */
3608 dyn_r_type
= r_type
;
3609 if (dynamic_symbol_p
)
3611 dynindx
= h
->dynindx
;
3612 addend
= rel
->r_addend
;
3619 case R_IA64_DIR32MSB
:
3620 dyn_r_type
= R_IA64_REL32MSB
;
3622 case R_IA64_DIR32LSB
:
3623 dyn_r_type
= R_IA64_REL32LSB
;
3625 case R_IA64_DIR64MSB
:
3626 dyn_r_type
= R_IA64_REL64MSB
;
3628 case R_IA64_DIR64LSB
:
3629 dyn_r_type
= R_IA64_REL64LSB
;
3633 /* We can't represent this without a dynamic symbol.
3634 Adjust the relocation to be against an output
3635 section symbol, which are always present in the
3636 dynamic symbol table. */
3637 /* ??? People shouldn't be doing non-pic code in
3638 shared libraries. Hork. */
3639 (*_bfd_error_handler
)
3640 (_("%s: linking non-pic code in a shared library"),
3641 bfd_archive_filename (input_bfd
));
3649 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
3650 rel
->r_addend
= value
;
3651 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3652 srel
, rel
->r_offset
, dyn_r_type
,
3657 case R_IA64_LTV32MSB
:
3658 case R_IA64_LTV32LSB
:
3659 case R_IA64_LTV64MSB
:
3660 case R_IA64_LTV64LSB
:
3661 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3664 case R_IA64_GPREL22
:
3665 case R_IA64_GPREL64I
:
3666 case R_IA64_GPREL32MSB
:
3667 case R_IA64_GPREL32LSB
:
3668 case R_IA64_GPREL64MSB
:
3669 case R_IA64_GPREL64LSB
:
3670 if (dynamic_symbol_p
)
3672 (*_bfd_error_handler
)
3673 (_("%s: @gprel relocation against dynamic symbol %s"),
3674 bfd_archive_filename (input_bfd
), h
->root
.root
.string
);
3679 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3682 case R_IA64_LTOFF22
:
3683 case R_IA64_LTOFF22X
:
3684 case R_IA64_LTOFF64I
:
3685 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3686 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
3687 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
3689 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3692 case R_IA64_PLTOFF22
:
3693 case R_IA64_PLTOFF64I
:
3694 case R_IA64_PLTOFF64MSB
:
3695 case R_IA64_PLTOFF64LSB
:
3696 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3697 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, false);
3699 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3702 case R_IA64_FPTR64I
:
3703 case R_IA64_FPTR32MSB
:
3704 case R_IA64_FPTR32LSB
:
3705 case R_IA64_FPTR64MSB
:
3706 case R_IA64_FPTR64LSB
:
3707 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3708 if (dyn_i
->want_fptr
)
3710 if (!undef_weak_ref
)
3711 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3717 /* Otherwise, we expect the dynamic linker to create
3722 if (h
->dynindx
!= -1)
3723 dynindx
= h
->dynindx
;
3725 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3726 (info
, h
->root
.u
.def
.section
->owner
,
3727 global_sym_index (h
)));
3731 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3732 (info
, input_bfd
, (long) r_symndx
));
3735 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3736 srel
, rel
->r_offset
, r_type
,
3737 dynindx
, rel
->r_addend
);
3741 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3744 case R_IA64_LTOFF_FPTR22
:
3745 case R_IA64_LTOFF_FPTR64I
:
3746 case R_IA64_LTOFF_FPTR32MSB
:
3747 case R_IA64_LTOFF_FPTR32LSB
:
3748 case R_IA64_LTOFF_FPTR64MSB
:
3749 case R_IA64_LTOFF_FPTR64LSB
:
3753 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3754 if (dyn_i
->want_fptr
)
3756 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
3757 if (!undef_weak_ref
)
3758 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3763 /* Otherwise, we expect the dynamic linker to create
3767 if (h
->dynindx
!= -1)
3768 dynindx
= h
->dynindx
;
3770 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3771 (info
, h
->root
.u
.def
.section
->owner
,
3772 global_sym_index (h
)));
3775 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3776 (info
, input_bfd
, (long) r_symndx
));
3780 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
3781 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
3783 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3787 case R_IA64_PCREL32MSB
:
3788 case R_IA64_PCREL32LSB
:
3789 case R_IA64_PCREL64MSB
:
3790 case R_IA64_PCREL64LSB
:
3791 /* Install a dynamic relocation for this reloc. */
3792 if ((dynamic_symbol_p
3793 || elfNN_ia64_aix_vec (info
->hash
->creator
))
3796 BFD_ASSERT (srel
!= NULL
);
3798 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3799 srel
, rel
->r_offset
, r_type
,
3800 h
->dynindx
, rel
->r_addend
);
3804 case R_IA64_PCREL21BI
:
3805 case R_IA64_PCREL21F
:
3806 case R_IA64_PCREL21M
:
3807 /* ??? These two are only used for speculation fixup code.
3808 They should never be dynamic. */
3809 if (dynamic_symbol_p
)
3811 (*_bfd_error_handler
)
3812 (_("%s: dynamic relocation against speculation fixup"),
3813 bfd_archive_filename (input_bfd
));
3819 (*_bfd_error_handler
)
3820 (_("%s: speculation fixup against undefined weak symbol"),
3821 bfd_archive_filename (input_bfd
));
3827 case R_IA64_PCREL21B
:
3828 case R_IA64_PCREL60B
:
3829 /* We should have created a PLT entry for any dynamic symbol. */
3832 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
3834 if (dyn_i
&& dyn_i
->want_plt2
)
3836 /* Should have caught this earlier. */
3837 BFD_ASSERT (rel
->r_addend
== 0);
3839 value
= (ia64_info
->plt_sec
->output_section
->vma
3840 + ia64_info
->plt_sec
->output_offset
3841 + dyn_i
->plt2_offset
);
3845 /* Since there's no PLT entry, Validate that this is
3847 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
3849 /* If the symbol is undef_weak, we shouldn't be trying
3850 to call it. There's every chance that we'd wind up
3851 with an out-of-range fixup here. Don't bother setting
3852 any value at all. */
3858 case R_IA64_PCREL22
:
3859 case R_IA64_PCREL64I
:
3861 /* Make pc-relative. */
3862 value
-= (input_section
->output_section
->vma
3863 + input_section
->output_offset
3864 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
3865 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3868 case R_IA64_SEGREL32MSB
:
3869 case R_IA64_SEGREL32LSB
:
3870 case R_IA64_SEGREL64MSB
:
3871 case R_IA64_SEGREL64LSB
:
3874 /* If the input section was discarded from the output, then
3880 struct elf_segment_map
*m
;
3881 Elf_Internal_Phdr
*p
;
3883 /* Find the segment that contains the output_section. */
3884 for (m
= elf_tdata (output_bfd
)->segment_map
,
3885 p
= elf_tdata (output_bfd
)->phdr
;
3890 for (i
= m
->count
- 1; i
>= 0; i
--)
3891 if (m
->sections
[i
] == sym_sec
->output_section
)
3899 r
= bfd_reloc_notsupported
;
3903 /* The VMA of the segment is the vaddr of the associated
3905 if (value
> p
->p_vaddr
)
3906 value
-= p
->p_vaddr
;
3909 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
3915 case R_IA64_SECREL32MSB
:
3916 case R_IA64_SECREL32LSB
:
3917 case R_IA64_SECREL64MSB
:
3918 case R_IA64_SECREL64LSB
:
3919 /* Make output-section relative. */
3920 if (value
> input_section
->output_section
->vma
)
3921 value
-= input_section
->output_section
->vma
;
3924 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3927 case R_IA64_IPLTMSB
:
3928 case R_IA64_IPLTLSB
:
3929 /* Install a dynamic relocation for this reloc. */
3930 if ((dynamic_symbol_p
|| info
->shared
)
3931 && (input_section
->flags
& SEC_ALLOC
) != 0)
3933 BFD_ASSERT (srel
!= NULL
);
3935 /* If we don't need dynamic symbol lookup, install two
3936 RELATIVE relocations. */
3937 if (! dynamic_symbol_p
)
3939 unsigned int dyn_r_type
;
3941 if (r_type
== R_IA64_IPLTMSB
)
3942 dyn_r_type
= R_IA64_REL64MSB
;
3944 dyn_r_type
= R_IA64_REL64LSB
;
3946 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3948 srel
, rel
->r_offset
,
3949 dyn_r_type
, 0, value
);
3950 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3952 srel
, rel
->r_offset
+ 8,
3953 dyn_r_type
, 0, gp_val
);
3956 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3957 srel
, rel
->r_offset
, r_type
,
3958 h
->dynindx
, rel
->r_addend
);
3961 if (r_type
== R_IA64_IPLTMSB
)
3962 r_type
= R_IA64_DIR64MSB
;
3964 r_type
= R_IA64_DIR64LSB
;
3965 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3966 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
3971 r
= bfd_reloc_notsupported
;
3980 case bfd_reloc_undefined
:
3981 /* This can happen for global table relative relocs if
3982 __gp is undefined. This is a panic situation so we
3983 don't try to continue. */
3984 (*info
->callbacks
->undefined_symbol
)
3985 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
3988 case bfd_reloc_notsupported
:
3993 name
= h
->root
.root
.string
;
3996 name
= bfd_elf_string_from_elf_section (input_bfd
,
3997 symtab_hdr
->sh_link
,
4002 name
= bfd_section_name (input_bfd
, input_section
);
4004 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
4006 input_section
, rel
->r_offset
))
4012 case bfd_reloc_dangerous
:
4013 case bfd_reloc_outofrange
:
4014 case bfd_reloc_overflow
:
4020 name
= h
->root
.root
.string
;
4023 name
= bfd_elf_string_from_elf_section (input_bfd
,
4024 symtab_hdr
->sh_link
,
4029 name
= bfd_section_name (input_bfd
, input_section
);
4031 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
4048 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
4050 struct bfd_link_info
*info
;
4051 struct elf_link_hash_entry
*h
;
4052 Elf_Internal_Sym
*sym
;
4054 struct elfNN_ia64_link_hash_table
*ia64_info
;
4055 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4057 ia64_info
= elfNN_ia64_hash_table (info
);
4058 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
4060 /* Fill in the PLT data, if required. */
4061 if (dyn_i
&& dyn_i
->want_plt
)
4063 Elf_Internal_Rela outrel
;
4066 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
4067 ElfNN_External_Rela
*rel
;
4069 gp_val
= _bfd_get_gp_value (output_bfd
);
4071 /* Initialize the minimal PLT entry. */
4073 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4074 plt_sec
= ia64_info
->plt_sec
;
4075 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4077 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4078 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4079 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4082 plt_addr
= (plt_sec
->output_section
->vma
4083 + plt_sec
->output_offset
4084 + dyn_i
->plt_offset
);
4085 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, true);
4087 /* Initialize the FULL PLT entry, if needed. */
4088 if (dyn_i
->want_plt2
)
4090 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4092 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4093 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4096 /* Mark the symbol as undefined, rather than as defined in the
4097 plt section. Leave the value alone. */
4098 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4099 first place. But perhaps elflink.h did some for us. */
4100 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4101 sym
->st_shndx
= SHN_UNDEF
;
4104 /* Create the dynamic relocation. */
4105 outrel
.r_offset
= pltoff_addr
;
4106 if (bfd_little_endian (output_bfd
))
4107 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4109 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4110 outrel
.r_addend
= 0;
4112 /* This is fun. In the .IA_64.pltoff section, we've got entries
4113 that correspond both to real PLT entries, and those that
4114 happened to resolve to local symbols but need to be created
4115 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4116 relocations for the real PLT should come at the end of the
4117 section, so that they can be indexed by plt entry at runtime.
4119 We emitted all of the relocations for the non-PLT @pltoff
4120 entries during relocate_section. So we can consider the
4121 existing sec->reloc_count to be the base of the array of
4124 rel
= (ElfNN_External_Rela
*)ia64_info
->rel_pltoff_sec
->contents
;
4125 rel
+= ia64_info
->rel_pltoff_sec
->reloc_count
;
4127 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, rel
+ index
);
4130 /* Mark some specially defined symbols as absolute. */
4131 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4132 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4133 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4134 sym
->st_shndx
= SHN_ABS
;
4140 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4142 struct bfd_link_info
*info
;
4144 struct elfNN_ia64_link_hash_table
*ia64_info
;
4147 ia64_info
= elfNN_ia64_hash_table (info
);
4148 dynobj
= ia64_info
->root
.dynobj
;
4150 if (elf_hash_table (info
)->dynamic_sections_created
)
4152 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4153 asection
*sdyn
, *sgotplt
;
4156 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4157 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4158 BFD_ASSERT (sdyn
!= NULL
);
4159 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4160 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4162 gp_val
= _bfd_get_gp_value (abfd
);
4164 for (; dyncon
< dynconend
; dyncon
++)
4166 Elf_Internal_Dyn dyn
;
4168 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4173 dyn
.d_un
.d_ptr
= gp_val
;
4177 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4178 * sizeof (ElfNN_External_Rela
));
4182 /* See the comment above in finish_dynamic_symbol. */
4183 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4184 + ia64_info
->rel_pltoff_sec
->output_offset
4185 + (ia64_info
->rel_pltoff_sec
->reloc_count
4186 * sizeof (ElfNN_External_Rela
)));
4189 case DT_IA_64_PLT_RESERVE
:
4190 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4191 + sgotplt
->output_offset
);
4195 /* Do not have RELASZ include JMPREL. This makes things
4196 easier on ld.so. This is not what the rest of BFD set up. */
4197 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4198 * sizeof (ElfNN_External_Rela
));
4202 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4205 /* Initialize the PLT0 entry */
4206 if (ia64_info
->plt_sec
)
4208 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4211 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4213 pltres
= (sgotplt
->output_section
->vma
4214 + sgotplt
->output_offset
4217 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4224 /* ELF file flag handling: */
4226 /* Function to keep IA-64 specific file flags. */
4228 elfNN_ia64_set_private_flags (abfd
, flags
)
4232 BFD_ASSERT (!elf_flags_init (abfd
)
4233 || elf_elfheader (abfd
)->e_flags
== flags
);
4235 elf_elfheader (abfd
)->e_flags
= flags
;
4236 elf_flags_init (abfd
) = true;
4240 /* Copy backend specific data from one object module to another */
4242 elfNN_ia64_copy_private_bfd_data (ibfd
, obfd
)
4245 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4246 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4249 BFD_ASSERT (!elf_flags_init (obfd
)
4250 || (elf_elfheader (obfd
)->e_flags
4251 == elf_elfheader (ibfd
)->e_flags
));
4253 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
4254 elf_flags_init (obfd
) = true;
4258 /* Merge backend specific data from an object file to the output
4259 object file when linking. */
4261 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4268 /* Don't even pretend to support mixed-format linking. */
4269 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4270 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4273 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4274 out_flags
= elf_elfheader (obfd
)->e_flags
;
4276 if (! elf_flags_init (obfd
))
4278 elf_flags_init (obfd
) = true;
4279 elf_elfheader (obfd
)->e_flags
= in_flags
;
4281 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4282 && bfd_get_arch_info (obfd
)->the_default
)
4284 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4285 bfd_get_mach (ibfd
));
4291 /* Check flag compatibility. */
4292 if (in_flags
== out_flags
)
4295 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4296 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4297 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4299 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4301 (*_bfd_error_handler
)
4302 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4303 bfd_archive_filename (ibfd
));
4305 bfd_set_error (bfd_error_bad_value
);
4308 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4310 (*_bfd_error_handler
)
4311 (_("%s: linking big-endian files with little-endian files"),
4312 bfd_archive_filename (ibfd
));
4314 bfd_set_error (bfd_error_bad_value
);
4317 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4319 (*_bfd_error_handler
)
4320 (_("%s: linking 64-bit files with 32-bit files"),
4321 bfd_archive_filename (ibfd
));
4323 bfd_set_error (bfd_error_bad_value
);
4326 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4328 (*_bfd_error_handler
)
4329 (_("%s: linking constant-gp files with non-constant-gp files"),
4330 bfd_archive_filename (ibfd
));
4332 bfd_set_error (bfd_error_bad_value
);
4335 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4336 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4338 (*_bfd_error_handler
)
4339 (_("%s: linking auto-pic files with non-auto-pic files"),
4340 bfd_archive_filename (ibfd
));
4342 bfd_set_error (bfd_error_bad_value
);
4350 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4354 FILE *file
= (FILE *) ptr
;
4355 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4357 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4359 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4360 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4361 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4362 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4363 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4364 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4365 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4366 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4367 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4369 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4373 static enum elf_reloc_type_class
4374 elfNN_ia64_reloc_type_class (rela
)
4375 const Elf_Internal_Rela
*rela
;
4377 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
4379 case R_IA64_REL32MSB
:
4380 case R_IA64_REL32LSB
:
4381 case R_IA64_REL64MSB
:
4382 case R_IA64_REL64LSB
:
4383 return reloc_class_relative
;
4384 case R_IA64_IPLTMSB
:
4385 case R_IA64_IPLTLSB
:
4386 return reloc_class_plt
;
4388 return reloc_class_copy
;
4390 return reloc_class_normal
;
4394 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4395 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4396 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4397 #define TARGET_BIG_NAME "elfNN-ia64-big"
4398 #define ELF_ARCH bfd_arch_ia64
4399 #define ELF_MACHINE_CODE EM_IA_64
4400 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4401 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4402 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4404 #define elf_backend_section_from_shdr \
4405 elfNN_ia64_section_from_shdr
4406 #define elf_backend_section_flags \
4407 elfNN_ia64_section_flags
4408 #define elf_backend_fake_sections \
4409 elfNN_ia64_fake_sections
4410 #define elf_backend_final_write_processing \
4411 elfNN_ia64_final_write_processing
4412 #define elf_backend_add_symbol_hook \
4413 elfNN_ia64_add_symbol_hook
4414 #define elf_backend_additional_program_headers \
4415 elfNN_ia64_additional_program_headers
4416 #define elf_backend_modify_segment_map \
4417 elfNN_ia64_modify_segment_map
4418 #define elf_info_to_howto \
4419 elfNN_ia64_info_to_howto
4421 #define bfd_elfNN_bfd_reloc_type_lookup \
4422 elfNN_ia64_reloc_type_lookup
4423 #define bfd_elfNN_bfd_is_local_label_name \
4424 elfNN_ia64_is_local_label_name
4425 #define bfd_elfNN_bfd_relax_section \
4426 elfNN_ia64_relax_section
4428 /* Stuff for the BFD linker: */
4429 #define bfd_elfNN_bfd_link_hash_table_create \
4430 elfNN_ia64_hash_table_create
4431 #define elf_backend_create_dynamic_sections \
4432 elfNN_ia64_create_dynamic_sections
4433 #define elf_backend_check_relocs \
4434 elfNN_ia64_check_relocs
4435 #define elf_backend_adjust_dynamic_symbol \
4436 elfNN_ia64_adjust_dynamic_symbol
4437 #define elf_backend_size_dynamic_sections \
4438 elfNN_ia64_size_dynamic_sections
4439 #define elf_backend_relocate_section \
4440 elfNN_ia64_relocate_section
4441 #define elf_backend_finish_dynamic_symbol \
4442 elfNN_ia64_finish_dynamic_symbol
4443 #define elf_backend_finish_dynamic_sections \
4444 elfNN_ia64_finish_dynamic_sections
4445 #define bfd_elfNN_bfd_final_link \
4446 elfNN_ia64_final_link
4448 #define bfd_elfNN_bfd_copy_private_bfd_data \
4449 elfNN_ia64_copy_private_bfd_data
4450 #define bfd_elfNN_bfd_merge_private_bfd_data \
4451 elfNN_ia64_merge_private_bfd_data
4452 #define bfd_elfNN_bfd_set_private_flags \
4453 elfNN_ia64_set_private_flags
4454 #define bfd_elfNN_bfd_print_private_bfd_data \
4455 elfNN_ia64_print_private_bfd_data
4457 #define elf_backend_plt_readonly 1
4458 #define elf_backend_want_plt_sym 0
4459 #define elf_backend_plt_alignment 5
4460 #define elf_backend_got_header_size 0
4461 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4462 #define elf_backend_want_got_plt 1
4463 #define elf_backend_may_use_rel_p 1
4464 #define elf_backend_may_use_rela_p 1
4465 #define elf_backend_default_use_rela_p 1
4466 #define elf_backend_want_dynbss 0
4467 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4468 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4469 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4471 #include "elfNN-target.h"
4473 /* AIX-specific vectors. */
4475 #undef TARGET_LITTLE_SYM
4476 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4477 #undef TARGET_LITTLE_NAME
4478 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4479 #undef TARGET_BIG_SYM
4480 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4481 #undef TARGET_BIG_NAME
4482 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4484 #undef elf_backend_add_symbol_hook
4485 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4487 #undef bfd_elfNN_bfd_link_add_symbols
4488 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4490 #define elfNN_bed elfNN_ia64_aix_bed
4492 #include "elfNN-target.h"