1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3 2009 Free Software Foundation, Inc.
4 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
27 #include "opcode/ia64.h"
35 #define LOG_SECTION_ALIGN 3
39 #define LOG_SECTION_ALIGN 2
42 /* THE RULES for all the stuff the linker creates --
44 GOT Entries created in response to LTOFF or LTOFF_FPTR
45 relocations. Dynamic relocs created for dynamic
46 symbols in an application; REL relocs for locals
49 FPTR The canonical function descriptor. Created for local
50 symbols in applications. Descriptors for dynamic symbols
51 and local symbols in shared libraries are created by
52 ld.so. Thus there are no dynamic relocs against these
53 objects. The FPTR relocs for such _are_ passed through
54 to the dynamic relocation tables.
56 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
57 Requires the creation of a PLTOFF entry. This does not
58 require any dynamic relocations.
60 PLTOFF Created by PLTOFF relocations. For local symbols, this
61 is an alternate function descriptor, and in shared libraries
62 requires two REL relocations. Note that this cannot be
63 transformed into an FPTR relocation, since it must be in
64 range of the GP. For dynamic symbols, this is a function
65 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
67 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
68 does not require dynamic relocations. */
70 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
72 typedef struct bfd_hash_entry
*(*new_hash_entry_func
)
73 PARAMS ((struct bfd_hash_entry
*, struct bfd_hash_table
*, const char *));
75 /* In dynamically (linker-) created sections, we generally need to keep track
76 of the place a symbol or expression got allocated to. This is done via hash
77 tables that store entries of the following type. */
79 struct elfNN_ia64_dyn_sym_info
81 /* The addend for which this entry is relevant. */
86 bfd_vma pltoff_offset
;
90 bfd_vma dtpmod_offset
;
91 bfd_vma dtprel_offset
;
93 /* The symbol table entry, if any, that this was derived from. */
94 struct elf_link_hash_entry
*h
;
96 /* Used to count non-got, non-plt relocations for delayed sizing
97 of relocation sections. */
98 struct elfNN_ia64_dyn_reloc_entry
100 struct elfNN_ia64_dyn_reloc_entry
*next
;
105 /* Is this reloc against readonly section? */
109 /* TRUE when the section contents have been updated. */
110 unsigned got_done
: 1;
111 unsigned fptr_done
: 1;
112 unsigned pltoff_done
: 1;
113 unsigned tprel_done
: 1;
114 unsigned dtpmod_done
: 1;
115 unsigned dtprel_done
: 1;
117 /* TRUE for the different kinds of linker data we want created. */
118 unsigned want_got
: 1;
119 unsigned want_gotx
: 1;
120 unsigned want_fptr
: 1;
121 unsigned want_ltoff_fptr
: 1;
122 unsigned want_plt
: 1;
123 unsigned want_plt2
: 1;
124 unsigned want_pltoff
: 1;
125 unsigned want_tprel
: 1;
126 unsigned want_dtpmod
: 1;
127 unsigned want_dtprel
: 1;
130 struct elfNN_ia64_local_hash_entry
134 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
136 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
137 unsigned int sorted_count
;
138 /* The size of elfNN_ia64_dyn_sym_info array. */
140 /* The array of elfNN_ia64_dyn_sym_info. */
141 struct elfNN_ia64_dyn_sym_info
*info
;
143 /* TRUE if this hash entry's addends was translated for
144 SHF_MERGE optimization. */
145 unsigned sec_merge_done
: 1;
148 struct elfNN_ia64_link_hash_entry
150 struct elf_link_hash_entry root
;
151 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
153 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
154 unsigned int sorted_count
;
155 /* The size of elfNN_ia64_dyn_sym_info array. */
157 /* The array of elfNN_ia64_dyn_sym_info. */
158 struct elfNN_ia64_dyn_sym_info
*info
;
161 struct elfNN_ia64_link_hash_table
163 /* The main hash table. */
164 struct elf_link_hash_table root
;
166 asection
*fptr_sec
; /* function descriptor table (or NULL) */
167 asection
*rel_fptr_sec
; /* dynamic relocation section for same */
168 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
169 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
171 bfd_size_type minplt_entries
; /* number of minplt entries */
172 unsigned reltext
: 1; /* are there relocs against readonly sections? */
173 unsigned self_dtpmod_done
: 1;/* has self DTPMOD entry been finished? */
174 bfd_vma self_dtpmod_offset
; /* .got offset to self DTPMOD entry */
176 htab_t loc_hash_table
;
177 void *loc_hash_memory
;
180 struct elfNN_ia64_allocate_data
182 struct bfd_link_info
*info
;
184 bfd_boolean only_got
;
187 #define elfNN_ia64_hash_table(p) \
188 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
190 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
191 (struct elfNN_ia64_link_hash_table
*ia64_info
,
192 struct elf_link_hash_entry
*h
,
193 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
);
194 static bfd_boolean elfNN_ia64_dynamic_symbol_p
195 (struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
, int);
196 static bfd_reloc_status_type elfNN_ia64_install_value
197 (bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
);
198 static bfd_boolean elfNN_ia64_choose_gp
199 (bfd
*abfd
, struct bfd_link_info
*info
);
200 static void elfNN_ia64_relax_ldxmov
201 (bfd_byte
*contents
, bfd_vma off
);
202 static void elfNN_ia64_dyn_sym_traverse
203 (struct elfNN_ia64_link_hash_table
*ia64_info
,
204 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
206 static bfd_boolean allocate_global_data_got
207 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
208 static bfd_boolean allocate_global_fptr_got
209 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
210 static bfd_boolean allocate_local_got
211 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
212 static bfd_boolean elfNN_ia64_hpux_vec
213 (const bfd_target
*vec
);
214 static bfd_boolean allocate_dynrel_entries
215 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
216 static asection
*get_pltoff
217 (bfd
*abfd
, struct bfd_link_info
*info
,
218 struct elfNN_ia64_link_hash_table
*ia64_info
);
220 /* ia64-specific relocation. */
222 /* Perform a relocation. Not much to do here as all the hard work is
223 done in elfNN_ia64_final_link_relocate. */
224 static bfd_reloc_status_type
225 elfNN_ia64_reloc (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*reloc
,
226 asymbol
*sym ATTRIBUTE_UNUSED
,
227 PTR data ATTRIBUTE_UNUSED
, asection
*input_section
,
228 bfd
*output_bfd
, char **error_message
)
232 reloc
->address
+= input_section
->output_offset
;
236 if (input_section
->flags
& SEC_DEBUGGING
)
237 return bfd_reloc_continue
;
239 *error_message
= "Unsupported call to elfNN_ia64_reloc";
240 return bfd_reloc_notsupported
;
243 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
244 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
245 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
247 /* This table has to be sorted according to increasing number of the
249 static reloc_howto_type ia64_howto_table
[] =
251 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, FALSE
, TRUE
),
253 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, FALSE
, TRUE
),
254 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, FALSE
, TRUE
),
255 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, FALSE
, TRUE
),
256 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, FALSE
, TRUE
),
257 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, FALSE
, TRUE
),
258 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, FALSE
, TRUE
),
259 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, FALSE
, TRUE
),
261 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, FALSE
, TRUE
),
262 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, FALSE
, TRUE
),
263 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, FALSE
, TRUE
),
264 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, FALSE
, TRUE
),
265 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, FALSE
, TRUE
),
266 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, FALSE
, TRUE
),
268 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, FALSE
, TRUE
),
269 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, FALSE
, TRUE
),
271 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, FALSE
, TRUE
),
272 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, FALSE
, TRUE
),
273 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, FALSE
, TRUE
),
274 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, FALSE
, TRUE
),
276 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, FALSE
, TRUE
),
277 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, FALSE
, TRUE
),
278 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, FALSE
, TRUE
),
279 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, FALSE
, TRUE
),
280 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, FALSE
, TRUE
),
282 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, TRUE
, TRUE
),
283 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, TRUE
, TRUE
),
284 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, TRUE
, TRUE
),
285 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, TRUE
, TRUE
),
286 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, TRUE
, TRUE
),
287 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, TRUE
, TRUE
),
288 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, TRUE
, TRUE
),
289 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, TRUE
, TRUE
),
291 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, FALSE
, TRUE
),
292 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, FALSE
, TRUE
),
293 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, FALSE
, TRUE
),
294 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, FALSE
, TRUE
),
295 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, FALSE
, TRUE
),
296 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, FALSE
, TRUE
),
298 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, FALSE
, TRUE
),
299 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, FALSE
, TRUE
),
300 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, FALSE
, TRUE
),
301 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, FALSE
, TRUE
),
303 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, FALSE
, TRUE
),
304 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, FALSE
, TRUE
),
305 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, FALSE
, TRUE
),
306 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, FALSE
, TRUE
),
308 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, FALSE
, TRUE
),
309 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, FALSE
, TRUE
),
310 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, FALSE
, TRUE
),
311 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, FALSE
, TRUE
),
313 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, FALSE
, TRUE
),
314 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, FALSE
, TRUE
),
315 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, FALSE
, TRUE
),
316 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, FALSE
, TRUE
),
318 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, TRUE
, TRUE
),
319 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, TRUE
, TRUE
),
320 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, TRUE
, TRUE
),
322 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, FALSE
, TRUE
),
323 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, FALSE
, TRUE
),
324 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, FALSE
, TRUE
),
325 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, FALSE
, TRUE
),
326 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, FALSE
, TRUE
),
328 IA64_HOWTO (R_IA64_TPREL14
, "TPREL14", 0, FALSE
, FALSE
),
329 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, FALSE
, FALSE
),
330 IA64_HOWTO (R_IA64_TPREL64I
, "TPREL64I", 0, FALSE
, FALSE
),
331 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 4, FALSE
, FALSE
),
332 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 4, FALSE
, FALSE
),
333 IA64_HOWTO (R_IA64_LTOFF_TPREL22
, "LTOFF_TPREL22", 0, FALSE
, FALSE
),
335 IA64_HOWTO (R_IA64_DTPMOD64MSB
, "DTPMOD64MSB", 4, FALSE
, FALSE
),
336 IA64_HOWTO (R_IA64_DTPMOD64LSB
, "DTPMOD64LSB", 4, FALSE
, FALSE
),
337 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22
, "LTOFF_DTPMOD22", 0, FALSE
, FALSE
),
339 IA64_HOWTO (R_IA64_DTPREL14
, "DTPREL14", 0, FALSE
, FALSE
),
340 IA64_HOWTO (R_IA64_DTPREL22
, "DTPREL22", 0, FALSE
, FALSE
),
341 IA64_HOWTO (R_IA64_DTPREL64I
, "DTPREL64I", 0, FALSE
, FALSE
),
342 IA64_HOWTO (R_IA64_DTPREL32MSB
, "DTPREL32MSB", 2, FALSE
, FALSE
),
343 IA64_HOWTO (R_IA64_DTPREL32LSB
, "DTPREL32LSB", 2, FALSE
, FALSE
),
344 IA64_HOWTO (R_IA64_DTPREL64MSB
, "DTPREL64MSB", 4, FALSE
, FALSE
),
345 IA64_HOWTO (R_IA64_DTPREL64LSB
, "DTPREL64LSB", 4, FALSE
, FALSE
),
346 IA64_HOWTO (R_IA64_LTOFF_DTPREL22
, "LTOFF_DTPREL22", 0, FALSE
, FALSE
),
349 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
351 /* Given a BFD reloc type, return the matching HOWTO structure. */
353 static reloc_howto_type
*
354 lookup_howto (unsigned int rtype
)
356 static int inited
= 0;
363 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
364 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
365 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
368 if (rtype
> R_IA64_MAX_RELOC_CODE
)
370 i
= elf_code_to_howto_index
[rtype
];
371 if (i
>= NELEMS (ia64_howto_table
))
373 return ia64_howto_table
+ i
;
376 static reloc_howto_type
*
377 elfNN_ia64_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
378 bfd_reloc_code_real_type bfd_code
)
384 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
386 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
387 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
388 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
390 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
391 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
392 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
393 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
395 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
396 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
397 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
398 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
399 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
400 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
402 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
403 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
405 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
406 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
407 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
408 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
409 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
410 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
411 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
412 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
413 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
415 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
416 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
417 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
418 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
419 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
420 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
421 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
422 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
423 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
424 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
425 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
427 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
428 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
429 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
430 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
431 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
432 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
434 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
435 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
436 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
437 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
439 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
440 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
441 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
442 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
444 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
445 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
446 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
447 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
449 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
450 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
451 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
452 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
454 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
455 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
456 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
457 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
458 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
460 case BFD_RELOC_IA64_TPREL14
: rtype
= R_IA64_TPREL14
; break;
461 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
462 case BFD_RELOC_IA64_TPREL64I
: rtype
= R_IA64_TPREL64I
; break;
463 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
464 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
465 case BFD_RELOC_IA64_LTOFF_TPREL22
: rtype
= R_IA64_LTOFF_TPREL22
; break;
467 case BFD_RELOC_IA64_DTPMOD64MSB
: rtype
= R_IA64_DTPMOD64MSB
; break;
468 case BFD_RELOC_IA64_DTPMOD64LSB
: rtype
= R_IA64_DTPMOD64LSB
; break;
469 case BFD_RELOC_IA64_LTOFF_DTPMOD22
: rtype
= R_IA64_LTOFF_DTPMOD22
; break;
471 case BFD_RELOC_IA64_DTPREL14
: rtype
= R_IA64_DTPREL14
; break;
472 case BFD_RELOC_IA64_DTPREL22
: rtype
= R_IA64_DTPREL22
; break;
473 case BFD_RELOC_IA64_DTPREL64I
: rtype
= R_IA64_DTPREL64I
; break;
474 case BFD_RELOC_IA64_DTPREL32MSB
: rtype
= R_IA64_DTPREL32MSB
; break;
475 case BFD_RELOC_IA64_DTPREL32LSB
: rtype
= R_IA64_DTPREL32LSB
; break;
476 case BFD_RELOC_IA64_DTPREL64MSB
: rtype
= R_IA64_DTPREL64MSB
; break;
477 case BFD_RELOC_IA64_DTPREL64LSB
: rtype
= R_IA64_DTPREL64LSB
; break;
478 case BFD_RELOC_IA64_LTOFF_DTPREL22
: rtype
= R_IA64_LTOFF_DTPREL22
; break;
482 return lookup_howto (rtype
);
485 static reloc_howto_type
*
486 elfNN_ia64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
492 i
< sizeof (ia64_howto_table
) / sizeof (ia64_howto_table
[0]);
494 if (ia64_howto_table
[i
].name
!= NULL
495 && strcasecmp (ia64_howto_table
[i
].name
, r_name
) == 0)
496 return &ia64_howto_table
[i
];
501 /* Given a ELF reloc, return the matching HOWTO structure. */
504 elfNN_ia64_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
506 Elf_Internal_Rela
*elf_reloc
)
509 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
512 #define PLT_HEADER_SIZE (3 * 16)
513 #define PLT_MIN_ENTRY_SIZE (1 * 16)
514 #define PLT_FULL_ENTRY_SIZE (2 * 16)
515 #define PLT_RESERVED_WORDS 3
517 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
519 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
520 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
521 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
522 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
523 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
524 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
525 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
526 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
527 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
530 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
532 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
533 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
534 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
537 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
539 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
540 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
541 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
542 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
543 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
544 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
547 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
549 static const bfd_byte oor_brl
[16] =
551 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
553 0x00, 0x00, 0x00, 0xc0
556 static const bfd_byte oor_ip
[48] =
558 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
559 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
560 0x01, 0x00, 0x00, 0x60,
561 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
562 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
563 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
564 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
565 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
566 0x60, 0x00, 0x80, 0x00 /* br b6;; */
569 static size_t oor_branch_size
= sizeof (oor_brl
);
572 bfd_elfNN_ia64_after_parse (int itanium
)
574 oor_branch_size
= itanium
? sizeof (oor_ip
) : sizeof (oor_brl
);
577 #define BTYPE_SHIFT 6
584 #define OPCODE_SHIFT 37
586 #define OPCODE_BITS (0xfLL << OPCODE_SHIFT)
587 #define X6_BITS (0x3fLL << X6_SHIFT)
588 #define X4_BITS (0xfLL << X4_SHIFT)
589 #define X3_BITS (0x7LL << X3_SHIFT)
590 #define X2_BITS (0x3LL << X2_SHIFT)
591 #define X_BITS (0x1LL << X_SHIFT)
592 #define Y_BITS (0x1LL << Y_SHIFT)
593 #define BTYPE_BITS (0x7LL << BTYPE_SHIFT)
594 #define PREDICATE_BITS (0x3fLL)
596 #define IS_NOP_B(i) \
597 (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
598 #define IS_NOP_F(i) \
599 (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
600 == (0x1LL << X6_SHIFT))
601 #define IS_NOP_I(i) \
602 (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
603 == (0x1LL << X6_SHIFT))
604 #define IS_NOP_M(i) \
605 (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
606 == (0x1LL << X4_SHIFT))
607 #define IS_BR_COND(i) \
608 (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
609 #define IS_BR_CALL(i) \
610 (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
613 elfNN_ia64_relax_br (bfd_byte
*contents
, bfd_vma off
)
615 unsigned int template, mlx
;
616 bfd_vma t0
, t1
, s0
, s1
, s2
, br_code
;
620 hit_addr
= (bfd_byte
*) (contents
+ off
);
621 br_slot
= (long) hit_addr
& 0x3;
623 t0
= bfd_getl64 (hit_addr
+ 0);
624 t1
= bfd_getl64 (hit_addr
+ 8);
626 /* Check if we can turn br into brl. A label is always at the start
627 of the bundle. Even if there are predicates on NOPs, we still
628 perform this optimization. */
629 template = t0
& 0x1e;
630 s0
= (t0
>> 5) & 0x1ffffffffffLL
;
631 s1
= ((t0
>> 46) | (t1
<< 18)) & 0x1ffffffffffLL
;
632 s2
= (t1
>> 23) & 0x1ffffffffffLL
;
636 /* Check if slot 1 and slot 2 are NOPs. Possible template is
637 BBB. We only need to check nop.b. */
638 if (!(IS_NOP_B (s1
) && IS_NOP_B (s2
)))
643 /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
644 For BBB, slot 0 also has to be nop.b. */
645 if (!((template == 0x12 /* MBB */
647 || (template == 0x16 /* BBB */
654 /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
655 MMB and MFB. For BBB, slot 0 also has to be nop.b. */
656 if (!((template == 0x10 /* MIB */
658 || (template == 0x12 /* MBB */
660 || (template == 0x16 /* BBB */
663 || (template == 0x18 /* MMB */
665 || (template == 0x1c /* MFB */
671 /* It should never happen. */
675 /* We can turn br.cond/br.call into brl.cond/brl.call. */
676 if (!(IS_BR_COND (br_code
) || IS_BR_CALL (br_code
)))
679 /* Turn br into brl by setting bit 40. */
680 br_code
|= 0x1LL
<< 40;
682 /* Turn the old bundle into a MLX bundle with the same stop-bit
689 if (template == 0x16)
691 /* For BBB, we need to put nop.m in slot 0. We keep the original
692 predicate only if slot 0 isn't br. */
696 t0
&= PREDICATE_BITS
<< 5;
697 t0
|= 0x1LL
<< (X4_SHIFT
+ 5);
701 /* Keep the original instruction in slot 0. */
702 t0
&= 0x1ffffffffffLL
<< 5;
707 /* Put brl in slot 1. */
710 bfd_putl64 (t0
, hit_addr
);
711 bfd_putl64 (t1
, hit_addr
+ 8);
716 elfNN_ia64_relax_brl (bfd_byte
*contents
, bfd_vma off
)
720 bfd_vma t0
, t1
, i0
, i1
, i2
;
722 hit_addr
= (bfd_byte
*) (contents
+ off
);
723 hit_addr
-= (long) hit_addr
& 0x3;
724 t0
= bfd_getl64 (hit_addr
);
725 t1
= bfd_getl64 (hit_addr
+ 8);
727 /* Keep the instruction in slot 0. */
728 i0
= (t0
>> 5) & 0x1ffffffffffLL
;
729 /* Use nop.b for slot 1. */
731 /* For slot 2, turn brl into br by masking out bit 40. */
732 i2
= (t1
>> 23) & 0x0ffffffffffLL
;
734 /* Turn a MLX bundle into a MBB bundle with the same stop-bit
740 t0
= (i1
<< 46) | (i0
<< 5) | template;
741 t1
= (i2
<< 23) | (i1
>> 18);
743 bfd_putl64 (t0
, hit_addr
);
744 bfd_putl64 (t1
, hit_addr
+ 8);
747 /* Rename some of the generic section flags to better document how they
749 #define skip_relax_pass_0 need_finalize_relax
750 #define skip_relax_pass_1 has_gp_reloc
753 /* These functions do relaxation for IA-64 ELF. */
756 elfNN_ia64_relax_section (bfd
*abfd
, asection
*sec
,
757 struct bfd_link_info
*link_info
,
762 struct one_fixup
*next
;
768 Elf_Internal_Shdr
*symtab_hdr
;
769 Elf_Internal_Rela
*internal_relocs
;
770 Elf_Internal_Rela
*irel
, *irelend
;
772 Elf_Internal_Sym
*isymbuf
= NULL
;
773 struct elfNN_ia64_link_hash_table
*ia64_info
;
774 struct one_fixup
*fixups
= NULL
;
775 bfd_boolean changed_contents
= FALSE
;
776 bfd_boolean changed_relocs
= FALSE
;
777 bfd_boolean changed_got
= FALSE
;
778 bfd_boolean skip_relax_pass_0
= TRUE
;
779 bfd_boolean skip_relax_pass_1
= TRUE
;
782 /* Assume we're not going to change any sizes, and we'll only need
786 if (link_info
->relocatable
)
787 (*link_info
->callbacks
->einfo
)
788 (_("%P%F: --relax and -r may not be used together\n"));
790 /* Don't even try to relax for non-ELF outputs. */
791 if (!is_elf_hash_table (link_info
->hash
))
794 /* Nothing to do if there are no relocations or there is no need for
796 if ((sec
->flags
& SEC_RELOC
) == 0
797 || sec
->reloc_count
== 0
798 || (link_info
->relax_pass
== 0 && sec
->skip_relax_pass_0
)
799 || (link_info
->relax_pass
== 1 && sec
->skip_relax_pass_1
))
802 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
804 /* Load the relocations for this section. */
805 internal_relocs
= (_bfd_elf_link_read_relocs
806 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
807 link_info
->keep_memory
));
808 if (internal_relocs
== NULL
)
811 ia64_info
= elfNN_ia64_hash_table (link_info
);
812 irelend
= internal_relocs
+ sec
->reloc_count
;
814 /* Get the section contents. */
815 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
816 contents
= elf_section_data (sec
)->this_hdr
.contents
;
819 if (!bfd_malloc_and_get_section (abfd
, sec
, &contents
))
823 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
825 unsigned long r_type
= ELFNN_R_TYPE (irel
->r_info
);
826 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
830 bfd_boolean is_branch
;
831 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
836 case R_IA64_PCREL21B
:
837 case R_IA64_PCREL21BI
:
838 case R_IA64_PCREL21M
:
839 case R_IA64_PCREL21F
:
840 /* In pass 1, all br relaxations are done. We can skip it. */
841 if (link_info
->relax_pass
== 1)
843 skip_relax_pass_0
= FALSE
;
847 case R_IA64_PCREL60B
:
848 /* We can't optimize brl to br in pass 0 since br relaxations
849 will increase the code size. Defer it to pass 1. */
850 if (link_info
->relax_pass
== 0)
852 skip_relax_pass_1
= FALSE
;
858 case R_IA64_LTOFF22X
:
860 /* We can't relax ldx/mov in pass 0 since br relaxations will
861 increase the code size. Defer it to pass 1. */
862 if (link_info
->relax_pass
== 0)
864 skip_relax_pass_1
= FALSE
;
874 /* Get the value of the symbol referred to by the reloc. */
875 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
877 /* A local symbol. */
878 Elf_Internal_Sym
*isym
;
880 /* Read this BFD's local symbols. */
883 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
885 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
886 symtab_hdr
->sh_info
, 0,
892 isym
= isymbuf
+ ELFNN_R_SYM (irel
->r_info
);
893 if (isym
->st_shndx
== SHN_UNDEF
)
894 continue; /* We can't do anything with undefined symbols. */
895 else if (isym
->st_shndx
== SHN_ABS
)
896 tsec
= bfd_abs_section_ptr
;
897 else if (isym
->st_shndx
== SHN_COMMON
)
898 tsec
= bfd_com_section_ptr
;
899 else if (isym
->st_shndx
== SHN_IA_64_ANSI_COMMON
)
900 tsec
= bfd_com_section_ptr
;
902 tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
904 toff
= isym
->st_value
;
905 dyn_i
= get_dyn_sym_info (ia64_info
, NULL
, abfd
, irel
, FALSE
);
906 symtype
= ELF_ST_TYPE (isym
->st_info
);
911 struct elf_link_hash_entry
*h
;
913 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
914 h
= elf_sym_hashes (abfd
)[indx
];
915 BFD_ASSERT (h
!= NULL
);
917 while (h
->root
.type
== bfd_link_hash_indirect
918 || h
->root
.type
== bfd_link_hash_warning
)
919 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
921 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, FALSE
);
923 /* For branches to dynamic symbols, we're interested instead
924 in a branch to the PLT entry. */
925 if (is_branch
&& dyn_i
&& dyn_i
->want_plt2
)
927 /* Internal branches shouldn't be sent to the PLT.
928 Leave this for now and we'll give an error later. */
929 if (r_type
!= R_IA64_PCREL21B
)
932 tsec
= ia64_info
->root
.splt
;
933 toff
= dyn_i
->plt2_offset
;
934 BFD_ASSERT (irel
->r_addend
== 0);
937 /* Can't do anything else with dynamic symbols. */
938 else if (elfNN_ia64_dynamic_symbol_p (h
, link_info
, r_type
))
943 /* We can't do anything with undefined symbols. */
944 if (h
->root
.type
== bfd_link_hash_undefined
945 || h
->root
.type
== bfd_link_hash_undefweak
)
948 tsec
= h
->root
.u
.def
.section
;
949 toff
= h
->root
.u
.def
.value
;
955 if (tsec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
957 /* At this stage in linking, no SEC_MERGE symbol has been
958 adjusted, so all references to such symbols need to be
959 passed through _bfd_merged_section_offset. (Later, in
960 relocate_section, all SEC_MERGE symbols *except* for
961 section symbols have been adjusted.)
963 gas may reduce relocations against symbols in SEC_MERGE
964 sections to a relocation against the section symbol when
965 the original addend was zero. When the reloc is against
966 a section symbol we should include the addend in the
967 offset passed to _bfd_merged_section_offset, since the
968 location of interest is the original symbol. On the
969 other hand, an access to "sym+addend" where "sym" is not
970 a section symbol should not include the addend; Such an
971 access is presumed to be an offset from "sym"; The
972 location of interest is just "sym". */
973 if (symtype
== STT_SECTION
)
974 toff
+= irel
->r_addend
;
976 toff
= _bfd_merged_section_offset (abfd
, &tsec
,
977 elf_section_data (tsec
)->sec_info
,
980 if (symtype
!= STT_SECTION
)
981 toff
+= irel
->r_addend
;
984 toff
+= irel
->r_addend
;
986 symaddr
= tsec
->output_section
->vma
+ tsec
->output_offset
+ toff
;
988 roff
= irel
->r_offset
;
992 bfd_signed_vma offset
;
994 reladdr
= (sec
->output_section
->vma
996 + roff
) & (bfd_vma
) -4;
998 /* The .plt section is aligned at 32byte and the .text section
999 is aligned at 64byte. The .text section is right after the
1000 .plt section. After the first relaxation pass, linker may
1001 increase the gap between the .plt and .text sections up
1002 to 32byte. We assume linker will always insert 32byte
1003 between the .plt and .text sections after the the first
1005 if (tsec
== ia64_info
->root
.splt
)
1006 offset
= -0x1000000 + 32;
1008 offset
= -0x1000000;
1010 /* If the branch is in range, no need to do anything. */
1011 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= offset
1012 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
1014 /* If the 60-bit branch is in 21-bit range, optimize it. */
1015 if (r_type
== R_IA64_PCREL60B
)
1017 elfNN_ia64_relax_brl (contents
, roff
);
1020 = ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1023 /* If the original relocation offset points to slot
1024 1, change it to slot 2. */
1025 if ((irel
->r_offset
& 3) == 1)
1026 irel
->r_offset
+= 1;
1031 else if (r_type
== R_IA64_PCREL60B
)
1033 else if (elfNN_ia64_relax_br (contents
, roff
))
1036 = ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1039 /* Make the relocation offset point to slot 1. */
1040 irel
->r_offset
= (irel
->r_offset
& ~((bfd_vma
) 0x3)) + 1;
1044 /* We can't put a trampoline in a .init/.fini section. Issue
1046 if (strcmp (sec
->output_section
->name
, ".init") == 0
1047 || strcmp (sec
->output_section
->name
, ".fini") == 0)
1049 (*_bfd_error_handler
)
1050 (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
1051 sec
->owner
, sec
, (unsigned long) roff
);
1052 bfd_set_error (bfd_error_bad_value
);
1056 /* If the branch and target are in the same section, you've
1057 got one honking big section and we can't help you unless
1058 you are branching backwards. You'll get an error message
1060 if (tsec
== sec
&& toff
> roff
)
1063 /* Look for an existing fixup to this address. */
1064 for (f
= fixups
; f
; f
= f
->next
)
1065 if (f
->tsec
== tsec
&& f
->toff
== toff
)
1070 /* Two alternatives: If it's a branch to a PLT entry, we can
1071 make a copy of the FULL_PLT entry. Otherwise, we'll have
1072 to use a `brl' insn to get where we're going. */
1076 if (tsec
== ia64_info
->root
.splt
)
1077 size
= sizeof (plt_full_entry
);
1079 size
= oor_branch_size
;
1081 /* Resize the current section to make room for the new branch. */
1082 trampoff
= (sec
->size
+ 15) & (bfd_vma
) -16;
1084 /* If trampoline is out of range, there is nothing we
1086 offset
= trampoff
- (roff
& (bfd_vma
) -4);
1087 if (offset
< -0x1000000 || offset
> 0x0FFFFF0)
1090 amt
= trampoff
+ size
;
1091 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
1092 if (contents
== NULL
)
1096 if (tsec
== ia64_info
->root
.splt
)
1098 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
1100 /* Hijack the old relocation for use as the PLTOFF reloc. */
1101 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1103 irel
->r_offset
= trampoff
;
1107 if (size
== sizeof (oor_ip
))
1109 memcpy (contents
+ trampoff
, oor_ip
, size
);
1110 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1112 irel
->r_addend
-= 16;
1113 irel
->r_offset
= trampoff
+ 2;
1117 memcpy (contents
+ trampoff
, oor_brl
, size
);
1118 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1120 irel
->r_offset
= trampoff
+ 2;
1125 /* Record the fixup so we don't do it again this section. */
1126 f
= (struct one_fixup
*)
1127 bfd_malloc ((bfd_size_type
) sizeof (*f
));
1131 f
->trampoff
= trampoff
;
1136 /* If trampoline is out of range, there is nothing we
1138 offset
= f
->trampoff
- (roff
& (bfd_vma
) -4);
1139 if (offset
< -0x1000000 || offset
> 0x0FFFFF0)
1142 /* Nop out the reloc, since we're finalizing things here. */
1143 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
1146 /* Fix up the existing branch to hit the trampoline. */
1147 if (elfNN_ia64_install_value (contents
+ roff
, offset
, r_type
)
1151 changed_contents
= TRUE
;
1152 changed_relocs
= TRUE
;
1159 bfd
*obfd
= sec
->output_section
->owner
;
1160 gp
= _bfd_get_gp_value (obfd
);
1163 if (!elfNN_ia64_choose_gp (obfd
, link_info
))
1165 gp
= _bfd_get_gp_value (obfd
);
1169 /* If the data is out of range, do nothing. */
1170 if ((bfd_signed_vma
) (symaddr
- gp
) >= 0x200000
1171 ||(bfd_signed_vma
) (symaddr
- gp
) < -0x200000)
1174 if (r_type
== R_IA64_LTOFF22X
)
1176 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1178 changed_relocs
= TRUE
;
1179 if (dyn_i
->want_gotx
)
1181 dyn_i
->want_gotx
= 0;
1182 changed_got
|= !dyn_i
->want_got
;
1187 elfNN_ia64_relax_ldxmov (contents
, roff
);
1188 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
1189 changed_contents
= TRUE
;
1190 changed_relocs
= TRUE
;
1195 /* ??? If we created fixups, this may push the code segment large
1196 enough that the data segment moves, which will change the GP.
1197 Reset the GP so that we re-calculate next round. We need to
1198 do this at the _beginning_ of the next round; now will not do. */
1200 /* Clean up and go home. */
1203 struct one_fixup
*f
= fixups
;
1204 fixups
= fixups
->next
;
1209 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1211 if (! link_info
->keep_memory
)
1215 /* Cache the symbols for elf_link_input_bfd. */
1216 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1220 if (contents
!= NULL
1221 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1223 if (!changed_contents
&& !link_info
->keep_memory
)
1227 /* Cache the section contents for elf_link_input_bfd. */
1228 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1232 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
1234 if (!changed_relocs
)
1235 free (internal_relocs
);
1237 elf_section_data (sec
)->relocs
= internal_relocs
;
1242 struct elfNN_ia64_allocate_data data
;
1243 data
.info
= link_info
;
1245 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
1247 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
1248 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
1249 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
1250 ia64_info
->root
.sgot
->size
= data
.ofs
;
1252 if (ia64_info
->root
.dynamic_sections_created
1253 && ia64_info
->root
.srelgot
!= NULL
)
1255 /* Resize .rela.got. */
1256 ia64_info
->root
.srelgot
->size
= 0;
1257 if (link_info
->shared
1258 && ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
1259 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
1260 data
.only_got
= TRUE
;
1261 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
,
1266 if (link_info
->relax_pass
== 0)
1268 /* Pass 0 is only needed to relax br. */
1269 sec
->skip_relax_pass_0
= skip_relax_pass_0
;
1270 sec
->skip_relax_pass_1
= skip_relax_pass_1
;
1273 *again
= changed_contents
|| changed_relocs
;
1277 if (isymbuf
!= NULL
&& (unsigned char *) isymbuf
!= symtab_hdr
->contents
)
1279 if (contents
!= NULL
1280 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1282 if (internal_relocs
!= NULL
1283 && elf_section_data (sec
)->relocs
!= internal_relocs
)
1284 free (internal_relocs
);
1287 #undef skip_relax_pass_0
1288 #undef skip_relax_pass_1
1291 elfNN_ia64_relax_ldxmov (bfd_byte
*contents
, bfd_vma off
)
1294 bfd_vma dword
, insn
;
1296 switch ((int)off
& 0x3)
1298 case 0: shift
= 5; break;
1299 case 1: shift
= 14; off
+= 3; break;
1300 case 2: shift
= 23; off
+= 6; break;
1305 dword
= bfd_getl64 (contents
+ off
);
1306 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
1308 r1
= (insn
>> 6) & 127;
1309 r3
= (insn
>> 20) & 127;
1311 insn
= 0x8000000; /* nop */
1313 insn
= (insn
& 0x7f01fff) | 0x10800000000LL
; /* (qp) mov r1 = r3 */
1315 dword
&= ~(0x1ffffffffffLL
<< shift
);
1316 dword
|= (insn
<< shift
);
1317 bfd_putl64 (dword
, contents
+ off
);
1320 /* Return TRUE if NAME is an unwind table section name. */
1322 static inline bfd_boolean
1323 is_unwind_section_name (bfd
*abfd
, const char *name
)
1325 if (elfNN_ia64_hpux_vec (abfd
->xvec
)
1326 && !strcmp (name
, ELF_STRING_ia64_unwind_hdr
))
1329 return ((CONST_STRNEQ (name
, ELF_STRING_ia64_unwind
)
1330 && ! CONST_STRNEQ (name
, ELF_STRING_ia64_unwind_info
))
1331 || CONST_STRNEQ (name
, ELF_STRING_ia64_unwind_once
));
1334 /* Handle an IA-64 specific section when reading an object file. This
1335 is called when bfd_section_from_shdr finds a section with an unknown
1339 elfNN_ia64_section_from_shdr (bfd
*abfd
,
1340 Elf_Internal_Shdr
*hdr
,
1346 /* There ought to be a place to keep ELF backend specific flags, but
1347 at the moment there isn't one. We just keep track of the
1348 sections by their name, instead. Fortunately, the ABI gives
1349 suggested names for all the MIPS specific sections, so we will
1350 probably get away with this. */
1351 switch (hdr
->sh_type
)
1353 case SHT_IA_64_UNWIND
:
1354 case SHT_IA_64_HP_OPT_ANOT
:
1358 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1366 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
1368 newsect
= hdr
->bfd_section
;
1373 /* Convert IA-64 specific section flags to bfd internal section flags. */
1375 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1379 elfNN_ia64_section_flags (flagword
*flags
,
1380 const Elf_Internal_Shdr
*hdr
)
1382 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1383 *flags
|= SEC_SMALL_DATA
;
1388 /* Set the correct type for an IA-64 ELF section. We do this by the
1389 section name, which is a hack, but ought to work. */
1392 elfNN_ia64_fake_sections (bfd
*abfd
, Elf_Internal_Shdr
*hdr
,
1395 register const char *name
;
1397 name
= bfd_get_section_name (abfd
, sec
);
1399 if (is_unwind_section_name (abfd
, name
))
1401 /* We don't have the sections numbered at this point, so sh_info
1402 is set later, in elfNN_ia64_final_write_processing. */
1403 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1404 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1406 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1407 hdr
->sh_type
= SHT_IA_64_EXT
;
1408 else if (strcmp (name
, ".HP.opt_annot") == 0)
1409 hdr
->sh_type
= SHT_IA_64_HP_OPT_ANOT
;
1410 else if (strcmp (name
, ".reloc") == 0)
1411 /* This is an ugly, but unfortunately necessary hack that is
1412 needed when producing EFI binaries on IA-64. It tells
1413 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1414 containing ELF relocation info. We need this hack in order to
1415 be able to generate ELF binaries that can be translated into
1416 EFI applications (which are essentially COFF objects). Those
1417 files contain a COFF ".reloc" section inside an ELFNN object,
1418 which would normally cause BFD to segfault because it would
1419 attempt to interpret this section as containing relocation
1420 entries for section "oc". With this hack enabled, ".reloc"
1421 will be treated as a normal data section, which will avoid the
1422 segfault. However, you won't be able to create an ELFNN binary
1423 with a section named "oc" that needs relocations, but that's
1424 the kind of ugly side-effects you get when detecting section
1425 types based on their names... In practice, this limitation is
1426 unlikely to bite. */
1427 hdr
->sh_type
= SHT_PROGBITS
;
1429 if (sec
->flags
& SEC_SMALL_DATA
)
1430 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1432 /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
1434 if (elfNN_ia64_hpux_vec (abfd
->xvec
) && (sec
->flags
& SHF_TLS
))
1435 hdr
->sh_flags
|= SHF_IA_64_HP_TLS
;
1440 /* The final processing done just before writing out an IA-64 ELF
1444 elfNN_ia64_final_write_processing (bfd
*abfd
,
1445 bfd_boolean linker ATTRIBUTE_UNUSED
)
1447 Elf_Internal_Shdr
*hdr
;
1450 for (s
= abfd
->sections
; s
; s
= s
->next
)
1452 hdr
= &elf_section_data (s
)->this_hdr
;
1453 switch (hdr
->sh_type
)
1455 case SHT_IA_64_UNWIND
:
1456 /* The IA-64 processor-specific ABI requires setting sh_link
1457 to the unwind section, whereas HP-UX requires sh_info to
1458 do so. For maximum compatibility, we'll set both for
1460 hdr
->sh_info
= hdr
->sh_link
;
1465 if (! elf_flags_init (abfd
))
1467 unsigned long flags
= 0;
1469 if (abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
)
1470 flags
|= EF_IA_64_BE
;
1471 if (bfd_get_mach (abfd
) == bfd_mach_ia64_elf64
)
1472 flags
|= EF_IA_64_ABI64
;
1474 elf_elfheader(abfd
)->e_flags
= flags
;
1475 elf_flags_init (abfd
) = TRUE
;
1479 /* Hook called by the linker routine which adds symbols from an object
1480 file. We use it to put .comm items in .sbss, and not .bss. */
1483 elfNN_ia64_add_symbol_hook (bfd
*abfd
,
1484 struct bfd_link_info
*info
,
1485 Elf_Internal_Sym
*sym
,
1486 const char **namep ATTRIBUTE_UNUSED
,
1487 flagword
*flagsp ATTRIBUTE_UNUSED
,
1491 if (sym
->st_shndx
== SHN_COMMON
1492 && !info
->relocatable
1493 && sym
->st_size
<= elf_gp_size (abfd
))
1495 /* Common symbols less than or equal to -G nn bytes are
1496 automatically put into .sbss. */
1498 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1502 scomm
= bfd_make_section_with_flags (abfd
, ".scommon",
1505 | SEC_LINKER_CREATED
));
1511 *valp
= sym
->st_size
;
1517 /* Return the number of additional phdrs we will need. */
1520 elfNN_ia64_additional_program_headers (bfd
*abfd
,
1521 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1526 /* See if we need a PT_IA_64_ARCHEXT segment. */
1527 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1528 if (s
&& (s
->flags
& SEC_LOAD
))
1531 /* Count how many PT_IA_64_UNWIND segments we need. */
1532 for (s
= abfd
->sections
; s
; s
= s
->next
)
1533 if (is_unwind_section_name (abfd
, s
->name
) && (s
->flags
& SEC_LOAD
))
1540 elfNN_ia64_modify_segment_map (bfd
*abfd
,
1541 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1543 struct elf_segment_map
*m
, **pm
;
1544 Elf_Internal_Shdr
*hdr
;
1547 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1548 all PT_LOAD segments. */
1549 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1550 if (s
&& (s
->flags
& SEC_LOAD
))
1552 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1553 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1557 m
= ((struct elf_segment_map
*)
1558 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1562 m
->p_type
= PT_IA_64_ARCHEXT
;
1566 /* We want to put it after the PHDR and INTERP segments. */
1567 pm
= &elf_tdata (abfd
)->segment_map
;
1569 && ((*pm
)->p_type
== PT_PHDR
1570 || (*pm
)->p_type
== PT_INTERP
))
1578 /* Install PT_IA_64_UNWIND segments, if needed. */
1579 for (s
= abfd
->sections
; s
; s
= s
->next
)
1581 hdr
= &elf_section_data (s
)->this_hdr
;
1582 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1585 if (s
&& (s
->flags
& SEC_LOAD
))
1587 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1588 if (m
->p_type
== PT_IA_64_UNWIND
)
1592 /* Look through all sections in the unwind segment
1593 for a match since there may be multiple sections
1595 for (i
= m
->count
- 1; i
>= 0; --i
)
1596 if (m
->sections
[i
] == s
)
1605 m
= ((struct elf_segment_map
*)
1606 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1610 m
->p_type
= PT_IA_64_UNWIND
;
1615 /* We want to put it last. */
1616 pm
= &elf_tdata (abfd
)->segment_map
;
1627 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1628 the input sections for each output section in the segment and testing
1629 for SHF_IA_64_NORECOV on each. */
1632 elfNN_ia64_modify_program_headers (bfd
*abfd
,
1633 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1635 struct elf_obj_tdata
*tdata
= elf_tdata (abfd
);
1636 struct elf_segment_map
*m
;
1637 Elf_Internal_Phdr
*p
;
1639 for (p
= tdata
->phdr
, m
= tdata
->segment_map
; m
!= NULL
; m
= m
->next
, p
++)
1640 if (m
->p_type
== PT_LOAD
)
1643 for (i
= m
->count
- 1; i
>= 0; --i
)
1645 struct bfd_link_order
*order
= m
->sections
[i
]->map_head
.link_order
;
1647 while (order
!= NULL
)
1649 if (order
->type
== bfd_indirect_link_order
)
1651 asection
*is
= order
->u
.indirect
.section
;
1652 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1653 if (flags
& SHF_IA_64_NORECOV
)
1655 p
->p_flags
|= PF_IA_64_NORECOV
;
1659 order
= order
->next
;
1668 /* According to the Tahoe assembler spec, all labels starting with a
1672 elfNN_ia64_is_local_label_name (bfd
*abfd ATTRIBUTE_UNUSED
,
1675 return name
[0] == '.';
1678 /* Should we do dynamic things to this symbol? */
1681 elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry
*h
,
1682 struct bfd_link_info
*info
, int r_type
)
1684 bfd_boolean ignore_protected
1685 = ((r_type
& 0xf8) == 0x40 /* FPTR relocs */
1686 || (r_type
& 0xf8) == 0x50); /* LTOFF_FPTR relocs */
1688 return _bfd_elf_dynamic_symbol_p (h
, info
, ignore_protected
);
1691 static struct bfd_hash_entry
*
1692 elfNN_ia64_new_elf_hash_entry (struct bfd_hash_entry
*entry
,
1693 struct bfd_hash_table
*table
,
1696 struct elfNN_ia64_link_hash_entry
*ret
;
1697 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1699 /* Allocate the structure if it has not already been allocated by a
1702 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1707 /* Call the allocation method of the superclass. */
1708 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1709 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1714 ret
->sorted_count
= 0;
1716 return (struct bfd_hash_entry
*) ret
;
1720 elfNN_ia64_hash_copy_indirect (struct bfd_link_info
*info
,
1721 struct elf_link_hash_entry
*xdir
,
1722 struct elf_link_hash_entry
*xind
)
1724 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1726 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1727 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1729 /* Copy down any references that we may have already seen to the
1730 symbol which just became indirect. */
1732 dir
->root
.ref_dynamic
|= ind
->root
.ref_dynamic
;
1733 dir
->root
.ref_regular
|= ind
->root
.ref_regular
;
1734 dir
->root
.ref_regular_nonweak
|= ind
->root
.ref_regular_nonweak
;
1735 dir
->root
.needs_plt
|= ind
->root
.needs_plt
;
1737 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1740 /* Copy over the got and plt data. This would have been done
1743 if (ind
->info
!= NULL
)
1745 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1751 dir
->info
= ind
->info
;
1752 dir
->count
= ind
->count
;
1753 dir
->sorted_count
= ind
->sorted_count
;
1754 dir
->size
= ind
->size
;
1758 ind
->sorted_count
= 0;
1761 /* Fix up the dyn_sym_info pointers to the global symbol. */
1762 for (count
= dir
->count
, dyn_i
= dir
->info
;
1765 dyn_i
->h
= &dir
->root
;
1768 /* Copy over the dynindx. */
1770 if (ind
->root
.dynindx
!= -1)
1772 if (dir
->root
.dynindx
!= -1)
1773 _bfd_elf_strtab_delref (elf_hash_table (info
)->dynstr
,
1774 dir
->root
.dynstr_index
);
1775 dir
->root
.dynindx
= ind
->root
.dynindx
;
1776 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1777 ind
->root
.dynindx
= -1;
1778 ind
->root
.dynstr_index
= 0;
1783 elfNN_ia64_hash_hide_symbol (struct bfd_link_info
*info
,
1784 struct elf_link_hash_entry
*xh
,
1785 bfd_boolean force_local
)
1787 struct elfNN_ia64_link_hash_entry
*h
;
1788 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1791 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1793 _bfd_elf_link_hash_hide_symbol (info
, &h
->root
, force_local
);
1795 for (count
= h
->count
, dyn_i
= h
->info
;
1799 dyn_i
->want_plt2
= 0;
1800 dyn_i
->want_plt
= 0;
1804 /* Compute a hash of a local hash entry. */
1807 elfNN_ia64_local_htab_hash (const void *ptr
)
1809 struct elfNN_ia64_local_hash_entry
*entry
1810 = (struct elfNN_ia64_local_hash_entry
*) ptr
;
1812 return (((entry
->id
& 0xff) << 24) | ((entry
->id
& 0xff00) << 8))
1813 ^ entry
->r_sym
^ (entry
->id
>> 16);
1816 /* Compare local hash entries. */
1819 elfNN_ia64_local_htab_eq (const void *ptr1
, const void *ptr2
)
1821 struct elfNN_ia64_local_hash_entry
*entry1
1822 = (struct elfNN_ia64_local_hash_entry
*) ptr1
;
1823 struct elfNN_ia64_local_hash_entry
*entry2
1824 = (struct elfNN_ia64_local_hash_entry
*) ptr2
;
1826 return entry1
->id
== entry2
->id
&& entry1
->r_sym
== entry2
->r_sym
;
1829 /* Create the derived linker hash table. The IA-64 ELF port uses this
1830 derived hash table to keep information specific to the IA-64 ElF
1831 linker (without using static variables). */
1833 static struct bfd_link_hash_table
*
1834 elfNN_ia64_hash_table_create (bfd
*abfd
)
1836 struct elfNN_ia64_link_hash_table
*ret
;
1838 ret
= bfd_zmalloc ((bfd_size_type
) sizeof (*ret
));
1842 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1843 elfNN_ia64_new_elf_hash_entry
,
1844 sizeof (struct elfNN_ia64_link_hash_entry
)))
1850 ret
->loc_hash_table
= htab_try_create (1024, elfNN_ia64_local_htab_hash
,
1851 elfNN_ia64_local_htab_eq
, NULL
);
1852 ret
->loc_hash_memory
= objalloc_create ();
1853 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
1859 return &ret
->root
.root
;
1862 /* Free the global elfNN_ia64_dyn_sym_info array. */
1865 elfNN_ia64_global_dyn_info_free (void **xentry
,
1866 PTR unused ATTRIBUTE_UNUSED
)
1868 struct elfNN_ia64_link_hash_entry
*entry
1869 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1871 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
1872 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
1879 entry
->sorted_count
= 0;
1886 /* Free the local elfNN_ia64_dyn_sym_info array. */
1889 elfNN_ia64_local_dyn_info_free (void **slot
,
1890 PTR unused ATTRIBUTE_UNUSED
)
1892 struct elfNN_ia64_local_hash_entry
*entry
1893 = (struct elfNN_ia64_local_hash_entry
*) *slot
;
1900 entry
->sorted_count
= 0;
1907 /* Destroy IA-64 linker hash table. */
1910 elfNN_ia64_hash_table_free (struct bfd_link_hash_table
*hash
)
1912 struct elfNN_ia64_link_hash_table
*ia64_info
1913 = (struct elfNN_ia64_link_hash_table
*) hash
;
1914 if (ia64_info
->loc_hash_table
)
1916 htab_traverse (ia64_info
->loc_hash_table
,
1917 elfNN_ia64_local_dyn_info_free
, NULL
);
1918 htab_delete (ia64_info
->loc_hash_table
);
1920 if (ia64_info
->loc_hash_memory
)
1921 objalloc_free ((struct objalloc
*) ia64_info
->loc_hash_memory
);
1922 elf_link_hash_traverse (&ia64_info
->root
,
1923 elfNN_ia64_global_dyn_info_free
, NULL
);
1924 _bfd_generic_link_hash_table_free (hash
);
1927 /* Traverse both local and global hash tables. */
1929 struct elfNN_ia64_dyn_sym_traverse_data
1931 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
);
1936 elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry
*xentry
,
1939 struct elfNN_ia64_link_hash_entry
*entry
1940 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1941 struct elfNN_ia64_dyn_sym_traverse_data
*data
1942 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1943 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1946 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
1947 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
1949 for (count
= entry
->count
, dyn_i
= entry
->info
;
1952 if (! (*data
->func
) (dyn_i
, data
->data
))
1958 elfNN_ia64_local_dyn_sym_thunk (void **slot
, PTR xdata
)
1960 struct elfNN_ia64_local_hash_entry
*entry
1961 = (struct elfNN_ia64_local_hash_entry
*) *slot
;
1962 struct elfNN_ia64_dyn_sym_traverse_data
*data
1963 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1964 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1967 for (count
= entry
->count
, dyn_i
= entry
->info
;
1970 if (! (*data
->func
) (dyn_i
, data
->data
))
1976 elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table
*ia64_info
,
1977 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
1980 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1985 elf_link_hash_traverse (&ia64_info
->root
,
1986 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1987 htab_traverse (ia64_info
->loc_hash_table
,
1988 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1992 elfNN_ia64_create_dynamic_sections (bfd
*abfd
,
1993 struct bfd_link_info
*info
)
1995 struct elfNN_ia64_link_hash_table
*ia64_info
;
1998 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
2001 ia64_info
= elfNN_ia64_hash_table (info
);
2004 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->root
.sgot
);
2005 bfd_set_section_flags (abfd
, ia64_info
->root
.sgot
,
2006 SEC_SMALL_DATA
| flags
);
2007 /* The .got section is always aligned at 8 bytes. */
2008 bfd_set_section_alignment (abfd
, ia64_info
->root
.sgot
, 3);
2011 if (!get_pltoff (abfd
, info
, ia64_info
))
2014 s
= bfd_make_section_with_flags (abfd
, ".rela.IA_64.pltoff",
2015 (SEC_ALLOC
| SEC_LOAD
2018 | SEC_LINKER_CREATED
2021 || !bfd_set_section_alignment (abfd
, s
, LOG_SECTION_ALIGN
))
2023 ia64_info
->rel_pltoff_sec
= s
;
2028 /* Find and/or create a hash entry for local symbol. */
2029 static struct elfNN_ia64_local_hash_entry
*
2030 get_local_sym_hash (struct elfNN_ia64_link_hash_table
*ia64_info
,
2031 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
2034 struct elfNN_ia64_local_hash_entry e
, *ret
;
2035 asection
*sec
= abfd
->sections
;
2036 hashval_t h
= (((sec
->id
& 0xff) << 24) | ((sec
->id
& 0xff00) << 8))
2037 ^ ELFNN_R_SYM (rel
->r_info
) ^ (sec
->id
>> 16);
2041 e
.r_sym
= ELFNN_R_SYM (rel
->r_info
);
2042 slot
= htab_find_slot_with_hash (ia64_info
->loc_hash_table
, &e
, h
,
2043 create
? INSERT
: NO_INSERT
);
2049 return (struct elfNN_ia64_local_hash_entry
*) *slot
;
2051 ret
= (struct elfNN_ia64_local_hash_entry
*)
2052 objalloc_alloc ((struct objalloc
*) ia64_info
->loc_hash_memory
,
2053 sizeof (struct elfNN_ia64_local_hash_entry
));
2056 memset (ret
, 0, sizeof (*ret
));
2058 ret
->r_sym
= ELFNN_R_SYM (rel
->r_info
);
2064 /* Used to sort elfNN_ia64_dyn_sym_info array. */
2067 addend_compare (const void *xp
, const void *yp
)
2069 const struct elfNN_ia64_dyn_sym_info
*x
2070 = (const struct elfNN_ia64_dyn_sym_info
*) xp
;
2071 const struct elfNN_ia64_dyn_sym_info
*y
2072 = (const struct elfNN_ia64_dyn_sym_info
*) yp
;
2074 return x
->addend
< y
->addend
? -1 : x
->addend
> y
->addend
? 1 : 0;
2077 /* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
2080 sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info
*info
,
2083 bfd_vma curr
, prev
, got_offset
;
2084 unsigned int i
, kept
, dup
, diff
, dest
, src
, len
;
2086 qsort (info
, count
, sizeof (*info
), addend_compare
);
2088 /* Find the first duplicate. */
2089 prev
= info
[0].addend
;
2090 got_offset
= info
[0].got_offset
;
2091 for (i
= 1; i
< count
; i
++)
2093 curr
= info
[i
].addend
;
2096 /* For duplicates, make sure that GOT_OFFSET is valid. */
2097 if (got_offset
== (bfd_vma
) -1)
2098 got_offset
= info
[i
].got_offset
;
2101 got_offset
= info
[i
].got_offset
;
2105 /* We may move a block of elements to here. */
2108 /* Remove duplicates. */
2113 /* For duplicates, make sure that the kept one has a valid
2116 if (got_offset
!= (bfd_vma
) -1)
2117 info
[kept
].got_offset
= got_offset
;
2119 curr
= info
[i
].addend
;
2120 got_offset
= info
[i
].got_offset
;
2122 /* Move a block of elements whose first one is different from
2126 for (src
= i
+ 1; src
< count
; src
++)
2128 if (info
[src
].addend
!= curr
)
2130 /* For duplicates, make sure that GOT_OFFSET is
2132 if (got_offset
== (bfd_vma
) -1)
2133 got_offset
= info
[src
].got_offset
;
2136 /* Make sure that the kept one has a valid got_offset. */
2137 if (got_offset
!= (bfd_vma
) -1)
2138 info
[kept
].got_offset
= got_offset
;
2146 /* Find the next duplicate. SRC will be kept. */
2147 prev
= info
[src
].addend
;
2148 got_offset
= info
[src
].got_offset
;
2149 for (dup
= src
+ 1; dup
< count
; dup
++)
2151 curr
= info
[dup
].addend
;
2154 /* Make sure that got_offset is valid. */
2155 if (got_offset
== (bfd_vma
) -1)
2156 got_offset
= info
[dup
].got_offset
;
2158 /* For duplicates, make sure that the kept one has
2159 a valid got_offset. */
2160 if (got_offset
!= (bfd_vma
) -1)
2161 info
[dup
- 1].got_offset
= got_offset
;
2164 got_offset
= info
[dup
].got_offset
;
2168 /* How much to move. */
2172 if (len
== 1 && dup
< count
)
2174 /* If we only move 1 element, we combine it with the next
2175 one. There must be at least a duplicate. Find the
2176 next different one. */
2177 for (diff
= dup
+ 1, src
++; diff
< count
; diff
++, src
++)
2179 if (info
[diff
].addend
!= curr
)
2181 /* Make sure that got_offset is valid. */
2182 if (got_offset
== (bfd_vma
) -1)
2183 got_offset
= info
[diff
].got_offset
;
2186 /* Makre sure that the last duplicated one has an valid
2188 BFD_ASSERT (curr
== prev
);
2189 if (got_offset
!= (bfd_vma
) -1)
2190 info
[diff
- 1].got_offset
= got_offset
;
2194 /* Find the next duplicate. Track the current valid
2196 prev
= info
[diff
].addend
;
2197 got_offset
= info
[diff
].got_offset
;
2198 for (dup
= diff
+ 1; dup
< count
; dup
++)
2200 curr
= info
[dup
].addend
;
2203 /* For duplicates, make sure that GOT_OFFSET
2205 if (got_offset
== (bfd_vma
) -1)
2206 got_offset
= info
[dup
].got_offset
;
2209 got_offset
= info
[dup
].got_offset
;
2214 len
= diff
- src
+ 1;
2219 memmove (&info
[dest
], &info
[src
], len
* sizeof (*info
));
2228 /* When we get here, either there is no duplicate at all or
2229 the only duplicate is the last element. */
2232 /* If the last element is a duplicate, make sure that the
2233 kept one has a valid got_offset. We also update count. */
2234 if (got_offset
!= (bfd_vma
) -1)
2235 info
[dest
- 1].got_offset
= got_offset
;
2243 /* Find and/or create a descriptor for dynamic symbol info. This will
2244 vary based on global or local symbol, and the addend to the reloc.
2246 We don't sort when inserting. Also, we sort and eliminate
2247 duplicates if there is an unsorted section. Typically, this will
2248 only happen once, because we do all insertions before lookups. We
2249 then use bsearch to do a lookup. This also allows lookups to be
2250 fast. So we have fast insertion (O(log N) due to duplicate check),
2251 fast lookup (O(log N)) and one sort (O(N log N) expected time).
2252 Previously, all lookups were O(N) because of the use of the linked
2253 list and also all insertions were O(N) because of the check for
2254 duplicates. There are some complications here because the array
2255 size grows occasionally, which may add an O(N) factor, but this
2256 should be rare. Also, we free the excess array allocation, which
2257 requires a copy which is O(N), but this only happens once. */
2259 static struct elfNN_ia64_dyn_sym_info
*
2260 get_dyn_sym_info (struct elfNN_ia64_link_hash_table
*ia64_info
,
2261 struct elf_link_hash_entry
*h
, bfd
*abfd
,
2262 const Elf_Internal_Rela
*rel
, bfd_boolean create
)
2264 struct elfNN_ia64_dyn_sym_info
**info_p
, *info
, *dyn_i
, key
;
2265 unsigned int *count_p
, *sorted_count_p
, *size_p
;
2266 unsigned int count
, sorted_count
, size
;
2267 bfd_vma addend
= rel
? rel
->r_addend
: 0;
2272 struct elfNN_ia64_link_hash_entry
*global_h
;
2274 global_h
= (struct elfNN_ia64_link_hash_entry
*) h
;
2275 info_p
= &global_h
->info
;
2276 count_p
= &global_h
->count
;
2277 sorted_count_p
= &global_h
->sorted_count
;
2278 size_p
= &global_h
->size
;
2282 struct elfNN_ia64_local_hash_entry
*loc_h
;
2284 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
2287 BFD_ASSERT (!create
);
2291 info_p
= &loc_h
->info
;
2292 count_p
= &loc_h
->count
;
2293 sorted_count_p
= &loc_h
->sorted_count
;
2294 size_p
= &loc_h
->size
;
2298 sorted_count
= *sorted_count_p
;
2303 /* When we create the array, we don't check for duplicates,
2304 except in the previously sorted section if one exists, and
2305 against the last inserted entry. This allows insertions to
2311 /* Try bsearch first on the sorted section. */
2312 key
.addend
= addend
;
2313 dyn_i
= bsearch (&key
, info
, sorted_count
,
2314 sizeof (*info
), addend_compare
);
2322 /* Do a quick check for the last inserted entry. */
2323 dyn_i
= info
+ count
- 1;
2324 if (dyn_i
->addend
== addend
)
2332 /* It is the very first element. We create the array of size
2335 amt
= size
* sizeof (*info
);
2336 info
= bfd_malloc (amt
);
2338 else if (size
<= count
)
2340 /* We double the array size every time when we reach the
2343 amt
= size
* sizeof (*info
);
2344 info
= bfd_realloc (info
, amt
);
2355 /* Append the new one to the array. */
2356 dyn_i
= info
+ count
;
2357 memset (dyn_i
, 0, sizeof (*dyn_i
));
2358 dyn_i
->got_offset
= (bfd_vma
) -1;
2359 dyn_i
->addend
= addend
;
2361 /* We increment count only since the new ones are unsorted and
2362 may have duplicate. */
2367 /* It is a lookup without insertion. Sort array if part of the
2368 array isn't sorted. */
2369 if (count
!= sorted_count
)
2371 count
= sort_dyn_sym_info (info
, count
);
2373 *sorted_count_p
= count
;
2376 /* Free unused memory. */
2379 amt
= count
* sizeof (*info
);
2380 info
= bfd_malloc (amt
);
2383 memcpy (info
, *info_p
, amt
);
2390 key
.addend
= addend
;
2391 dyn_i
= bsearch (&key
, info
, count
,
2392 sizeof (*info
), addend_compare
);
2399 get_got (bfd
*abfd
, struct bfd_link_info
*info
,
2400 struct elfNN_ia64_link_hash_table
*ia64_info
)
2405 got
= ia64_info
->root
.sgot
;
2410 dynobj
= ia64_info
->root
.dynobj
;
2412 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2413 if (!_bfd_elf_create_got_section (dynobj
, info
))
2416 got
= ia64_info
->root
.sgot
;
2418 /* The .got section is always aligned at 8 bytes. */
2419 if (!bfd_set_section_alignment (abfd
, got
, 3))
2422 flags
= bfd_get_section_flags (abfd
, got
);
2423 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
2429 /* Create function descriptor section (.opd). This section is called .opd
2430 because it contains "official procedure descriptors". The "official"
2431 refers to the fact that these descriptors are used when taking the address
2432 of a procedure, thus ensuring a unique address for each procedure. */
2435 get_fptr (bfd
*abfd
, struct bfd_link_info
*info
,
2436 struct elfNN_ia64_link_hash_table
*ia64_info
)
2441 fptr
= ia64_info
->fptr_sec
;
2444 dynobj
= ia64_info
->root
.dynobj
;
2446 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2448 fptr
= bfd_make_section_with_flags (dynobj
, ".opd",
2453 | (info
->pie
? 0 : SEC_READONLY
)
2454 | SEC_LINKER_CREATED
));
2456 || !bfd_set_section_alignment (abfd
, fptr
, 4))
2462 ia64_info
->fptr_sec
= fptr
;
2467 fptr_rel
= bfd_make_section_with_flags (dynobj
, ".rela.opd",
2468 (SEC_ALLOC
| SEC_LOAD
2471 | SEC_LINKER_CREATED
2473 if (fptr_rel
== NULL
2474 || !bfd_set_section_alignment (abfd
, fptr_rel
,
2481 ia64_info
->rel_fptr_sec
= fptr_rel
;
2489 get_pltoff (bfd
*abfd
, struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
2490 struct elfNN_ia64_link_hash_table
*ia64_info
)
2495 pltoff
= ia64_info
->pltoff_sec
;
2498 dynobj
= ia64_info
->root
.dynobj
;
2500 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2502 pltoff
= bfd_make_section_with_flags (dynobj
,
2503 ELF_STRING_ia64_pltoff
,
2509 | SEC_LINKER_CREATED
));
2511 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
2517 ia64_info
->pltoff_sec
= pltoff
;
2524 get_reloc_section (bfd
*abfd
,
2525 struct elfNN_ia64_link_hash_table
*ia64_info
,
2526 asection
*sec
, bfd_boolean create
)
2528 const char *srel_name
;
2532 srel_name
= (bfd_elf_string_from_elf_section
2533 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
2534 elf_section_data(sec
)->rel_hdr
.sh_name
));
2535 if (srel_name
== NULL
)
2538 BFD_ASSERT ((CONST_STRNEQ (srel_name
, ".rela")
2539 && strcmp (bfd_get_section_name (abfd
, sec
),
2541 || (CONST_STRNEQ (srel_name
, ".rel")
2542 && strcmp (bfd_get_section_name (abfd
, sec
),
2543 srel_name
+4) == 0));
2545 dynobj
= ia64_info
->root
.dynobj
;
2547 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2549 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
2550 if (srel
== NULL
&& create
)
2552 srel
= bfd_make_section_with_flags (dynobj
, srel_name
,
2553 (SEC_ALLOC
| SEC_LOAD
2556 | SEC_LINKER_CREATED
2559 || !bfd_set_section_alignment (dynobj
, srel
,
2568 count_dyn_reloc (bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
2569 asection
*srel
, int type
, bfd_boolean reltext
)
2571 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2573 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2574 if (rent
->srel
== srel
&& rent
->type
== type
)
2579 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
2580 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
2584 rent
->next
= dyn_i
->reloc_entries
;
2588 dyn_i
->reloc_entries
= rent
;
2590 rent
->reltext
= reltext
;
2597 elfNN_ia64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
2599 const Elf_Internal_Rela
*relocs
)
2601 struct elfNN_ia64_link_hash_table
*ia64_info
;
2602 const Elf_Internal_Rela
*relend
;
2603 Elf_Internal_Shdr
*symtab_hdr
;
2604 const Elf_Internal_Rela
*rel
;
2605 asection
*got
, *fptr
, *srel
, *pltoff
;
2614 NEED_LTOFF_FPTR
= 128,
2620 struct elf_link_hash_entry
*h
;
2621 unsigned long r_symndx
;
2622 bfd_boolean maybe_dynamic
;
2624 if (info
->relocatable
)
2627 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2628 ia64_info
= elfNN_ia64_hash_table (info
);
2630 got
= fptr
= srel
= pltoff
= NULL
;
2632 relend
= relocs
+ sec
->reloc_count
;
2634 /* We scan relocations first to create dynamic relocation arrays. We
2635 modified get_dyn_sym_info to allow fast insertion and support fast
2636 lookup in the next loop. */
2637 for (rel
= relocs
; rel
< relend
; ++rel
)
2639 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2640 if (r_symndx
>= symtab_hdr
->sh_info
)
2642 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2643 h
= elf_sym_hashes (abfd
)[indx
];
2644 while (h
->root
.type
== bfd_link_hash_indirect
2645 || h
->root
.type
== bfd_link_hash_warning
)
2646 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2651 /* We can only get preliminary data on whether a symbol is
2652 locally or externally defined, as not all of the input files
2653 have yet been processed. Do something with what we know, as
2654 this may help reduce memory usage and processing time later. */
2655 maybe_dynamic
= (h
&& ((!info
->executable
2656 && (!SYMBOLIC_BIND (info
, h
)
2657 || info
->unresolved_syms_in_shared_libs
== RM_IGNORE
))
2659 || h
->root
.type
== bfd_link_hash_defweak
));
2662 switch (ELFNN_R_TYPE (rel
->r_info
))
2664 case R_IA64_TPREL64MSB
:
2665 case R_IA64_TPREL64LSB
:
2666 if (info
->shared
|| maybe_dynamic
)
2667 need_entry
= NEED_DYNREL
;
2670 case R_IA64_LTOFF_TPREL22
:
2671 need_entry
= NEED_TPREL
;
2673 info
->flags
|= DF_STATIC_TLS
;
2676 case R_IA64_DTPREL32MSB
:
2677 case R_IA64_DTPREL32LSB
:
2678 case R_IA64_DTPREL64MSB
:
2679 case R_IA64_DTPREL64LSB
:
2680 if (info
->shared
|| maybe_dynamic
)
2681 need_entry
= NEED_DYNREL
;
2684 case R_IA64_LTOFF_DTPREL22
:
2685 need_entry
= NEED_DTPREL
;
2688 case R_IA64_DTPMOD64MSB
:
2689 case R_IA64_DTPMOD64LSB
:
2690 if (info
->shared
|| maybe_dynamic
)
2691 need_entry
= NEED_DYNREL
;
2694 case R_IA64_LTOFF_DTPMOD22
:
2695 need_entry
= NEED_DTPMOD
;
2698 case R_IA64_LTOFF_FPTR22
:
2699 case R_IA64_LTOFF_FPTR64I
:
2700 case R_IA64_LTOFF_FPTR32MSB
:
2701 case R_IA64_LTOFF_FPTR32LSB
:
2702 case R_IA64_LTOFF_FPTR64MSB
:
2703 case R_IA64_LTOFF_FPTR64LSB
:
2704 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2707 case R_IA64_FPTR64I
:
2708 case R_IA64_FPTR32MSB
:
2709 case R_IA64_FPTR32LSB
:
2710 case R_IA64_FPTR64MSB
:
2711 case R_IA64_FPTR64LSB
:
2712 if (info
->shared
|| h
)
2713 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2715 need_entry
= NEED_FPTR
;
2718 case R_IA64_LTOFF22
:
2719 case R_IA64_LTOFF64I
:
2720 need_entry
= NEED_GOT
;
2723 case R_IA64_LTOFF22X
:
2724 need_entry
= NEED_GOTX
;
2727 case R_IA64_PLTOFF22
:
2728 case R_IA64_PLTOFF64I
:
2729 case R_IA64_PLTOFF64MSB
:
2730 case R_IA64_PLTOFF64LSB
:
2731 need_entry
= NEED_PLTOFF
;
2735 need_entry
|= NEED_MIN_PLT
;
2739 (*info
->callbacks
->warning
)
2740 (info
, _("@pltoff reloc against local symbol"), 0,
2741 abfd
, 0, (bfd_vma
) 0);
2745 case R_IA64_PCREL21B
:
2746 case R_IA64_PCREL60B
:
2747 /* Depending on where this symbol is defined, we may or may not
2748 need a full plt entry. Only skip if we know we'll not need
2749 the entry -- static or symbolic, and the symbol definition
2750 has already been seen. */
2751 if (maybe_dynamic
&& rel
->r_addend
== 0)
2752 need_entry
= NEED_FULL_PLT
;
2758 case R_IA64_DIR32MSB
:
2759 case R_IA64_DIR32LSB
:
2760 case R_IA64_DIR64MSB
:
2761 case R_IA64_DIR64LSB
:
2762 /* Shared objects will always need at least a REL relocation. */
2763 if (info
->shared
|| maybe_dynamic
)
2764 need_entry
= NEED_DYNREL
;
2767 case R_IA64_IPLTMSB
:
2768 case R_IA64_IPLTLSB
:
2769 /* Shared objects will always need at least a REL relocation. */
2770 if (info
->shared
|| maybe_dynamic
)
2771 need_entry
= NEED_DYNREL
;
2774 case R_IA64_PCREL22
:
2775 case R_IA64_PCREL64I
:
2776 case R_IA64_PCREL32MSB
:
2777 case R_IA64_PCREL32LSB
:
2778 case R_IA64_PCREL64MSB
:
2779 case R_IA64_PCREL64LSB
:
2781 need_entry
= NEED_DYNREL
;
2788 if ((need_entry
& NEED_FPTR
) != 0
2791 (*info
->callbacks
->warning
)
2792 (info
, _("non-zero addend in @fptr reloc"), 0,
2793 abfd
, 0, (bfd_vma
) 0);
2796 if (get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, TRUE
) == NULL
)
2800 /* Now, we only do lookup without insertion, which is very fast
2801 with the modified get_dyn_sym_info. */
2802 for (rel
= relocs
; rel
< relend
; ++rel
)
2804 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2805 int dynrel_type
= R_IA64_NONE
;
2807 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2808 if (r_symndx
>= symtab_hdr
->sh_info
)
2810 /* We're dealing with a global symbol -- find its hash entry
2811 and mark it as being referenced. */
2812 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2813 h
= elf_sym_hashes (abfd
)[indx
];
2814 while (h
->root
.type
== bfd_link_hash_indirect
2815 || h
->root
.type
== bfd_link_hash_warning
)
2816 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2823 /* We can only get preliminary data on whether a symbol is
2824 locally or externally defined, as not all of the input files
2825 have yet been processed. Do something with what we know, as
2826 this may help reduce memory usage and processing time later. */
2827 maybe_dynamic
= (h
&& ((!info
->executable
2828 && (!SYMBOLIC_BIND (info
, h
)
2829 || info
->unresolved_syms_in_shared_libs
== RM_IGNORE
))
2831 || h
->root
.type
== bfd_link_hash_defweak
));
2834 switch (ELFNN_R_TYPE (rel
->r_info
))
2836 case R_IA64_TPREL64MSB
:
2837 case R_IA64_TPREL64LSB
:
2838 if (info
->shared
|| maybe_dynamic
)
2839 need_entry
= NEED_DYNREL
;
2840 dynrel_type
= R_IA64_TPREL64LSB
;
2842 info
->flags
|= DF_STATIC_TLS
;
2845 case R_IA64_LTOFF_TPREL22
:
2846 need_entry
= NEED_TPREL
;
2848 info
->flags
|= DF_STATIC_TLS
;
2851 case R_IA64_DTPREL32MSB
:
2852 case R_IA64_DTPREL32LSB
:
2853 case R_IA64_DTPREL64MSB
:
2854 case R_IA64_DTPREL64LSB
:
2855 if (info
->shared
|| maybe_dynamic
)
2856 need_entry
= NEED_DYNREL
;
2857 dynrel_type
= R_IA64_DTPRELNNLSB
;
2860 case R_IA64_LTOFF_DTPREL22
:
2861 need_entry
= NEED_DTPREL
;
2864 case R_IA64_DTPMOD64MSB
:
2865 case R_IA64_DTPMOD64LSB
:
2866 if (info
->shared
|| maybe_dynamic
)
2867 need_entry
= NEED_DYNREL
;
2868 dynrel_type
= R_IA64_DTPMOD64LSB
;
2871 case R_IA64_LTOFF_DTPMOD22
:
2872 need_entry
= NEED_DTPMOD
;
2875 case R_IA64_LTOFF_FPTR22
:
2876 case R_IA64_LTOFF_FPTR64I
:
2877 case R_IA64_LTOFF_FPTR32MSB
:
2878 case R_IA64_LTOFF_FPTR32LSB
:
2879 case R_IA64_LTOFF_FPTR64MSB
:
2880 case R_IA64_LTOFF_FPTR64LSB
:
2881 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2884 case R_IA64_FPTR64I
:
2885 case R_IA64_FPTR32MSB
:
2886 case R_IA64_FPTR32LSB
:
2887 case R_IA64_FPTR64MSB
:
2888 case R_IA64_FPTR64LSB
:
2889 if (info
->shared
|| h
)
2890 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2892 need_entry
= NEED_FPTR
;
2893 dynrel_type
= R_IA64_FPTRNNLSB
;
2896 case R_IA64_LTOFF22
:
2897 case R_IA64_LTOFF64I
:
2898 need_entry
= NEED_GOT
;
2901 case R_IA64_LTOFF22X
:
2902 need_entry
= NEED_GOTX
;
2905 case R_IA64_PLTOFF22
:
2906 case R_IA64_PLTOFF64I
:
2907 case R_IA64_PLTOFF64MSB
:
2908 case R_IA64_PLTOFF64LSB
:
2909 need_entry
= NEED_PLTOFF
;
2913 need_entry
|= NEED_MIN_PLT
;
2917 case R_IA64_PCREL21B
:
2918 case R_IA64_PCREL60B
:
2919 /* Depending on where this symbol is defined, we may or may not
2920 need a full plt entry. Only skip if we know we'll not need
2921 the entry -- static or symbolic, and the symbol definition
2922 has already been seen. */
2923 if (maybe_dynamic
&& rel
->r_addend
== 0)
2924 need_entry
= NEED_FULL_PLT
;
2930 case R_IA64_DIR32MSB
:
2931 case R_IA64_DIR32LSB
:
2932 case R_IA64_DIR64MSB
:
2933 case R_IA64_DIR64LSB
:
2934 /* Shared objects will always need at least a REL relocation. */
2935 if (info
->shared
|| maybe_dynamic
)
2936 need_entry
= NEED_DYNREL
;
2937 dynrel_type
= R_IA64_DIRNNLSB
;
2940 case R_IA64_IPLTMSB
:
2941 case R_IA64_IPLTLSB
:
2942 /* Shared objects will always need at least a REL relocation. */
2943 if (info
->shared
|| maybe_dynamic
)
2944 need_entry
= NEED_DYNREL
;
2945 dynrel_type
= R_IA64_IPLTLSB
;
2948 case R_IA64_PCREL22
:
2949 case R_IA64_PCREL64I
:
2950 case R_IA64_PCREL32MSB
:
2951 case R_IA64_PCREL32LSB
:
2952 case R_IA64_PCREL64MSB
:
2953 case R_IA64_PCREL64LSB
:
2955 need_entry
= NEED_DYNREL
;
2956 dynrel_type
= R_IA64_PCRELNNLSB
;
2963 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, FALSE
);
2965 /* Record whether or not this is a local symbol. */
2968 /* Create what's needed. */
2969 if (need_entry
& (NEED_GOT
| NEED_GOTX
| NEED_TPREL
2970 | NEED_DTPMOD
| NEED_DTPREL
))
2974 got
= get_got (abfd
, info
, ia64_info
);
2978 if (need_entry
& NEED_GOT
)
2979 dyn_i
->want_got
= 1;
2980 if (need_entry
& NEED_GOTX
)
2981 dyn_i
->want_gotx
= 1;
2982 if (need_entry
& NEED_TPREL
)
2983 dyn_i
->want_tprel
= 1;
2984 if (need_entry
& NEED_DTPMOD
)
2985 dyn_i
->want_dtpmod
= 1;
2986 if (need_entry
& NEED_DTPREL
)
2987 dyn_i
->want_dtprel
= 1;
2989 if (need_entry
& NEED_FPTR
)
2993 fptr
= get_fptr (abfd
, info
, ia64_info
);
2998 /* FPTRs for shared libraries are allocated by the dynamic
2999 linker. Make sure this local symbol will appear in the
3000 dynamic symbol table. */
3001 if (!h
&& info
->shared
)
3003 if (! (bfd_elf_link_record_local_dynamic_symbol
3004 (info
, abfd
, (long) r_symndx
)))
3008 dyn_i
->want_fptr
= 1;
3010 if (need_entry
& NEED_LTOFF_FPTR
)
3011 dyn_i
->want_ltoff_fptr
= 1;
3012 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
3014 if (!ia64_info
->root
.dynobj
)
3015 ia64_info
->root
.dynobj
= abfd
;
3017 dyn_i
->want_plt
= 1;
3019 if (need_entry
& NEED_FULL_PLT
)
3020 dyn_i
->want_plt2
= 1;
3021 if (need_entry
& NEED_PLTOFF
)
3023 /* This is needed here, in case @pltoff is used in a non-shared
3027 pltoff
= get_pltoff (abfd
, info
, ia64_info
);
3032 dyn_i
->want_pltoff
= 1;
3034 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
3038 srel
= get_reloc_section (abfd
, ia64_info
, sec
, TRUE
);
3042 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
,
3043 (sec
->flags
& SEC_READONLY
) != 0))
3051 /* For cleanliness, and potentially faster dynamic loading, allocate
3052 external GOT entries first. */
3055 allocate_global_data_got (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3058 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3060 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
3061 && ! dyn_i
->want_fptr
3062 && elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3064 dyn_i
->got_offset
= x
->ofs
;
3067 if (dyn_i
->want_tprel
)
3069 dyn_i
->tprel_offset
= x
->ofs
;
3072 if (dyn_i
->want_dtpmod
)
3074 if (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3076 dyn_i
->dtpmod_offset
= x
->ofs
;
3081 struct elfNN_ia64_link_hash_table
*ia64_info
;
3083 ia64_info
= elfNN_ia64_hash_table (x
->info
);
3084 if (ia64_info
->self_dtpmod_offset
== (bfd_vma
) -1)
3086 ia64_info
->self_dtpmod_offset
= x
->ofs
;
3089 dyn_i
->dtpmod_offset
= ia64_info
->self_dtpmod_offset
;
3092 if (dyn_i
->want_dtprel
)
3094 dyn_i
->dtprel_offset
= x
->ofs
;
3100 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
3103 allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3106 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3110 && elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, R_IA64_FPTRNNLSB
))
3112 dyn_i
->got_offset
= x
->ofs
;
3118 /* Lastly, allocate all the GOT entries for local data. */
3121 allocate_local_got (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3124 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3126 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
3127 && !elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3129 dyn_i
->got_offset
= x
->ofs
;
3135 /* Search for the index of a global symbol in it's defining object file. */
3138 global_sym_index (struct elf_link_hash_entry
*h
)
3140 struct elf_link_hash_entry
**p
;
3143 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
3144 || h
->root
.type
== bfd_link_hash_defweak
);
3146 obj
= h
->root
.u
.def
.section
->owner
;
3147 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
3150 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
3153 /* Allocate function descriptors. We can do these for every function
3154 in a main executable that is not exported. */
3157 allocate_fptr (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
)
3159 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3161 if (dyn_i
->want_fptr
)
3163 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3166 while (h
->root
.type
== bfd_link_hash_indirect
3167 || h
->root
.type
== bfd_link_hash_warning
)
3168 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3170 if (!x
->info
->executable
3172 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
3173 || (h
->root
.type
!= bfd_link_hash_undefweak
3174 && h
->root
.type
!= bfd_link_hash_undefined
)))
3176 if (h
&& h
->dynindx
== -1)
3178 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
3179 || (h
->root
.type
== bfd_link_hash_defweak
));
3181 if (!bfd_elf_link_record_local_dynamic_symbol
3182 (x
->info
, h
->root
.u
.def
.section
->owner
,
3183 global_sym_index (h
)))
3187 dyn_i
->want_fptr
= 0;
3189 else if (h
== NULL
|| h
->dynindx
== -1)
3191 dyn_i
->fptr_offset
= x
->ofs
;
3195 dyn_i
->want_fptr
= 0;
3200 /* Allocate all the minimal PLT entries. */
3203 allocate_plt_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3206 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3208 if (dyn_i
->want_plt
)
3210 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3213 while (h
->root
.type
== bfd_link_hash_indirect
3214 || h
->root
.type
== bfd_link_hash_warning
)
3215 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3217 /* ??? Versioned symbols seem to lose NEEDS_PLT. */
3218 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
, 0))
3220 bfd_size_type offset
= x
->ofs
;
3222 offset
= PLT_HEADER_SIZE
;
3223 dyn_i
->plt_offset
= offset
;
3224 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
3226 dyn_i
->want_pltoff
= 1;
3230 dyn_i
->want_plt
= 0;
3231 dyn_i
->want_plt2
= 0;
3237 /* Allocate all the full PLT entries. */
3240 allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3243 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3245 if (dyn_i
->want_plt2
)
3247 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3248 bfd_size_type ofs
= x
->ofs
;
3250 dyn_i
->plt2_offset
= ofs
;
3251 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
3253 while (h
->root
.type
== bfd_link_hash_indirect
3254 || h
->root
.type
== bfd_link_hash_warning
)
3255 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3256 dyn_i
->h
->plt
.offset
= ofs
;
3261 /* Allocate all the PLTOFF entries requested by relocations and
3262 plt entries. We can't share space with allocated FPTR entries,
3263 because the latter are not necessarily addressable by the GP.
3264 ??? Relaxation might be able to determine that they are. */
3267 allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3270 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3272 if (dyn_i
->want_pltoff
)
3274 dyn_i
->pltoff_offset
= x
->ofs
;
3280 /* Allocate dynamic relocations for those symbols that turned out
3284 allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3287 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3288 struct elfNN_ia64_link_hash_table
*ia64_info
;
3289 struct elfNN_ia64_dyn_reloc_entry
*rent
;
3290 bfd_boolean dynamic_symbol
, shared
, resolved_zero
;
3292 ia64_info
= elfNN_ia64_hash_table (x
->info
);
3294 /* Note that this can't be used in relation to FPTR relocs below. */
3295 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0);
3297 shared
= x
->info
->shared
;
3298 resolved_zero
= (dyn_i
->h
3299 && ELF_ST_VISIBILITY (dyn_i
->h
->other
)
3300 && dyn_i
->h
->root
.type
== bfd_link_hash_undefweak
);
3302 /* Take care of the GOT and PLT relocations. */
3305 && (dynamic_symbol
|| shared
)
3306 && (dyn_i
->want_got
|| dyn_i
->want_gotx
))
3307 || (dyn_i
->want_ltoff_fptr
3309 && dyn_i
->h
->dynindx
!= -1))
3311 if (!dyn_i
->want_ltoff_fptr
3314 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
3315 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
3317 if ((dynamic_symbol
|| shared
) && dyn_i
->want_tprel
)
3318 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
3319 if (dynamic_symbol
&& dyn_i
->want_dtpmod
)
3320 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
3321 if (dynamic_symbol
&& dyn_i
->want_dtprel
)
3322 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
3327 if (ia64_info
->rel_fptr_sec
&& dyn_i
->want_fptr
)
3329 if (dyn_i
->h
== NULL
|| dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
3330 ia64_info
->rel_fptr_sec
->size
+= sizeof (ElfNN_External_Rela
);
3333 if (!resolved_zero
&& dyn_i
->want_pltoff
)
3335 bfd_size_type t
= 0;
3337 /* Dynamic symbols get one IPLT relocation. Local symbols in
3338 shared libraries get two REL relocations. Local symbols in
3339 main applications get nothing. */
3341 t
= sizeof (ElfNN_External_Rela
);
3343 t
= 2 * sizeof (ElfNN_External_Rela
);
3345 ia64_info
->rel_pltoff_sec
->size
+= t
;
3348 /* Take care of the normal data relocations. */
3350 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
3352 int count
= rent
->count
;
3356 case R_IA64_FPTR32LSB
:
3357 case R_IA64_FPTR64LSB
:
3358 /* Allocate one iff !want_fptr and not PIE, which by this point
3359 will be true only if we're actually allocating one statically
3360 in the main executable. Position independent executables
3361 need a relative reloc. */
3362 if (dyn_i
->want_fptr
&& !x
->info
->pie
)
3365 case R_IA64_PCREL32LSB
:
3366 case R_IA64_PCREL64LSB
:
3367 if (!dynamic_symbol
)
3370 case R_IA64_DIR32LSB
:
3371 case R_IA64_DIR64LSB
:
3372 if (!dynamic_symbol
&& !shared
)
3375 case R_IA64_IPLTLSB
:
3376 if (!dynamic_symbol
&& !shared
)
3378 /* Use two REL relocations for IPLT relocations
3379 against local symbols. */
3380 if (!dynamic_symbol
)
3383 case R_IA64_DTPREL32LSB
:
3384 case R_IA64_TPREL64LSB
:
3385 case R_IA64_DTPREL64LSB
:
3386 case R_IA64_DTPMOD64LSB
:
3392 ia64_info
->reltext
= 1;
3393 rent
->srel
->size
+= sizeof (ElfNN_External_Rela
) * count
;
3400 elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
3401 struct elf_link_hash_entry
*h
)
3403 /* ??? Undefined symbols with PLT entries should be re-defined
3404 to be the PLT entry. */
3406 /* If this is a weak symbol, and there is a real definition, the
3407 processor independent code will have arranged for us to see the
3408 real definition first, and we can just use the same value. */
3409 if (h
->u
.weakdef
!= NULL
)
3411 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
3412 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
3413 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
3414 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
3418 /* If this is a reference to a symbol defined by a dynamic object which
3419 is not a function, we might allocate the symbol in our .dynbss section
3420 and allocate a COPY dynamic relocation.
3422 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
3429 elfNN_ia64_size_dynamic_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
3430 struct bfd_link_info
*info
)
3432 struct elfNN_ia64_allocate_data data
;
3433 struct elfNN_ia64_link_hash_table
*ia64_info
;
3436 bfd_boolean relplt
= FALSE
;
3438 dynobj
= elf_hash_table(info
)->dynobj
;
3439 ia64_info
= elfNN_ia64_hash_table (info
);
3440 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
3441 BFD_ASSERT(dynobj
!= NULL
);
3444 /* Set the contents of the .interp section to the interpreter. */
3445 if (ia64_info
->root
.dynamic_sections_created
3446 && info
->executable
)
3448 sec
= bfd_get_section_by_name (dynobj
, ".interp");
3449 BFD_ASSERT (sec
!= NULL
);
3450 sec
->contents
= (bfd_byte
*) ELF_DYNAMIC_INTERPRETER
;
3451 sec
->size
= strlen (ELF_DYNAMIC_INTERPRETER
) + 1;
3454 /* Allocate the GOT entries. */
3456 if (ia64_info
->root
.sgot
)
3459 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
3460 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
3461 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
3462 ia64_info
->root
.sgot
->size
= data
.ofs
;
3465 /* Allocate the FPTR entries. */
3467 if (ia64_info
->fptr_sec
)
3470 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
3471 ia64_info
->fptr_sec
->size
= data
.ofs
;
3474 /* Now that we've seen all of the input files, we can decide which
3475 symbols need plt entries. Allocate the minimal PLT entries first.
3476 We do this even though dynamic_sections_created may be FALSE, because
3477 this has the side-effect of clearing want_plt and want_plt2. */
3480 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
3482 ia64_info
->minplt_entries
= 0;
3485 ia64_info
->minplt_entries
3486 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
3489 /* Align the pointer for the plt2 entries. */
3490 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
3492 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
3493 if (data
.ofs
!= 0 || ia64_info
->root
.dynamic_sections_created
)
3495 /* FIXME: we always reserve the memory for dynamic linker even if
3496 there are no PLT entries since dynamic linker may assume the
3497 reserved memory always exists. */
3499 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
3501 ia64_info
->root
.splt
->size
= data
.ofs
;
3503 /* If we've got a .plt, we need some extra memory for the dynamic
3504 linker. We stuff these in .got.plt. */
3505 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
3506 sec
->size
= 8 * PLT_RESERVED_WORDS
;
3509 /* Allocate the PLTOFF entries. */
3511 if (ia64_info
->pltoff_sec
)
3514 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
3515 ia64_info
->pltoff_sec
->size
= data
.ofs
;
3518 if (ia64_info
->root
.dynamic_sections_created
)
3520 /* Allocate space for the dynamic relocations that turned out to be
3523 if (info
->shared
&& ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
3524 ia64_info
->root
.srelgot
->size
+= sizeof (ElfNN_External_Rela
);
3525 data
.only_got
= FALSE
;
3526 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
3529 /* We have now determined the sizes of the various dynamic sections.
3530 Allocate memory for them. */
3531 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
3535 if (!(sec
->flags
& SEC_LINKER_CREATED
))
3538 /* If we don't need this section, strip it from the output file.
3539 There were several sections primarily related to dynamic
3540 linking that must be create before the linker maps input
3541 sections to output sections. The linker does that before
3542 bfd_elf_size_dynamic_sections is called, and it is that
3543 function which decides whether anything needs to go into
3546 strip
= (sec
->size
== 0);
3548 if (sec
== ia64_info
->root
.sgot
)
3550 else if (sec
== ia64_info
->root
.srelgot
)
3553 ia64_info
->root
.srelgot
= NULL
;
3555 /* We use the reloc_count field as a counter if we need to
3556 copy relocs into the output file. */
3557 sec
->reloc_count
= 0;
3559 else if (sec
== ia64_info
->fptr_sec
)
3562 ia64_info
->fptr_sec
= NULL
;
3564 else if (sec
== ia64_info
->rel_fptr_sec
)
3567 ia64_info
->rel_fptr_sec
= NULL
;
3569 /* We use the reloc_count field as a counter if we need to
3570 copy relocs into the output file. */
3571 sec
->reloc_count
= 0;
3573 else if (sec
== ia64_info
->root
.splt
)
3576 ia64_info
->root
.splt
= NULL
;
3578 else if (sec
== ia64_info
->pltoff_sec
)
3581 ia64_info
->pltoff_sec
= NULL
;
3583 else if (sec
== ia64_info
->rel_pltoff_sec
)
3586 ia64_info
->rel_pltoff_sec
= NULL
;
3590 /* We use the reloc_count field as a counter if we need to
3591 copy relocs into the output file. */
3592 sec
->reloc_count
= 0;
3599 /* It's OK to base decisions on the section name, because none
3600 of the dynobj section names depend upon the input files. */
3601 name
= bfd_get_section_name (dynobj
, sec
);
3603 if (strcmp (name
, ".got.plt") == 0)
3605 else if (CONST_STRNEQ (name
, ".rel"))
3609 /* We use the reloc_count field as a counter if we need to
3610 copy relocs into the output file. */
3611 sec
->reloc_count
= 0;
3619 sec
->flags
|= SEC_EXCLUDE
;
3622 /* Allocate memory for the section contents. */
3623 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->size
);
3624 if (sec
->contents
== NULL
&& sec
->size
!= 0)
3629 if (elf_hash_table (info
)->dynamic_sections_created
)
3631 /* Add some entries to the .dynamic section. We fill in the values
3632 later (in finish_dynamic_sections) but we must add the entries now
3633 so that we get the correct size for the .dynamic section. */
3635 if (info
->executable
)
3637 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3639 #define add_dynamic_entry(TAG, VAL) \
3640 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3642 if (!add_dynamic_entry (DT_DEBUG
, 0))
3646 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
3648 if (!add_dynamic_entry (DT_PLTGOT
, 0))
3653 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
3654 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
3655 || !add_dynamic_entry (DT_JMPREL
, 0))
3659 if (!add_dynamic_entry (DT_RELA
, 0)
3660 || !add_dynamic_entry (DT_RELASZ
, 0)
3661 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
3664 if (ia64_info
->reltext
)
3666 if (!add_dynamic_entry (DT_TEXTREL
, 0))
3668 info
->flags
|= DF_TEXTREL
;
3672 /* ??? Perhaps force __gp local. */
3677 static bfd_reloc_status_type
3678 elfNN_ia64_install_value (bfd_byte
*hit_addr
, bfd_vma v
,
3679 unsigned int r_type
)
3681 const struct ia64_operand
*op
;
3682 int bigendian
= 0, shift
= 0;
3683 bfd_vma t0
, t1
, dword
;
3685 enum ia64_opnd opnd
;
3688 #ifdef BFD_HOST_U_64_BIT
3689 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
3694 opnd
= IA64_OPND_NIL
;
3699 return bfd_reloc_ok
;
3701 /* Instruction relocations. */
3704 case R_IA64_TPREL14
:
3705 case R_IA64_DTPREL14
:
3706 opnd
= IA64_OPND_IMM14
;
3709 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
3710 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
3711 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
3712 case R_IA64_PCREL21B
:
3713 case R_IA64_PCREL21BI
:
3714 opnd
= IA64_OPND_TGT25c
;
3718 case R_IA64_GPREL22
:
3719 case R_IA64_LTOFF22
:
3720 case R_IA64_LTOFF22X
:
3721 case R_IA64_PLTOFF22
:
3722 case R_IA64_PCREL22
:
3723 case R_IA64_LTOFF_FPTR22
:
3724 case R_IA64_TPREL22
:
3725 case R_IA64_DTPREL22
:
3726 case R_IA64_LTOFF_TPREL22
:
3727 case R_IA64_LTOFF_DTPMOD22
:
3728 case R_IA64_LTOFF_DTPREL22
:
3729 opnd
= IA64_OPND_IMM22
;
3733 case R_IA64_GPREL64I
:
3734 case R_IA64_LTOFF64I
:
3735 case R_IA64_PLTOFF64I
:
3736 case R_IA64_PCREL64I
:
3737 case R_IA64_FPTR64I
:
3738 case R_IA64_LTOFF_FPTR64I
:
3739 case R_IA64_TPREL64I
:
3740 case R_IA64_DTPREL64I
:
3741 opnd
= IA64_OPND_IMMU64
;
3744 /* Data relocations. */
3746 case R_IA64_DIR32MSB
:
3747 case R_IA64_GPREL32MSB
:
3748 case R_IA64_FPTR32MSB
:
3749 case R_IA64_PCREL32MSB
:
3750 case R_IA64_LTOFF_FPTR32MSB
:
3751 case R_IA64_SEGREL32MSB
:
3752 case R_IA64_SECREL32MSB
:
3753 case R_IA64_LTV32MSB
:
3754 case R_IA64_DTPREL32MSB
:
3755 size
= 4; bigendian
= 1;
3758 case R_IA64_DIR32LSB
:
3759 case R_IA64_GPREL32LSB
:
3760 case R_IA64_FPTR32LSB
:
3761 case R_IA64_PCREL32LSB
:
3762 case R_IA64_LTOFF_FPTR32LSB
:
3763 case R_IA64_SEGREL32LSB
:
3764 case R_IA64_SECREL32LSB
:
3765 case R_IA64_LTV32LSB
:
3766 case R_IA64_DTPREL32LSB
:
3767 size
= 4; bigendian
= 0;
3770 case R_IA64_DIR64MSB
:
3771 case R_IA64_GPREL64MSB
:
3772 case R_IA64_PLTOFF64MSB
:
3773 case R_IA64_FPTR64MSB
:
3774 case R_IA64_PCREL64MSB
:
3775 case R_IA64_LTOFF_FPTR64MSB
:
3776 case R_IA64_SEGREL64MSB
:
3777 case R_IA64_SECREL64MSB
:
3778 case R_IA64_LTV64MSB
:
3779 case R_IA64_TPREL64MSB
:
3780 case R_IA64_DTPMOD64MSB
:
3781 case R_IA64_DTPREL64MSB
:
3782 size
= 8; bigendian
= 1;
3785 case R_IA64_DIR64LSB
:
3786 case R_IA64_GPREL64LSB
:
3787 case R_IA64_PLTOFF64LSB
:
3788 case R_IA64_FPTR64LSB
:
3789 case R_IA64_PCREL64LSB
:
3790 case R_IA64_LTOFF_FPTR64LSB
:
3791 case R_IA64_SEGREL64LSB
:
3792 case R_IA64_SECREL64LSB
:
3793 case R_IA64_LTV64LSB
:
3794 case R_IA64_TPREL64LSB
:
3795 case R_IA64_DTPMOD64LSB
:
3796 case R_IA64_DTPREL64LSB
:
3797 size
= 8; bigendian
= 0;
3800 /* Unsupported / Dynamic relocations. */
3802 return bfd_reloc_notsupported
;
3807 case IA64_OPND_IMMU64
:
3808 hit_addr
-= (long) hit_addr
& 0x3;
3809 t0
= bfd_getl64 (hit_addr
);
3810 t1
= bfd_getl64 (hit_addr
+ 8);
3812 /* tmpl/s: bits 0.. 5 in t0
3813 slot 0: bits 5..45 in t0
3814 slot 1: bits 46..63 in t0, bits 0..22 in t1
3815 slot 2: bits 23..63 in t1 */
3817 /* First, clear the bits that form the 64 bit constant. */
3818 t0
&= ~(0x3ffffLL
<< 46);
3820 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
3821 | (0x01fLL
<< 22) | (0x001LL
<< 21)
3822 | (0x001LL
<< 36)) << 23));
3824 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
3825 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
3826 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
3827 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
3828 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
3829 | (((val
>> 21) & 0x001) << 21) /* ic */
3830 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
3832 bfd_putl64 (t0
, hit_addr
);
3833 bfd_putl64 (t1
, hit_addr
+ 8);
3836 case IA64_OPND_TGT64
:
3837 hit_addr
-= (long) hit_addr
& 0x3;
3838 t0
= bfd_getl64 (hit_addr
);
3839 t1
= bfd_getl64 (hit_addr
+ 8);
3841 /* tmpl/s: bits 0.. 5 in t0
3842 slot 0: bits 5..45 in t0
3843 slot 1: bits 46..63 in t0, bits 0..22 in t1
3844 slot 2: bits 23..63 in t1 */
3846 /* First, clear the bits that form the 64 bit constant. */
3847 t0
&= ~(0x3ffffLL
<< 46);
3849 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
3852 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
3853 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
3854 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
3855 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
3857 bfd_putl64 (t0
, hit_addr
);
3858 bfd_putl64 (t1
, hit_addr
+ 8);
3862 switch ((long) hit_addr
& 0x3)
3864 case 0: shift
= 5; break;
3865 case 1: shift
= 14; hit_addr
+= 3; break;
3866 case 2: shift
= 23; hit_addr
+= 6; break;
3867 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
3869 dword
= bfd_getl64 (hit_addr
);
3870 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
3872 op
= elf64_ia64_operands
+ opnd
;
3873 err
= (*op
->insert
) (op
, val
, &insn
);
3875 return bfd_reloc_overflow
;
3877 dword
&= ~(0x1ffffffffffLL
<< shift
);
3878 dword
|= (insn
<< shift
);
3879 bfd_putl64 (dword
, hit_addr
);
3883 /* A data relocation. */
3886 bfd_putb32 (val
, hit_addr
);
3888 bfd_putb64 (val
, hit_addr
);
3891 bfd_putl32 (val
, hit_addr
);
3893 bfd_putl64 (val
, hit_addr
);
3897 return bfd_reloc_ok
;
3901 elfNN_ia64_install_dyn_reloc (bfd
*abfd
, struct bfd_link_info
*info
,
3902 asection
*sec
, asection
*srel
,
3903 bfd_vma offset
, unsigned int type
,
3904 long dynindx
, bfd_vma addend
)
3906 Elf_Internal_Rela outrel
;
3909 BFD_ASSERT (dynindx
!= -1);
3910 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3911 outrel
.r_addend
= addend
;
3912 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3913 if (outrel
.r_offset
>= (bfd_vma
) -2)
3915 /* Run for the hills. We shouldn't be outputting a relocation
3916 for this. So do what everyone else does and output a no-op. */
3917 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3918 outrel
.r_addend
= 0;
3919 outrel
.r_offset
= 0;
3922 outrel
.r_offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3924 loc
= srel
->contents
;
3925 loc
+= srel
->reloc_count
++ * sizeof (ElfNN_External_Rela
);
3926 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
3927 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
<= srel
->size
);
3930 /* Store an entry for target address TARGET_ADDR in the linkage table
3931 and return the gp-relative address of the linkage table entry. */
3934 set_got_entry (bfd
*abfd
, struct bfd_link_info
*info
,
3935 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3936 long dynindx
, bfd_vma addend
, bfd_vma value
,
3937 unsigned int dyn_r_type
)
3939 struct elfNN_ia64_link_hash_table
*ia64_info
;
3944 ia64_info
= elfNN_ia64_hash_table (info
);
3945 got_sec
= ia64_info
->root
.sgot
;
3949 case R_IA64_TPREL64LSB
:
3950 done
= dyn_i
->tprel_done
;
3951 dyn_i
->tprel_done
= TRUE
;
3952 got_offset
= dyn_i
->tprel_offset
;
3954 case R_IA64_DTPMOD64LSB
:
3955 if (dyn_i
->dtpmod_offset
!= ia64_info
->self_dtpmod_offset
)
3957 done
= dyn_i
->dtpmod_done
;
3958 dyn_i
->dtpmod_done
= TRUE
;
3962 done
= ia64_info
->self_dtpmod_done
;
3963 ia64_info
->self_dtpmod_done
= TRUE
;
3966 got_offset
= dyn_i
->dtpmod_offset
;
3968 case R_IA64_DTPREL32LSB
:
3969 case R_IA64_DTPREL64LSB
:
3970 done
= dyn_i
->dtprel_done
;
3971 dyn_i
->dtprel_done
= TRUE
;
3972 got_offset
= dyn_i
->dtprel_offset
;
3975 done
= dyn_i
->got_done
;
3976 dyn_i
->got_done
= TRUE
;
3977 got_offset
= dyn_i
->got_offset
;
3981 BFD_ASSERT ((got_offset
& 7) == 0);
3985 /* Store the target address in the linkage table entry. */
3986 bfd_put_64 (abfd
, value
, got_sec
->contents
+ got_offset
);
3988 /* Install a dynamic relocation if needed. */
3991 || ELF_ST_VISIBILITY (dyn_i
->h
->other
) == STV_DEFAULT
3992 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
3993 && dyn_r_type
!= R_IA64_DTPREL32LSB
3994 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
3995 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
, dyn_r_type
)
3997 && (dyn_r_type
== R_IA64_FPTR32LSB
3998 || dyn_r_type
== R_IA64_FPTR64LSB
)))
3999 && (!dyn_i
->want_ltoff_fptr
4002 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
))
4005 && dyn_r_type
!= R_IA64_TPREL64LSB
4006 && dyn_r_type
!= R_IA64_DTPMOD64LSB
4007 && dyn_r_type
!= R_IA64_DTPREL32LSB
4008 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
4010 dyn_r_type
= R_IA64_RELNNLSB
;
4015 if (bfd_big_endian (abfd
))
4019 case R_IA64_REL32LSB
:
4020 dyn_r_type
= R_IA64_REL32MSB
;
4022 case R_IA64_DIR32LSB
:
4023 dyn_r_type
= R_IA64_DIR32MSB
;
4025 case R_IA64_FPTR32LSB
:
4026 dyn_r_type
= R_IA64_FPTR32MSB
;
4028 case R_IA64_DTPREL32LSB
:
4029 dyn_r_type
= R_IA64_DTPREL32MSB
;
4031 case R_IA64_REL64LSB
:
4032 dyn_r_type
= R_IA64_REL64MSB
;
4034 case R_IA64_DIR64LSB
:
4035 dyn_r_type
= R_IA64_DIR64MSB
;
4037 case R_IA64_FPTR64LSB
:
4038 dyn_r_type
= R_IA64_FPTR64MSB
;
4040 case R_IA64_TPREL64LSB
:
4041 dyn_r_type
= R_IA64_TPREL64MSB
;
4043 case R_IA64_DTPMOD64LSB
:
4044 dyn_r_type
= R_IA64_DTPMOD64MSB
;
4046 case R_IA64_DTPREL64LSB
:
4047 dyn_r_type
= R_IA64_DTPREL64MSB
;
4055 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
4056 ia64_info
->root
.srelgot
,
4057 got_offset
, dyn_r_type
,
4062 /* Return the address of the linkage table entry. */
4063 value
= (got_sec
->output_section
->vma
4064 + got_sec
->output_offset
4070 /* Fill in a function descriptor consisting of the function's code
4071 address and its global pointer. Return the descriptor's address. */
4074 set_fptr_entry (bfd
*abfd
, struct bfd_link_info
*info
,
4075 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
4078 struct elfNN_ia64_link_hash_table
*ia64_info
;
4081 ia64_info
= elfNN_ia64_hash_table (info
);
4082 fptr_sec
= ia64_info
->fptr_sec
;
4084 if (!dyn_i
->fptr_done
)
4086 dyn_i
->fptr_done
= 1;
4088 /* Fill in the function descriptor. */
4089 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
4090 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
4091 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
4092 if (ia64_info
->rel_fptr_sec
)
4094 Elf_Internal_Rela outrel
;
4097 if (bfd_little_endian (abfd
))
4098 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_IPLTLSB
);
4100 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_IPLTMSB
);
4101 outrel
.r_addend
= value
;
4102 outrel
.r_offset
= (fptr_sec
->output_section
->vma
4103 + fptr_sec
->output_offset
4104 + dyn_i
->fptr_offset
);
4105 loc
= ia64_info
->rel_fptr_sec
->contents
;
4106 loc
+= ia64_info
->rel_fptr_sec
->reloc_count
++
4107 * sizeof (ElfNN_External_Rela
);
4108 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
4112 /* Return the descriptor's address. */
4113 value
= (fptr_sec
->output_section
->vma
4114 + fptr_sec
->output_offset
4115 + dyn_i
->fptr_offset
);
4120 /* Fill in a PLTOFF entry consisting of the function's code address
4121 and its global pointer. Return the descriptor's address. */
4124 set_pltoff_entry (bfd
*abfd
, struct bfd_link_info
*info
,
4125 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
4126 bfd_vma value
, bfd_boolean is_plt
)
4128 struct elfNN_ia64_link_hash_table
*ia64_info
;
4129 asection
*pltoff_sec
;
4131 ia64_info
= elfNN_ia64_hash_table (info
);
4132 pltoff_sec
= ia64_info
->pltoff_sec
;
4134 /* Don't do anything if this symbol uses a real PLT entry. In
4135 that case, we'll fill this in during finish_dynamic_symbol. */
4136 if ((! dyn_i
->want_plt
|| is_plt
)
4137 && !dyn_i
->pltoff_done
)
4139 bfd_vma gp
= _bfd_get_gp_value (abfd
);
4141 /* Fill in the function descriptor. */
4142 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
4143 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
4145 /* Install dynamic relocations if needed. */
4149 || ELF_ST_VISIBILITY (dyn_i
->h
->other
) == STV_DEFAULT
4150 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
))
4152 unsigned int dyn_r_type
;
4154 if (bfd_big_endian (abfd
))
4155 dyn_r_type
= R_IA64_RELNNMSB
;
4157 dyn_r_type
= R_IA64_RELNNLSB
;
4159 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
4160 ia64_info
->rel_pltoff_sec
,
4161 dyn_i
->pltoff_offset
,
4162 dyn_r_type
, 0, value
);
4163 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
4164 ia64_info
->rel_pltoff_sec
,
4165 dyn_i
->pltoff_offset
+ ARCH_SIZE
/ 8,
4169 dyn_i
->pltoff_done
= 1;
4172 /* Return the descriptor's address. */
4173 value
= (pltoff_sec
->output_section
->vma
4174 + pltoff_sec
->output_offset
4175 + dyn_i
->pltoff_offset
);
4180 /* Return the base VMA address which should be subtracted from real addresses
4181 when resolving @tprel() relocation.
4182 Main program TLS (whose template starts at PT_TLS p_vaddr)
4183 is assigned offset round(2 * size of pointer, PT_TLS p_align). */
4186 elfNN_ia64_tprel_base (struct bfd_link_info
*info
)
4188 asection
*tls_sec
= elf_hash_table (info
)->tls_sec
;
4189 return tls_sec
->vma
- align_power ((bfd_vma
) ARCH_SIZE
/ 4,
4190 tls_sec
->alignment_power
);
4193 /* Return the base VMA address which should be subtracted from real addresses
4194 when resolving @dtprel() relocation.
4195 This is PT_TLS segment p_vaddr. */
4198 elfNN_ia64_dtprel_base (struct bfd_link_info
*info
)
4200 return elf_hash_table (info
)->tls_sec
->vma
;
4203 /* Called through qsort to sort the .IA_64.unwind section during a
4204 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
4205 to the output bfd so we can do proper endianness frobbing. */
4207 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
4210 elfNN_ia64_unwind_entry_compare (const PTR a
, const PTR b
)
4214 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
4215 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
4217 return (av
< bv
? -1 : av
> bv
? 1 : 0);
4220 /* Make sure we've got ourselves a nice fat __gp value. */
4222 elfNN_ia64_choose_gp (bfd
*abfd
, struct bfd_link_info
*info
)
4224 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
4225 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
4226 struct elf_link_hash_entry
*gp
;
4229 struct elfNN_ia64_link_hash_table
*ia64_info
;
4231 ia64_info
= elfNN_ia64_hash_table (info
);
4233 /* Find the min and max vma of all sections marked short. Also collect
4234 min and max vma of any type, for use in selecting a nice gp. */
4235 for (os
= abfd
->sections
; os
; os
= os
->next
)
4239 if ((os
->flags
& SEC_ALLOC
) == 0)
4243 hi
= os
->vma
+ (os
->rawsize
? os
->rawsize
: os
->size
);
4251 if (os
->flags
& SEC_SMALL_DATA
)
4253 if (min_short_vma
> lo
)
4255 if (max_short_vma
< hi
)
4260 /* See if the user wants to force a value. */
4261 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
4265 && (gp
->root
.type
== bfd_link_hash_defined
4266 || gp
->root
.type
== bfd_link_hash_defweak
))
4268 asection
*gp_sec
= gp
->root
.u
.def
.section
;
4269 gp_val
= (gp
->root
.u
.def
.value
4270 + gp_sec
->output_section
->vma
4271 + gp_sec
->output_offset
);
4275 /* Pick a sensible value. */
4277 asection
*got_sec
= ia64_info
->root
.sgot
;
4279 /* Start with just the address of the .got. */
4281 gp_val
= got_sec
->output_section
->vma
;
4282 else if (max_short_vma
!= 0)
4283 gp_val
= min_short_vma
;
4284 else if (max_vma
- min_vma
< 0x200000)
4287 gp_val
= max_vma
- 0x200000 + 8;
4289 /* If it is possible to address the entire image, but we
4290 don't with the choice above, adjust. */
4291 if (max_vma
- min_vma
< 0x400000
4292 && (max_vma
- gp_val
>= 0x200000
4293 || gp_val
- min_vma
> 0x200000))
4294 gp_val
= min_vma
+ 0x200000;
4295 else if (max_short_vma
!= 0)
4297 /* If we don't cover all the short data, adjust. */
4298 if (max_short_vma
- gp_val
>= 0x200000)
4299 gp_val
= min_short_vma
+ 0x200000;
4301 /* If we're addressing stuff past the end, adjust back. */
4302 if (gp_val
> max_vma
)
4303 gp_val
= max_vma
- 0x200000 + 8;
4307 /* Validate whether all SHF_IA_64_SHORT sections are within
4308 range of the chosen GP. */
4310 if (max_short_vma
!= 0)
4312 if (max_short_vma
- min_short_vma
>= 0x400000)
4314 (*_bfd_error_handler
)
4315 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
4316 bfd_get_filename (abfd
),
4317 (unsigned long) (max_short_vma
- min_short_vma
));
4320 else if ((gp_val
> min_short_vma
4321 && gp_val
- min_short_vma
> 0x200000)
4322 || (gp_val
< max_short_vma
4323 && max_short_vma
- gp_val
>= 0x200000))
4325 (*_bfd_error_handler
)
4326 (_("%s: __gp does not cover short data segment"),
4327 bfd_get_filename (abfd
));
4332 _bfd_set_gp_value (abfd
, gp_val
);
4338 elfNN_ia64_final_link (bfd
*abfd
, struct bfd_link_info
*info
)
4340 struct elfNN_ia64_link_hash_table
*ia64_info
;
4341 asection
*unwind_output_sec
;
4343 ia64_info
= elfNN_ia64_hash_table (info
);
4345 /* Make sure we've got ourselves a nice fat __gp value. */
4346 if (!info
->relocatable
)
4349 struct elf_link_hash_entry
*gp
;
4351 /* We assume after gp is set, section size will only decrease. We
4352 need to adjust gp for it. */
4353 _bfd_set_gp_value (abfd
, 0);
4354 if (! elfNN_ia64_choose_gp (abfd
, info
))
4356 gp_val
= _bfd_get_gp_value (abfd
);
4358 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
4362 gp
->root
.type
= bfd_link_hash_defined
;
4363 gp
->root
.u
.def
.value
= gp_val
;
4364 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
4368 /* If we're producing a final executable, we need to sort the contents
4369 of the .IA_64.unwind section. Force this section to be relocated
4370 into memory rather than written immediately to the output file. */
4371 unwind_output_sec
= NULL
;
4372 if (!info
->relocatable
)
4374 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
4377 unwind_output_sec
= s
->output_section
;
4378 unwind_output_sec
->contents
4379 = bfd_malloc (unwind_output_sec
->size
);
4380 if (unwind_output_sec
->contents
== NULL
)
4385 /* Invoke the regular ELF backend linker to do all the work. */
4386 if (!bfd_elf_final_link (abfd
, info
))
4389 if (unwind_output_sec
)
4391 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
4392 qsort (unwind_output_sec
->contents
,
4393 (size_t) (unwind_output_sec
->size
/ 24),
4395 elfNN_ia64_unwind_entry_compare
);
4397 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
4398 unwind_output_sec
->contents
, (bfd_vma
) 0,
4399 unwind_output_sec
->size
))
4407 elfNN_ia64_relocate_section (bfd
*output_bfd
,
4408 struct bfd_link_info
*info
,
4410 asection
*input_section
,
4412 Elf_Internal_Rela
*relocs
,
4413 Elf_Internal_Sym
*local_syms
,
4414 asection
**local_sections
)
4416 struct elfNN_ia64_link_hash_table
*ia64_info
;
4417 Elf_Internal_Shdr
*symtab_hdr
;
4418 Elf_Internal_Rela
*rel
;
4419 Elf_Internal_Rela
*relend
;
4421 bfd_boolean ret_val
= TRUE
; /* for non-fatal errors */
4424 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
4425 ia64_info
= elfNN_ia64_hash_table (info
);
4427 /* Infect various flags from the input section to the output section. */
4428 if (info
->relocatable
)
4432 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
4433 flags
&= SHF_IA_64_NORECOV
;
4435 elf_section_data(input_section
->output_section
)
4436 ->this_hdr
.sh_flags
|= flags
;
4439 gp_val
= _bfd_get_gp_value (output_bfd
);
4440 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, FALSE
);
4443 relend
= relocs
+ input_section
->reloc_count
;
4444 for (; rel
< relend
; ++rel
)
4446 struct elf_link_hash_entry
*h
;
4447 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4448 bfd_reloc_status_type r
;
4449 reloc_howto_type
*howto
;
4450 unsigned long r_symndx
;
4451 Elf_Internal_Sym
*sym
;
4452 unsigned int r_type
;
4456 bfd_boolean dynamic_symbol_p
;
4457 bfd_boolean undef_weak_ref
;
4459 r_type
= ELFNN_R_TYPE (rel
->r_info
);
4460 if (r_type
> R_IA64_MAX_RELOC_CODE
)
4462 (*_bfd_error_handler
)
4463 (_("%B: unknown relocation type %d"),
4464 input_bfd
, (int) r_type
);
4465 bfd_set_error (bfd_error_bad_value
);
4470 howto
= lookup_howto (r_type
);
4471 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4475 undef_weak_ref
= FALSE
;
4477 if (r_symndx
< symtab_hdr
->sh_info
)
4479 /* Reloc against local symbol. */
4481 sym
= local_syms
+ r_symndx
;
4482 sym_sec
= local_sections
[r_symndx
];
4484 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &msec
, rel
);
4485 if (!info
->relocatable
4486 && (sym_sec
->flags
& SEC_MERGE
) != 0
4487 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
4488 && sym_sec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
4490 struct elfNN_ia64_local_hash_entry
*loc_h
;
4492 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, FALSE
);
4493 if (loc_h
&& ! loc_h
->sec_merge_done
)
4495 struct elfNN_ia64_dyn_sym_info
*dynent
;
4498 for (count
= loc_h
->count
, dynent
= loc_h
->info
;
4504 _bfd_merged_section_offset (output_bfd
, &msec
,
4505 elf_section_data (msec
)->
4509 dynent
->addend
-= sym
->st_value
;
4510 dynent
->addend
+= msec
->output_section
->vma
4511 + msec
->output_offset
4512 - sym_sec
->output_section
->vma
4513 - sym_sec
->output_offset
;
4516 /* We may have introduced duplicated entries. We need
4517 to remove them properly. */
4518 count
= sort_dyn_sym_info (loc_h
->info
, loc_h
->count
);
4519 if (count
!= loc_h
->count
)
4521 loc_h
->count
= count
;
4522 loc_h
->sorted_count
= count
;
4525 loc_h
->sec_merge_done
= 1;
4531 bfd_boolean unresolved_reloc
;
4533 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
4535 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
4536 r_symndx
, symtab_hdr
, sym_hashes
,
4538 unresolved_reloc
, warned
);
4540 if (h
->root
.type
== bfd_link_hash_undefweak
)
4541 undef_weak_ref
= TRUE
;
4546 /* For relocs against symbols from removed linkonce sections,
4547 or sections discarded by a linker script, we just want the
4548 section contents zeroed. Avoid any special processing. */
4549 if (sym_sec
!= NULL
&& elf_discarded_section (sym_sec
))
4551 _bfd_clear_contents (howto
, input_bfd
, contents
+ rel
->r_offset
);
4557 if (info
->relocatable
)
4560 hit_addr
= contents
+ rel
->r_offset
;
4561 value
+= rel
->r_addend
;
4562 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
, r_type
);
4573 case R_IA64_DIR32MSB
:
4574 case R_IA64_DIR32LSB
:
4575 case R_IA64_DIR64MSB
:
4576 case R_IA64_DIR64LSB
:
4577 /* Install a dynamic relocation for this reloc. */
4578 if ((dynamic_symbol_p
|| info
->shared
)
4580 && (input_section
->flags
& SEC_ALLOC
) != 0)
4582 unsigned int dyn_r_type
;
4586 BFD_ASSERT (srel
!= NULL
);
4593 /* ??? People shouldn't be doing non-pic code in
4594 shared libraries nor dynamic executables. */
4595 (*_bfd_error_handler
)
4596 (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4598 h
? h
->root
.root
.string
4599 : bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4608 /* If we don't need dynamic symbol lookup, find a
4609 matching RELATIVE relocation. */
4610 dyn_r_type
= r_type
;
4611 if (dynamic_symbol_p
)
4613 dynindx
= h
->dynindx
;
4614 addend
= rel
->r_addend
;
4621 case R_IA64_DIR32MSB
:
4622 dyn_r_type
= R_IA64_REL32MSB
;
4624 case R_IA64_DIR32LSB
:
4625 dyn_r_type
= R_IA64_REL32LSB
;
4627 case R_IA64_DIR64MSB
:
4628 dyn_r_type
= R_IA64_REL64MSB
;
4630 case R_IA64_DIR64LSB
:
4631 dyn_r_type
= R_IA64_REL64LSB
;
4641 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4642 srel
, rel
->r_offset
, dyn_r_type
,
4647 case R_IA64_LTV32MSB
:
4648 case R_IA64_LTV32LSB
:
4649 case R_IA64_LTV64MSB
:
4650 case R_IA64_LTV64LSB
:
4651 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4654 case R_IA64_GPREL22
:
4655 case R_IA64_GPREL64I
:
4656 case R_IA64_GPREL32MSB
:
4657 case R_IA64_GPREL32LSB
:
4658 case R_IA64_GPREL64MSB
:
4659 case R_IA64_GPREL64LSB
:
4660 if (dynamic_symbol_p
)
4662 (*_bfd_error_handler
)
4663 (_("%B: @gprel relocation against dynamic symbol %s"),
4665 h
? h
->root
.root
.string
4666 : bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4672 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4675 case R_IA64_LTOFF22
:
4676 case R_IA64_LTOFF22X
:
4677 case R_IA64_LTOFF64I
:
4678 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4679 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
4680 rel
->r_addend
, value
, R_IA64_DIRNNLSB
);
4682 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4685 case R_IA64_PLTOFF22
:
4686 case R_IA64_PLTOFF64I
:
4687 case R_IA64_PLTOFF64MSB
:
4688 case R_IA64_PLTOFF64LSB
:
4689 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4690 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, FALSE
);
4692 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4695 case R_IA64_FPTR64I
:
4696 case R_IA64_FPTR32MSB
:
4697 case R_IA64_FPTR32LSB
:
4698 case R_IA64_FPTR64MSB
:
4699 case R_IA64_FPTR64LSB
:
4700 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4701 if (dyn_i
->want_fptr
)
4703 if (!undef_weak_ref
)
4704 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4706 if (!dyn_i
->want_fptr
|| info
->pie
)
4709 unsigned int dyn_r_type
= r_type
;
4710 bfd_vma addend
= rel
->r_addend
;
4712 /* Otherwise, we expect the dynamic linker to create
4715 if (dyn_i
->want_fptr
)
4717 if (r_type
== R_IA64_FPTR64I
)
4719 /* We can't represent this without a dynamic symbol.
4720 Adjust the relocation to be against an output
4721 section symbol, which are always present in the
4722 dynamic symbol table. */
4723 /* ??? People shouldn't be doing non-pic code in
4724 shared libraries. Hork. */
4725 (*_bfd_error_handler
)
4726 (_("%B: linking non-pic code in a position independent executable"),
4733 dyn_r_type
= r_type
+ R_IA64_RELNNLSB
- R_IA64_FPTRNNLSB
;
4737 if (h
->dynindx
!= -1)
4738 dynindx
= h
->dynindx
;
4740 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4741 (info
, h
->root
.u
.def
.section
->owner
,
4742 global_sym_index (h
)));
4747 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4748 (info
, input_bfd
, (long) r_symndx
));
4752 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4753 srel
, rel
->r_offset
, dyn_r_type
,
4757 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4760 case R_IA64_LTOFF_FPTR22
:
4761 case R_IA64_LTOFF_FPTR64I
:
4762 case R_IA64_LTOFF_FPTR32MSB
:
4763 case R_IA64_LTOFF_FPTR32LSB
:
4764 case R_IA64_LTOFF_FPTR64MSB
:
4765 case R_IA64_LTOFF_FPTR64LSB
:
4769 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4770 if (dyn_i
->want_fptr
)
4772 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1);
4773 if (!undef_weak_ref
)
4774 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4779 /* Otherwise, we expect the dynamic linker to create
4783 if (h
->dynindx
!= -1)
4784 dynindx
= h
->dynindx
;
4786 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4787 (info
, h
->root
.u
.def
.section
->owner
,
4788 global_sym_index (h
)));
4791 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4792 (info
, input_bfd
, (long) r_symndx
));
4796 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
4797 rel
->r_addend
, value
, R_IA64_FPTRNNLSB
);
4799 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4803 case R_IA64_PCREL32MSB
:
4804 case R_IA64_PCREL32LSB
:
4805 case R_IA64_PCREL64MSB
:
4806 case R_IA64_PCREL64LSB
:
4807 /* Install a dynamic relocation for this reloc. */
4808 if (dynamic_symbol_p
&& r_symndx
!= 0)
4810 BFD_ASSERT (srel
!= NULL
);
4812 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4813 srel
, rel
->r_offset
, r_type
,
4814 h
->dynindx
, rel
->r_addend
);
4818 case R_IA64_PCREL21B
:
4819 case R_IA64_PCREL60B
:
4820 /* We should have created a PLT entry for any dynamic symbol. */
4823 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4825 if (dyn_i
&& dyn_i
->want_plt2
)
4827 /* Should have caught this earlier. */
4828 BFD_ASSERT (rel
->r_addend
== 0);
4830 value
= (ia64_info
->root
.splt
->output_section
->vma
4831 + ia64_info
->root
.splt
->output_offset
4832 + dyn_i
->plt2_offset
);
4836 /* Since there's no PLT entry, Validate that this is
4838 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
4840 /* If the symbol is undef_weak, we shouldn't be trying
4841 to call it. There's every chance that we'd wind up
4842 with an out-of-range fixup here. Don't bother setting
4843 any value at all. */
4849 case R_IA64_PCREL21BI
:
4850 case R_IA64_PCREL21F
:
4851 case R_IA64_PCREL21M
:
4852 case R_IA64_PCREL22
:
4853 case R_IA64_PCREL64I
:
4854 /* The PCREL21BI reloc is specifically not intended for use with
4855 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4856 fixup code, and thus probably ought not be dynamic. The
4857 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4858 if (dynamic_symbol_p
)
4862 if (r_type
== R_IA64_PCREL21BI
)
4863 msg
= _("%B: @internal branch to dynamic symbol %s");
4864 else if (r_type
== R_IA64_PCREL21F
|| r_type
== R_IA64_PCREL21M
)
4865 msg
= _("%B: speculation fixup to dynamic symbol %s");
4867 msg
= _("%B: @pcrel relocation against dynamic symbol %s");
4868 (*_bfd_error_handler
) (msg
, input_bfd
,
4869 h
? h
->root
.root
.string
4870 : bfd_elf_sym_name (input_bfd
,
4880 /* Make pc-relative. */
4881 value
-= (input_section
->output_section
->vma
4882 + input_section
->output_offset
4883 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
4884 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4887 case R_IA64_SEGREL32MSB
:
4888 case R_IA64_SEGREL32LSB
:
4889 case R_IA64_SEGREL64MSB
:
4890 case R_IA64_SEGREL64LSB
:
4892 /* Find the segment that contains the output_section. */
4893 Elf_Internal_Phdr
*p
= _bfd_elf_find_segment_containing_section
4894 (output_bfd
, input_section
->output_section
);
4898 r
= bfd_reloc_notsupported
;
4902 /* The VMA of the segment is the vaddr of the associated
4904 if (value
> p
->p_vaddr
)
4905 value
-= p
->p_vaddr
;
4908 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4913 case R_IA64_SECREL32MSB
:
4914 case R_IA64_SECREL32LSB
:
4915 case R_IA64_SECREL64MSB
:
4916 case R_IA64_SECREL64LSB
:
4917 /* Make output-section relative to section where the symbol
4918 is defined. PR 475 */
4920 value
-= sym_sec
->output_section
->vma
;
4921 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4924 case R_IA64_IPLTMSB
:
4925 case R_IA64_IPLTLSB
:
4926 /* Install a dynamic relocation for this reloc. */
4927 if ((dynamic_symbol_p
|| info
->shared
)
4928 && (input_section
->flags
& SEC_ALLOC
) != 0)
4930 BFD_ASSERT (srel
!= NULL
);
4932 /* If we don't need dynamic symbol lookup, install two
4933 RELATIVE relocations. */
4934 if (!dynamic_symbol_p
)
4936 unsigned int dyn_r_type
;
4938 if (r_type
== R_IA64_IPLTMSB
)
4939 dyn_r_type
= R_IA64_REL64MSB
;
4941 dyn_r_type
= R_IA64_REL64LSB
;
4943 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4945 srel
, rel
->r_offset
,
4946 dyn_r_type
, 0, value
);
4947 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4949 srel
, rel
->r_offset
+ 8,
4950 dyn_r_type
, 0, gp_val
);
4953 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4954 srel
, rel
->r_offset
, r_type
,
4955 h
->dynindx
, rel
->r_addend
);
4958 if (r_type
== R_IA64_IPLTMSB
)
4959 r_type
= R_IA64_DIR64MSB
;
4961 r_type
= R_IA64_DIR64LSB
;
4962 elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4963 r
= elfNN_ia64_install_value (hit_addr
+ 8, gp_val
, r_type
);
4966 case R_IA64_TPREL14
:
4967 case R_IA64_TPREL22
:
4968 case R_IA64_TPREL64I
:
4969 if (elf_hash_table (info
)->tls_sec
== NULL
)
4970 goto missing_tls_sec
;
4971 value
-= elfNN_ia64_tprel_base (info
);
4972 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4975 case R_IA64_DTPREL14
:
4976 case R_IA64_DTPREL22
:
4977 case R_IA64_DTPREL64I
:
4978 case R_IA64_DTPREL32LSB
:
4979 case R_IA64_DTPREL32MSB
:
4980 case R_IA64_DTPREL64LSB
:
4981 case R_IA64_DTPREL64MSB
:
4982 if (elf_hash_table (info
)->tls_sec
== NULL
)
4983 goto missing_tls_sec
;
4984 value
-= elfNN_ia64_dtprel_base (info
);
4985 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4988 case R_IA64_LTOFF_TPREL22
:
4989 case R_IA64_LTOFF_DTPMOD22
:
4990 case R_IA64_LTOFF_DTPREL22
:
4993 long dynindx
= h
? h
->dynindx
: -1;
4994 bfd_vma r_addend
= rel
->r_addend
;
4999 case R_IA64_LTOFF_TPREL22
:
5000 if (!dynamic_symbol_p
)
5002 if (elf_hash_table (info
)->tls_sec
== NULL
)
5003 goto missing_tls_sec
;
5005 value
-= elfNN_ia64_tprel_base (info
);
5008 r_addend
+= value
- elfNN_ia64_dtprel_base (info
);
5012 got_r_type
= R_IA64_TPREL64LSB
;
5014 case R_IA64_LTOFF_DTPMOD22
:
5015 if (!dynamic_symbol_p
&& !info
->shared
)
5017 got_r_type
= R_IA64_DTPMOD64LSB
;
5019 case R_IA64_LTOFF_DTPREL22
:
5020 if (!dynamic_symbol_p
)
5022 if (elf_hash_table (info
)->tls_sec
== NULL
)
5023 goto missing_tls_sec
;
5024 value
-= elfNN_ia64_dtprel_base (info
);
5026 got_r_type
= R_IA64_DTPRELNNLSB
;
5029 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
5030 value
= set_got_entry (input_bfd
, info
, dyn_i
, dynindx
, r_addend
,
5033 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5038 r
= bfd_reloc_notsupported
;
5047 case bfd_reloc_undefined
:
5048 /* This can happen for global table relative relocs if
5049 __gp is undefined. This is a panic situation so we
5050 don't try to continue. */
5051 (*info
->callbacks
->undefined_symbol
)
5052 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
5055 case bfd_reloc_notsupported
:
5060 name
= h
->root
.root
.string
;
5062 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
5064 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
5066 input_section
, rel
->r_offset
))
5072 case bfd_reloc_dangerous
:
5073 case bfd_reloc_outofrange
:
5074 case bfd_reloc_overflow
:
5081 name
= h
->root
.root
.string
;
5083 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
5088 case R_IA64_TPREL14
:
5089 case R_IA64_TPREL22
:
5090 case R_IA64_TPREL64I
:
5091 case R_IA64_DTPREL14
:
5092 case R_IA64_DTPREL22
:
5093 case R_IA64_DTPREL64I
:
5094 case R_IA64_DTPREL32LSB
:
5095 case R_IA64_DTPREL32MSB
:
5096 case R_IA64_DTPREL64LSB
:
5097 case R_IA64_DTPREL64MSB
:
5098 case R_IA64_LTOFF_TPREL22
:
5099 case R_IA64_LTOFF_DTPMOD22
:
5100 case R_IA64_LTOFF_DTPREL22
:
5101 (*_bfd_error_handler
)
5102 (_("%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."),
5103 input_bfd
, input_section
, howto
->name
, name
,
5107 case R_IA64_PCREL21B
:
5108 case R_IA64_PCREL21BI
:
5109 case R_IA64_PCREL21M
:
5110 case R_IA64_PCREL21F
:
5111 if (is_elf_hash_table (info
->hash
))
5113 /* Relaxtion is always performed for ELF output.
5114 Overflow failures for those relocations mean
5115 that the section is too big to relax. */
5116 (*_bfd_error_handler
)
5117 (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
5118 input_bfd
, input_section
, howto
->name
, name
,
5119 rel
->r_offset
, input_section
->size
);
5123 if (!(*info
->callbacks
->reloc_overflow
) (info
,
5145 elfNN_ia64_finish_dynamic_symbol (bfd
*output_bfd
,
5146 struct bfd_link_info
*info
,
5147 struct elf_link_hash_entry
*h
,
5148 Elf_Internal_Sym
*sym
)
5150 struct elfNN_ia64_link_hash_table
*ia64_info
;
5151 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
5153 ia64_info
= elfNN_ia64_hash_table (info
);
5154 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
5156 /* Fill in the PLT data, if required. */
5157 if (dyn_i
&& dyn_i
->want_plt
)
5159 Elf_Internal_Rela outrel
;
5162 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
5164 gp_val
= _bfd_get_gp_value (output_bfd
);
5166 /* Initialize the minimal PLT entry. */
5168 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
5169 plt_sec
= ia64_info
->root
.splt
;
5170 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
5172 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
5173 elfNN_ia64_install_value (loc
, index
, R_IA64_IMM22
);
5174 elfNN_ia64_install_value (loc
+2, -dyn_i
->plt_offset
, R_IA64_PCREL21B
);
5176 plt_addr
= (plt_sec
->output_section
->vma
5177 + plt_sec
->output_offset
5178 + dyn_i
->plt_offset
);
5179 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, TRUE
);
5181 /* Initialize the FULL PLT entry, if needed. */
5182 if (dyn_i
->want_plt2
)
5184 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
5186 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
5187 elfNN_ia64_install_value (loc
, pltoff_addr
- gp_val
, R_IA64_IMM22
);
5189 /* Mark the symbol as undefined, rather than as defined in the
5190 plt section. Leave the value alone. */
5191 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
5192 first place. But perhaps elflink.c did some for us. */
5193 if (!h
->def_regular
)
5194 sym
->st_shndx
= SHN_UNDEF
;
5197 /* Create the dynamic relocation. */
5198 outrel
.r_offset
= pltoff_addr
;
5199 if (bfd_little_endian (output_bfd
))
5200 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
5202 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
5203 outrel
.r_addend
= 0;
5205 /* This is fun. In the .IA_64.pltoff section, we've got entries
5206 that correspond both to real PLT entries, and those that
5207 happened to resolve to local symbols but need to be created
5208 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
5209 relocations for the real PLT should come at the end of the
5210 section, so that they can be indexed by plt entry at runtime.
5212 We emitted all of the relocations for the non-PLT @pltoff
5213 entries during relocate_section. So we can consider the
5214 existing sec->reloc_count to be the base of the array of
5217 loc
= ia64_info
->rel_pltoff_sec
->contents
;
5218 loc
+= ((ia64_info
->rel_pltoff_sec
->reloc_count
+ index
)
5219 * sizeof (ElfNN_External_Rela
));
5220 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
5223 /* Mark some specially defined symbols as absolute. */
5224 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
5225 || h
== ia64_info
->root
.hgot
5226 || h
== ia64_info
->root
.hplt
)
5227 sym
->st_shndx
= SHN_ABS
;
5233 elfNN_ia64_finish_dynamic_sections (bfd
*abfd
,
5234 struct bfd_link_info
*info
)
5236 struct elfNN_ia64_link_hash_table
*ia64_info
;
5239 ia64_info
= elfNN_ia64_hash_table (info
);
5240 dynobj
= ia64_info
->root
.dynobj
;
5242 if (elf_hash_table (info
)->dynamic_sections_created
)
5244 ElfNN_External_Dyn
*dyncon
, *dynconend
;
5245 asection
*sdyn
, *sgotplt
;
5248 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
5249 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
5250 BFD_ASSERT (sdyn
!= NULL
);
5251 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
5252 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
5254 gp_val
= _bfd_get_gp_value (abfd
);
5256 for (; dyncon
< dynconend
; dyncon
++)
5258 Elf_Internal_Dyn dyn
;
5260 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
5265 dyn
.d_un
.d_ptr
= gp_val
;
5269 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
5270 * sizeof (ElfNN_External_Rela
));
5274 /* See the comment above in finish_dynamic_symbol. */
5275 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
5276 + ia64_info
->rel_pltoff_sec
->output_offset
5277 + (ia64_info
->rel_pltoff_sec
->reloc_count
5278 * sizeof (ElfNN_External_Rela
)));
5281 case DT_IA_64_PLT_RESERVE
:
5282 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
5283 + sgotplt
->output_offset
);
5287 /* Do not have RELASZ include JMPREL. This makes things
5288 easier on ld.so. This is not what the rest of BFD set up. */
5289 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
5290 * sizeof (ElfNN_External_Rela
));
5294 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
5297 /* Initialize the PLT0 entry. */
5298 if (ia64_info
->root
.splt
)
5300 bfd_byte
*loc
= ia64_info
->root
.splt
->contents
;
5303 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
5305 pltres
= (sgotplt
->output_section
->vma
5306 + sgotplt
->output_offset
5309 elfNN_ia64_install_value (loc
+1, pltres
, R_IA64_GPREL22
);
5316 /* ELF file flag handling: */
5318 /* Function to keep IA-64 specific file flags. */
5320 elfNN_ia64_set_private_flags (bfd
*abfd
, flagword flags
)
5322 BFD_ASSERT (!elf_flags_init (abfd
)
5323 || elf_elfheader (abfd
)->e_flags
== flags
);
5325 elf_elfheader (abfd
)->e_flags
= flags
;
5326 elf_flags_init (abfd
) = TRUE
;
5330 /* Merge backend specific data from an object file to the output
5331 object file when linking. */
5333 elfNN_ia64_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
5337 bfd_boolean ok
= TRUE
;
5339 /* Don't even pretend to support mixed-format linking. */
5340 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
5341 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
5344 in_flags
= elf_elfheader (ibfd
)->e_flags
;
5345 out_flags
= elf_elfheader (obfd
)->e_flags
;
5347 if (! elf_flags_init (obfd
))
5349 elf_flags_init (obfd
) = TRUE
;
5350 elf_elfheader (obfd
)->e_flags
= in_flags
;
5352 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
5353 && bfd_get_arch_info (obfd
)->the_default
)
5355 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
5356 bfd_get_mach (ibfd
));
5362 /* Check flag compatibility. */
5363 if (in_flags
== out_flags
)
5366 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
5367 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
5368 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
5370 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
5372 (*_bfd_error_handler
)
5373 (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5376 bfd_set_error (bfd_error_bad_value
);
5379 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
5381 (*_bfd_error_handler
)
5382 (_("%B: linking big-endian files with little-endian files"),
5385 bfd_set_error (bfd_error_bad_value
);
5388 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
5390 (*_bfd_error_handler
)
5391 (_("%B: linking 64-bit files with 32-bit files"),
5394 bfd_set_error (bfd_error_bad_value
);
5397 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
5399 (*_bfd_error_handler
)
5400 (_("%B: linking constant-gp files with non-constant-gp files"),
5403 bfd_set_error (bfd_error_bad_value
);
5406 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
5407 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
5409 (*_bfd_error_handler
)
5410 (_("%B: linking auto-pic files with non-auto-pic files"),
5413 bfd_set_error (bfd_error_bad_value
);
5421 elfNN_ia64_print_private_bfd_data (bfd
*abfd
, PTR ptr
)
5423 FILE *file
= (FILE *) ptr
;
5424 flagword flags
= elf_elfheader (abfd
)->e_flags
;
5426 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
5428 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
5429 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
5430 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
5431 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
5432 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
5433 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
5434 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
5435 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
5436 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
5438 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
5442 static enum elf_reloc_type_class
5443 elfNN_ia64_reloc_type_class (const Elf_Internal_Rela
*rela
)
5445 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
5447 case R_IA64_REL32MSB
:
5448 case R_IA64_REL32LSB
:
5449 case R_IA64_REL64MSB
:
5450 case R_IA64_REL64LSB
:
5451 return reloc_class_relative
;
5452 case R_IA64_IPLTMSB
:
5453 case R_IA64_IPLTLSB
:
5454 return reloc_class_plt
;
5456 return reloc_class_copy
;
5458 return reloc_class_normal
;
5462 static const struct bfd_elf_special_section elfNN_ia64_special_sections
[] =
5464 { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_IA_64_SHORT
},
5465 { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_IA_64_SHORT
},
5466 { NULL
, 0, 0, 0, 0 }
5470 elfNN_ia64_object_p (bfd
*abfd
)
5473 asection
*group
, *unwi
, *unw
;
5476 char *unwi_name
, *unw_name
;
5479 if (abfd
->flags
& DYNAMIC
)
5482 /* Flags for fake group section. */
5483 flags
= (SEC_LINKER_CREATED
| SEC_GROUP
| SEC_LINK_ONCE
5486 /* We add a fake section group for each .gnu.linkonce.t.* section,
5487 which isn't in a section group, and its unwind sections. */
5488 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
5490 if (elf_sec_group (sec
) == NULL
5491 && ((sec
->flags
& (SEC_LINK_ONCE
| SEC_CODE
| SEC_GROUP
))
5492 == (SEC_LINK_ONCE
| SEC_CODE
))
5493 && CONST_STRNEQ (sec
->name
, ".gnu.linkonce.t."))
5495 name
= sec
->name
+ 16;
5497 amt
= strlen (name
) + sizeof (".gnu.linkonce.ia64unwi.");
5498 unwi_name
= bfd_alloc (abfd
, amt
);
5502 strcpy (stpcpy (unwi_name
, ".gnu.linkonce.ia64unwi."), name
);
5503 unwi
= bfd_get_section_by_name (abfd
, unwi_name
);
5505 amt
= strlen (name
) + sizeof (".gnu.linkonce.ia64unw.");
5506 unw_name
= bfd_alloc (abfd
, amt
);
5510 strcpy (stpcpy (unw_name
, ".gnu.linkonce.ia64unw."), name
);
5511 unw
= bfd_get_section_by_name (abfd
, unw_name
);
5513 /* We need to create a fake group section for it and its
5515 group
= bfd_make_section_anyway_with_flags (abfd
, name
,
5520 /* Move the fake group section to the beginning. */
5521 bfd_section_list_remove (abfd
, group
);
5522 bfd_section_list_prepend (abfd
, group
);
5524 elf_next_in_group (group
) = sec
;
5526 elf_group_name (sec
) = name
;
5527 elf_next_in_group (sec
) = sec
;
5528 elf_sec_group (sec
) = group
;
5532 elf_group_name (unwi
) = name
;
5533 elf_next_in_group (unwi
) = sec
;
5534 elf_next_in_group (sec
) = unwi
;
5535 elf_sec_group (unwi
) = group
;
5540 elf_group_name (unw
) = name
;
5543 elf_next_in_group (unw
) = elf_next_in_group (unwi
);
5544 elf_next_in_group (unwi
) = unw
;
5548 elf_next_in_group (unw
) = sec
;
5549 elf_next_in_group (sec
) = unw
;
5551 elf_sec_group (unw
) = group
;
5554 /* Fake SHT_GROUP section header. */
5555 elf_section_data (group
)->this_hdr
.bfd_section
= group
;
5556 elf_section_data (group
)->this_hdr
.sh_type
= SHT_GROUP
;
5563 elfNN_ia64_hpux_vec (const bfd_target
*vec
)
5565 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec
;
5566 return (vec
== & bfd_elfNN_ia64_hpux_big_vec
);
5570 elfNN_hpux_post_process_headers (bfd
*abfd
,
5571 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
5573 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
5575 i_ehdrp
->e_ident
[EI_OSABI
] = get_elf_backend_data (abfd
)->elf_osabi
;
5576 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 1;
5580 elfNN_hpux_backend_section_from_bfd_section (bfd
*abfd ATTRIBUTE_UNUSED
,
5581 asection
*sec
, int *retval
)
5583 if (bfd_is_com_section (sec
))
5585 *retval
= SHN_IA_64_ANSI_COMMON
;
5592 elfNN_hpux_backend_symbol_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
5595 elf_symbol_type
*elfsym
= (elf_symbol_type
*) asym
;
5597 switch (elfsym
->internal_elf_sym
.st_shndx
)
5599 case SHN_IA_64_ANSI_COMMON
:
5600 asym
->section
= bfd_com_section_ptr
;
5601 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
5602 asym
->flags
&= ~BSF_GLOBAL
;
5608 elfNN_vms_section_from_shdr (bfd
*abfd
,
5609 Elf_Internal_Shdr
*hdr
,
5615 switch (hdr
->sh_type
)
5617 case SHT_IA_64_VMS_TRACE
:
5618 case SHT_IA_64_VMS_DEBUG
:
5619 case SHT_IA_64_VMS_DEBUG_STR
:
5623 return elfNN_ia64_section_from_shdr (abfd
, hdr
, name
, shindex
);
5626 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
5628 newsect
= hdr
->bfd_section
;
5634 elfNN_vms_object_p (bfd
*abfd
)
5636 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
5637 Elf_Internal_Phdr
*i_phdr
= elf_tdata (abfd
)->phdr
;
5639 unsigned int num_text
= 0;
5640 unsigned int num_data
= 0;
5641 unsigned int num_rodata
= 0;
5644 if (!elfNN_ia64_object_p (abfd
))
5647 for (i
= 0; i
< i_ehdrp
->e_phnum
; i
++, i_phdr
++)
5649 /* Is there a section for this segment? */
5650 bfd_vma base_vma
= i_phdr
->p_vaddr
;
5651 bfd_vma limit_vma
= base_vma
+ i_phdr
->p_filesz
;
5653 if (i_phdr
->p_type
!= PT_LOAD
)
5657 while (base_vma
< limit_vma
)
5659 bfd_vma next_vma
= limit_vma
;
5665 /* Find a section covering base_vma. */
5666 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
5668 if ((sec
->flags
& (SEC_ALLOC
| SEC_LOAD
)) == 0)
5670 if (sec
->vma
<= base_vma
&& sec
->vma
+ sec
->size
> base_vma
)
5672 base_vma
= sec
->vma
+ sec
->size
;
5675 if (sec
->vma
< next_vma
&& sec
->vma
+ sec
->size
>= base_vma
)
5676 next_vma
= sec
->vma
;
5679 /* No section covering [base_vma; next_vma). Create a fake one. */
5680 flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
;
5681 if (i_phdr
->p_flags
& PF_X
)
5684 if (num_text
++ == 0)
5687 sprintf (name
, ".text$%u", num_text
);
5689 else if ((i_phdr
->p_flags
& (PF_R
| PF_W
)) == PF_R
)
5691 flags
|= SEC_READONLY
;
5692 sprintf (name
, ".rodata$%u", num_rodata
++);
5697 sprintf (name
, ".data$%u", num_data
++);
5700 /* Allocate name. */
5703 size_t name_len
= strlen (name
) + 1;
5704 nname
= bfd_alloc (abfd
, name_len
);
5707 memcpy (nname
, name
, name_len
);
5710 /* Create and fill new section. */
5711 nsec
= bfd_make_section_anyway_with_flags (abfd
, nname
, flags
);
5714 nsec
->vma
= base_vma
;
5715 nsec
->size
= next_vma
- base_vma
;
5716 nsec
->filepos
= i_phdr
->p_offset
+ (base_vma
- i_phdr
->p_vaddr
);
5718 base_vma
= next_vma
;
5725 elfNN_vms_post_process_headers (bfd
*abfd
,
5726 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
5728 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
5730 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_OPENVMS
;
5731 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 2;
5735 elfNN_vms_section_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
5736 Elf_Internal_Shdr
*hdr
)
5738 if (hdr
->bfd_section
!= NULL
)
5740 const char *name
= bfd_get_section_name (abfd
, hdr
->bfd_section
);
5742 if (strcmp (name
, ".text") == 0)
5743 hdr
->sh_flags
|= SHF_IA_64_VMS_SHARED
;
5744 else if ((strcmp (name
, ".debug") == 0)
5745 || (strcmp (name
, ".debug_abbrev") == 0)
5746 || (strcmp (name
, ".debug_aranges") == 0)
5747 || (strcmp (name
, ".debug_frame") == 0)
5748 || (strcmp (name
, ".debug_info") == 0)
5749 || (strcmp (name
, ".debug_loc") == 0)
5750 || (strcmp (name
, ".debug_macinfo") == 0)
5751 || (strcmp (name
, ".debug_pubnames") == 0)
5752 || (strcmp (name
, ".debug_pubtypes") == 0))
5753 hdr
->sh_type
= SHT_IA_64_VMS_DEBUG
;
5754 else if ((strcmp (name
, ".debug_line") == 0)
5755 || (strcmp (name
, ".debug_ranges") == 0))
5756 hdr
->sh_type
= SHT_IA_64_VMS_TRACE
;
5757 else if (strcmp (name
, ".debug_str") == 0)
5758 hdr
->sh_type
= SHT_IA_64_VMS_DEBUG_STR
;
5759 else if (strcmp (name
, ".vms_display_name_info") == 0)
5763 struct elf_obj_tdata
*t
= elf_tdata (abfd
);
5765 int demangler_sym_idx
= -1;
5767 symcount
= bfd_get_symcount (abfd
);
5768 syms
= bfd_get_outsymbols (abfd
);
5769 for (idx
= 0; idx
< symcount
; idx
++)
5773 if ((sym
->flags
& (BSF_DEBUGGING
| BSF_DYNAMIC
))
5774 && strchr (sym
->name
, '@')
5775 && (strcmp (sym
->section
->name
, BFD_ABS_SECTION_NAME
) == 0))
5777 demangler_sym_idx
= sym
->udata
.i
;
5782 hdr
->sh_type
= SHT_IA_64_VMS_DISPLAY_NAME_INFO
;
5783 hdr
->sh_entsize
= 4;
5784 hdr
->sh_addralign
= 0;
5785 hdr
->sh_link
= t
->symtab_section
;
5787 /* Find symtab index of demangler routine and stuff it in
5788 the second long word of section data. */
5790 if (demangler_sym_idx
> -1)
5792 bfd_seek (abfd
, hdr
->sh_offset
, SEEK_SET
);
5793 bfd_bread (buf
, hdr
->sh_size
, abfd
);
5794 buf
[1] = demangler_sym_idx
;
5795 bfd_seek (abfd
, hdr
->sh_offset
, SEEK_SET
);
5796 bfd_bwrite (buf
, hdr
->sh_size
, abfd
);
5804 /* The final processing done just before writing out a VMS IA-64 ELF
5808 elfNN_vms_final_write_processing (bfd
*abfd
,
5809 bfd_boolean linker ATTRIBUTE_UNUSED
)
5811 Elf_Internal_Shdr
*hdr
;
5813 int unwind_info_sect_idx
= 0;
5815 for (s
= abfd
->sections
; s
; s
= s
->next
)
5817 hdr
= &elf_section_data (s
)->this_hdr
;
5819 if (strcmp (bfd_get_section_name (abfd
, hdr
->bfd_section
),
5820 ".IA_64.unwind_info") == 0)
5821 unwind_info_sect_idx
= elf_section_data (s
)->this_idx
;
5823 switch (hdr
->sh_type
)
5825 case SHT_IA_64_UNWIND
:
5826 /* VMS requires sh_info to point to the unwind info section. */
5827 hdr
->sh_info
= unwind_info_sect_idx
;
5832 if (! elf_flags_init (abfd
))
5834 unsigned long flags
= 0;
5836 if (abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
)
5837 flags
|= EF_IA_64_BE
;
5838 if (bfd_get_mach (abfd
) == bfd_mach_ia64_elf64
)
5839 flags
|= EF_IA_64_ABI64
;
5841 elf_elfheader(abfd
)->e_flags
= flags
;
5842 elf_flags_init (abfd
) = TRUE
;
5847 elfNN_vms_close_and_cleanup (bfd
*abfd
)
5849 if (bfd_get_format (abfd
) == bfd_object
)
5853 if (elf_shstrtab (abfd
) != NULL
)
5854 _bfd_elf_strtab_free (elf_shstrtab (abfd
));
5856 /* Pad to 8 byte boundary for IPF/VMS. */
5857 isize
= bfd_get_size (abfd
);
5858 if ((irsize
= isize
/8*8) < isize
)
5860 int ishort
= (irsize
+ 8) - isize
;
5861 bfd_seek (abfd
, isize
, SEEK_SET
);
5862 bfd_bwrite (bfd_zmalloc (ishort
), ishort
, abfd
);
5866 return _bfd_generic_close_and_cleanup (abfd
);
5869 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
5870 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
5871 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
5872 #define TARGET_BIG_NAME "elfNN-ia64-big"
5873 #define ELF_ARCH bfd_arch_ia64
5874 #define ELF_MACHINE_CODE EM_IA_64
5875 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
5876 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
5877 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
5878 #define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
5880 #define elf_backend_section_from_shdr \
5881 elfNN_ia64_section_from_shdr
5882 #define elf_backend_section_flags \
5883 elfNN_ia64_section_flags
5884 #define elf_backend_fake_sections \
5885 elfNN_ia64_fake_sections
5886 #define elf_backend_final_write_processing \
5887 elfNN_ia64_final_write_processing
5888 #define elf_backend_add_symbol_hook \
5889 elfNN_ia64_add_symbol_hook
5890 #define elf_backend_additional_program_headers \
5891 elfNN_ia64_additional_program_headers
5892 #define elf_backend_modify_segment_map \
5893 elfNN_ia64_modify_segment_map
5894 #define elf_backend_modify_program_headers \
5895 elfNN_ia64_modify_program_headers
5896 #define elf_info_to_howto \
5897 elfNN_ia64_info_to_howto
5899 #define bfd_elfNN_bfd_reloc_type_lookup \
5900 elfNN_ia64_reloc_type_lookup
5901 #define bfd_elfNN_bfd_reloc_name_lookup \
5902 elfNN_ia64_reloc_name_lookup
5903 #define bfd_elfNN_bfd_is_local_label_name \
5904 elfNN_ia64_is_local_label_name
5905 #define bfd_elfNN_bfd_relax_section \
5906 elfNN_ia64_relax_section
5908 #define elf_backend_object_p \
5911 /* Stuff for the BFD linker: */
5912 #define bfd_elfNN_bfd_link_hash_table_create \
5913 elfNN_ia64_hash_table_create
5914 #define bfd_elfNN_bfd_link_hash_table_free \
5915 elfNN_ia64_hash_table_free
5916 #define elf_backend_create_dynamic_sections \
5917 elfNN_ia64_create_dynamic_sections
5918 #define elf_backend_check_relocs \
5919 elfNN_ia64_check_relocs
5920 #define elf_backend_adjust_dynamic_symbol \
5921 elfNN_ia64_adjust_dynamic_symbol
5922 #define elf_backend_size_dynamic_sections \
5923 elfNN_ia64_size_dynamic_sections
5924 #define elf_backend_omit_section_dynsym \
5925 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
5926 #define elf_backend_relocate_section \
5927 elfNN_ia64_relocate_section
5928 #define elf_backend_finish_dynamic_symbol \
5929 elfNN_ia64_finish_dynamic_symbol
5930 #define elf_backend_finish_dynamic_sections \
5931 elfNN_ia64_finish_dynamic_sections
5932 #define bfd_elfNN_bfd_final_link \
5933 elfNN_ia64_final_link
5935 #define bfd_elfNN_bfd_merge_private_bfd_data \
5936 elfNN_ia64_merge_private_bfd_data
5937 #define bfd_elfNN_bfd_set_private_flags \
5938 elfNN_ia64_set_private_flags
5939 #define bfd_elfNN_bfd_print_private_bfd_data \
5940 elfNN_ia64_print_private_bfd_data
5942 #define elf_backend_plt_readonly 1
5943 #define elf_backend_want_plt_sym 0
5944 #define elf_backend_plt_alignment 5
5945 #define elf_backend_got_header_size 0
5946 #define elf_backend_want_got_plt 1
5947 #define elf_backend_may_use_rel_p 1
5948 #define elf_backend_may_use_rela_p 1
5949 #define elf_backend_default_use_rela_p 1
5950 #define elf_backend_want_dynbss 0
5951 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5952 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
5953 #define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
5954 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
5955 #define elf_backend_rela_normal 1
5956 #define elf_backend_special_sections elfNN_ia64_special_sections
5957 #define elf_backend_default_execstack 0
5959 /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5960 SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
5961 We don't want to flood users with so many error messages. We turn
5962 off the warning for now. It will be turned on later when the Intel
5963 compiler is fixed. */
5964 #define elf_backend_link_order_error_handler NULL
5966 #include "elfNN-target.h"
5968 /* HPUX-specific vectors. */
5970 #undef TARGET_LITTLE_SYM
5971 #undef TARGET_LITTLE_NAME
5972 #undef TARGET_BIG_SYM
5973 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
5974 #undef TARGET_BIG_NAME
5975 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
5977 /* These are HP-UX specific functions. */
5979 #undef elf_backend_post_process_headers
5980 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5982 #undef elf_backend_section_from_bfd_section
5983 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5985 #undef elf_backend_symbol_processing
5986 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5988 #undef elf_backend_want_p_paddr_set_to_zero
5989 #define elf_backend_want_p_paddr_set_to_zero 1
5991 #undef ELF_COMMONPAGESIZE
5993 #define ELF_OSABI ELFOSABI_HPUX
5996 #define elfNN_bed elfNN_ia64_hpux_bed
5998 #include "elfNN-target.h"
6000 /* VMS-specific vectors. */
6002 #undef TARGET_LITTLE_SYM
6003 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_vms_vec
6004 #undef TARGET_LITTLE_NAME
6005 #define TARGET_LITTLE_NAME "elfNN-ia64-vms"
6006 #undef TARGET_BIG_SYM
6007 #undef TARGET_BIG_NAME
6009 /* These are VMS specific functions. */
6011 #undef elf_backend_object_p
6012 #define elf_backend_object_p elfNN_vms_object_p
6014 #undef elf_backend_section_from_shdr
6015 #define elf_backend_section_from_shdr elfNN_vms_section_from_shdr
6017 #undef elf_backend_post_process_headers
6018 #define elf_backend_post_process_headers elfNN_vms_post_process_headers
6020 #undef elf_backend_section_processing
6021 #define elf_backend_section_processing elfNN_vms_section_processing
6023 #undef elf_backend_final_write_processing
6024 #define elf_backend_final_write_processing elfNN_vms_final_write_processing
6026 #undef bfd_elfNN_close_and_cleanup
6027 #define bfd_elfNN_close_and_cleanup elfNN_vms_close_and_cleanup
6029 #undef elf_backend_section_from_bfd_section
6031 #undef elf_backend_symbol_processing
6033 #undef elf_backend_want_p_paddr_set_to_zero
6035 #undef ELF_MAXPAGESIZE
6036 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
6039 #define elfNN_bed elfNN_ia64_vms_bed
6041 #include "elfNN-target.h"