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_merge_private_bfd_data
305 PARAMS ((bfd
*ibfd
, bfd
*obfd
));
306 static boolean elfNN_ia64_print_private_bfd_data
307 PARAMS ((bfd
*abfd
, PTR ptr
));
308 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
309 PARAMS ((const Elf_Internal_Rela
*));
311 /* ia64-specific relocation */
313 /* Perform a relocation. Not much to do here as all the hard work is
314 done in elfNN_ia64_final_link_relocate. */
315 static bfd_reloc_status_type
316 elfNN_ia64_reloc (abfd
, reloc
, sym
, data
, input_section
,
317 output_bfd
, error_message
)
318 bfd
*abfd ATTRIBUTE_UNUSED
;
320 asymbol
*sym ATTRIBUTE_UNUSED
;
321 PTR data ATTRIBUTE_UNUSED
;
322 asection
*input_section
;
324 char **error_message
;
328 reloc
->address
+= input_section
->output_offset
;
331 *error_message
= "Unsupported call to elfNN_ia64_reloc";
332 return bfd_reloc_notsupported
;
335 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
336 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
337 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
339 /* This table has to be sorted according to increasing number of the
341 static reloc_howto_type ia64_howto_table
[] =
343 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, false, true),
345 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, false, true),
346 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, false, true),
347 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, false, true),
348 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, false, true),
349 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, false, true),
350 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, false, true),
351 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, false, true),
353 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, false, true),
354 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, false, true),
355 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, false, true),
356 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, false, true),
357 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, false, true),
358 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, false, true),
360 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, false, true),
361 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, false, true),
363 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, false, true),
364 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, false, true),
365 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, false, true),
366 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, false, true),
368 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, false, true),
369 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, false, true),
370 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, false, true),
371 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, false, true),
372 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, false, true),
374 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, true, true),
375 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, true, true),
376 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, true, true),
377 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, true, true),
378 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, true, true),
379 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, true, true),
380 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, true, true),
381 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, true, true),
383 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, false, true),
384 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, false, true),
385 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, false, true),
386 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, false, true),
387 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, false, true),
388 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, false, true),
390 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, false, true),
391 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, false, true),
392 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, false, true),
393 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, false, true),
395 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, false, true),
396 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, false, true),
397 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, false, true),
398 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, false, true),
400 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, false, true),
401 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, false, true),
402 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, false, true),
403 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, false, true),
405 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, false, true),
406 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, false, true),
407 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, false, true),
408 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, false, true),
410 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, true, true),
411 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, true, true),
412 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, true, true),
414 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, false, true),
415 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, false, true),
416 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, false, true),
417 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, false, true),
418 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, false, true),
420 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, false, false),
421 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 8, false, false),
422 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 8, false, false),
423 IA64_HOWTO (R_IA64_LTOFF_TP22
, "LTOFF_TP22", 0, false, false),
426 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
428 /* Given a BFD reloc type, return the matching HOWTO structure. */
430 static reloc_howto_type
*
434 static int inited
= 0;
441 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
442 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
443 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
446 BFD_ASSERT (rtype
<= R_IA64_MAX_RELOC_CODE
);
447 i
= elf_code_to_howto_index
[rtype
];
448 if (i
>= NELEMS (ia64_howto_table
))
450 return ia64_howto_table
+ i
;
453 static reloc_howto_type
*
454 elfNN_ia64_reloc_type_lookup (abfd
, bfd_code
)
455 bfd
*abfd ATTRIBUTE_UNUSED
;
456 bfd_reloc_code_real_type bfd_code
;
462 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
464 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
465 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
466 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
468 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
469 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
470 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
471 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
473 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
474 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
475 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
476 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
477 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
478 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
480 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
481 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
483 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
484 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
485 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
486 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
487 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
488 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
489 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
490 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
491 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
493 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
494 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
495 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
496 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
497 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
498 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
499 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
500 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
501 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
502 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
503 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
505 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
506 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
507 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
508 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
509 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
510 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
512 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
513 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
514 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
515 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
517 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
518 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
519 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
520 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
522 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
523 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
524 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
525 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
527 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
528 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
529 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
530 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
532 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
533 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
534 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
535 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
536 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
538 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
539 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
540 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
541 case BFD_RELOC_IA64_LTOFF_TP22
: rtype
= R_IA64_LTOFF_TP22
; break;
545 return lookup_howto (rtype
);
548 /* Given a ELF reloc, return the matching HOWTO structure. */
551 elfNN_ia64_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
552 bfd
*abfd ATTRIBUTE_UNUSED
;
554 ElfNN_Internal_Rela
*elf_reloc
;
557 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
560 #define PLT_HEADER_SIZE (3 * 16)
561 #define PLT_MIN_ENTRY_SIZE (1 * 16)
562 #define PLT_FULL_ENTRY_SIZE (2 * 16)
563 #define PLT_RESERVED_WORDS 3
565 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
567 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
568 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
569 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
570 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
571 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
572 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
573 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
574 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
575 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
578 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
580 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
581 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
582 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
585 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
587 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
588 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
589 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
590 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
591 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
592 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
595 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
596 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
597 #define DYNAMIC_INTERPRETER(abfd) \
598 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
600 /* Select out of range branch fixup type. Note that Itanium does
601 not support brl, and so it gets emulated by the kernel. */
604 static const bfd_byte oor_brl
[16] =
606 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
608 0x00, 0x00, 0x00, 0xc0
611 static const bfd_byte oor_ip
[48] =
613 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
614 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
615 0x01, 0x00, 0x00, 0x60,
616 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
617 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
618 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
619 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
620 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
621 0x60, 0x00, 0x80, 0x00 /* br b6;; */
624 /* These functions do relaxation for IA-64 ELF.
626 This is primarily to support branches to targets out of range;
627 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
630 elfNN_ia64_relax_section (abfd
, sec
, link_info
, again
)
633 struct bfd_link_info
*link_info
;
638 struct one_fixup
*next
;
644 Elf_Internal_Shdr
*symtab_hdr
;
645 Elf_Internal_Shdr
*shndx_hdr
;
646 Elf_Internal_Rela
*internal_relocs
;
647 Elf_Internal_Rela
*free_relocs
= NULL
;
648 Elf_Internal_Rela
*irel
, *irelend
;
650 bfd_byte
*free_contents
= NULL
;
651 ElfNN_External_Sym
*extsyms
;
652 ElfNN_External_Sym
*free_extsyms
= NULL
;
653 Elf_External_Sym_Shndx
*shndx_buf
= 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 local symbols. */
716 if (symtab_hdr
->contents
!= NULL
)
717 extsyms
= (ElfNN_External_Sym
*) symtab_hdr
->contents
;
722 amt
= symtab_hdr
->sh_info
* sizeof (ElfNN_External_Sym
);
723 extsyms
= (ElfNN_External_Sym
*) bfd_malloc (amt
);
726 free_extsyms
= extsyms
;
727 if (bfd_seek (abfd
, symtab_hdr
->sh_offset
, SEEK_SET
) != 0
728 || bfd_bread (extsyms
, amt
, abfd
) != amt
)
732 shndx_hdr
= &elf_tdata (abfd
)->symtab_shndx_hdr
;
733 if (shndx_hdr
->sh_size
!= 0)
737 amt
= symtab_hdr
->sh_info
* sizeof (Elf_External_Sym_Shndx
);
738 shndx_buf
= (Elf_External_Sym_Shndx
*) bfd_malloc (amt
);
739 if (shndx_buf
== NULL
)
741 if (bfd_seek (abfd
, shndx_hdr
->sh_offset
, SEEK_SET
) != 0
742 || bfd_bread (shndx_buf
, amt
, abfd
) != amt
)
746 for (; irel
< irelend
; irel
++)
748 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
749 Elf_Internal_Sym isym
;
754 if (ELFNN_R_TYPE (irel
->r_info
) != (int) R_IA64_PCREL21B
)
757 /* Get the value of the symbol referred to by the reloc. */
758 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
760 ElfNN_External_Sym
*esym
;
761 Elf_External_Sym_Shndx
*shndx
;
763 /* A local symbol. */
764 esym
= extsyms
+ ELFNN_R_SYM (irel
->r_info
);
765 shndx
= shndx_buf
+ (shndx_buf
? ELFNN_R_SYM (irel
->r_info
) : 0);
766 bfd_elfNN_swap_symbol_in (abfd
, esym
, shndx
, &isym
);
767 if (isym
.st_shndx
== SHN_UNDEF
)
768 continue; /* We can't do anthing with undefined symbols. */
769 else if (isym
.st_shndx
== SHN_ABS
)
770 tsec
= bfd_abs_section_ptr
;
771 else if (isym
.st_shndx
== SHN_COMMON
)
772 tsec
= bfd_com_section_ptr
;
774 tsec
= bfd_section_from_elf_index (abfd
, isym
.st_shndx
);
776 toff
= isym
.st_value
;
781 struct elf_link_hash_entry
*h
;
782 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
784 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
785 h
= elf_sym_hashes (abfd
)[indx
];
786 BFD_ASSERT (h
!= NULL
);
788 while (h
->root
.type
== bfd_link_hash_indirect
789 || h
->root
.type
== bfd_link_hash_warning
)
790 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
792 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, false);
794 /* For branches to dynamic symbols, we're interested instead
795 in a branch to the PLT entry. */
796 if (dyn_i
&& dyn_i
->want_plt2
)
798 tsec
= ia64_info
->plt_sec
;
799 toff
= dyn_i
->plt2_offset
;
803 /* We can't do anthing with undefined symbols. */
804 if (h
->root
.type
== bfd_link_hash_undefined
805 || h
->root
.type
== bfd_link_hash_undefweak
)
808 tsec
= h
->root
.u
.def
.section
;
809 toff
= h
->root
.u
.def
.value
;
813 symaddr
= (tsec
->output_section
->vma
814 + tsec
->output_offset
818 roff
= irel
->r_offset
;
819 reladdr
= (sec
->output_section
->vma
821 + roff
) & (bfd_vma
) -4;
823 /* If the branch is in range, no need to do anything. */
824 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= -0x1000000
825 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
828 /* If the branch and target are in the same section, you've
829 got one honking big section and we can't help you. You'll
830 get an error message later. */
834 /* Look for an existing fixup to this address. */
835 for (f
= fixups
; f
; f
= f
->next
)
836 if (f
->tsec
== tsec
&& f
->toff
== toff
)
841 /* Two alternatives: If it's a branch to a PLT entry, we can
842 make a copy of the FULL_PLT entry. Otherwise, we'll have
843 to use a `brl' insn to get where we're going. */
847 if (tsec
== ia64_info
->plt_sec
)
848 size
= sizeof (plt_full_entry
);
852 size
= sizeof (oor_brl
);
854 size
= sizeof (oor_ip
);
858 /* Resize the current section to make room for the new branch. */
859 trampoff
= (sec
->_cooked_size
+ 15) & (bfd_vma
) -16;
860 amt
= trampoff
+ size
;
861 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
862 if (contents
== NULL
)
864 sec
->_cooked_size
= amt
;
866 if (tsec
== ia64_info
->plt_sec
)
868 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
870 /* Hijack the old relocation for use as the PLTOFF reloc. */
871 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
873 irel
->r_offset
= trampoff
;
878 memcpy (contents
+ trampoff
, oor_brl
, size
);
879 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
881 irel
->r_offset
= trampoff
+ 2;
883 memcpy (contents
+ trampoff
, oor_ip
, size
);
884 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
886 irel
->r_addend
-= 16;
887 irel
->r_offset
= trampoff
+ 2;
891 /* Record the fixup so we don't do it again this section. */
892 f
= (struct one_fixup
*) bfd_malloc ((bfd_size_type
) sizeof (*f
));
896 f
->trampoff
= trampoff
;
901 /* Nop out the reloc, since we're finalizing things here. */
902 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
905 /* Fix up the existing branch to hit the trampoline. Hope like
906 hell this doesn't overflow too. */
907 if (elfNN_ia64_install_value (abfd
, contents
+ roff
,
908 f
->trampoff
- (roff
& (bfd_vma
) -4),
909 R_IA64_PCREL21B
) != bfd_reloc_ok
)
912 changed_contents
= true;
913 changed_relocs
= true;
916 /* Clean up and go home. */
919 struct one_fixup
*f
= fixups
;
920 fixups
= fixups
->next
;
925 elf_section_data (sec
)->relocs
= internal_relocs
;
926 else if (free_relocs
!= NULL
)
929 if (changed_contents
)
930 elf_section_data (sec
)->this_hdr
.contents
= contents
;
931 else if (free_contents
!= NULL
)
933 if (! link_info
->keep_memory
)
934 free (free_contents
);
937 /* Cache the section contents for elf_link_input_bfd. */
938 elf_section_data (sec
)->this_hdr
.contents
= contents
;
942 if (shndx_buf
!= NULL
)
945 if (free_extsyms
!= NULL
)
947 if (! link_info
->keep_memory
)
951 /* Cache the symbols for elf_link_input_bfd. */
952 symtab_hdr
->contents
= (unsigned char *) extsyms
;
956 *again
= changed_contents
|| changed_relocs
;
960 if (free_relocs
!= NULL
)
962 if (free_contents
!= NULL
)
963 free (free_contents
);
964 if (shndx_buf
!= NULL
)
966 if (free_extsyms
!= NULL
)
971 /* Return true if NAME is an unwind table section name. */
973 static inline boolean
974 is_unwind_section_name (name
)
977 size_t len1
, len2
, len3
;
979 len1
= sizeof (ELF_STRING_ia64_unwind
) - 1;
980 len2
= sizeof (ELF_STRING_ia64_unwind_info
) - 1;
981 len3
= sizeof (ELF_STRING_ia64_unwind_once
) - 1;
982 return ((strncmp (name
, ELF_STRING_ia64_unwind
, len1
) == 0
983 && strncmp (name
, ELF_STRING_ia64_unwind_info
, len2
) != 0)
984 || strncmp (name
, ELF_STRING_ia64_unwind_once
, len3
) == 0);
987 /* Handle an IA-64 specific section when reading an object file. This
988 is called when elfcode.h finds a section with an unknown type. */
991 elfNN_ia64_section_from_shdr (abfd
, hdr
, name
)
993 ElfNN_Internal_Shdr
*hdr
;
998 /* There ought to be a place to keep ELF backend specific flags, but
999 at the moment there isn't one. We just keep track of the
1000 sections by their name, instead. Fortunately, the ABI gives
1001 suggested names for all the MIPS specific sections, so we will
1002 probably get away with this. */
1003 switch (hdr
->sh_type
)
1005 case SHT_IA_64_UNWIND
:
1009 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1017 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
1019 newsect
= hdr
->bfd_section
;
1024 /* Convert IA-64 specific section flags to bfd internal section flags. */
1026 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1030 elfNN_ia64_section_flags (flags
, hdr
)
1032 ElfNN_Internal_Shdr
*hdr
;
1034 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1035 *flags
|= SEC_SMALL_DATA
;
1040 /* Set the correct type for an IA-64 ELF section. We do this by the
1041 section name, which is a hack, but ought to work. */
1044 elfNN_ia64_fake_sections (abfd
, hdr
, sec
)
1045 bfd
*abfd ATTRIBUTE_UNUSED
;
1046 ElfNN_Internal_Shdr
*hdr
;
1049 register const char *name
;
1051 name
= bfd_get_section_name (abfd
, sec
);
1053 if (is_unwind_section_name (name
))
1055 /* We don't have the sections numbered at this point, so sh_info
1056 is set later, in elfNN_ia64_final_write_processing. */
1057 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1058 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1060 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1061 hdr
->sh_type
= SHT_IA_64_EXT
;
1062 else if (strcmp (name
, ".reloc") == 0)
1064 * This is an ugly, but unfortunately necessary hack that is
1065 * needed when producing EFI binaries on IA-64. It tells
1066 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1067 * containing ELF relocation info. We need this hack in order to
1068 * be able to generate ELF binaries that can be translated into
1069 * EFI applications (which are essentially COFF objects). Those
1070 * files contain a COFF ".reloc" section inside an ELFNN object,
1071 * which would normally cause BFD to segfault because it would
1072 * attempt to interpret this section as containing relocation
1073 * entries for section "oc". With this hack enabled, ".reloc"
1074 * will be treated as a normal data section, which will avoid the
1075 * segfault. However, you won't be able to create an ELFNN binary
1076 * with a section named "oc" that needs relocations, but that's
1077 * the kind of ugly side-effects you get when detecting section
1078 * types based on their names... In practice, this limitation is
1081 hdr
->sh_type
= SHT_PROGBITS
;
1083 if (sec
->flags
& SEC_SMALL_DATA
)
1084 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1089 /* The final processing done just before writing out an IA-64 ELF
1093 elfNN_ia64_final_write_processing (abfd
, linker
)
1095 boolean linker ATTRIBUTE_UNUSED
;
1097 Elf_Internal_Shdr
*hdr
;
1099 asection
*text_sect
, *s
;
1102 for (s
= abfd
->sections
; s
; s
= s
->next
)
1104 hdr
= &elf_section_data (s
)->this_hdr
;
1105 switch (hdr
->sh_type
)
1107 case SHT_IA_64_UNWIND
:
1108 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1110 sname
= bfd_get_section_name (abfd
, s
);
1111 len
= sizeof (ELF_STRING_ia64_unwind
) - 1;
1112 if (sname
&& strncmp (sname
, ELF_STRING_ia64_unwind
, len
) == 0)
1116 if (sname
[0] == '\0')
1117 /* .IA_64.unwind -> .text */
1118 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1120 /* .IA_64.unwindFOO -> FOO */
1121 text_sect
= bfd_get_section_by_name (abfd
, sname
);
1124 && (len
= sizeof (ELF_STRING_ia64_unwind_once
) - 1,
1125 strncmp (sname
, ELF_STRING_ia64_unwind_once
, len
)) == 0)
1127 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1128 size_t len2
= sizeof (".gnu.linkonce.t.") - 1;
1129 char *once_name
= alloca (len2
+ strlen (sname
) - len
+ 1);
1131 memcpy (once_name
, ".gnu.linkonce.t.", len2
);
1132 strcpy (once_name
+ len2
, sname
+ len
);
1133 text_sect
= bfd_get_section_by_name (abfd
, once_name
);
1136 /* last resort: fall back on .text */
1137 text_sect
= bfd_get_section_by_name (abfd
, ".text");
1141 /* The IA-64 processor-specific ABI requires setting
1142 sh_link to the unwind section, whereas HP-UX requires
1143 sh_info to do so. For maximum compatibility, we'll
1144 set both for now... */
1145 hdr
->sh_link
= elf_section_data (text_sect
)->this_idx
;
1146 hdr
->sh_info
= elf_section_data (text_sect
)->this_idx
;
1153 /* Hook called by the linker routine which adds symbols from an object
1154 file. We use it to put .comm items in .sbss, and not .bss. */
1157 elfNN_ia64_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1159 struct bfd_link_info
*info
;
1160 const Elf_Internal_Sym
*sym
;
1161 const char **namep ATTRIBUTE_UNUSED
;
1162 flagword
*flagsp ATTRIBUTE_UNUSED
;
1166 if (sym
->st_shndx
== SHN_COMMON
1167 && !info
->relocateable
1168 && sym
->st_size
<= elf_gp_size (abfd
))
1170 /* Common symbols less than or equal to -G nn bytes are
1171 automatically put into .sbss. */
1173 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1177 scomm
= bfd_make_section (abfd
, ".scommon");
1179 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
1181 | SEC_LINKER_CREATED
)))
1186 *valp
= sym
->st_size
;
1193 elfNN_ia64_aix_vec (const bfd_target
*vec
)
1195 extern const bfd_target bfd_elfNN_ia64_aix_little_vec
;
1196 extern const bfd_target bfd_elfNN_ia64_aix_big_vec
;
1198 return (/**/vec
== & bfd_elfNN_ia64_aix_little_vec
1199 || vec
== & bfd_elfNN_ia64_aix_big_vec
);
1202 /* Hook called by the linker routine which adds symbols from an object
1203 file. We use it to handle OS-specific symbols. */
1206 elfNN_ia64_aix_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1208 struct bfd_link_info
*info
;
1209 const Elf_Internal_Sym
*sym
;
1215 if (strcmp (*namep
, "__GLOB_DATA_PTR") == 0)
1217 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1218 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1219 no one else should use it b/c it is undocumented. */
1220 struct elf_link_hash_entry
*h
;
1222 h
= elf_link_hash_lookup (elf_hash_table (info
), *namep
,
1223 false, false, false);
1226 struct elf_backend_data
*bed
;
1227 struct elfNN_ia64_link_hash_table
*ia64_info
;
1229 bed
= get_elf_backend_data (abfd
);
1230 ia64_info
= elfNN_ia64_hash_table (info
);
1232 if (!(_bfd_generic_link_add_one_symbol
1233 (info
, abfd
, *namep
, BSF_GLOBAL
,
1234 bfd_get_section_by_name (abfd
, ".bss"),
1235 bed
->got_symbol_offset
, (const char *) NULL
, false,
1236 bed
->collect
, (struct bfd_link_hash_entry
**) &h
)))
1239 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
1240 h
->type
= STT_OBJECT
;
1242 if (! _bfd_elf_link_record_dynamic_symbol (info
, h
))
1248 else if (sym
->st_shndx
== SHN_LOOS
)
1252 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1253 is only relevant when compiling code for extended system calls.
1254 Replace the "special" section with .text, if possible.
1255 Note that these symbols are always assumed to be in .text. */
1256 for (i
= 1; i
< elf_numsections (abfd
); i
++)
1258 asection
* sec
= bfd_section_from_elf_index (abfd
, i
);
1260 if (sec
&& strcmp (sec
->name
, ".text") == 0)
1268 *secp
= bfd_abs_section_ptr
;
1270 *valp
= sym
->st_size
;
1276 return elfNN_ia64_add_symbol_hook (abfd
, info
, sym
,
1277 namep
, flagsp
, secp
, valp
);
1282 elfNN_ia64_aix_link_add_symbols (abfd
, info
)
1284 struct bfd_link_info
*info
;
1286 /* Make sure dynamic sections are always created. */
1287 if (! elf_hash_table (info
)->dynamic_sections_created
1288 && abfd
->xvec
== info
->hash
->creator
)
1290 if (! bfd_elfNN_link_create_dynamic_sections (abfd
, info
))
1294 /* Now do the standard call. */
1295 return bfd_elfNN_bfd_link_add_symbols (abfd
, info
);
1298 /* Return the number of additional phdrs we will need. */
1301 elfNN_ia64_additional_program_headers (abfd
)
1307 /* See if we need a PT_IA_64_ARCHEXT segment. */
1308 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1309 if (s
&& (s
->flags
& SEC_LOAD
))
1312 /* Count how many PT_IA_64_UNWIND segments we need. */
1313 for (s
= abfd
->sections
; s
; s
= s
->next
)
1314 if (is_unwind_section_name(s
->name
) && (s
->flags
& SEC_LOAD
))
1321 elfNN_ia64_modify_segment_map (abfd
)
1324 struct elf_segment_map
*m
, **pm
;
1325 Elf_Internal_Shdr
*hdr
;
1328 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1329 all PT_LOAD segments. */
1330 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1331 if (s
&& (s
->flags
& SEC_LOAD
))
1333 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1334 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1338 m
= ((struct elf_segment_map
*)
1339 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1343 m
->p_type
= PT_IA_64_ARCHEXT
;
1347 /* We want to put it after the PHDR and INTERP segments. */
1348 pm
= &elf_tdata (abfd
)->segment_map
;
1350 && ((*pm
)->p_type
== PT_PHDR
1351 || (*pm
)->p_type
== PT_INTERP
))
1359 /* Install PT_IA_64_UNWIND segments, if needed. */
1360 for (s
= abfd
->sections
; s
; s
= s
->next
)
1362 hdr
= &elf_section_data (s
)->this_hdr
;
1363 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1366 if (s
&& (s
->flags
& SEC_LOAD
))
1368 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1369 if (m
->p_type
== PT_IA_64_UNWIND
&& m
->sections
[0] == s
)
1374 m
= ((struct elf_segment_map
*)
1375 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1379 m
->p_type
= PT_IA_64_UNWIND
;
1384 /* We want to put it last. */
1385 pm
= &elf_tdata (abfd
)->segment_map
;
1393 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1394 the input sections for each output section in the segment and testing
1395 for SHF_IA_64_NORECOV on each. */
1396 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1397 if (m
->p_type
== PT_LOAD
)
1400 for (i
= m
->count
- 1; i
>= 0; --i
)
1402 struct bfd_link_order
*order
= m
->sections
[i
]->link_order_head
;
1405 if (order
->type
== bfd_indirect_link_order
)
1407 asection
*is
= order
->u
.indirect
.section
;
1408 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1409 if (flags
& SHF_IA_64_NORECOV
)
1411 m
->p_flags
|= PF_IA_64_NORECOV
;
1415 order
= order
->next
;
1424 /* According to the Tahoe assembler spec, all labels starting with a
1428 elfNN_ia64_is_local_label_name (abfd
, name
)
1429 bfd
*abfd ATTRIBUTE_UNUSED
;
1432 return name
[0] == '.';
1435 /* Should we do dynamic things to this symbol? */
1438 elfNN_ia64_dynamic_symbol_p (h
, info
)
1439 struct elf_link_hash_entry
*h
;
1440 struct bfd_link_info
*info
;
1445 while (h
->root
.type
== bfd_link_hash_indirect
1446 || h
->root
.type
== bfd_link_hash_warning
)
1447 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1449 if (h
->dynindx
== -1)
1451 switch (ELF_ST_VISIBILITY (h
->other
))
1458 if (h
->root
.type
== bfd_link_hash_undefweak
1459 || h
->root
.type
== bfd_link_hash_defweak
)
1462 if ((info
->shared
&& (!info
->symbolic
|| info
->allow_shlib_undefined
))
1463 || ((h
->elf_link_hash_flags
1464 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
1465 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
1472 elfNN_ia64_local_hash_table_init (ht
, abfd
, new)
1473 struct elfNN_ia64_local_hash_table
*ht
;
1474 bfd
*abfd ATTRIBUTE_UNUSED
;
1475 new_hash_entry_func
new;
1477 memset (ht
, 0, sizeof (*ht
));
1478 return bfd_hash_table_init (&ht
->root
, new);
1481 static struct bfd_hash_entry
*
1482 elfNN_ia64_new_loc_hash_entry (entry
, table
, string
)
1483 struct bfd_hash_entry
*entry
;
1484 struct bfd_hash_table
*table
;
1487 struct elfNN_ia64_local_hash_entry
*ret
;
1488 ret
= (struct elfNN_ia64_local_hash_entry
*) entry
;
1490 /* Allocate the structure if it has not already been allocated by a
1493 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1498 /* Initialize our local data. All zeros, and definitely easier
1499 than setting a handful of bit fields. */
1500 memset (ret
, 0, sizeof (*ret
));
1502 /* Call the allocation method of the superclass. */
1503 ret
= ((struct elfNN_ia64_local_hash_entry
*)
1504 bfd_hash_newfunc ((struct bfd_hash_entry
*) ret
, table
, string
));
1506 return (struct bfd_hash_entry
*) ret
;
1509 static struct bfd_hash_entry
*
1510 elfNN_ia64_new_elf_hash_entry (entry
, table
, string
)
1511 struct bfd_hash_entry
*entry
;
1512 struct bfd_hash_table
*table
;
1515 struct elfNN_ia64_link_hash_entry
*ret
;
1516 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1518 /* Allocate the structure if it has not already been allocated by a
1521 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1526 /* Initialize our local data. All zeros, and definitely easier
1527 than setting a handful of bit fields. */
1528 memset (ret
, 0, sizeof (*ret
));
1530 /* Call the allocation method of the superclass. */
1531 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1532 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1535 return (struct bfd_hash_entry
*) ret
;
1539 elfNN_ia64_hash_copy_indirect (xdir
, xind
)
1540 struct elf_link_hash_entry
*xdir
, *xind
;
1542 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1544 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1545 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1547 /* Copy down any references that we may have already seen to the
1548 symbol which just became indirect. */
1550 dir
->root
.elf_link_hash_flags
|=
1551 (ind
->root
.elf_link_hash_flags
1552 & (ELF_LINK_HASH_REF_DYNAMIC
1553 | ELF_LINK_HASH_REF_REGULAR
1554 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
));
1556 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1559 /* Copy over the got and plt data. This would have been done
1562 if (dir
->info
== NULL
)
1564 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1566 dir
->info
= dyn_i
= ind
->info
;
1569 /* Fix up the dyn_sym_info pointers to the global symbol. */
1570 for (; dyn_i
; dyn_i
= dyn_i
->next
)
1571 dyn_i
->h
= &dir
->root
;
1573 BFD_ASSERT (ind
->info
== NULL
);
1575 /* Copy over the dynindx. */
1577 if (dir
->root
.dynindx
== -1)
1579 dir
->root
.dynindx
= ind
->root
.dynindx
;
1580 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1581 ind
->root
.dynindx
= -1;
1582 ind
->root
.dynstr_index
= 0;
1584 BFD_ASSERT (ind
->root
.dynindx
== -1);
1588 elfNN_ia64_hash_hide_symbol (info
, xh
)
1589 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1590 struct elf_link_hash_entry
*xh
;
1592 struct elfNN_ia64_link_hash_entry
*h
;
1593 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1595 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1597 h
->root
.elf_link_hash_flags
&= ~ELF_LINK_HASH_NEEDS_PLT
;
1598 if ((h
->root
.elf_link_hash_flags
& ELF_LINK_FORCED_LOCAL
) != 0)
1599 h
->root
.dynindx
= -1;
1601 for (dyn_i
= h
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1602 dyn_i
->want_plt2
= 0;
1605 /* Create the derived linker hash table. The IA-64 ELF port uses this
1606 derived hash table to keep information specific to the IA-64 ElF
1607 linker (without using static variables). */
1609 static struct bfd_link_hash_table
*
1610 elfNN_ia64_hash_table_create (abfd
)
1613 struct elfNN_ia64_link_hash_table
*ret
;
1615 ret
= bfd_zalloc (abfd
, (bfd_size_type
) sizeof (*ret
));
1618 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1619 elfNN_ia64_new_elf_hash_entry
))
1621 bfd_release (abfd
, ret
);
1625 if (!elfNN_ia64_local_hash_table_init (&ret
->loc_hash_table
, abfd
,
1626 elfNN_ia64_new_loc_hash_entry
))
1628 return &ret
->root
.root
;
1631 /* Look up an entry in a Alpha ELF linker hash table. */
1633 static INLINE
struct elfNN_ia64_local_hash_entry
*
1634 elfNN_ia64_local_hash_lookup(table
, string
, create
, copy
)
1635 struct elfNN_ia64_local_hash_table
*table
;
1637 boolean create
, copy
;
1639 return ((struct elfNN_ia64_local_hash_entry
*)
1640 bfd_hash_lookup (&table
->root
, string
, create
, copy
));
1643 /* Traverse both local and global hash tables. */
1645 struct elfNN_ia64_dyn_sym_traverse_data
1647 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1652 elfNN_ia64_global_dyn_sym_thunk (xentry
, xdata
)
1653 struct bfd_hash_entry
*xentry
;
1656 struct elfNN_ia64_link_hash_entry
*entry
1657 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1658 struct elfNN_ia64_dyn_sym_traverse_data
*data
1659 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1660 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1662 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1663 if (! (*data
->func
) (dyn_i
, data
->data
))
1669 elfNN_ia64_local_dyn_sym_thunk (xentry
, xdata
)
1670 struct bfd_hash_entry
*xentry
;
1673 struct elfNN_ia64_local_hash_entry
*entry
1674 = (struct elfNN_ia64_local_hash_entry
*) xentry
;
1675 struct elfNN_ia64_dyn_sym_traverse_data
*data
1676 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1677 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1679 for (dyn_i
= entry
->info
; dyn_i
; dyn_i
= dyn_i
->next
)
1680 if (! (*data
->func
) (dyn_i
, data
->data
))
1686 elfNN_ia64_dyn_sym_traverse (ia64_info
, func
, data
)
1687 struct elfNN_ia64_link_hash_table
*ia64_info
;
1688 boolean (*func
) PARAMS ((struct elfNN_ia64_dyn_sym_info
*, PTR
));
1691 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1696 elf_link_hash_traverse (&ia64_info
->root
,
1697 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1698 bfd_hash_traverse (&ia64_info
->loc_hash_table
.root
,
1699 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1703 elfNN_ia64_create_dynamic_sections (abfd
, info
)
1705 struct bfd_link_info
*info
;
1707 struct elfNN_ia64_link_hash_table
*ia64_info
;
1710 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
1713 ia64_info
= elfNN_ia64_hash_table (info
);
1715 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
1716 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
1719 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
1720 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
1723 if (!get_pltoff (abfd
, info
, ia64_info
))
1726 s
= bfd_make_section(abfd
, ".rela.IA_64.pltoff");
1728 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1731 | SEC_LINKER_CREATED
1733 || !bfd_set_section_alignment (abfd
, s
, 3))
1735 ia64_info
->rel_pltoff_sec
= s
;
1737 s
= bfd_make_section(abfd
, ".rela.got");
1739 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
1742 | SEC_LINKER_CREATED
1744 || !bfd_set_section_alignment (abfd
, s
, 3))
1746 ia64_info
->rel_got_sec
= s
;
1751 /* Find and/or create a hash entry for local symbol. */
1752 static struct elfNN_ia64_local_hash_entry
*
1753 get_local_sym_hash (ia64_info
, abfd
, rel
, create
)
1754 struct elfNN_ia64_link_hash_table
*ia64_info
;
1756 const Elf_Internal_Rela
*rel
;
1762 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1763 name describes what was once anonymous memory. */
1765 len
= sizeof (void*)*2 + 1 + sizeof (bfd_vma
)*4 + 1 + 1;
1766 len
+= 10; /* %p slop */
1768 addr_name
= alloca (len
);
1769 sprintf (addr_name
, "%p:%lx",
1770 (void *) abfd
, (unsigned long) ELFNN_R_SYM (rel
->r_info
));
1772 /* Collect the canonical entry data for this address. */
1773 return elfNN_ia64_local_hash_lookup (&ia64_info
->loc_hash_table
,
1774 addr_name
, create
, create
);
1777 /* Find and/or create a descriptor for dynamic symbol info. This will
1778 vary based on global or local symbol, and the addend to the reloc. */
1780 static struct elfNN_ia64_dyn_sym_info
*
1781 get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, create
)
1782 struct elfNN_ia64_link_hash_table
*ia64_info
;
1783 struct elf_link_hash_entry
*h
;
1785 const Elf_Internal_Rela
*rel
;
1788 struct elfNN_ia64_dyn_sym_info
**pp
;
1789 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1790 bfd_vma addend
= rel
? rel
->r_addend
: 0;
1793 pp
= &((struct elfNN_ia64_link_hash_entry
*)h
)->info
;
1796 struct elfNN_ia64_local_hash_entry
*loc_h
;
1798 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
1804 for (dyn_i
= *pp
; dyn_i
&& dyn_i
->addend
!= addend
; dyn_i
= *pp
)
1807 if (dyn_i
== NULL
&& create
)
1809 dyn_i
= ((struct elfNN_ia64_dyn_sym_info
*)
1810 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *dyn_i
));
1812 dyn_i
->addend
= addend
;
1819 get_got (abfd
, info
, ia64_info
)
1821 struct bfd_link_info
*info
;
1822 struct elfNN_ia64_link_hash_table
*ia64_info
;
1827 got
= ia64_info
->got_sec
;
1832 dynobj
= ia64_info
->root
.dynobj
;
1834 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1835 if (!_bfd_elf_create_got_section (dynobj
, info
))
1838 got
= bfd_get_section_by_name (dynobj
, ".got");
1840 ia64_info
->got_sec
= got
;
1842 flags
= bfd_get_section_flags (abfd
, got
);
1843 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
1849 /* Create function descriptor section (.opd). This section is called .opd
1850 because it contains "official prodecure descriptors". The "official"
1851 refers to the fact that these descriptors are used when taking the address
1852 of a procedure, thus ensuring a unique address for each procedure. */
1855 get_fptr (abfd
, info
, ia64_info
)
1857 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1858 struct elfNN_ia64_link_hash_table
*ia64_info
;
1863 fptr
= ia64_info
->fptr_sec
;
1866 dynobj
= ia64_info
->root
.dynobj
;
1868 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1870 fptr
= bfd_make_section (dynobj
, ".opd");
1872 || !bfd_set_section_flags (dynobj
, fptr
,
1878 | SEC_LINKER_CREATED
))
1879 || !bfd_set_section_alignment (abfd
, fptr
, 4))
1885 ia64_info
->fptr_sec
= fptr
;
1892 get_pltoff (abfd
, info
, ia64_info
)
1894 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
1895 struct elfNN_ia64_link_hash_table
*ia64_info
;
1900 pltoff
= ia64_info
->pltoff_sec
;
1903 dynobj
= ia64_info
->root
.dynobj
;
1905 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1907 pltoff
= bfd_make_section (dynobj
, ELF_STRING_ia64_pltoff
);
1909 || !bfd_set_section_flags (dynobj
, pltoff
,
1915 | SEC_LINKER_CREATED
))
1916 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
1922 ia64_info
->pltoff_sec
= pltoff
;
1929 get_reloc_section (abfd
, ia64_info
, sec
, create
)
1931 struct elfNN_ia64_link_hash_table
*ia64_info
;
1935 const char *srel_name
;
1939 srel_name
= (bfd_elf_string_from_elf_section
1940 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
1941 elf_section_data(sec
)->rel_hdr
.sh_name
));
1942 if (srel_name
== NULL
)
1945 BFD_ASSERT ((strncmp (srel_name
, ".rela", 5) == 0
1946 && strcmp (bfd_get_section_name (abfd
, sec
),
1948 || (strncmp (srel_name
, ".rel", 4) == 0
1949 && strcmp (bfd_get_section_name (abfd
, sec
),
1950 srel_name
+4) == 0));
1952 dynobj
= ia64_info
->root
.dynobj
;
1954 ia64_info
->root
.dynobj
= dynobj
= abfd
;
1956 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
1957 if (srel
== NULL
&& create
)
1959 srel
= bfd_make_section (dynobj
, srel_name
);
1961 || !bfd_set_section_flags (dynobj
, srel
,
1966 | SEC_LINKER_CREATED
1968 || !bfd_set_section_alignment (dynobj
, srel
, 3))
1972 if (sec
->flags
& SEC_READONLY
)
1973 ia64_info
->reltext
= 1;
1979 count_dyn_reloc (abfd
, dyn_i
, srel
, type
)
1981 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1985 struct elfNN_ia64_dyn_reloc_entry
*rent
;
1987 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
1988 if (rent
->srel
== srel
&& rent
->type
== type
)
1993 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
1994 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
1998 rent
->next
= dyn_i
->reloc_entries
;
2002 dyn_i
->reloc_entries
= rent
;
2010 elfNN_ia64_check_relocs (abfd
, info
, sec
, relocs
)
2012 struct bfd_link_info
*info
;
2014 const Elf_Internal_Rela
*relocs
;
2016 struct elfNN_ia64_link_hash_table
*ia64_info
;
2017 const Elf_Internal_Rela
*relend
;
2018 Elf_Internal_Shdr
*symtab_hdr
;
2019 const Elf_Internal_Rela
*rel
;
2020 asection
*got
, *fptr
, *srel
;
2022 if (info
->relocateable
)
2025 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2026 ia64_info
= elfNN_ia64_hash_table (info
);
2028 got
= fptr
= srel
= NULL
;
2030 relend
= relocs
+ sec
->reloc_count
;
2031 for (rel
= relocs
; rel
< relend
; ++rel
)
2040 NEED_LTOFF_FPTR
= 64,
2043 struct elf_link_hash_entry
*h
= NULL
;
2044 unsigned long r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2045 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2047 boolean maybe_dynamic
;
2048 int dynrel_type
= R_IA64_NONE
;
2050 if (r_symndx
>= symtab_hdr
->sh_info
)
2052 /* We're dealing with a global symbol -- find its hash entry
2053 and mark it as being referenced. */
2054 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2055 h
= elf_sym_hashes (abfd
)[indx
];
2056 while (h
->root
.type
== bfd_link_hash_indirect
2057 || h
->root
.type
== bfd_link_hash_warning
)
2058 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2060 h
->elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
2063 /* We can only get preliminary data on whether a symbol is
2064 locally or externally defined, as not all of the input files
2065 have yet been processed. Do something with what we know, as
2066 this may help reduce memory usage and processing time later. */
2067 maybe_dynamic
= false;
2068 if (h
&& ((info
->shared
2069 && (!info
->symbolic
|| info
->allow_shlib_undefined
))
2070 || ! (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
2071 || h
->root
.type
== bfd_link_hash_defweak
2072 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2073 maybe_dynamic
= true;
2076 switch (ELFNN_R_TYPE (rel
->r_info
))
2078 case R_IA64_TPREL22
:
2079 case R_IA64_TPREL64MSB
:
2080 case R_IA64_TPREL64LSB
:
2081 case R_IA64_LTOFF_TP22
:
2084 case R_IA64_LTOFF_FPTR22
:
2085 case R_IA64_LTOFF_FPTR64I
:
2086 case R_IA64_LTOFF_FPTR32MSB
:
2087 case R_IA64_LTOFF_FPTR32LSB
:
2088 case R_IA64_LTOFF_FPTR64MSB
:
2089 case R_IA64_LTOFF_FPTR64LSB
:
2090 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2093 case R_IA64_FPTR64I
:
2094 case R_IA64_FPTR32MSB
:
2095 case R_IA64_FPTR32LSB
:
2096 case R_IA64_FPTR64MSB
:
2097 case R_IA64_FPTR64LSB
:
2098 if (info
->shared
|| h
|| elfNN_ia64_aix_vec (abfd
->xvec
))
2099 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2101 need_entry
= NEED_FPTR
;
2102 dynrel_type
= R_IA64_FPTR64LSB
;
2105 case R_IA64_LTOFF22
:
2106 case R_IA64_LTOFF22X
:
2107 case R_IA64_LTOFF64I
:
2108 need_entry
= NEED_GOT
;
2111 case R_IA64_PLTOFF22
:
2112 case R_IA64_PLTOFF64I
:
2113 case R_IA64_PLTOFF64MSB
:
2114 case R_IA64_PLTOFF64LSB
:
2115 need_entry
= NEED_PLTOFF
;
2119 need_entry
|= NEED_MIN_PLT
;
2123 (*info
->callbacks
->warning
)
2124 (info
, _("@pltoff reloc against local symbol"), 0,
2125 abfd
, 0, (bfd_vma
) 0);
2129 case R_IA64_PCREL21B
:
2130 case R_IA64_PCREL60B
:
2131 /* Depending on where this symbol is defined, we may or may not
2132 need a full plt entry. Only skip if we know we'll not need
2133 the entry -- static or symbolic, and the symbol definition
2134 has already been seen. */
2135 if (maybe_dynamic
&& rel
->r_addend
== 0)
2136 need_entry
= NEED_FULL_PLT
;
2142 case R_IA64_DIR32MSB
:
2143 case R_IA64_DIR32LSB
:
2144 case R_IA64_DIR64MSB
:
2145 case R_IA64_DIR64LSB
:
2146 /* Shared objects will always need at least a REL relocation. */
2147 if (info
->shared
|| maybe_dynamic
2148 || (elfNN_ia64_aix_vec (abfd
->xvec
)
2149 && (!h
|| strcmp (h
->root
.root
.string
,
2150 "__GLOB_DATA_PTR") != 0)))
2151 need_entry
= NEED_DYNREL
;
2152 dynrel_type
= R_IA64_DIR64LSB
;
2155 case R_IA64_IPLTMSB
:
2156 case R_IA64_IPLTLSB
:
2157 /* Shared objects will always need at least a REL relocation. */
2158 if (info
->shared
|| maybe_dynamic
)
2159 need_entry
= NEED_DYNREL
;
2160 dynrel_type
= R_IA64_IPLTLSB
;
2163 case R_IA64_PCREL22
:
2164 case R_IA64_PCREL64I
:
2165 case R_IA64_PCREL32MSB
:
2166 case R_IA64_PCREL32LSB
:
2167 case R_IA64_PCREL64MSB
:
2168 case R_IA64_PCREL64LSB
:
2170 need_entry
= NEED_DYNREL
;
2171 dynrel_type
= R_IA64_PCREL64LSB
;
2178 if ((need_entry
& NEED_FPTR
) != 0
2181 (*info
->callbacks
->warning
)
2182 (info
, _("non-zero addend in @fptr reloc"), 0,
2183 abfd
, 0, (bfd_vma
) 0);
2186 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, true);
2188 /* Record whether or not this is a local symbol. */
2191 /* Create what's needed. */
2192 if (need_entry
& NEED_GOT
)
2196 got
= get_got (abfd
, info
, ia64_info
);
2200 dyn_i
->want_got
= 1;
2202 if (need_entry
& NEED_FPTR
)
2206 fptr
= get_fptr (abfd
, info
, ia64_info
);
2211 /* FPTRs for shared libraries are allocated by the dynamic
2212 linker. Make sure this local symbol will appear in the
2213 dynamic symbol table. */
2214 if (!h
&& (info
->shared
2215 /* AIX also needs one */
2216 || elfNN_ia64_aix_vec (abfd
->xvec
)))
2218 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2219 (info
, abfd
, (long) r_symndx
)))
2223 dyn_i
->want_fptr
= 1;
2225 if (need_entry
& NEED_LTOFF_FPTR
)
2226 dyn_i
->want_ltoff_fptr
= 1;
2227 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
2229 if (!ia64_info
->root
.dynobj
)
2230 ia64_info
->root
.dynobj
= abfd
;
2231 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
2232 dyn_i
->want_plt
= 1;
2234 if (need_entry
& NEED_FULL_PLT
)
2235 dyn_i
->want_plt2
= 1;
2236 if (need_entry
& NEED_PLTOFF
)
2237 dyn_i
->want_pltoff
= 1;
2238 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
2242 srel
= get_reloc_section (abfd
, ia64_info
, sec
, true);
2246 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
))
2254 struct elfNN_ia64_allocate_data
2256 struct bfd_link_info
*info
;
2260 /* For cleanliness, and potentially faster dynamic loading, allocate
2261 external GOT entries first. */
2264 allocate_global_data_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
;
2271 && ! dyn_i
->want_fptr
2272 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2273 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2274 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2275 "__GLOB_DATA_PTR") != 0))))
2277 dyn_i
->got_offset
= x
->ofs
;
2283 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2286 allocate_global_fptr_got (dyn_i
, data
)
2287 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2290 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2294 && (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2295 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2297 dyn_i
->got_offset
= x
->ofs
;
2303 /* Lastly, allocate all the GOT entries for local data. */
2306 allocate_local_got (dyn_i
, data
)
2307 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2310 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2313 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2314 || elfNN_ia64_aix_vec (x
->info
->hash
->creator
)))
2316 dyn_i
->got_offset
= x
->ofs
;
2322 /* Search for the index of a global symbol in it's defining object file. */
2325 global_sym_index (h
)
2326 struct elf_link_hash_entry
*h
;
2328 struct elf_link_hash_entry
**p
;
2331 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
2332 || h
->root
.type
== bfd_link_hash_defweak
);
2334 obj
= h
->root
.u
.def
.section
->owner
;
2335 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
2338 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
2341 /* Allocate function descriptors. We can do these for every function
2342 in a main executable that is not exported. */
2345 allocate_fptr (dyn_i
, data
)
2346 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2349 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2351 if (dyn_i
->want_fptr
)
2353 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2356 while (h
->root
.type
== bfd_link_hash_indirect
2357 || h
->root
.type
== bfd_link_hash_warning
)
2358 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2361 /* AIX needs an FPTR in this case. */
2362 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2364 || h
->root
.type
== bfd_link_hash_defined
2365 || h
->root
.type
== bfd_link_hash_defweak
)))
2367 if (h
&& h
->dynindx
== -1)
2369 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
2370 || (h
->root
.type
== bfd_link_hash_defweak
));
2372 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2373 (x
->info
, h
->root
.u
.def
.section
->owner
,
2374 global_sym_index (h
)))
2378 dyn_i
->want_fptr
= 0;
2380 else if (h
== NULL
|| h
->dynindx
== -1)
2382 dyn_i
->fptr_offset
= x
->ofs
;
2386 dyn_i
->want_fptr
= 0;
2391 /* Allocate all the minimal PLT entries. */
2394 allocate_plt_entries (dyn_i
, data
)
2395 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2398 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2400 if (dyn_i
->want_plt
)
2402 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2405 while (h
->root
.type
== bfd_link_hash_indirect
2406 || h
->root
.type
== bfd_link_hash_warning
)
2407 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2409 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2410 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
))
2412 bfd_size_type offset
= x
->ofs
;
2414 offset
= PLT_HEADER_SIZE
;
2415 dyn_i
->plt_offset
= offset
;
2416 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
2418 dyn_i
->want_pltoff
= 1;
2422 dyn_i
->want_plt
= 0;
2423 dyn_i
->want_plt2
= 0;
2429 /* Allocate all the full PLT entries. */
2432 allocate_plt2_entries (dyn_i
, data
)
2433 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2436 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2438 if (dyn_i
->want_plt2
)
2440 struct elf_link_hash_entry
*h
= dyn_i
->h
;
2441 bfd_size_type ofs
= x
->ofs
;
2443 dyn_i
->plt2_offset
= ofs
;
2444 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
2446 while (h
->root
.type
== bfd_link_hash_indirect
2447 || h
->root
.type
== bfd_link_hash_warning
)
2448 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2449 dyn_i
->h
->plt
.offset
= ofs
;
2454 /* Allocate all the PLTOFF entries requested by relocations and
2455 plt entries. We can't share space with allocated FPTR entries,
2456 because the latter are not necessarily addressable by the GP.
2457 ??? Relaxation might be able to determine that they are. */
2460 allocate_pltoff_entries (dyn_i
, data
)
2461 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2464 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2466 if (dyn_i
->want_pltoff
)
2468 dyn_i
->pltoff_offset
= x
->ofs
;
2474 /* Allocate dynamic relocations for those symbols that turned out
2478 allocate_dynrel_entries (dyn_i
, data
)
2479 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2482 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
2483 struct elfNN_ia64_link_hash_table
*ia64_info
;
2484 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2485 boolean dynamic_symbol
, shared
;
2487 ia64_info
= elfNN_ia64_hash_table (x
->info
);
2488 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
)
2489 || (elfNN_ia64_aix_vec (x
->info
->hash
->creator
)
2490 /* Don't allocate an entry for __GLOB_DATA_PTR */
2491 && (!dyn_i
->h
|| strcmp (dyn_i
->h
->root
.root
.string
,
2492 "__GLOB_DATA_PTR") != 0));
2493 shared
= x
->info
->shared
;
2495 /* Take care of the normal data relocations. */
2497 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2499 int count
= rent
->count
;
2503 case R_IA64_FPTR64LSB
:
2504 /* Allocate one iff !want_fptr, which by this point will
2505 be true only if we're actually allocating one statically
2506 in the main executable. */
2507 if (dyn_i
->want_fptr
)
2510 case R_IA64_PCREL64LSB
:
2511 if (!dynamic_symbol
)
2514 case R_IA64_DIR64LSB
:
2515 if (!dynamic_symbol
&& !shared
)
2518 case R_IA64_IPLTLSB
:
2519 if (!dynamic_symbol
&& !shared
)
2521 /* Use two REL relocations for IPLT relocations
2522 against local symbols. */
2523 if (!dynamic_symbol
)
2529 rent
->srel
->_raw_size
+= sizeof (ElfNN_External_Rela
) * count
;
2532 /* Take care of the GOT and PLT relocations. */
2534 if (((dynamic_symbol
|| shared
) && dyn_i
->want_got
)
2535 || (dyn_i
->want_ltoff_fptr
&& dyn_i
->h
&& dyn_i
->h
->dynindx
!= -1))
2536 ia64_info
->rel_got_sec
->_raw_size
+= sizeof (ElfNN_External_Rela
);
2538 if (dyn_i
->want_pltoff
)
2540 bfd_size_type t
= 0;
2542 /* Dynamic symbols get one IPLT relocation. Local symbols in
2543 shared libraries get two REL relocations. Local symbols in
2544 main applications get nothing. */
2546 t
= sizeof (ElfNN_External_Rela
);
2548 t
= 2 * sizeof (ElfNN_External_Rela
);
2550 ia64_info
->rel_pltoff_sec
->_raw_size
+= t
;
2557 elfNN_ia64_adjust_dynamic_symbol (info
, h
)
2558 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2559 struct elf_link_hash_entry
*h
;
2561 /* ??? Undefined symbols with PLT entries should be re-defined
2562 to be the PLT entry. */
2564 /* If this is a weak symbol, and there is a real definition, the
2565 processor independent code will have arranged for us to see the
2566 real definition first, and we can just use the same value. */
2567 if (h
->weakdef
!= NULL
)
2569 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
2570 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
2571 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
2572 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
2576 /* If this is a reference to a symbol defined by a dynamic object which
2577 is not a function, we might allocate the symbol in our .dynbss section
2578 and allocate a COPY dynamic relocation.
2580 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2587 elfNN_ia64_size_dynamic_sections (output_bfd
, info
)
2589 struct bfd_link_info
*info
;
2591 struct elfNN_ia64_allocate_data data
;
2592 struct elfNN_ia64_link_hash_table
*ia64_info
;
2595 boolean relplt
= false;
2597 dynobj
= elf_hash_table(info
)->dynobj
;
2598 ia64_info
= elfNN_ia64_hash_table (info
);
2599 BFD_ASSERT(dynobj
!= NULL
);
2602 /* Set the contents of the .interp section to the interpreter. */
2603 if (ia64_info
->root
.dynamic_sections_created
2606 sec
= bfd_get_section_by_name (dynobj
, ".interp");
2607 BFD_ASSERT (sec
!= NULL
);
2608 sec
->contents
= (bfd_byte
*) DYNAMIC_INTERPRETER (output_bfd
);
2609 sec
->_raw_size
= strlen (DYNAMIC_INTERPRETER (output_bfd
)) + 1;
2612 /* Allocate the GOT entries. */
2614 if (ia64_info
->got_sec
)
2617 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
2618 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
2619 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
2620 ia64_info
->got_sec
->_raw_size
= data
.ofs
;
2623 /* Allocate the FPTR entries. */
2625 if (ia64_info
->fptr_sec
)
2628 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
2629 ia64_info
->fptr_sec
->_raw_size
= data
.ofs
;
2632 /* Now that we've seen all of the input files, we can decide which
2633 symbols need plt entries. Allocate the minimal PLT entries first.
2634 We do this even though dynamic_sections_created may be false, because
2635 this has the side-effect of clearing want_plt and want_plt2. */
2638 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
2640 ia64_info
->minplt_entries
= 0;
2643 ia64_info
->minplt_entries
2644 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
2647 /* Align the pointer for the plt2 entries. */
2648 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
2650 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
2653 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
2655 ia64_info
->plt_sec
->_raw_size
= data
.ofs
;
2657 /* If we've got a .plt, we need some extra memory for the dynamic
2658 linker. We stuff these in .got.plt. */
2659 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
2660 sec
->_raw_size
= 8 * PLT_RESERVED_WORDS
;
2663 /* Allocate the PLTOFF entries. */
2665 if (ia64_info
->pltoff_sec
)
2668 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
2669 ia64_info
->pltoff_sec
->_raw_size
= data
.ofs
;
2672 if (ia64_info
->root
.dynamic_sections_created
)
2674 /* Allocate space for the dynamic relocations that turned out to be
2677 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
2680 /* We have now determined the sizes of the various dynamic sections.
2681 Allocate memory for them. */
2682 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
2686 if (!(sec
->flags
& SEC_LINKER_CREATED
))
2689 /* If we don't need this section, strip it from the output file.
2690 There were several sections primarily related to dynamic
2691 linking that must be create before the linker maps input
2692 sections to output sections. The linker does that before
2693 bfd_elf_size_dynamic_sections is called, and it is that
2694 function which decides whether anything needs to go into
2697 strip
= (sec
->_raw_size
== 0);
2699 if (sec
== ia64_info
->got_sec
)
2701 else if (sec
== ia64_info
->rel_got_sec
)
2704 ia64_info
->rel_got_sec
= NULL
;
2706 /* We use the reloc_count field as a counter if we need to
2707 copy relocs into the output file. */
2708 sec
->reloc_count
= 0;
2710 else if (sec
== ia64_info
->fptr_sec
)
2713 ia64_info
->fptr_sec
= NULL
;
2715 else if (sec
== ia64_info
->plt_sec
)
2718 ia64_info
->plt_sec
= NULL
;
2720 else if (sec
== ia64_info
->pltoff_sec
)
2723 ia64_info
->pltoff_sec
= NULL
;
2725 else if (sec
== ia64_info
->rel_pltoff_sec
)
2728 ia64_info
->rel_pltoff_sec
= NULL
;
2732 /* We use the reloc_count field as a counter if we need to
2733 copy relocs into the output file. */
2734 sec
->reloc_count
= 0;
2741 /* It's OK to base decisions on the section name, because none
2742 of the dynobj section names depend upon the input files. */
2743 name
= bfd_get_section_name (dynobj
, sec
);
2745 if (strcmp (name
, ".got.plt") == 0)
2747 else if (strncmp (name
, ".rel", 4) == 0)
2751 /* We use the reloc_count field as a counter if we need to
2752 copy relocs into the output file. */
2753 sec
->reloc_count
= 0;
2761 _bfd_strip_section_from_output (info
, sec
);
2764 /* Allocate memory for the section contents. */
2765 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->_raw_size
);
2766 if (sec
->contents
== NULL
&& sec
->_raw_size
!= 0)
2771 if (elf_hash_table (info
)->dynamic_sections_created
)
2773 /* Add some entries to the .dynamic section. We fill in the values
2774 later (in finish_dynamic_sections) but we must add the entries now
2775 so that we get the correct size for the .dynamic section. */
2779 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2781 #define add_dynamic_entry(TAG, VAL) \
2782 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
2784 if (!add_dynamic_entry (DT_DEBUG
, 0))
2788 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
2790 if (!add_dynamic_entry (DT_PLTGOT
, 0))
2795 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
2796 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
2797 || !add_dynamic_entry (DT_JMPREL
, 0))
2801 if (!add_dynamic_entry (DT_RELA
, 0)
2802 || !add_dynamic_entry (DT_RELASZ
, 0)
2803 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
2806 if (ia64_info
->reltext
)
2808 if (!add_dynamic_entry (DT_TEXTREL
, 0))
2810 info
->flags
|= DF_TEXTREL
;
2814 /* ??? Perhaps force __gp local. */
2819 static bfd_reloc_status_type
2820 elfNN_ia64_install_value (abfd
, hit_addr
, v
, r_type
)
2824 unsigned int r_type
;
2826 const struct ia64_operand
*op
;
2827 int bigendian
= 0, shift
= 0;
2828 bfd_vma t0
, t1
, insn
, dword
;
2829 enum ia64_opnd opnd
;
2832 #ifdef BFD_HOST_U_64_BIT
2833 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
2838 opnd
= IA64_OPND_NIL
;
2843 return bfd_reloc_ok
;
2845 /* Instruction relocations. */
2847 case R_IA64_IMM14
: opnd
= IA64_OPND_IMM14
; break;
2849 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
2850 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
2851 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
2852 case R_IA64_PCREL21B
:
2853 case R_IA64_PCREL21BI
:
2854 opnd
= IA64_OPND_TGT25c
;
2858 case R_IA64_GPREL22
:
2859 case R_IA64_LTOFF22
:
2860 case R_IA64_LTOFF22X
:
2861 case R_IA64_PLTOFF22
:
2862 case R_IA64_PCREL22
:
2863 case R_IA64_LTOFF_FPTR22
:
2864 opnd
= IA64_OPND_IMM22
;
2868 case R_IA64_GPREL64I
:
2869 case R_IA64_LTOFF64I
:
2870 case R_IA64_PLTOFF64I
:
2871 case R_IA64_PCREL64I
:
2872 case R_IA64_FPTR64I
:
2873 case R_IA64_LTOFF_FPTR64I
:
2874 opnd
= IA64_OPND_IMMU64
;
2877 /* Data relocations. */
2879 case R_IA64_DIR32MSB
:
2880 case R_IA64_GPREL32MSB
:
2881 case R_IA64_FPTR32MSB
:
2882 case R_IA64_PCREL32MSB
:
2883 case R_IA64_LTOFF_FPTR32MSB
:
2884 case R_IA64_SEGREL32MSB
:
2885 case R_IA64_SECREL32MSB
:
2886 case R_IA64_LTV32MSB
:
2887 size
= 4; bigendian
= 1;
2890 case R_IA64_DIR32LSB
:
2891 case R_IA64_GPREL32LSB
:
2892 case R_IA64_FPTR32LSB
:
2893 case R_IA64_PCREL32LSB
:
2894 case R_IA64_LTOFF_FPTR32LSB
:
2895 case R_IA64_SEGREL32LSB
:
2896 case R_IA64_SECREL32LSB
:
2897 case R_IA64_LTV32LSB
:
2898 size
= 4; bigendian
= 0;
2901 case R_IA64_DIR64MSB
:
2902 case R_IA64_GPREL64MSB
:
2903 case R_IA64_PLTOFF64MSB
:
2904 case R_IA64_FPTR64MSB
:
2905 case R_IA64_PCREL64MSB
:
2906 case R_IA64_LTOFF_FPTR64MSB
:
2907 case R_IA64_SEGREL64MSB
:
2908 case R_IA64_SECREL64MSB
:
2909 case R_IA64_LTV64MSB
:
2910 size
= 8; bigendian
= 1;
2913 case R_IA64_DIR64LSB
:
2914 case R_IA64_GPREL64LSB
:
2915 case R_IA64_PLTOFF64LSB
:
2916 case R_IA64_FPTR64LSB
:
2917 case R_IA64_PCREL64LSB
:
2918 case R_IA64_LTOFF_FPTR64LSB
:
2919 case R_IA64_SEGREL64LSB
:
2920 case R_IA64_SECREL64LSB
:
2921 case R_IA64_LTV64LSB
:
2922 size
= 8; bigendian
= 0;
2925 /* Unsupported / Dynamic relocations. */
2927 return bfd_reloc_notsupported
;
2932 case IA64_OPND_IMMU64
:
2933 hit_addr
-= (long) hit_addr
& 0x3;
2934 t0
= bfd_get_64 (abfd
, hit_addr
);
2935 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2937 /* tmpl/s: bits 0.. 5 in t0
2938 slot 0: bits 5..45 in t0
2939 slot 1: bits 46..63 in t0, bits 0..22 in t1
2940 slot 2: bits 23..63 in t1 */
2942 /* First, clear the bits that form the 64 bit constant. */
2943 t0
&= ~(0x3ffffLL
<< 46);
2945 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
2946 | (0x01fLL
<< 22) | (0x001LL
<< 21)
2947 | (0x001LL
<< 36)) << 23));
2949 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
2950 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
2951 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
2952 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
2953 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
2954 | (((val
>> 21) & 0x001) << 21) /* ic */
2955 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
2957 bfd_put_64 (abfd
, t0
, hit_addr
);
2958 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2961 case IA64_OPND_TGT64
:
2962 hit_addr
-= (long) hit_addr
& 0x3;
2963 t0
= bfd_get_64 (abfd
, hit_addr
);
2964 t1
= bfd_get_64 (abfd
, hit_addr
+ 8);
2966 /* tmpl/s: bits 0.. 5 in t0
2967 slot 0: bits 5..45 in t0
2968 slot 1: bits 46..63 in t0, bits 0..22 in t1
2969 slot 2: bits 23..63 in t1 */
2971 /* First, clear the bits that form the 64 bit constant. */
2972 t0
&= ~(0x3ffffLL
<< 46);
2974 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
2977 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
2978 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
2979 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
2980 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
2982 bfd_put_64 (abfd
, t0
, hit_addr
);
2983 bfd_put_64 (abfd
, t1
, hit_addr
+ 8);
2987 switch ((long) hit_addr
& 0x3)
2989 case 0: shift
= 5; break;
2990 case 1: shift
= 14; hit_addr
+= 3; break;
2991 case 2: shift
= 23; hit_addr
+= 6; break;
2992 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
2994 dword
= bfd_get_64 (abfd
, hit_addr
);
2995 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
2997 op
= elf64_ia64_operands
+ opnd
;
2998 err
= (*op
->insert
) (op
, val
, (ia64_insn
*)& insn
);
3000 return bfd_reloc_overflow
;
3002 dword
&= ~(0x1ffffffffffLL
<< shift
);
3003 dword
|= (insn
<< shift
);
3004 bfd_put_64 (abfd
, dword
, hit_addr
);
3008 /* A data relocation. */
3011 bfd_putb32 (val
, hit_addr
);
3013 bfd_putb64 (val
, hit_addr
);
3016 bfd_putl32 (val
, hit_addr
);
3018 bfd_putl64 (val
, hit_addr
);
3022 return bfd_reloc_ok
;
3026 elfNN_ia64_install_dyn_reloc (abfd
, info
, sec
, srel
, offset
, type
,
3029 struct bfd_link_info
*info
;
3037 Elf_Internal_Rela outrel
;
3039 offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3041 BFD_ASSERT (dynindx
!= -1);
3042 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3043 outrel
.r_addend
= addend
;
3044 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3045 if (outrel
.r_offset
== (bfd_vma
) -1)
3047 /* Run for the hills. We shouldn't be outputting a relocation
3048 for this. So do what everyone else does and output a no-op. */
3049 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3050 outrel
.r_addend
= 0;
3051 outrel
.r_offset
= 0;
3054 bfd_elfNN_swap_reloca_out (abfd
, &outrel
,
3055 ((ElfNN_External_Rela
*) srel
->contents
3056 + srel
->reloc_count
++));
3057 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
3058 <= srel
->_cooked_size
);
3061 /* Store an entry for target address TARGET_ADDR in the linkage table
3062 and return the gp-relative address of the linkage table entry. */
3065 set_got_entry (abfd
, info
, dyn_i
, dynindx
, addend
, value
, dyn_r_type
)
3067 struct bfd_link_info
*info
;
3068 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3072 unsigned int dyn_r_type
;
3074 struct elfNN_ia64_link_hash_table
*ia64_info
;
3077 ia64_info
= elfNN_ia64_hash_table (info
);
3078 got_sec
= ia64_info
->got_sec
;
3080 BFD_ASSERT ((dyn_i
->got_offset
& 7) == 0);
3082 if (! dyn_i
->got_done
)
3084 dyn_i
->got_done
= true;
3086 /* Store the target address in the linkage table entry. */
3087 bfd_put_64 (abfd
, value
, got_sec
->contents
+ dyn_i
->got_offset
);
3089 /* Install a dynamic relocation if needed. */
3091 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
)
3092 || elfNN_ia64_aix_vec (abfd
->xvec
)
3093 || (dynindx
!= -1 && dyn_r_type
== R_IA64_FPTR64LSB
))
3097 dyn_r_type
= R_IA64_REL64LSB
;
3102 if (bfd_big_endian (abfd
))
3106 case R_IA64_REL64LSB
:
3107 dyn_r_type
= R_IA64_REL64MSB
;
3109 case R_IA64_DIR64LSB
:
3110 dyn_r_type
= R_IA64_DIR64MSB
;
3112 case R_IA64_FPTR64LSB
:
3113 dyn_r_type
= R_IA64_FPTR64MSB
;
3121 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
3122 ia64_info
->rel_got_sec
,
3123 dyn_i
->got_offset
, dyn_r_type
,
3128 /* Return the address of the linkage table entry. */
3129 value
= (got_sec
->output_section
->vma
3130 + got_sec
->output_offset
3131 + dyn_i
->got_offset
);
3136 /* Fill in a function descriptor consisting of the function's code
3137 address and its global pointer. Return the descriptor's address. */
3140 set_fptr_entry (abfd
, info
, dyn_i
, value
)
3142 struct bfd_link_info
*info
;
3143 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3146 struct elfNN_ia64_link_hash_table
*ia64_info
;
3149 ia64_info
= elfNN_ia64_hash_table (info
);
3150 fptr_sec
= ia64_info
->fptr_sec
;
3152 if (!dyn_i
->fptr_done
)
3154 dyn_i
->fptr_done
= 1;
3156 /* Fill in the function descriptor. */
3157 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
3158 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
3159 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
3162 /* Return the descriptor's address. */
3163 value
= (fptr_sec
->output_section
->vma
3164 + fptr_sec
->output_offset
3165 + dyn_i
->fptr_offset
);
3170 /* Fill in a PLTOFF entry consisting of the function's code address
3171 and its global pointer. Return the descriptor's address. */
3174 set_pltoff_entry (abfd
, info
, dyn_i
, value
, is_plt
)
3176 struct bfd_link_info
*info
;
3177 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3181 struct elfNN_ia64_link_hash_table
*ia64_info
;
3182 asection
*pltoff_sec
;
3184 ia64_info
= elfNN_ia64_hash_table (info
);
3185 pltoff_sec
= ia64_info
->pltoff_sec
;
3187 /* Don't do anything if this symbol uses a real PLT entry. In
3188 that case, we'll fill this in during finish_dynamic_symbol. */
3189 if ((! dyn_i
->want_plt
|| is_plt
)
3190 && !dyn_i
->pltoff_done
)
3192 bfd_vma gp
= _bfd_get_gp_value (abfd
);
3194 /* Fill in the function descriptor. */
3195 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
3196 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
3198 /* Install dynamic relocations if needed. */
3199 if (!is_plt
&& info
->shared
)
3201 unsigned int dyn_r_type
;
3203 if (bfd_big_endian (abfd
))
3204 dyn_r_type
= R_IA64_REL64MSB
;
3206 dyn_r_type
= R_IA64_REL64LSB
;
3208 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3209 ia64_info
->rel_pltoff_sec
,
3210 dyn_i
->pltoff_offset
,
3211 dyn_r_type
, 0, value
);
3212 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
3213 ia64_info
->rel_pltoff_sec
,
3214 dyn_i
->pltoff_offset
+ 8,
3218 dyn_i
->pltoff_done
= 1;
3221 /* Return the descriptor's address. */
3222 value
= (pltoff_sec
->output_section
->vma
3223 + pltoff_sec
->output_offset
3224 + dyn_i
->pltoff_offset
);
3229 /* Called through qsort to sort the .IA_64.unwind section during a
3230 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3231 to the output bfd so we can do proper endianness frobbing. */
3233 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
3236 elfNN_ia64_unwind_entry_compare (a
, b
)
3242 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
3243 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
3245 return (av
< bv
? -1 : av
> bv
? 1 : 0);
3249 elfNN_ia64_final_link (abfd
, info
)
3251 struct bfd_link_info
*info
;
3253 struct elfNN_ia64_link_hash_table
*ia64_info
;
3254 asection
*unwind_output_sec
;
3256 ia64_info
= elfNN_ia64_hash_table (info
);
3258 /* Make sure we've got ourselves a nice fat __gp value. */
3259 if (!info
->relocateable
)
3261 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
3262 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
3263 struct elf_link_hash_entry
*gp
;
3267 /* Find the min and max vma of all sections marked short. Also
3268 collect min and max vma of any type, for use in selecting a
3270 for (os
= abfd
->sections
; os
; os
= os
->next
)
3274 if ((os
->flags
& SEC_ALLOC
) == 0)
3278 hi
= os
->vma
+ os
->_raw_size
;
3286 if (os
->flags
& SEC_SMALL_DATA
)
3288 if (min_short_vma
> lo
)
3290 if (max_short_vma
< hi
)
3295 /* See if the user wants to force a value. */
3296 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", false,
3300 && (gp
->root
.type
== bfd_link_hash_defined
3301 || gp
->root
.type
== bfd_link_hash_defweak
))
3303 asection
*gp_sec
= gp
->root
.u
.def
.section
;
3304 gp_val
= (gp
->root
.u
.def
.value
3305 + gp_sec
->output_section
->vma
3306 + gp_sec
->output_offset
);
3310 /* Pick a sensible value. */
3312 asection
*got_sec
= ia64_info
->got_sec
;
3314 /* Start with just the address of the .got. */
3316 gp_val
= got_sec
->output_section
->vma
;
3317 else if (max_short_vma
!= 0)
3318 gp_val
= min_short_vma
;
3322 /* If it is possible to address the entire image, but we
3323 don't with the choice above, adjust. */
3324 if (max_vma
- min_vma
< 0x400000
3325 && max_vma
- gp_val
<= 0x200000
3326 && gp_val
- min_vma
> 0x200000)
3327 gp_val
= min_vma
+ 0x200000;
3328 else if (max_short_vma
!= 0)
3330 /* If we don't cover all the short data, adjust. */
3331 if (max_short_vma
- gp_val
>= 0x200000)
3332 gp_val
= min_short_vma
+ 0x200000;
3334 /* If we're addressing stuff past the end, adjust back. */
3335 if (gp_val
> max_vma
)
3336 gp_val
= max_vma
- 0x200000 + 8;
3340 /* Validate whether all SHF_IA_64_SHORT sections are within
3341 range of the chosen GP. */
3343 if (max_short_vma
!= 0)
3345 if (max_short_vma
- min_short_vma
>= 0x400000)
3347 (*_bfd_error_handler
)
3348 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3349 bfd_get_filename (abfd
),
3350 (unsigned long) (max_short_vma
- min_short_vma
));
3353 else if ((gp_val
> min_short_vma
3354 && gp_val
- min_short_vma
> 0x200000)
3355 || (gp_val
< max_short_vma
3356 && max_short_vma
- gp_val
>= 0x200000))
3358 (*_bfd_error_handler
)
3359 (_("%s: __gp does not cover short data segment"),
3360 bfd_get_filename (abfd
));
3365 _bfd_set_gp_value (abfd
, gp_val
);
3369 gp
->root
.type
= bfd_link_hash_defined
;
3370 gp
->root
.u
.def
.value
= gp_val
;
3371 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
3375 /* If we're producing a final executable, we need to sort the contents
3376 of the .IA_64.unwind section. Force this section to be relocated
3377 into memory rather than written immediately to the output file. */
3378 unwind_output_sec
= NULL
;
3379 if (!info
->relocateable
)
3381 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
3384 unwind_output_sec
= s
->output_section
;
3385 unwind_output_sec
->contents
3386 = bfd_malloc (unwind_output_sec
->_raw_size
);
3387 if (unwind_output_sec
->contents
== NULL
)
3392 /* Invoke the regular ELF backend linker to do all the work. */
3393 if (!bfd_elfNN_bfd_final_link (abfd
, info
))
3396 if (unwind_output_sec
)
3398 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
3399 qsort (unwind_output_sec
->contents
,
3400 (size_t) (unwind_output_sec
->_raw_size
/ 24),
3402 elfNN_ia64_unwind_entry_compare
);
3404 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
3405 unwind_output_sec
->contents
, (bfd_vma
) 0,
3406 unwind_output_sec
->_raw_size
))
3414 elfNN_ia64_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
3415 contents
, relocs
, local_syms
, local_sections
)
3417 struct bfd_link_info
*info
;
3419 asection
*input_section
;
3421 Elf_Internal_Rela
*relocs
;
3422 Elf_Internal_Sym
*local_syms
;
3423 asection
**local_sections
;
3425 struct elfNN_ia64_link_hash_table
*ia64_info
;
3426 Elf_Internal_Shdr
*symtab_hdr
;
3427 Elf_Internal_Rela
*rel
;
3428 Elf_Internal_Rela
*relend
;
3430 boolean ret_val
= true; /* for non-fatal errors */
3433 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3434 ia64_info
= elfNN_ia64_hash_table (info
);
3436 /* Infect various flags from the input section to the output section. */
3437 if (info
->relocateable
)
3441 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
3442 flags
&= SHF_IA_64_NORECOV
;
3444 elf_section_data(input_section
->output_section
)
3445 ->this_hdr
.sh_flags
|= flags
;
3448 gp_val
= _bfd_get_gp_value (output_bfd
);
3449 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, false);
3452 relend
= relocs
+ input_section
->reloc_count
;
3453 for (; rel
< relend
; ++rel
)
3455 struct elf_link_hash_entry
*h
;
3456 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
3457 bfd_reloc_status_type r
;
3458 reloc_howto_type
*howto
;
3459 unsigned long r_symndx
;
3460 Elf_Internal_Sym
*sym
;
3461 unsigned int r_type
;
3465 boolean dynamic_symbol_p
;
3466 boolean undef_weak_ref
;
3468 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3469 if (r_type
> R_IA64_MAX_RELOC_CODE
)
3471 (*_bfd_error_handler
)
3472 (_("%s: unknown relocation type %d"),
3473 bfd_archive_filename (input_bfd
), (int)r_type
);
3474 bfd_set_error (bfd_error_bad_value
);
3478 howto
= lookup_howto (r_type
);
3479 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
3481 if (info
->relocateable
)
3483 /* This is a relocateable link. We don't have to change
3484 anything, unless the reloc is against a section symbol,
3485 in which case we have to adjust according to where the
3486 section symbol winds up in the output section. */
3487 if (r_symndx
< symtab_hdr
->sh_info
)
3489 sym
= local_syms
+ r_symndx
;
3490 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
3492 sym_sec
= local_sections
[r_symndx
];
3493 rel
->r_addend
+= sym_sec
->output_offset
;
3499 /* This is a final link. */
3504 undef_weak_ref
= false;
3506 if (r_symndx
< symtab_hdr
->sh_info
)
3508 /* Reloc against local symbol. */
3509 sym
= local_syms
+ r_symndx
;
3510 sym_sec
= local_sections
[r_symndx
];
3511 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, sym_sec
, rel
);
3512 if ((sym_sec
->flags
& SEC_MERGE
)
3513 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
3514 && (elf_section_data (sym_sec
)->sec_info_type
3515 == ELF_INFO_TYPE_MERGE
))
3517 struct elfNN_ia64_local_hash_entry
*loc_h
;
3519 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, false);
3520 if (loc_h
&& ! loc_h
->sec_merge_done
)
3522 struct elfNN_ia64_dyn_sym_info
*dynent
;
3525 for (dynent
= loc_h
->info
; dynent
; dynent
= dynent
->next
)
3529 _bfd_merged_section_offset (output_bfd
, &msec
,
3530 elf_section_data (msec
)->
3535 dynent
->addend
-= sym
->st_value
;
3536 dynent
->addend
+= msec
->output_section
->vma
3537 + msec
->output_offset
3538 - sym_sec
->output_section
->vma
3539 - sym_sec
->output_offset
;
3541 loc_h
->sec_merge_done
= 1;
3549 /* Reloc against global symbol. */
3550 indx
= r_symndx
- symtab_hdr
->sh_info
;
3551 h
= elf_sym_hashes (input_bfd
)[indx
];
3552 while (h
->root
.type
== bfd_link_hash_indirect
3553 || h
->root
.type
== bfd_link_hash_warning
)
3554 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3557 if (h
->root
.type
== bfd_link_hash_defined
3558 || h
->root
.type
== bfd_link_hash_defweak
)
3560 sym_sec
= h
->root
.u
.def
.section
;
3562 /* Detect the cases that sym_sec->output_section is
3563 expected to be NULL -- all cases in which the symbol
3564 is defined in another shared module. This includes
3565 PLT relocs for which we've created a PLT entry and
3566 other relocs for which we're prepared to create
3567 dynamic relocations. */
3568 /* ??? Just accept it NULL and continue. */
3570 if (sym_sec
->output_section
!= NULL
)
3572 value
= (h
->root
.u
.def
.value
3573 + sym_sec
->output_section
->vma
3574 + sym_sec
->output_offset
);
3577 else if (h
->root
.type
== bfd_link_hash_undefweak
)
3578 undef_weak_ref
= true;
3579 else if (info
->shared
3580 && (!info
->symbolic
|| info
->allow_shlib_undefined
)
3581 && !info
->no_undefined
3582 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
3586 if (! ((*info
->callbacks
->undefined_symbol
)
3587 (info
, h
->root
.root
.string
, input_bfd
,
3588 input_section
, rel
->r_offset
,
3589 (!info
->shared
|| info
->no_undefined
3590 || ELF_ST_VISIBILITY (h
->other
)))))
3597 hit_addr
= contents
+ rel
->r_offset
;
3598 value
+= rel
->r_addend
;
3599 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
);
3610 case R_IA64_DIR32MSB
:
3611 case R_IA64_DIR32LSB
:
3612 case R_IA64_DIR64MSB
:
3613 case R_IA64_DIR64LSB
:
3614 /* Install a dynamic relocation for this reloc. */
3615 if ((dynamic_symbol_p
|| info
->shared
3616 || (elfNN_ia64_aix_vec (info
->hash
->creator
)
3617 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3618 && (!h
|| strcmp (h
->root
.root
.string
,
3619 "__GLOB_DATA_PTR") != 0)))
3621 && (input_section
->flags
& SEC_ALLOC
) != 0)
3623 unsigned int dyn_r_type
;
3627 BFD_ASSERT (srel
!= NULL
);
3629 /* If we don't need dynamic symbol lookup, find a
3630 matching RELATIVE relocation. */
3631 dyn_r_type
= r_type
;
3632 if (dynamic_symbol_p
)
3634 dynindx
= h
->dynindx
;
3635 addend
= rel
->r_addend
;
3642 case R_IA64_DIR32MSB
:
3643 dyn_r_type
= R_IA64_REL32MSB
;
3645 case R_IA64_DIR32LSB
:
3646 dyn_r_type
= R_IA64_REL32LSB
;
3648 case R_IA64_DIR64MSB
:
3649 dyn_r_type
= R_IA64_REL64MSB
;
3651 case R_IA64_DIR64LSB
:
3652 dyn_r_type
= R_IA64_REL64LSB
;
3656 /* We can't represent this without a dynamic symbol.
3657 Adjust the relocation to be against an output
3658 section symbol, which are always present in the
3659 dynamic symbol table. */
3660 /* ??? People shouldn't be doing non-pic code in
3661 shared libraries. Hork. */
3662 (*_bfd_error_handler
)
3663 (_("%s: linking non-pic code in a shared library"),
3664 bfd_archive_filename (input_bfd
));
3672 if (elfNN_ia64_aix_vec (info
->hash
->creator
))
3673 rel
->r_addend
= value
;
3674 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3675 srel
, rel
->r_offset
, dyn_r_type
,
3680 case R_IA64_LTV32MSB
:
3681 case R_IA64_LTV32LSB
:
3682 case R_IA64_LTV64MSB
:
3683 case R_IA64_LTV64LSB
:
3684 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3687 case R_IA64_GPREL22
:
3688 case R_IA64_GPREL64I
:
3689 case R_IA64_GPREL32MSB
:
3690 case R_IA64_GPREL32LSB
:
3691 case R_IA64_GPREL64MSB
:
3692 case R_IA64_GPREL64LSB
:
3693 if (dynamic_symbol_p
)
3695 (*_bfd_error_handler
)
3696 (_("%s: @gprel relocation against dynamic symbol %s"),
3697 bfd_archive_filename (input_bfd
), h
->root
.root
.string
);
3702 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3705 case R_IA64_LTOFF22
:
3706 case R_IA64_LTOFF22X
:
3707 case R_IA64_LTOFF64I
:
3708 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3709 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
3710 rel
->r_addend
, value
, R_IA64_DIR64LSB
);
3712 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3715 case R_IA64_PLTOFF22
:
3716 case R_IA64_PLTOFF64I
:
3717 case R_IA64_PLTOFF64MSB
:
3718 case R_IA64_PLTOFF64LSB
:
3719 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3720 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, false);
3722 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3725 case R_IA64_FPTR64I
:
3726 case R_IA64_FPTR32MSB
:
3727 case R_IA64_FPTR32LSB
:
3728 case R_IA64_FPTR64MSB
:
3729 case R_IA64_FPTR64LSB
:
3730 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3731 if (dyn_i
->want_fptr
)
3733 if (!undef_weak_ref
)
3734 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3740 /* Otherwise, we expect the dynamic linker to create
3745 if (h
->dynindx
!= -1)
3746 dynindx
= h
->dynindx
;
3748 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3749 (info
, h
->root
.u
.def
.section
->owner
,
3750 global_sym_index (h
)));
3754 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3755 (info
, input_bfd
, (long) r_symndx
));
3758 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3759 srel
, rel
->r_offset
, r_type
,
3760 dynindx
, rel
->r_addend
);
3764 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3767 case R_IA64_LTOFF_FPTR22
:
3768 case R_IA64_LTOFF_FPTR64I
:
3769 case R_IA64_LTOFF_FPTR32MSB
:
3770 case R_IA64_LTOFF_FPTR32LSB
:
3771 case R_IA64_LTOFF_FPTR64MSB
:
3772 case R_IA64_LTOFF_FPTR64LSB
:
3776 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, false);
3777 if (dyn_i
->want_fptr
)
3779 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1)
3780 if (!undef_weak_ref
)
3781 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
3786 /* Otherwise, we expect the dynamic linker to create
3790 if (h
->dynindx
!= -1)
3791 dynindx
= h
->dynindx
;
3793 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3794 (info
, h
->root
.u
.def
.section
->owner
,
3795 global_sym_index (h
)));
3798 dynindx
= (_bfd_elf_link_lookup_local_dynindx
3799 (info
, input_bfd
, (long) r_symndx
));
3803 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
3804 rel
->r_addend
, value
, R_IA64_FPTR64LSB
);
3806 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3810 case R_IA64_PCREL32MSB
:
3811 case R_IA64_PCREL32LSB
:
3812 case R_IA64_PCREL64MSB
:
3813 case R_IA64_PCREL64LSB
:
3814 /* Install a dynamic relocation for this reloc. */
3815 if ((dynamic_symbol_p
3816 || elfNN_ia64_aix_vec (info
->hash
->creator
))
3819 BFD_ASSERT (srel
!= NULL
);
3821 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3822 srel
, rel
->r_offset
, r_type
,
3823 h
->dynindx
, rel
->r_addend
);
3827 case R_IA64_PCREL21BI
:
3828 case R_IA64_PCREL21F
:
3829 case R_IA64_PCREL21M
:
3830 /* ??? These two are only used for speculation fixup code.
3831 They should never be dynamic. */
3832 if (dynamic_symbol_p
)
3834 (*_bfd_error_handler
)
3835 (_("%s: dynamic relocation against speculation fixup"),
3836 bfd_archive_filename (input_bfd
));
3842 (*_bfd_error_handler
)
3843 (_("%s: speculation fixup against undefined weak symbol"),
3844 bfd_archive_filename (input_bfd
));
3850 case R_IA64_PCREL21B
:
3851 case R_IA64_PCREL60B
:
3852 /* We should have created a PLT entry for any dynamic symbol. */
3855 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
3857 if (dyn_i
&& dyn_i
->want_plt2
)
3859 /* Should have caught this earlier. */
3860 BFD_ASSERT (rel
->r_addend
== 0);
3862 value
= (ia64_info
->plt_sec
->output_section
->vma
3863 + ia64_info
->plt_sec
->output_offset
3864 + dyn_i
->plt2_offset
);
3868 /* Since there's no PLT entry, Validate that this is
3870 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
3872 /* If the symbol is undef_weak, we shouldn't be trying
3873 to call it. There's every chance that we'd wind up
3874 with an out-of-range fixup here. Don't bother setting
3875 any value at all. */
3881 case R_IA64_PCREL22
:
3882 case R_IA64_PCREL64I
:
3884 /* Make pc-relative. */
3885 value
-= (input_section
->output_section
->vma
3886 + input_section
->output_offset
3887 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
3888 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3891 case R_IA64_SEGREL32MSB
:
3892 case R_IA64_SEGREL32LSB
:
3893 case R_IA64_SEGREL64MSB
:
3894 case R_IA64_SEGREL64LSB
:
3897 /* If the input section was discarded from the output, then
3903 struct elf_segment_map
*m
;
3904 Elf_Internal_Phdr
*p
;
3906 /* Find the segment that contains the output_section. */
3907 for (m
= elf_tdata (output_bfd
)->segment_map
,
3908 p
= elf_tdata (output_bfd
)->phdr
;
3913 for (i
= m
->count
- 1; i
>= 0; i
--)
3914 if (m
->sections
[i
] == sym_sec
->output_section
)
3922 r
= bfd_reloc_notsupported
;
3926 /* The VMA of the segment is the vaddr of the associated
3928 if (value
> p
->p_vaddr
)
3929 value
-= p
->p_vaddr
;
3932 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
,
3938 case R_IA64_SECREL32MSB
:
3939 case R_IA64_SECREL32LSB
:
3940 case R_IA64_SECREL64MSB
:
3941 case R_IA64_SECREL64LSB
:
3942 /* Make output-section relative. */
3943 if (value
> input_section
->output_section
->vma
)
3944 value
-= input_section
->output_section
->vma
;
3947 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3950 case R_IA64_IPLTMSB
:
3951 case R_IA64_IPLTLSB
:
3952 /* Install a dynamic relocation for this reloc. */
3953 if ((dynamic_symbol_p
|| info
->shared
)
3954 && (input_section
->flags
& SEC_ALLOC
) != 0)
3956 BFD_ASSERT (srel
!= NULL
);
3958 /* If we don't need dynamic symbol lookup, install two
3959 RELATIVE relocations. */
3960 if (! dynamic_symbol_p
)
3962 unsigned int dyn_r_type
;
3964 if (r_type
== R_IA64_IPLTMSB
)
3965 dyn_r_type
= R_IA64_REL64MSB
;
3967 dyn_r_type
= R_IA64_REL64LSB
;
3969 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3971 srel
, rel
->r_offset
,
3972 dyn_r_type
, 0, value
);
3973 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
3975 srel
, rel
->r_offset
+ 8,
3976 dyn_r_type
, 0, gp_val
);
3979 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
3980 srel
, rel
->r_offset
, r_type
,
3981 h
->dynindx
, rel
->r_addend
);
3984 if (r_type
== R_IA64_IPLTMSB
)
3985 r_type
= R_IA64_DIR64MSB
;
3987 r_type
= R_IA64_DIR64LSB
;
3988 elfNN_ia64_install_value (output_bfd
, hit_addr
, value
, r_type
);
3989 r
= elfNN_ia64_install_value (output_bfd
, hit_addr
+ 8, gp_val
,
3994 r
= bfd_reloc_notsupported
;
4003 case bfd_reloc_undefined
:
4004 /* This can happen for global table relative relocs if
4005 __gp is undefined. This is a panic situation so we
4006 don't try to continue. */
4007 (*info
->callbacks
->undefined_symbol
)
4008 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
4011 case bfd_reloc_notsupported
:
4016 name
= h
->root
.root
.string
;
4019 name
= bfd_elf_string_from_elf_section (input_bfd
,
4020 symtab_hdr
->sh_link
,
4025 name
= bfd_section_name (input_bfd
, input_section
);
4027 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
4029 input_section
, rel
->r_offset
))
4035 case bfd_reloc_dangerous
:
4036 case bfd_reloc_outofrange
:
4037 case bfd_reloc_overflow
:
4043 name
= h
->root
.root
.string
;
4046 name
= bfd_elf_string_from_elf_section (input_bfd
,
4047 symtab_hdr
->sh_link
,
4052 name
= bfd_section_name (input_bfd
, input_section
);
4054 if (!(*info
->callbacks
->reloc_overflow
) (info
, name
,
4071 elfNN_ia64_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
4073 struct bfd_link_info
*info
;
4074 struct elf_link_hash_entry
*h
;
4075 Elf_Internal_Sym
*sym
;
4077 struct elfNN_ia64_link_hash_table
*ia64_info
;
4078 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4080 ia64_info
= elfNN_ia64_hash_table (info
);
4081 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, false);
4083 /* Fill in the PLT data, if required. */
4084 if (dyn_i
&& dyn_i
->want_plt
)
4086 Elf_Internal_Rela outrel
;
4089 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
4090 ElfNN_External_Rela
*rel
;
4092 gp_val
= _bfd_get_gp_value (output_bfd
);
4094 /* Initialize the minimal PLT entry. */
4096 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
4097 plt_sec
= ia64_info
->plt_sec
;
4098 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
4100 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
4101 elfNN_ia64_install_value (output_bfd
, loc
, index
, R_IA64_IMM22
);
4102 elfNN_ia64_install_value (output_bfd
, loc
+2, -dyn_i
->plt_offset
,
4105 plt_addr
= (plt_sec
->output_section
->vma
4106 + plt_sec
->output_offset
4107 + dyn_i
->plt_offset
);
4108 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, true);
4110 /* Initialize the FULL PLT entry, if needed. */
4111 if (dyn_i
->want_plt2
)
4113 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
4115 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
4116 elfNN_ia64_install_value (output_bfd
, loc
, pltoff_addr
- gp_val
,
4119 /* Mark the symbol as undefined, rather than as defined in the
4120 plt section. Leave the value alone. */
4121 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4122 first place. But perhaps elflink.h did some for us. */
4123 if ((h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0)
4124 sym
->st_shndx
= SHN_UNDEF
;
4127 /* Create the dynamic relocation. */
4128 outrel
.r_offset
= pltoff_addr
;
4129 if (bfd_little_endian (output_bfd
))
4130 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
4132 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
4133 outrel
.r_addend
= 0;
4135 /* This is fun. In the .IA_64.pltoff section, we've got entries
4136 that correspond both to real PLT entries, and those that
4137 happened to resolve to local symbols but need to be created
4138 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4139 relocations for the real PLT should come at the end of the
4140 section, so that they can be indexed by plt entry at runtime.
4142 We emitted all of the relocations for the non-PLT @pltoff
4143 entries during relocate_section. So we can consider the
4144 existing sec->reloc_count to be the base of the array of
4147 rel
= (ElfNN_External_Rela
*)ia64_info
->rel_pltoff_sec
->contents
;
4148 rel
+= ia64_info
->rel_pltoff_sec
->reloc_count
;
4150 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, rel
+ index
);
4153 /* Mark some specially defined symbols as absolute. */
4154 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
4155 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
4156 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4157 sym
->st_shndx
= SHN_ABS
;
4163 elfNN_ia64_finish_dynamic_sections (abfd
, info
)
4165 struct bfd_link_info
*info
;
4167 struct elfNN_ia64_link_hash_table
*ia64_info
;
4170 ia64_info
= elfNN_ia64_hash_table (info
);
4171 dynobj
= ia64_info
->root
.dynobj
;
4173 if (elf_hash_table (info
)->dynamic_sections_created
)
4175 ElfNN_External_Dyn
*dyncon
, *dynconend
;
4176 asection
*sdyn
, *sgotplt
;
4179 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
4180 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
4181 BFD_ASSERT (sdyn
!= NULL
);
4182 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
4183 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
4185 gp_val
= _bfd_get_gp_value (abfd
);
4187 for (; dyncon
< dynconend
; dyncon
++)
4189 Elf_Internal_Dyn dyn
;
4191 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
4196 dyn
.d_un
.d_ptr
= gp_val
;
4200 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
4201 * sizeof (ElfNN_External_Rela
));
4205 /* See the comment above in finish_dynamic_symbol. */
4206 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
4207 + ia64_info
->rel_pltoff_sec
->output_offset
4208 + (ia64_info
->rel_pltoff_sec
->reloc_count
4209 * sizeof (ElfNN_External_Rela
)));
4212 case DT_IA_64_PLT_RESERVE
:
4213 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
4214 + sgotplt
->output_offset
);
4218 /* Do not have RELASZ include JMPREL. This makes things
4219 easier on ld.so. This is not what the rest of BFD set up. */
4220 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
4221 * sizeof (ElfNN_External_Rela
));
4225 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
4228 /* Initialize the PLT0 entry */
4229 if (ia64_info
->plt_sec
)
4231 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
4234 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
4236 pltres
= (sgotplt
->output_section
->vma
4237 + sgotplt
->output_offset
4240 elfNN_ia64_install_value (abfd
, loc
+1, pltres
, R_IA64_GPREL22
);
4247 /* ELF file flag handling: */
4249 /* Function to keep IA-64 specific file flags. */
4251 elfNN_ia64_set_private_flags (abfd
, flags
)
4255 BFD_ASSERT (!elf_flags_init (abfd
)
4256 || elf_elfheader (abfd
)->e_flags
== flags
);
4258 elf_elfheader (abfd
)->e_flags
= flags
;
4259 elf_flags_init (abfd
) = true;
4263 /* Merge backend specific data from an object file to the output
4264 object file when linking. */
4266 elfNN_ia64_merge_private_bfd_data (ibfd
, obfd
)
4273 /* Don't even pretend to support mixed-format linking. */
4274 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
4275 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
4278 in_flags
= elf_elfheader (ibfd
)->e_flags
;
4279 out_flags
= elf_elfheader (obfd
)->e_flags
;
4281 if (! elf_flags_init (obfd
))
4283 elf_flags_init (obfd
) = true;
4284 elf_elfheader (obfd
)->e_flags
= in_flags
;
4286 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
4287 && bfd_get_arch_info (obfd
)->the_default
)
4289 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
4290 bfd_get_mach (ibfd
));
4296 /* Check flag compatibility. */
4297 if (in_flags
== out_flags
)
4300 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4301 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
4302 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
4304 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
4306 (*_bfd_error_handler
)
4307 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4308 bfd_archive_filename (ibfd
));
4310 bfd_set_error (bfd_error_bad_value
);
4313 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
4315 (*_bfd_error_handler
)
4316 (_("%s: linking big-endian files with little-endian files"),
4317 bfd_archive_filename (ibfd
));
4319 bfd_set_error (bfd_error_bad_value
);
4322 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
4324 (*_bfd_error_handler
)
4325 (_("%s: linking 64-bit files with 32-bit files"),
4326 bfd_archive_filename (ibfd
));
4328 bfd_set_error (bfd_error_bad_value
);
4331 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
4333 (*_bfd_error_handler
)
4334 (_("%s: linking constant-gp files with non-constant-gp files"),
4335 bfd_archive_filename (ibfd
));
4337 bfd_set_error (bfd_error_bad_value
);
4340 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
4341 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
4343 (*_bfd_error_handler
)
4344 (_("%s: linking auto-pic files with non-auto-pic files"),
4345 bfd_archive_filename (ibfd
));
4347 bfd_set_error (bfd_error_bad_value
);
4355 elfNN_ia64_print_private_bfd_data (abfd
, ptr
)
4359 FILE *file
= (FILE *) ptr
;
4360 flagword flags
= elf_elfheader (abfd
)->e_flags
;
4362 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
4364 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
4365 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
4366 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
4367 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
4368 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
4369 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
4370 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
4371 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
4372 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
4374 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
4378 static enum elf_reloc_type_class
4379 elfNN_ia64_reloc_type_class (rela
)
4380 const Elf_Internal_Rela
*rela
;
4382 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
4384 case R_IA64_REL32MSB
:
4385 case R_IA64_REL32LSB
:
4386 case R_IA64_REL64MSB
:
4387 case R_IA64_REL64LSB
:
4388 return reloc_class_relative
;
4389 case R_IA64_IPLTMSB
:
4390 case R_IA64_IPLTLSB
:
4391 return reloc_class_plt
;
4393 return reloc_class_copy
;
4395 return reloc_class_normal
;
4399 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4400 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4401 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4402 #define TARGET_BIG_NAME "elfNN-ia64-big"
4403 #define ELF_ARCH bfd_arch_ia64
4404 #define ELF_MACHINE_CODE EM_IA_64
4405 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4406 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4407 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4409 #define elf_backend_section_from_shdr \
4410 elfNN_ia64_section_from_shdr
4411 #define elf_backend_section_flags \
4412 elfNN_ia64_section_flags
4413 #define elf_backend_fake_sections \
4414 elfNN_ia64_fake_sections
4415 #define elf_backend_final_write_processing \
4416 elfNN_ia64_final_write_processing
4417 #define elf_backend_add_symbol_hook \
4418 elfNN_ia64_add_symbol_hook
4419 #define elf_backend_additional_program_headers \
4420 elfNN_ia64_additional_program_headers
4421 #define elf_backend_modify_segment_map \
4422 elfNN_ia64_modify_segment_map
4423 #define elf_info_to_howto \
4424 elfNN_ia64_info_to_howto
4426 #define bfd_elfNN_bfd_reloc_type_lookup \
4427 elfNN_ia64_reloc_type_lookup
4428 #define bfd_elfNN_bfd_is_local_label_name \
4429 elfNN_ia64_is_local_label_name
4430 #define bfd_elfNN_bfd_relax_section \
4431 elfNN_ia64_relax_section
4433 /* Stuff for the BFD linker: */
4434 #define bfd_elfNN_bfd_link_hash_table_create \
4435 elfNN_ia64_hash_table_create
4436 #define elf_backend_create_dynamic_sections \
4437 elfNN_ia64_create_dynamic_sections
4438 #define elf_backend_check_relocs \
4439 elfNN_ia64_check_relocs
4440 #define elf_backend_adjust_dynamic_symbol \
4441 elfNN_ia64_adjust_dynamic_symbol
4442 #define elf_backend_size_dynamic_sections \
4443 elfNN_ia64_size_dynamic_sections
4444 #define elf_backend_relocate_section \
4445 elfNN_ia64_relocate_section
4446 #define elf_backend_finish_dynamic_symbol \
4447 elfNN_ia64_finish_dynamic_symbol
4448 #define elf_backend_finish_dynamic_sections \
4449 elfNN_ia64_finish_dynamic_sections
4450 #define bfd_elfNN_bfd_final_link \
4451 elfNN_ia64_final_link
4453 #define bfd_elfNN_bfd_merge_private_bfd_data \
4454 elfNN_ia64_merge_private_bfd_data
4455 #define bfd_elfNN_bfd_set_private_flags \
4456 elfNN_ia64_set_private_flags
4457 #define bfd_elfNN_bfd_print_private_bfd_data \
4458 elfNN_ia64_print_private_bfd_data
4460 #define elf_backend_plt_readonly 1
4461 #define elf_backend_want_plt_sym 0
4462 #define elf_backend_plt_alignment 5
4463 #define elf_backend_got_header_size 0
4464 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4465 #define elf_backend_want_got_plt 1
4466 #define elf_backend_may_use_rel_p 1
4467 #define elf_backend_may_use_rela_p 1
4468 #define elf_backend_default_use_rela_p 1
4469 #define elf_backend_want_dynbss 0
4470 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4471 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4472 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4474 #include "elfNN-target.h"
4476 /* AIX-specific vectors. */
4478 #undef TARGET_LITTLE_SYM
4479 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4480 #undef TARGET_LITTLE_NAME
4481 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4482 #undef TARGET_BIG_SYM
4483 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4484 #undef TARGET_BIG_NAME
4485 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4487 #undef elf_backend_add_symbol_hook
4488 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4490 #undef bfd_elfNN_bfd_link_add_symbols
4491 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4493 #define elfNN_bed elfNN_ia64_aix_bed
4495 #include "elfNN-target.h"