1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 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
*got_sec
; /* the linkage table section (or NULL) */
167 asection
*rel_got_sec
; /* dynamic relocation section for same */
168 asection
*fptr_sec
; /* function descriptor table (or NULL) */
169 asection
*rel_fptr_sec
; /* dynamic relocation section for same */
170 asection
*plt_sec
; /* the primary plt section (or NULL) */
171 asection
*pltoff_sec
; /* private descriptors for plt (or NULL) */
172 asection
*rel_pltoff_sec
; /* dynamic relocation section for same */
174 bfd_size_type minplt_entries
; /* number of minplt entries */
175 unsigned reltext
: 1; /* are there relocs against readonly sections? */
176 unsigned self_dtpmod_done
: 1;/* has self DTPMOD entry been finished? */
177 bfd_vma self_dtpmod_offset
; /* .got offset to self DTPMOD entry */
179 htab_t loc_hash_table
;
180 void *loc_hash_memory
;
183 struct elfNN_ia64_allocate_data
185 struct bfd_link_info
*info
;
187 bfd_boolean only_got
;
190 #define elfNN_ia64_hash_table(p) \
191 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
193 static struct elfNN_ia64_dyn_sym_info
* get_dyn_sym_info
194 (struct elfNN_ia64_link_hash_table
*ia64_info
,
195 struct elf_link_hash_entry
*h
,
196 bfd
*abfd
, const Elf_Internal_Rela
*rel
, bfd_boolean create
);
197 static bfd_boolean elfNN_ia64_dynamic_symbol_p
198 (struct elf_link_hash_entry
*h
, struct bfd_link_info
*info
, int);
199 static bfd_reloc_status_type elfNN_ia64_install_value
200 (bfd_byte
*hit_addr
, bfd_vma val
, unsigned int r_type
);
201 static bfd_boolean elfNN_ia64_choose_gp
202 (bfd
*abfd
, struct bfd_link_info
*info
);
203 static void elfNN_ia64_relax_ldxmov
204 (bfd_byte
*contents
, bfd_vma off
);
205 static void elfNN_ia64_dyn_sym_traverse
206 (struct elfNN_ia64_link_hash_table
*ia64_info
,
207 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
209 static bfd_boolean allocate_global_data_got
210 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
211 static bfd_boolean allocate_global_fptr_got
212 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
213 static bfd_boolean allocate_local_got
214 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
215 static bfd_boolean elfNN_ia64_hpux_vec
216 (const bfd_target
*vec
);
217 static bfd_boolean allocate_dynrel_entries
218 (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
);
219 static asection
*get_pltoff
220 (bfd
*abfd
, struct bfd_link_info
*info
,
221 struct elfNN_ia64_link_hash_table
*ia64_info
);
223 /* ia64-specific relocation. */
225 /* Perform a relocation. Not much to do here as all the hard work is
226 done in elfNN_ia64_final_link_relocate. */
227 static bfd_reloc_status_type
228 elfNN_ia64_reloc (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*reloc
,
229 asymbol
*sym ATTRIBUTE_UNUSED
,
230 PTR data ATTRIBUTE_UNUSED
, asection
*input_section
,
231 bfd
*output_bfd
, char **error_message
)
235 reloc
->address
+= input_section
->output_offset
;
239 if (input_section
->flags
& SEC_DEBUGGING
)
240 return bfd_reloc_continue
;
242 *error_message
= "Unsupported call to elfNN_ia64_reloc";
243 return bfd_reloc_notsupported
;
246 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
247 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
248 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
250 /* This table has to be sorted according to increasing number of the
252 static reloc_howto_type ia64_howto_table
[] =
254 IA64_HOWTO (R_IA64_NONE
, "NONE", 0, FALSE
, TRUE
),
256 IA64_HOWTO (R_IA64_IMM14
, "IMM14", 0, FALSE
, TRUE
),
257 IA64_HOWTO (R_IA64_IMM22
, "IMM22", 0, FALSE
, TRUE
),
258 IA64_HOWTO (R_IA64_IMM64
, "IMM64", 0, FALSE
, TRUE
),
259 IA64_HOWTO (R_IA64_DIR32MSB
, "DIR32MSB", 2, FALSE
, TRUE
),
260 IA64_HOWTO (R_IA64_DIR32LSB
, "DIR32LSB", 2, FALSE
, TRUE
),
261 IA64_HOWTO (R_IA64_DIR64MSB
, "DIR64MSB", 4, FALSE
, TRUE
),
262 IA64_HOWTO (R_IA64_DIR64LSB
, "DIR64LSB", 4, FALSE
, TRUE
),
264 IA64_HOWTO (R_IA64_GPREL22
, "GPREL22", 0, FALSE
, TRUE
),
265 IA64_HOWTO (R_IA64_GPREL64I
, "GPREL64I", 0, FALSE
, TRUE
),
266 IA64_HOWTO (R_IA64_GPREL32MSB
, "GPREL32MSB", 2, FALSE
, TRUE
),
267 IA64_HOWTO (R_IA64_GPREL32LSB
, "GPREL32LSB", 2, FALSE
, TRUE
),
268 IA64_HOWTO (R_IA64_GPREL64MSB
, "GPREL64MSB", 4, FALSE
, TRUE
),
269 IA64_HOWTO (R_IA64_GPREL64LSB
, "GPREL64LSB", 4, FALSE
, TRUE
),
271 IA64_HOWTO (R_IA64_LTOFF22
, "LTOFF22", 0, FALSE
, TRUE
),
272 IA64_HOWTO (R_IA64_LTOFF64I
, "LTOFF64I", 0, FALSE
, TRUE
),
274 IA64_HOWTO (R_IA64_PLTOFF22
, "PLTOFF22", 0, FALSE
, TRUE
),
275 IA64_HOWTO (R_IA64_PLTOFF64I
, "PLTOFF64I", 0, FALSE
, TRUE
),
276 IA64_HOWTO (R_IA64_PLTOFF64MSB
, "PLTOFF64MSB", 4, FALSE
, TRUE
),
277 IA64_HOWTO (R_IA64_PLTOFF64LSB
, "PLTOFF64LSB", 4, FALSE
, TRUE
),
279 IA64_HOWTO (R_IA64_FPTR64I
, "FPTR64I", 0, FALSE
, TRUE
),
280 IA64_HOWTO (R_IA64_FPTR32MSB
, "FPTR32MSB", 2, FALSE
, TRUE
),
281 IA64_HOWTO (R_IA64_FPTR32LSB
, "FPTR32LSB", 2, FALSE
, TRUE
),
282 IA64_HOWTO (R_IA64_FPTR64MSB
, "FPTR64MSB", 4, FALSE
, TRUE
),
283 IA64_HOWTO (R_IA64_FPTR64LSB
, "FPTR64LSB", 4, FALSE
, TRUE
),
285 IA64_HOWTO (R_IA64_PCREL60B
, "PCREL60B", 0, TRUE
, TRUE
),
286 IA64_HOWTO (R_IA64_PCREL21B
, "PCREL21B", 0, TRUE
, TRUE
),
287 IA64_HOWTO (R_IA64_PCREL21M
, "PCREL21M", 0, TRUE
, TRUE
),
288 IA64_HOWTO (R_IA64_PCREL21F
, "PCREL21F", 0, TRUE
, TRUE
),
289 IA64_HOWTO (R_IA64_PCREL32MSB
, "PCREL32MSB", 2, TRUE
, TRUE
),
290 IA64_HOWTO (R_IA64_PCREL32LSB
, "PCREL32LSB", 2, TRUE
, TRUE
),
291 IA64_HOWTO (R_IA64_PCREL64MSB
, "PCREL64MSB", 4, TRUE
, TRUE
),
292 IA64_HOWTO (R_IA64_PCREL64LSB
, "PCREL64LSB", 4, TRUE
, TRUE
),
294 IA64_HOWTO (R_IA64_LTOFF_FPTR22
, "LTOFF_FPTR22", 0, FALSE
, TRUE
),
295 IA64_HOWTO (R_IA64_LTOFF_FPTR64I
, "LTOFF_FPTR64I", 0, FALSE
, TRUE
),
296 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB
, "LTOFF_FPTR32MSB", 2, FALSE
, TRUE
),
297 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB
, "LTOFF_FPTR32LSB", 2, FALSE
, TRUE
),
298 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB
, "LTOFF_FPTR64MSB", 4, FALSE
, TRUE
),
299 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB
, "LTOFF_FPTR64LSB", 4, FALSE
, TRUE
),
301 IA64_HOWTO (R_IA64_SEGREL32MSB
, "SEGREL32MSB", 2, FALSE
, TRUE
),
302 IA64_HOWTO (R_IA64_SEGREL32LSB
, "SEGREL32LSB", 2, FALSE
, TRUE
),
303 IA64_HOWTO (R_IA64_SEGREL64MSB
, "SEGREL64MSB", 4, FALSE
, TRUE
),
304 IA64_HOWTO (R_IA64_SEGREL64LSB
, "SEGREL64LSB", 4, FALSE
, TRUE
),
306 IA64_HOWTO (R_IA64_SECREL32MSB
, "SECREL32MSB", 2, FALSE
, TRUE
),
307 IA64_HOWTO (R_IA64_SECREL32LSB
, "SECREL32LSB", 2, FALSE
, TRUE
),
308 IA64_HOWTO (R_IA64_SECREL64MSB
, "SECREL64MSB", 4, FALSE
, TRUE
),
309 IA64_HOWTO (R_IA64_SECREL64LSB
, "SECREL64LSB", 4, FALSE
, TRUE
),
311 IA64_HOWTO (R_IA64_REL32MSB
, "REL32MSB", 2, FALSE
, TRUE
),
312 IA64_HOWTO (R_IA64_REL32LSB
, "REL32LSB", 2, FALSE
, TRUE
),
313 IA64_HOWTO (R_IA64_REL64MSB
, "REL64MSB", 4, FALSE
, TRUE
),
314 IA64_HOWTO (R_IA64_REL64LSB
, "REL64LSB", 4, FALSE
, TRUE
),
316 IA64_HOWTO (R_IA64_LTV32MSB
, "LTV32MSB", 2, FALSE
, TRUE
),
317 IA64_HOWTO (R_IA64_LTV32LSB
, "LTV32LSB", 2, FALSE
, TRUE
),
318 IA64_HOWTO (R_IA64_LTV64MSB
, "LTV64MSB", 4, FALSE
, TRUE
),
319 IA64_HOWTO (R_IA64_LTV64LSB
, "LTV64LSB", 4, FALSE
, TRUE
),
321 IA64_HOWTO (R_IA64_PCREL21BI
, "PCREL21BI", 0, TRUE
, TRUE
),
322 IA64_HOWTO (R_IA64_PCREL22
, "PCREL22", 0, TRUE
, TRUE
),
323 IA64_HOWTO (R_IA64_PCREL64I
, "PCREL64I", 0, TRUE
, TRUE
),
325 IA64_HOWTO (R_IA64_IPLTMSB
, "IPLTMSB", 4, FALSE
, TRUE
),
326 IA64_HOWTO (R_IA64_IPLTLSB
, "IPLTLSB", 4, FALSE
, TRUE
),
327 IA64_HOWTO (R_IA64_COPY
, "COPY", 4, FALSE
, TRUE
),
328 IA64_HOWTO (R_IA64_LTOFF22X
, "LTOFF22X", 0, FALSE
, TRUE
),
329 IA64_HOWTO (R_IA64_LDXMOV
, "LDXMOV", 0, FALSE
, TRUE
),
331 IA64_HOWTO (R_IA64_TPREL14
, "TPREL14", 0, FALSE
, FALSE
),
332 IA64_HOWTO (R_IA64_TPREL22
, "TPREL22", 0, FALSE
, FALSE
),
333 IA64_HOWTO (R_IA64_TPREL64I
, "TPREL64I", 0, FALSE
, FALSE
),
334 IA64_HOWTO (R_IA64_TPREL64MSB
, "TPREL64MSB", 4, FALSE
, FALSE
),
335 IA64_HOWTO (R_IA64_TPREL64LSB
, "TPREL64LSB", 4, FALSE
, FALSE
),
336 IA64_HOWTO (R_IA64_LTOFF_TPREL22
, "LTOFF_TPREL22", 0, FALSE
, FALSE
),
338 IA64_HOWTO (R_IA64_DTPMOD64MSB
, "DTPMOD64MSB", 4, FALSE
, FALSE
),
339 IA64_HOWTO (R_IA64_DTPMOD64LSB
, "DTPMOD64LSB", 4, FALSE
, FALSE
),
340 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22
, "LTOFF_DTPMOD22", 0, FALSE
, FALSE
),
342 IA64_HOWTO (R_IA64_DTPREL14
, "DTPREL14", 0, FALSE
, FALSE
),
343 IA64_HOWTO (R_IA64_DTPREL22
, "DTPREL22", 0, FALSE
, FALSE
),
344 IA64_HOWTO (R_IA64_DTPREL64I
, "DTPREL64I", 0, FALSE
, FALSE
),
345 IA64_HOWTO (R_IA64_DTPREL32MSB
, "DTPREL32MSB", 2, FALSE
, FALSE
),
346 IA64_HOWTO (R_IA64_DTPREL32LSB
, "DTPREL32LSB", 2, FALSE
, FALSE
),
347 IA64_HOWTO (R_IA64_DTPREL64MSB
, "DTPREL64MSB", 4, FALSE
, FALSE
),
348 IA64_HOWTO (R_IA64_DTPREL64LSB
, "DTPREL64LSB", 4, FALSE
, FALSE
),
349 IA64_HOWTO (R_IA64_LTOFF_DTPREL22
, "LTOFF_DTPREL22", 0, FALSE
, FALSE
),
352 static unsigned char elf_code_to_howto_index
[R_IA64_MAX_RELOC_CODE
+ 1];
354 /* Given a BFD reloc type, return the matching HOWTO structure. */
356 static reloc_howto_type
*
357 lookup_howto (unsigned int rtype
)
359 static int inited
= 0;
366 memset (elf_code_to_howto_index
, 0xff, sizeof (elf_code_to_howto_index
));
367 for (i
= 0; i
< NELEMS (ia64_howto_table
); ++i
)
368 elf_code_to_howto_index
[ia64_howto_table
[i
].type
] = i
;
371 if (rtype
> R_IA64_MAX_RELOC_CODE
)
373 i
= elf_code_to_howto_index
[rtype
];
374 if (i
>= NELEMS (ia64_howto_table
))
376 return ia64_howto_table
+ i
;
379 static reloc_howto_type
*
380 elfNN_ia64_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
381 bfd_reloc_code_real_type bfd_code
)
387 case BFD_RELOC_NONE
: rtype
= R_IA64_NONE
; break;
389 case BFD_RELOC_IA64_IMM14
: rtype
= R_IA64_IMM14
; break;
390 case BFD_RELOC_IA64_IMM22
: rtype
= R_IA64_IMM22
; break;
391 case BFD_RELOC_IA64_IMM64
: rtype
= R_IA64_IMM64
; break;
393 case BFD_RELOC_IA64_DIR32MSB
: rtype
= R_IA64_DIR32MSB
; break;
394 case BFD_RELOC_IA64_DIR32LSB
: rtype
= R_IA64_DIR32LSB
; break;
395 case BFD_RELOC_IA64_DIR64MSB
: rtype
= R_IA64_DIR64MSB
; break;
396 case BFD_RELOC_IA64_DIR64LSB
: rtype
= R_IA64_DIR64LSB
; break;
398 case BFD_RELOC_IA64_GPREL22
: rtype
= R_IA64_GPREL22
; break;
399 case BFD_RELOC_IA64_GPREL64I
: rtype
= R_IA64_GPREL64I
; break;
400 case BFD_RELOC_IA64_GPREL32MSB
: rtype
= R_IA64_GPREL32MSB
; break;
401 case BFD_RELOC_IA64_GPREL32LSB
: rtype
= R_IA64_GPREL32LSB
; break;
402 case BFD_RELOC_IA64_GPREL64MSB
: rtype
= R_IA64_GPREL64MSB
; break;
403 case BFD_RELOC_IA64_GPREL64LSB
: rtype
= R_IA64_GPREL64LSB
; break;
405 case BFD_RELOC_IA64_LTOFF22
: rtype
= R_IA64_LTOFF22
; break;
406 case BFD_RELOC_IA64_LTOFF64I
: rtype
= R_IA64_LTOFF64I
; break;
408 case BFD_RELOC_IA64_PLTOFF22
: rtype
= R_IA64_PLTOFF22
; break;
409 case BFD_RELOC_IA64_PLTOFF64I
: rtype
= R_IA64_PLTOFF64I
; break;
410 case BFD_RELOC_IA64_PLTOFF64MSB
: rtype
= R_IA64_PLTOFF64MSB
; break;
411 case BFD_RELOC_IA64_PLTOFF64LSB
: rtype
= R_IA64_PLTOFF64LSB
; break;
412 case BFD_RELOC_IA64_FPTR64I
: rtype
= R_IA64_FPTR64I
; break;
413 case BFD_RELOC_IA64_FPTR32MSB
: rtype
= R_IA64_FPTR32MSB
; break;
414 case BFD_RELOC_IA64_FPTR32LSB
: rtype
= R_IA64_FPTR32LSB
; break;
415 case BFD_RELOC_IA64_FPTR64MSB
: rtype
= R_IA64_FPTR64MSB
; break;
416 case BFD_RELOC_IA64_FPTR64LSB
: rtype
= R_IA64_FPTR64LSB
; break;
418 case BFD_RELOC_IA64_PCREL21B
: rtype
= R_IA64_PCREL21B
; break;
419 case BFD_RELOC_IA64_PCREL21BI
: rtype
= R_IA64_PCREL21BI
; break;
420 case BFD_RELOC_IA64_PCREL21M
: rtype
= R_IA64_PCREL21M
; break;
421 case BFD_RELOC_IA64_PCREL21F
: rtype
= R_IA64_PCREL21F
; break;
422 case BFD_RELOC_IA64_PCREL22
: rtype
= R_IA64_PCREL22
; break;
423 case BFD_RELOC_IA64_PCREL60B
: rtype
= R_IA64_PCREL60B
; break;
424 case BFD_RELOC_IA64_PCREL64I
: rtype
= R_IA64_PCREL64I
; break;
425 case BFD_RELOC_IA64_PCREL32MSB
: rtype
= R_IA64_PCREL32MSB
; break;
426 case BFD_RELOC_IA64_PCREL32LSB
: rtype
= R_IA64_PCREL32LSB
; break;
427 case BFD_RELOC_IA64_PCREL64MSB
: rtype
= R_IA64_PCREL64MSB
; break;
428 case BFD_RELOC_IA64_PCREL64LSB
: rtype
= R_IA64_PCREL64LSB
; break;
430 case BFD_RELOC_IA64_LTOFF_FPTR22
: rtype
= R_IA64_LTOFF_FPTR22
; break;
431 case BFD_RELOC_IA64_LTOFF_FPTR64I
: rtype
= R_IA64_LTOFF_FPTR64I
; break;
432 case BFD_RELOC_IA64_LTOFF_FPTR32MSB
: rtype
= R_IA64_LTOFF_FPTR32MSB
; break;
433 case BFD_RELOC_IA64_LTOFF_FPTR32LSB
: rtype
= R_IA64_LTOFF_FPTR32LSB
; break;
434 case BFD_RELOC_IA64_LTOFF_FPTR64MSB
: rtype
= R_IA64_LTOFF_FPTR64MSB
; break;
435 case BFD_RELOC_IA64_LTOFF_FPTR64LSB
: rtype
= R_IA64_LTOFF_FPTR64LSB
; break;
437 case BFD_RELOC_IA64_SEGREL32MSB
: rtype
= R_IA64_SEGREL32MSB
; break;
438 case BFD_RELOC_IA64_SEGREL32LSB
: rtype
= R_IA64_SEGREL32LSB
; break;
439 case BFD_RELOC_IA64_SEGREL64MSB
: rtype
= R_IA64_SEGREL64MSB
; break;
440 case BFD_RELOC_IA64_SEGREL64LSB
: rtype
= R_IA64_SEGREL64LSB
; break;
442 case BFD_RELOC_IA64_SECREL32MSB
: rtype
= R_IA64_SECREL32MSB
; break;
443 case BFD_RELOC_IA64_SECREL32LSB
: rtype
= R_IA64_SECREL32LSB
; break;
444 case BFD_RELOC_IA64_SECREL64MSB
: rtype
= R_IA64_SECREL64MSB
; break;
445 case BFD_RELOC_IA64_SECREL64LSB
: rtype
= R_IA64_SECREL64LSB
; break;
447 case BFD_RELOC_IA64_REL32MSB
: rtype
= R_IA64_REL32MSB
; break;
448 case BFD_RELOC_IA64_REL32LSB
: rtype
= R_IA64_REL32LSB
; break;
449 case BFD_RELOC_IA64_REL64MSB
: rtype
= R_IA64_REL64MSB
; break;
450 case BFD_RELOC_IA64_REL64LSB
: rtype
= R_IA64_REL64LSB
; break;
452 case BFD_RELOC_IA64_LTV32MSB
: rtype
= R_IA64_LTV32MSB
; break;
453 case BFD_RELOC_IA64_LTV32LSB
: rtype
= R_IA64_LTV32LSB
; break;
454 case BFD_RELOC_IA64_LTV64MSB
: rtype
= R_IA64_LTV64MSB
; break;
455 case BFD_RELOC_IA64_LTV64LSB
: rtype
= R_IA64_LTV64LSB
; break;
457 case BFD_RELOC_IA64_IPLTMSB
: rtype
= R_IA64_IPLTMSB
; break;
458 case BFD_RELOC_IA64_IPLTLSB
: rtype
= R_IA64_IPLTLSB
; break;
459 case BFD_RELOC_IA64_COPY
: rtype
= R_IA64_COPY
; break;
460 case BFD_RELOC_IA64_LTOFF22X
: rtype
= R_IA64_LTOFF22X
; break;
461 case BFD_RELOC_IA64_LDXMOV
: rtype
= R_IA64_LDXMOV
; break;
463 case BFD_RELOC_IA64_TPREL14
: rtype
= R_IA64_TPREL14
; break;
464 case BFD_RELOC_IA64_TPREL22
: rtype
= R_IA64_TPREL22
; break;
465 case BFD_RELOC_IA64_TPREL64I
: rtype
= R_IA64_TPREL64I
; break;
466 case BFD_RELOC_IA64_TPREL64MSB
: rtype
= R_IA64_TPREL64MSB
; break;
467 case BFD_RELOC_IA64_TPREL64LSB
: rtype
= R_IA64_TPREL64LSB
; break;
468 case BFD_RELOC_IA64_LTOFF_TPREL22
: rtype
= R_IA64_LTOFF_TPREL22
; break;
470 case BFD_RELOC_IA64_DTPMOD64MSB
: rtype
= R_IA64_DTPMOD64MSB
; break;
471 case BFD_RELOC_IA64_DTPMOD64LSB
: rtype
= R_IA64_DTPMOD64LSB
; break;
472 case BFD_RELOC_IA64_LTOFF_DTPMOD22
: rtype
= R_IA64_LTOFF_DTPMOD22
; break;
474 case BFD_RELOC_IA64_DTPREL14
: rtype
= R_IA64_DTPREL14
; break;
475 case BFD_RELOC_IA64_DTPREL22
: rtype
= R_IA64_DTPREL22
; break;
476 case BFD_RELOC_IA64_DTPREL64I
: rtype
= R_IA64_DTPREL64I
; break;
477 case BFD_RELOC_IA64_DTPREL32MSB
: rtype
= R_IA64_DTPREL32MSB
; break;
478 case BFD_RELOC_IA64_DTPREL32LSB
: rtype
= R_IA64_DTPREL32LSB
; break;
479 case BFD_RELOC_IA64_DTPREL64MSB
: rtype
= R_IA64_DTPREL64MSB
; break;
480 case BFD_RELOC_IA64_DTPREL64LSB
: rtype
= R_IA64_DTPREL64LSB
; break;
481 case BFD_RELOC_IA64_LTOFF_DTPREL22
: rtype
= R_IA64_LTOFF_DTPREL22
; break;
485 return lookup_howto (rtype
);
488 static reloc_howto_type
*
489 elfNN_ia64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
495 i
< sizeof (ia64_howto_table
) / sizeof (ia64_howto_table
[0]);
497 if (ia64_howto_table
[i
].name
!= NULL
498 && strcasecmp (ia64_howto_table
[i
].name
, r_name
) == 0)
499 return &ia64_howto_table
[i
];
504 /* Given a ELF reloc, return the matching HOWTO structure. */
507 elfNN_ia64_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
509 Elf_Internal_Rela
*elf_reloc
)
512 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc
->r_info
));
515 #define PLT_HEADER_SIZE (3 * 16)
516 #define PLT_MIN_ENTRY_SIZE (1 * 16)
517 #define PLT_FULL_ENTRY_SIZE (2 * 16)
518 #define PLT_RESERVED_WORDS 3
520 static const bfd_byte plt_header
[PLT_HEADER_SIZE
] =
522 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
523 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
524 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
525 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
526 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
527 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
528 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
529 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
530 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
533 static const bfd_byte plt_min_entry
[PLT_MIN_ENTRY_SIZE
] =
535 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
536 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
537 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
540 static const bfd_byte plt_full_entry
[PLT_FULL_ENTRY_SIZE
] =
542 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
543 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
544 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
545 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
546 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
547 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
550 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
552 static const bfd_byte oor_brl
[16] =
554 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
556 0x00, 0x00, 0x00, 0xc0
559 static const bfd_byte oor_ip
[48] =
561 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
562 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
563 0x01, 0x00, 0x00, 0x60,
564 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
565 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
566 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
567 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
568 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
569 0x60, 0x00, 0x80, 0x00 /* br b6;; */
572 static size_t oor_branch_size
= sizeof (oor_brl
);
575 bfd_elfNN_ia64_after_parse (int itanium
)
577 oor_branch_size
= itanium
? sizeof (oor_ip
) : sizeof (oor_brl
);
580 #define BTYPE_SHIFT 6
587 #define OPCODE_SHIFT 37
589 #define OPCODE_BITS (0xfLL << OPCODE_SHIFT)
590 #define X6_BITS (0x3fLL << X6_SHIFT)
591 #define X4_BITS (0xfLL << X4_SHIFT)
592 #define X3_BITS (0x7LL << X3_SHIFT)
593 #define X2_BITS (0x3LL << X2_SHIFT)
594 #define X_BITS (0x1LL << X_SHIFT)
595 #define Y_BITS (0x1LL << Y_SHIFT)
596 #define BTYPE_BITS (0x7LL << BTYPE_SHIFT)
597 #define PREDICATE_BITS (0x3fLL)
599 #define IS_NOP_B(i) \
600 (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
601 #define IS_NOP_F(i) \
602 (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
603 == (0x1LL << X6_SHIFT))
604 #define IS_NOP_I(i) \
605 (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
606 == (0x1LL << X6_SHIFT))
607 #define IS_NOP_M(i) \
608 (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
609 == (0x1LL << X4_SHIFT))
610 #define IS_BR_COND(i) \
611 (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
612 #define IS_BR_CALL(i) \
613 (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
616 elfNN_ia64_relax_br (bfd_byte
*contents
, bfd_vma off
)
618 unsigned int template, mlx
;
619 bfd_vma t0
, t1
, s0
, s1
, s2
, br_code
;
623 hit_addr
= (bfd_byte
*) (contents
+ off
);
624 br_slot
= (long) hit_addr
& 0x3;
626 t0
= bfd_getl64 (hit_addr
+ 0);
627 t1
= bfd_getl64 (hit_addr
+ 8);
629 /* Check if we can turn br into brl. A label is always at the start
630 of the bundle. Even if there are predicates on NOPs, we still
631 perform this optimization. */
632 template = t0
& 0x1e;
633 s0
= (t0
>> 5) & 0x1ffffffffffLL
;
634 s1
= ((t0
>> 46) | (t1
<< 18)) & 0x1ffffffffffLL
;
635 s2
= (t1
>> 23) & 0x1ffffffffffLL
;
639 /* Check if slot 1 and slot 2 are NOPs. Possible template is
640 BBB. We only need to check nop.b. */
641 if (!(IS_NOP_B (s1
) && IS_NOP_B (s2
)))
646 /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
647 For BBB, slot 0 also has to be nop.b. */
648 if (!((template == 0x12 /* MBB */
650 || (template == 0x16 /* BBB */
657 /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
658 MMB and MFB. For BBB, slot 0 also has to be nop.b. */
659 if (!((template == 0x10 /* MIB */
661 || (template == 0x12 /* MBB */
663 || (template == 0x16 /* BBB */
666 || (template == 0x18 /* MMB */
668 || (template == 0x1c /* MFB */
674 /* It should never happen. */
678 /* We can turn br.cond/br.call into brl.cond/brl.call. */
679 if (!(IS_BR_COND (br_code
) || IS_BR_CALL (br_code
)))
682 /* Turn br into brl by setting bit 40. */
683 br_code
|= 0x1LL
<< 40;
685 /* Turn the old bundle into a MLX bundle with the same stop-bit
692 if (template == 0x16)
694 /* For BBB, we need to put nop.m in slot 0. We keep the original
695 predicate only if slot 0 isn't br. */
699 t0
&= PREDICATE_BITS
<< 5;
700 t0
|= 0x1LL
<< (X4_SHIFT
+ 5);
704 /* Keep the original instruction in slot 0. */
705 t0
&= 0x1ffffffffffLL
<< 5;
710 /* Put brl in slot 1. */
713 bfd_putl64 (t0
, hit_addr
);
714 bfd_putl64 (t1
, hit_addr
+ 8);
719 elfNN_ia64_relax_brl (bfd_byte
*contents
, bfd_vma off
)
723 bfd_vma t0
, t1
, i0
, i1
, i2
;
725 hit_addr
= (bfd_byte
*) (contents
+ off
);
726 hit_addr
-= (long) hit_addr
& 0x3;
727 t0
= bfd_getl64 (hit_addr
);
728 t1
= bfd_getl64 (hit_addr
+ 8);
730 /* Keep the instruction in slot 0. */
731 i0
= (t0
>> 5) & 0x1ffffffffffLL
;
732 /* Use nop.b for slot 1. */
734 /* For slot 2, turn brl into br by masking out bit 40. */
735 i2
= (t1
>> 23) & 0x0ffffffffffLL
;
737 /* Turn a MLX bundle into a MBB bundle with the same stop-bit
743 t0
= (i1
<< 46) | (i0
<< 5) | template;
744 t1
= (i2
<< 23) | (i1
>> 18);
746 bfd_putl64 (t0
, hit_addr
);
747 bfd_putl64 (t1
, hit_addr
+ 8);
750 /* Rename some of the generic section flags to better document how they
752 #define skip_relax_pass_0 need_finalize_relax
753 #define skip_relax_pass_1 has_gp_reloc
756 /* These functions do relaxation for IA-64 ELF. */
759 elfNN_ia64_relax_section (bfd
*abfd
, asection
*sec
,
760 struct bfd_link_info
*link_info
,
765 struct one_fixup
*next
;
771 Elf_Internal_Shdr
*symtab_hdr
;
772 Elf_Internal_Rela
*internal_relocs
;
773 Elf_Internal_Rela
*irel
, *irelend
;
775 Elf_Internal_Sym
*isymbuf
= NULL
;
776 struct elfNN_ia64_link_hash_table
*ia64_info
;
777 struct one_fixup
*fixups
= NULL
;
778 bfd_boolean changed_contents
= FALSE
;
779 bfd_boolean changed_relocs
= FALSE
;
780 bfd_boolean changed_got
= FALSE
;
781 bfd_boolean skip_relax_pass_0
= TRUE
;
782 bfd_boolean skip_relax_pass_1
= TRUE
;
785 /* Assume we're not going to change any sizes, and we'll only need
789 /* Don't even try to relax for non-ELF outputs. */
790 if (!is_elf_hash_table (link_info
->hash
))
793 /* Nothing to do if there are no relocations or there is no need for
795 if ((sec
->flags
& SEC_RELOC
) == 0
796 || sec
->reloc_count
== 0
797 || (link_info
->relax_pass
== 0 && sec
->skip_relax_pass_0
)
798 || (link_info
->relax_pass
== 1 && sec
->skip_relax_pass_1
))
801 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
803 /* Load the relocations for this section. */
804 internal_relocs
= (_bfd_elf_link_read_relocs
805 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
806 link_info
->keep_memory
));
807 if (internal_relocs
== NULL
)
810 ia64_info
= elfNN_ia64_hash_table (link_info
);
811 irelend
= internal_relocs
+ sec
->reloc_count
;
813 /* Get the section contents. */
814 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
815 contents
= elf_section_data (sec
)->this_hdr
.contents
;
818 if (!bfd_malloc_and_get_section (abfd
, sec
, &contents
))
822 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
824 unsigned long r_type
= ELFNN_R_TYPE (irel
->r_info
);
825 bfd_vma symaddr
, reladdr
, trampoff
, toff
, roff
;
829 bfd_boolean is_branch
;
830 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
835 case R_IA64_PCREL21B
:
836 case R_IA64_PCREL21BI
:
837 case R_IA64_PCREL21M
:
838 case R_IA64_PCREL21F
:
839 /* In pass 1, all br relaxations are done. We can skip it. */
840 if (link_info
->relax_pass
== 1)
842 skip_relax_pass_0
= FALSE
;
846 case R_IA64_PCREL60B
:
847 /* We can't optimize brl to br in pass 0 since br relaxations
848 will increase the code size. Defer it to pass 1. */
849 if (link_info
->relax_pass
== 0)
851 skip_relax_pass_1
= FALSE
;
857 case R_IA64_LTOFF22X
:
859 /* We can't relax ldx/mov in pass 0 since br relaxations will
860 increase the code size. Defer it to pass 1. */
861 if (link_info
->relax_pass
== 0)
863 skip_relax_pass_1
= FALSE
;
873 /* Get the value of the symbol referred to by the reloc. */
874 if (ELFNN_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
876 /* A local symbol. */
877 Elf_Internal_Sym
*isym
;
879 /* Read this BFD's local symbols. */
882 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
884 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
885 symtab_hdr
->sh_info
, 0,
891 isym
= isymbuf
+ ELFNN_R_SYM (irel
->r_info
);
892 if (isym
->st_shndx
== SHN_UNDEF
)
893 continue; /* We can't do anything with undefined symbols. */
894 else if (isym
->st_shndx
== SHN_ABS
)
895 tsec
= bfd_abs_section_ptr
;
896 else if (isym
->st_shndx
== SHN_COMMON
)
897 tsec
= bfd_com_section_ptr
;
898 else if (isym
->st_shndx
== SHN_IA_64_ANSI_COMMON
)
899 tsec
= bfd_com_section_ptr
;
901 tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
903 toff
= isym
->st_value
;
904 dyn_i
= get_dyn_sym_info (ia64_info
, NULL
, abfd
, irel
, FALSE
);
905 symtype
= ELF_ST_TYPE (isym
->st_info
);
910 struct elf_link_hash_entry
*h
;
912 indx
= ELFNN_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
913 h
= elf_sym_hashes (abfd
)[indx
];
914 BFD_ASSERT (h
!= NULL
);
916 while (h
->root
.type
== bfd_link_hash_indirect
917 || h
->root
.type
== bfd_link_hash_warning
)
918 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
920 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, irel
, FALSE
);
922 /* For branches to dynamic symbols, we're interested instead
923 in a branch to the PLT entry. */
924 if (is_branch
&& dyn_i
&& dyn_i
->want_plt2
)
926 /* Internal branches shouldn't be sent to the PLT.
927 Leave this for now and we'll give an error later. */
928 if (r_type
!= R_IA64_PCREL21B
)
931 tsec
= ia64_info
->plt_sec
;
932 toff
= dyn_i
->plt2_offset
;
933 BFD_ASSERT (irel
->r_addend
== 0);
936 /* Can't do anything else with dynamic symbols. */
937 else if (elfNN_ia64_dynamic_symbol_p (h
, link_info
, r_type
))
942 /* We can't do anything with undefined symbols. */
943 if (h
->root
.type
== bfd_link_hash_undefined
944 || h
->root
.type
== bfd_link_hash_undefweak
)
947 tsec
= h
->root
.u
.def
.section
;
948 toff
= h
->root
.u
.def
.value
;
954 if (tsec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
956 /* At this stage in linking, no SEC_MERGE symbol has been
957 adjusted, so all references to such symbols need to be
958 passed through _bfd_merged_section_offset. (Later, in
959 relocate_section, all SEC_MERGE symbols *except* for
960 section symbols have been adjusted.)
962 gas may reduce relocations against symbols in SEC_MERGE
963 sections to a relocation against the section symbol when
964 the original addend was zero. When the reloc is against
965 a section symbol we should include the addend in the
966 offset passed to _bfd_merged_section_offset, since the
967 location of interest is the original symbol. On the
968 other hand, an access to "sym+addend" where "sym" is not
969 a section symbol should not include the addend; Such an
970 access is presumed to be an offset from "sym"; The
971 location of interest is just "sym". */
972 if (symtype
== STT_SECTION
)
973 toff
+= irel
->r_addend
;
975 toff
= _bfd_merged_section_offset (abfd
, &tsec
,
976 elf_section_data (tsec
)->sec_info
,
979 if (symtype
!= STT_SECTION
)
980 toff
+= irel
->r_addend
;
983 toff
+= irel
->r_addend
;
985 symaddr
= tsec
->output_section
->vma
+ tsec
->output_offset
+ toff
;
987 roff
= irel
->r_offset
;
991 bfd_signed_vma offset
;
993 reladdr
= (sec
->output_section
->vma
995 + roff
) & (bfd_vma
) -4;
997 /* The .plt section is aligned at 32byte and the .text section
998 is aligned at 64byte. The .text section is right after the
999 .plt section. After the first relaxation pass, linker may
1000 increase the gap between the .plt and .text sections up
1001 to 32byte. We assume linker will always insert 32byte
1002 between the .plt and .text sections after the the first
1004 if (tsec
== ia64_info
->plt_sec
)
1005 offset
= -0x1000000 + 32;
1007 offset
= -0x1000000;
1009 /* If the branch is in range, no need to do anything. */
1010 if ((bfd_signed_vma
) (symaddr
- reladdr
) >= offset
1011 && (bfd_signed_vma
) (symaddr
- reladdr
) <= 0x0FFFFF0)
1013 /* If the 60-bit branch is in 21-bit range, optimize it. */
1014 if (r_type
== R_IA64_PCREL60B
)
1016 elfNN_ia64_relax_brl (contents
, roff
);
1019 = ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1022 /* If the original relocation offset points to slot
1023 1, change it to slot 2. */
1024 if ((irel
->r_offset
& 3) == 1)
1025 irel
->r_offset
+= 1;
1030 else if (r_type
== R_IA64_PCREL60B
)
1032 else if (elfNN_ia64_relax_br (contents
, roff
))
1035 = ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1038 /* Make the relocation offset point to slot 1. */
1039 irel
->r_offset
= (irel
->r_offset
& ~((bfd_vma
) 0x3)) + 1;
1043 /* We can't put a trampoline in a .init/.fini section. Issue
1045 if (strcmp (sec
->output_section
->name
, ".init") == 0
1046 || strcmp (sec
->output_section
->name
, ".fini") == 0)
1048 (*_bfd_error_handler
)
1049 (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
1050 sec
->owner
, sec
, (unsigned long) roff
);
1051 bfd_set_error (bfd_error_bad_value
);
1055 /* If the branch and target are in the same section, you've
1056 got one honking big section and we can't help you unless
1057 you are branching backwards. You'll get an error message
1059 if (tsec
== sec
&& toff
> roff
)
1062 /* Look for an existing fixup to this address. */
1063 for (f
= fixups
; f
; f
= f
->next
)
1064 if (f
->tsec
== tsec
&& f
->toff
== toff
)
1069 /* Two alternatives: If it's a branch to a PLT entry, we can
1070 make a copy of the FULL_PLT entry. Otherwise, we'll have
1071 to use a `brl' insn to get where we're going. */
1075 if (tsec
== ia64_info
->plt_sec
)
1076 size
= sizeof (plt_full_entry
);
1078 size
= oor_branch_size
;
1080 /* Resize the current section to make room for the new branch. */
1081 trampoff
= (sec
->size
+ 15) & (bfd_vma
) -16;
1083 /* If trampoline is out of range, there is nothing we
1085 offset
= trampoff
- (roff
& (bfd_vma
) -4);
1086 if (offset
< -0x1000000 || offset
> 0x0FFFFF0)
1089 amt
= trampoff
+ size
;
1090 contents
= (bfd_byte
*) bfd_realloc (contents
, amt
);
1091 if (contents
== NULL
)
1095 if (tsec
== ia64_info
->plt_sec
)
1097 memcpy (contents
+ trampoff
, plt_full_entry
, size
);
1099 /* Hijack the old relocation for use as the PLTOFF reloc. */
1100 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1102 irel
->r_offset
= trampoff
;
1106 if (size
== sizeof (oor_ip
))
1108 memcpy (contents
+ trampoff
, oor_ip
, size
);
1109 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1111 irel
->r_addend
-= 16;
1112 irel
->r_offset
= trampoff
+ 2;
1116 memcpy (contents
+ trampoff
, oor_brl
, size
);
1117 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1119 irel
->r_offset
= trampoff
+ 2;
1124 /* Record the fixup so we don't do it again this section. */
1125 f
= (struct one_fixup
*)
1126 bfd_malloc ((bfd_size_type
) sizeof (*f
));
1130 f
->trampoff
= trampoff
;
1135 /* If trampoline is out of range, there is nothing we
1137 offset
= f
->trampoff
- (roff
& (bfd_vma
) -4);
1138 if (offset
< -0x1000000 || offset
> 0x0FFFFF0)
1141 /* Nop out the reloc, since we're finalizing things here. */
1142 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
1145 /* Fix up the existing branch to hit the trampoline. */
1146 if (elfNN_ia64_install_value (contents
+ roff
, offset
, r_type
)
1150 changed_contents
= TRUE
;
1151 changed_relocs
= TRUE
;
1158 bfd
*obfd
= sec
->output_section
->owner
;
1159 gp
= _bfd_get_gp_value (obfd
);
1162 if (!elfNN_ia64_choose_gp (obfd
, link_info
))
1164 gp
= _bfd_get_gp_value (obfd
);
1168 /* If the data is out of range, do nothing. */
1169 if ((bfd_signed_vma
) (symaddr
- gp
) >= 0x200000
1170 ||(bfd_signed_vma
) (symaddr
- gp
) < -0x200000)
1173 if (r_type
== R_IA64_LTOFF22X
)
1175 irel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (irel
->r_info
),
1177 changed_relocs
= TRUE
;
1178 if (dyn_i
->want_gotx
)
1180 dyn_i
->want_gotx
= 0;
1181 changed_got
|= !dyn_i
->want_got
;
1186 elfNN_ia64_relax_ldxmov (contents
, roff
);
1187 irel
->r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
1188 changed_contents
= TRUE
;
1189 changed_relocs
= TRUE
;
1194 /* ??? If we created fixups, this may push the code segment large
1195 enough that the data segment moves, which will change the GP.
1196 Reset the GP so that we re-calculate next round. We need to
1197 do this at the _beginning_ of the next round; now will not do. */
1199 /* Clean up and go home. */
1202 struct one_fixup
*f
= fixups
;
1203 fixups
= fixups
->next
;
1208 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1210 if (! link_info
->keep_memory
)
1214 /* Cache the symbols for elf_link_input_bfd. */
1215 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1219 if (contents
!= NULL
1220 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1222 if (!changed_contents
&& !link_info
->keep_memory
)
1226 /* Cache the section contents for elf_link_input_bfd. */
1227 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1231 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
1233 if (!changed_relocs
)
1234 free (internal_relocs
);
1236 elf_section_data (sec
)->relocs
= internal_relocs
;
1241 struct elfNN_ia64_allocate_data data
;
1242 data
.info
= link_info
;
1244 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
1246 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
1247 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
1248 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
1249 ia64_info
->got_sec
->size
= data
.ofs
;
1251 if (ia64_info
->root
.dynamic_sections_created
1252 && ia64_info
->rel_got_sec
!= NULL
)
1254 /* Resize .rela.got. */
1255 ia64_info
->rel_got_sec
->size
= 0;
1256 if (link_info
->shared
1257 && ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
1258 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
1259 data
.only_got
= TRUE
;
1260 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
,
1265 if (link_info
->relax_pass
== 0)
1267 /* Pass 0 is only needed to relax br. */
1268 sec
->skip_relax_pass_0
= skip_relax_pass_0
;
1269 sec
->skip_relax_pass_1
= skip_relax_pass_1
;
1272 *again
= changed_contents
|| changed_relocs
;
1276 if (isymbuf
!= NULL
&& (unsigned char *) isymbuf
!= symtab_hdr
->contents
)
1278 if (contents
!= NULL
1279 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
1281 if (internal_relocs
!= NULL
1282 && elf_section_data (sec
)->relocs
!= internal_relocs
)
1283 free (internal_relocs
);
1286 #undef skip_relax_pass_0
1287 #undef skip_relax_pass_1
1290 elfNN_ia64_relax_ldxmov (bfd_byte
*contents
, bfd_vma off
)
1293 bfd_vma dword
, insn
;
1295 switch ((int)off
& 0x3)
1297 case 0: shift
= 5; break;
1298 case 1: shift
= 14; off
+= 3; break;
1299 case 2: shift
= 23; off
+= 6; break;
1304 dword
= bfd_getl64 (contents
+ off
);
1305 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
1307 r1
= (insn
>> 6) & 127;
1308 r3
= (insn
>> 20) & 127;
1310 insn
= 0x8000000; /* nop */
1312 insn
= (insn
& 0x7f01fff) | 0x10800000000LL
; /* (qp) mov r1 = r3 */
1314 dword
&= ~(0x1ffffffffffLL
<< shift
);
1315 dword
|= (insn
<< shift
);
1316 bfd_putl64 (dword
, contents
+ off
);
1319 /* Return TRUE if NAME is an unwind table section name. */
1321 static inline bfd_boolean
1322 is_unwind_section_name (bfd
*abfd
, const char *name
)
1324 if (elfNN_ia64_hpux_vec (abfd
->xvec
)
1325 && !strcmp (name
, ELF_STRING_ia64_unwind_hdr
))
1328 return ((CONST_STRNEQ (name
, ELF_STRING_ia64_unwind
)
1329 && ! CONST_STRNEQ (name
, ELF_STRING_ia64_unwind_info
))
1330 || CONST_STRNEQ (name
, ELF_STRING_ia64_unwind_once
));
1333 /* Handle an IA-64 specific section when reading an object file. This
1334 is called when bfd_section_from_shdr finds a section with an unknown
1338 elfNN_ia64_section_from_shdr (bfd
*abfd
,
1339 Elf_Internal_Shdr
*hdr
,
1345 /* There ought to be a place to keep ELF backend specific flags, but
1346 at the moment there isn't one. We just keep track of the
1347 sections by their name, instead. Fortunately, the ABI gives
1348 suggested names for all the MIPS specific sections, so we will
1349 probably get away with this. */
1350 switch (hdr
->sh_type
)
1352 case SHT_IA_64_UNWIND
:
1353 case SHT_IA_64_HP_OPT_ANOT
:
1357 if (strcmp (name
, ELF_STRING_ia64_archext
) != 0)
1365 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
1367 newsect
= hdr
->bfd_section
;
1372 /* Convert IA-64 specific section flags to bfd internal section flags. */
1374 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1378 elfNN_ia64_section_flags (flagword
*flags
,
1379 const Elf_Internal_Shdr
*hdr
)
1381 if (hdr
->sh_flags
& SHF_IA_64_SHORT
)
1382 *flags
|= SEC_SMALL_DATA
;
1387 /* Set the correct type for an IA-64 ELF section. We do this by the
1388 section name, which is a hack, but ought to work. */
1391 elfNN_ia64_fake_sections (bfd
*abfd
, Elf_Internal_Shdr
*hdr
,
1394 register const char *name
;
1396 name
= bfd_get_section_name (abfd
, sec
);
1398 if (is_unwind_section_name (abfd
, name
))
1400 /* We don't have the sections numbered at this point, so sh_info
1401 is set later, in elfNN_ia64_final_write_processing. */
1402 hdr
->sh_type
= SHT_IA_64_UNWIND
;
1403 hdr
->sh_flags
|= SHF_LINK_ORDER
;
1405 else if (strcmp (name
, ELF_STRING_ia64_archext
) == 0)
1406 hdr
->sh_type
= SHT_IA_64_EXT
;
1407 else if (strcmp (name
, ".HP.opt_annot") == 0)
1408 hdr
->sh_type
= SHT_IA_64_HP_OPT_ANOT
;
1409 else if (strcmp (name
, ".reloc") == 0)
1410 /* This is an ugly, but unfortunately necessary hack that is
1411 needed when producing EFI binaries on IA-64. It tells
1412 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1413 containing ELF relocation info. We need this hack in order to
1414 be able to generate ELF binaries that can be translated into
1415 EFI applications (which are essentially COFF objects). Those
1416 files contain a COFF ".reloc" section inside an ELFNN object,
1417 which would normally cause BFD to segfault because it would
1418 attempt to interpret this section as containing relocation
1419 entries for section "oc". With this hack enabled, ".reloc"
1420 will be treated as a normal data section, which will avoid the
1421 segfault. However, you won't be able to create an ELFNN binary
1422 with a section named "oc" that needs relocations, but that's
1423 the kind of ugly side-effects you get when detecting section
1424 types based on their names... In practice, this limitation is
1425 unlikely to bite. */
1426 hdr
->sh_type
= SHT_PROGBITS
;
1428 if (sec
->flags
& SEC_SMALL_DATA
)
1429 hdr
->sh_flags
|= SHF_IA_64_SHORT
;
1431 /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
1433 if (elfNN_ia64_hpux_vec (abfd
->xvec
) && (sec
->flags
& SHF_TLS
))
1434 hdr
->sh_flags
|= SHF_IA_64_HP_TLS
;
1439 /* The final processing done just before writing out an IA-64 ELF
1443 elfNN_ia64_final_write_processing (bfd
*abfd
,
1444 bfd_boolean linker ATTRIBUTE_UNUSED
)
1446 Elf_Internal_Shdr
*hdr
;
1449 for (s
= abfd
->sections
; s
; s
= s
->next
)
1451 hdr
= &elf_section_data (s
)->this_hdr
;
1452 switch (hdr
->sh_type
)
1454 case SHT_IA_64_UNWIND
:
1455 /* The IA-64 processor-specific ABI requires setting sh_link
1456 to the unwind section, whereas HP-UX requires sh_info to
1457 do so. For maximum compatibility, we'll set both for
1459 hdr
->sh_info
= hdr
->sh_link
;
1464 if (! elf_flags_init (abfd
))
1466 unsigned long flags
= 0;
1468 if (abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
)
1469 flags
|= EF_IA_64_BE
;
1470 if (bfd_get_mach (abfd
) == bfd_mach_ia64_elf64
)
1471 flags
|= EF_IA_64_ABI64
;
1473 elf_elfheader(abfd
)->e_flags
= flags
;
1474 elf_flags_init (abfd
) = TRUE
;
1478 /* Hook called by the linker routine which adds symbols from an object
1479 file. We use it to put .comm items in .sbss, and not .bss. */
1482 elfNN_ia64_add_symbol_hook (bfd
*abfd
,
1483 struct bfd_link_info
*info
,
1484 Elf_Internal_Sym
*sym
,
1485 const char **namep ATTRIBUTE_UNUSED
,
1486 flagword
*flagsp ATTRIBUTE_UNUSED
,
1490 if (sym
->st_shndx
== SHN_COMMON
1491 && !info
->relocatable
1492 && sym
->st_size
<= elf_gp_size (abfd
))
1494 /* Common symbols less than or equal to -G nn bytes are
1495 automatically put into .sbss. */
1497 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
1501 scomm
= bfd_make_section_with_flags (abfd
, ".scommon",
1504 | SEC_LINKER_CREATED
));
1510 *valp
= sym
->st_size
;
1516 /* Return the number of additional phdrs we will need. */
1519 elfNN_ia64_additional_program_headers (bfd
*abfd
,
1520 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1525 /* See if we need a PT_IA_64_ARCHEXT segment. */
1526 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1527 if (s
&& (s
->flags
& SEC_LOAD
))
1530 /* Count how many PT_IA_64_UNWIND segments we need. */
1531 for (s
= abfd
->sections
; s
; s
= s
->next
)
1532 if (is_unwind_section_name (abfd
, s
->name
) && (s
->flags
& SEC_LOAD
))
1539 elfNN_ia64_modify_segment_map (bfd
*abfd
,
1540 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1542 struct elf_segment_map
*m
, **pm
;
1543 Elf_Internal_Shdr
*hdr
;
1546 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1547 all PT_LOAD segments. */
1548 s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_archext
);
1549 if (s
&& (s
->flags
& SEC_LOAD
))
1551 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1552 if (m
->p_type
== PT_IA_64_ARCHEXT
)
1556 m
= ((struct elf_segment_map
*)
1557 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1561 m
->p_type
= PT_IA_64_ARCHEXT
;
1565 /* We want to put it after the PHDR and INTERP segments. */
1566 pm
= &elf_tdata (abfd
)->segment_map
;
1568 && ((*pm
)->p_type
== PT_PHDR
1569 || (*pm
)->p_type
== PT_INTERP
))
1577 /* Install PT_IA_64_UNWIND segments, if needed. */
1578 for (s
= abfd
->sections
; s
; s
= s
->next
)
1580 hdr
= &elf_section_data (s
)->this_hdr
;
1581 if (hdr
->sh_type
!= SHT_IA_64_UNWIND
)
1584 if (s
&& (s
->flags
& SEC_LOAD
))
1586 for (m
= elf_tdata (abfd
)->segment_map
; m
!= NULL
; m
= m
->next
)
1587 if (m
->p_type
== PT_IA_64_UNWIND
)
1591 /* Look through all sections in the unwind segment
1592 for a match since there may be multiple sections
1594 for (i
= m
->count
- 1; i
>= 0; --i
)
1595 if (m
->sections
[i
] == s
)
1604 m
= ((struct elf_segment_map
*)
1605 bfd_zalloc (abfd
, (bfd_size_type
) sizeof *m
));
1609 m
->p_type
= PT_IA_64_UNWIND
;
1614 /* We want to put it last. */
1615 pm
= &elf_tdata (abfd
)->segment_map
;
1626 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1627 the input sections for each output section in the segment and testing
1628 for SHF_IA_64_NORECOV on each. */
1631 elfNN_ia64_modify_program_headers (bfd
*abfd
,
1632 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1634 struct elf_obj_tdata
*tdata
= elf_tdata (abfd
);
1635 struct elf_segment_map
*m
;
1636 Elf_Internal_Phdr
*p
;
1638 for (p
= tdata
->phdr
, m
= tdata
->segment_map
; m
!= NULL
; m
= m
->next
, p
++)
1639 if (m
->p_type
== PT_LOAD
)
1642 for (i
= m
->count
- 1; i
>= 0; --i
)
1644 struct bfd_link_order
*order
= m
->sections
[i
]->map_head
.link_order
;
1646 while (order
!= NULL
)
1648 if (order
->type
== bfd_indirect_link_order
)
1650 asection
*is
= order
->u
.indirect
.section
;
1651 bfd_vma flags
= elf_section_data(is
)->this_hdr
.sh_flags
;
1652 if (flags
& SHF_IA_64_NORECOV
)
1654 p
->p_flags
|= PF_IA_64_NORECOV
;
1658 order
= order
->next
;
1667 /* According to the Tahoe assembler spec, all labels starting with a
1671 elfNN_ia64_is_local_label_name (bfd
*abfd ATTRIBUTE_UNUSED
,
1674 return name
[0] == '.';
1677 /* Should we do dynamic things to this symbol? */
1680 elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry
*h
,
1681 struct bfd_link_info
*info
, int r_type
)
1683 bfd_boolean ignore_protected
1684 = ((r_type
& 0xf8) == 0x40 /* FPTR relocs */
1685 || (r_type
& 0xf8) == 0x50); /* LTOFF_FPTR relocs */
1687 return _bfd_elf_dynamic_symbol_p (h
, info
, ignore_protected
);
1690 static struct bfd_hash_entry
*
1691 elfNN_ia64_new_elf_hash_entry (struct bfd_hash_entry
*entry
,
1692 struct bfd_hash_table
*table
,
1695 struct elfNN_ia64_link_hash_entry
*ret
;
1696 ret
= (struct elfNN_ia64_link_hash_entry
*) entry
;
1698 /* Allocate the structure if it has not already been allocated by a
1701 ret
= bfd_hash_allocate (table
, sizeof (*ret
));
1706 /* Call the allocation method of the superclass. */
1707 ret
= ((struct elfNN_ia64_link_hash_entry
*)
1708 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1713 ret
->sorted_count
= 0;
1715 return (struct bfd_hash_entry
*) ret
;
1719 elfNN_ia64_hash_copy_indirect (struct bfd_link_info
*info
,
1720 struct elf_link_hash_entry
*xdir
,
1721 struct elf_link_hash_entry
*xind
)
1723 struct elfNN_ia64_link_hash_entry
*dir
, *ind
;
1725 dir
= (struct elfNN_ia64_link_hash_entry
*) xdir
;
1726 ind
= (struct elfNN_ia64_link_hash_entry
*) xind
;
1728 /* Copy down any references that we may have already seen to the
1729 symbol which just became indirect. */
1731 dir
->root
.ref_dynamic
|= ind
->root
.ref_dynamic
;
1732 dir
->root
.ref_regular
|= ind
->root
.ref_regular
;
1733 dir
->root
.ref_regular_nonweak
|= ind
->root
.ref_regular_nonweak
;
1734 dir
->root
.needs_plt
|= ind
->root
.needs_plt
;
1736 if (ind
->root
.root
.type
!= bfd_link_hash_indirect
)
1739 /* Copy over the got and plt data. This would have been done
1742 if (ind
->info
!= NULL
)
1744 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1750 dir
->info
= ind
->info
;
1751 dir
->count
= ind
->count
;
1752 dir
->sorted_count
= ind
->sorted_count
;
1753 dir
->size
= ind
->size
;
1757 ind
->sorted_count
= 0;
1760 /* Fix up the dyn_sym_info pointers to the global symbol. */
1761 for (count
= dir
->count
, dyn_i
= dir
->info
;
1764 dyn_i
->h
= &dir
->root
;
1767 /* Copy over the dynindx. */
1769 if (ind
->root
.dynindx
!= -1)
1771 if (dir
->root
.dynindx
!= -1)
1772 _bfd_elf_strtab_delref (elf_hash_table (info
)->dynstr
,
1773 dir
->root
.dynstr_index
);
1774 dir
->root
.dynindx
= ind
->root
.dynindx
;
1775 dir
->root
.dynstr_index
= ind
->root
.dynstr_index
;
1776 ind
->root
.dynindx
= -1;
1777 ind
->root
.dynstr_index
= 0;
1782 elfNN_ia64_hash_hide_symbol (struct bfd_link_info
*info
,
1783 struct elf_link_hash_entry
*xh
,
1784 bfd_boolean force_local
)
1786 struct elfNN_ia64_link_hash_entry
*h
;
1787 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1790 h
= (struct elfNN_ia64_link_hash_entry
*)xh
;
1792 _bfd_elf_link_hash_hide_symbol (info
, &h
->root
, force_local
);
1794 for (count
= h
->count
, dyn_i
= h
->info
;
1798 dyn_i
->want_plt2
= 0;
1799 dyn_i
->want_plt
= 0;
1803 /* Compute a hash of a local hash entry. */
1806 elfNN_ia64_local_htab_hash (const void *ptr
)
1808 struct elfNN_ia64_local_hash_entry
*entry
1809 = (struct elfNN_ia64_local_hash_entry
*) ptr
;
1811 return (((entry
->id
& 0xff) << 24) | ((entry
->id
& 0xff00) << 8))
1812 ^ entry
->r_sym
^ (entry
->id
>> 16);
1815 /* Compare local hash entries. */
1818 elfNN_ia64_local_htab_eq (const void *ptr1
, const void *ptr2
)
1820 struct elfNN_ia64_local_hash_entry
*entry1
1821 = (struct elfNN_ia64_local_hash_entry
*) ptr1
;
1822 struct elfNN_ia64_local_hash_entry
*entry2
1823 = (struct elfNN_ia64_local_hash_entry
*) ptr2
;
1825 return entry1
->id
== entry2
->id
&& entry1
->r_sym
== entry2
->r_sym
;
1828 /* Create the derived linker hash table. The IA-64 ELF port uses this
1829 derived hash table to keep information specific to the IA-64 ElF
1830 linker (without using static variables). */
1832 static struct bfd_link_hash_table
*
1833 elfNN_ia64_hash_table_create (bfd
*abfd
)
1835 struct elfNN_ia64_link_hash_table
*ret
;
1837 ret
= bfd_zmalloc ((bfd_size_type
) sizeof (*ret
));
1841 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
1842 elfNN_ia64_new_elf_hash_entry
,
1843 sizeof (struct elfNN_ia64_link_hash_entry
)))
1849 ret
->loc_hash_table
= htab_try_create (1024, elfNN_ia64_local_htab_hash
,
1850 elfNN_ia64_local_htab_eq
, NULL
);
1851 ret
->loc_hash_memory
= objalloc_create ();
1852 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
1858 return &ret
->root
.root
;
1861 /* Free the global elfNN_ia64_dyn_sym_info array. */
1864 elfNN_ia64_global_dyn_info_free (void **xentry
,
1865 PTR unused ATTRIBUTE_UNUSED
)
1867 struct elfNN_ia64_link_hash_entry
*entry
1868 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1870 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
1871 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
1878 entry
->sorted_count
= 0;
1885 /* Free the local elfNN_ia64_dyn_sym_info array. */
1888 elfNN_ia64_local_dyn_info_free (void **slot
,
1889 PTR unused ATTRIBUTE_UNUSED
)
1891 struct elfNN_ia64_local_hash_entry
*entry
1892 = (struct elfNN_ia64_local_hash_entry
*) *slot
;
1899 entry
->sorted_count
= 0;
1906 /* Destroy IA-64 linker hash table. */
1909 elfNN_ia64_hash_table_free (struct bfd_link_hash_table
*hash
)
1911 struct elfNN_ia64_link_hash_table
*ia64_info
1912 = (struct elfNN_ia64_link_hash_table
*) hash
;
1913 if (ia64_info
->loc_hash_table
)
1915 htab_traverse (ia64_info
->loc_hash_table
,
1916 elfNN_ia64_local_dyn_info_free
, NULL
);
1917 htab_delete (ia64_info
->loc_hash_table
);
1919 if (ia64_info
->loc_hash_memory
)
1920 objalloc_free ((struct objalloc
*) ia64_info
->loc_hash_memory
);
1921 elf_link_hash_traverse (&ia64_info
->root
,
1922 elfNN_ia64_global_dyn_info_free
, NULL
);
1923 _bfd_generic_link_hash_table_free (hash
);
1926 /* Traverse both local and global hash tables. */
1928 struct elfNN_ia64_dyn_sym_traverse_data
1930 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
);
1935 elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry
*xentry
,
1938 struct elfNN_ia64_link_hash_entry
*entry
1939 = (struct elfNN_ia64_link_hash_entry
*) xentry
;
1940 struct elfNN_ia64_dyn_sym_traverse_data
*data
1941 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1942 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1945 if (entry
->root
.root
.type
== bfd_link_hash_warning
)
1946 entry
= (struct elfNN_ia64_link_hash_entry
*) entry
->root
.root
.u
.i
.link
;
1948 for (count
= entry
->count
, dyn_i
= entry
->info
;
1951 if (! (*data
->func
) (dyn_i
, data
->data
))
1957 elfNN_ia64_local_dyn_sym_thunk (void **slot
, PTR xdata
)
1959 struct elfNN_ia64_local_hash_entry
*entry
1960 = (struct elfNN_ia64_local_hash_entry
*) *slot
;
1961 struct elfNN_ia64_dyn_sym_traverse_data
*data
1962 = (struct elfNN_ia64_dyn_sym_traverse_data
*) xdata
;
1963 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
1966 for (count
= entry
->count
, dyn_i
= entry
->info
;
1969 if (! (*data
->func
) (dyn_i
, data
->data
))
1975 elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table
*ia64_info
,
1976 bfd_boolean (*func
) (struct elfNN_ia64_dyn_sym_info
*, PTR
),
1979 struct elfNN_ia64_dyn_sym_traverse_data xdata
;
1984 elf_link_hash_traverse (&ia64_info
->root
,
1985 elfNN_ia64_global_dyn_sym_thunk
, &xdata
);
1986 htab_traverse (ia64_info
->loc_hash_table
,
1987 elfNN_ia64_local_dyn_sym_thunk
, &xdata
);
1991 elfNN_ia64_create_dynamic_sections (bfd
*abfd
,
1992 struct bfd_link_info
*info
)
1994 struct elfNN_ia64_link_hash_table
*ia64_info
;
1997 if (! _bfd_elf_create_dynamic_sections (abfd
, info
))
2000 ia64_info
= elfNN_ia64_hash_table (info
);
2002 ia64_info
->plt_sec
= bfd_get_section_by_name (abfd
, ".plt");
2003 ia64_info
->got_sec
= bfd_get_section_by_name (abfd
, ".got");
2006 flagword flags
= bfd_get_section_flags (abfd
, ia64_info
->got_sec
);
2007 bfd_set_section_flags (abfd
, ia64_info
->got_sec
, SEC_SMALL_DATA
| flags
);
2008 /* The .got section is always aligned at 8 bytes. */
2009 bfd_set_section_alignment (abfd
, ia64_info
->got_sec
, 3);
2012 if (!get_pltoff (abfd
, info
, ia64_info
))
2015 s
= bfd_make_section_with_flags (abfd
, ".rela.IA_64.pltoff",
2016 (SEC_ALLOC
| SEC_LOAD
2019 | SEC_LINKER_CREATED
2022 || !bfd_set_section_alignment (abfd
, s
, LOG_SECTION_ALIGN
))
2024 ia64_info
->rel_pltoff_sec
= s
;
2026 s
= bfd_make_section_with_flags (abfd
, ".rela.got",
2027 (SEC_ALLOC
| SEC_LOAD
2030 | SEC_LINKER_CREATED
2033 || !bfd_set_section_alignment (abfd
, s
, LOG_SECTION_ALIGN
))
2035 ia64_info
->rel_got_sec
= s
;
2040 /* Find and/or create a hash entry for local symbol. */
2041 static struct elfNN_ia64_local_hash_entry
*
2042 get_local_sym_hash (struct elfNN_ia64_link_hash_table
*ia64_info
,
2043 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
2046 struct elfNN_ia64_local_hash_entry e
, *ret
;
2047 asection
*sec
= abfd
->sections
;
2048 hashval_t h
= (((sec
->id
& 0xff) << 24) | ((sec
->id
& 0xff00) << 8))
2049 ^ ELFNN_R_SYM (rel
->r_info
) ^ (sec
->id
>> 16);
2053 e
.r_sym
= ELFNN_R_SYM (rel
->r_info
);
2054 slot
= htab_find_slot_with_hash (ia64_info
->loc_hash_table
, &e
, h
,
2055 create
? INSERT
: NO_INSERT
);
2061 return (struct elfNN_ia64_local_hash_entry
*) *slot
;
2063 ret
= (struct elfNN_ia64_local_hash_entry
*)
2064 objalloc_alloc ((struct objalloc
*) ia64_info
->loc_hash_memory
,
2065 sizeof (struct elfNN_ia64_local_hash_entry
));
2068 memset (ret
, 0, sizeof (*ret
));
2070 ret
->r_sym
= ELFNN_R_SYM (rel
->r_info
);
2076 /* Used to sort elfNN_ia64_dyn_sym_info array. */
2079 addend_compare (const void *xp
, const void *yp
)
2081 const struct elfNN_ia64_dyn_sym_info
*x
2082 = (const struct elfNN_ia64_dyn_sym_info
*) xp
;
2083 const struct elfNN_ia64_dyn_sym_info
*y
2084 = (const struct elfNN_ia64_dyn_sym_info
*) yp
;
2086 return x
->addend
< y
->addend
? -1 : x
->addend
> y
->addend
? 1 : 0;
2089 /* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
2092 sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info
*info
,
2095 bfd_vma curr
, prev
, got_offset
;
2096 unsigned int i
, kept
, dup
, diff
, dest
, src
, len
;
2098 qsort (info
, count
, sizeof (*info
), addend_compare
);
2100 /* Find the first duplicate. */
2101 prev
= info
[0].addend
;
2102 got_offset
= info
[0].got_offset
;
2103 for (i
= 1; i
< count
; i
++)
2105 curr
= info
[i
].addend
;
2108 /* For duplicates, make sure that GOT_OFFSET is valid. */
2109 if (got_offset
== (bfd_vma
) -1)
2110 got_offset
= info
[i
].got_offset
;
2113 got_offset
= info
[i
].got_offset
;
2117 /* We may move a block of elements to here. */
2120 /* Remove duplicates. */
2125 /* For duplicates, make sure that the kept one has a valid
2128 if (got_offset
!= (bfd_vma
) -1)
2129 info
[kept
].got_offset
= got_offset
;
2131 curr
= info
[i
].addend
;
2132 got_offset
= info
[i
].got_offset
;
2134 /* Move a block of elements whose first one is different from
2138 for (src
= i
+ 1; src
< count
; src
++)
2140 if (info
[src
].addend
!= curr
)
2142 /* For duplicates, make sure that GOT_OFFSET is
2144 if (got_offset
== (bfd_vma
) -1)
2145 got_offset
= info
[src
].got_offset
;
2148 /* Make sure that the kept one has a valid got_offset. */
2149 if (got_offset
!= (bfd_vma
) -1)
2150 info
[kept
].got_offset
= got_offset
;
2158 /* Find the next duplicate. SRC will be kept. */
2159 prev
= info
[src
].addend
;
2160 got_offset
= info
[src
].got_offset
;
2161 for (dup
= src
+ 1; dup
< count
; dup
++)
2163 curr
= info
[dup
].addend
;
2166 /* Make sure that got_offset is valid. */
2167 if (got_offset
== (bfd_vma
) -1)
2168 got_offset
= info
[dup
].got_offset
;
2170 /* For duplicates, make sure that the kept one has
2171 a valid got_offset. */
2172 if (got_offset
!= (bfd_vma
) -1)
2173 info
[dup
- 1].got_offset
= got_offset
;
2176 got_offset
= info
[dup
].got_offset
;
2180 /* How much to move. */
2184 if (len
== 1 && dup
< count
)
2186 /* If we only move 1 element, we combine it with the next
2187 one. There must be at least a duplicate. Find the
2188 next different one. */
2189 for (diff
= dup
+ 1, src
++; diff
< count
; diff
++, src
++)
2191 if (info
[diff
].addend
!= curr
)
2193 /* Make sure that got_offset is valid. */
2194 if (got_offset
== (bfd_vma
) -1)
2195 got_offset
= info
[diff
].got_offset
;
2198 /* Makre sure that the last duplicated one has an valid
2200 BFD_ASSERT (curr
== prev
);
2201 if (got_offset
!= (bfd_vma
) -1)
2202 info
[diff
- 1].got_offset
= got_offset
;
2206 /* Find the next duplicate. Track the current valid
2208 prev
= info
[diff
].addend
;
2209 got_offset
= info
[diff
].got_offset
;
2210 for (dup
= diff
+ 1; dup
< count
; dup
++)
2212 curr
= info
[dup
].addend
;
2215 /* For duplicates, make sure that GOT_OFFSET
2217 if (got_offset
== (bfd_vma
) -1)
2218 got_offset
= info
[dup
].got_offset
;
2221 got_offset
= info
[dup
].got_offset
;
2226 len
= diff
- src
+ 1;
2231 memmove (&info
[dest
], &info
[src
], len
* sizeof (*info
));
2240 /* When we get here, either there is no duplicate at all or
2241 the only duplicate is the last element. */
2244 /* If the last element is a duplicate, make sure that the
2245 kept one has a valid got_offset. We also update count. */
2246 if (got_offset
!= (bfd_vma
) -1)
2247 info
[dest
- 1].got_offset
= got_offset
;
2255 /* Find and/or create a descriptor for dynamic symbol info. This will
2256 vary based on global or local symbol, and the addend to the reloc.
2258 We don't sort when inserting. Also, we sort and eliminate
2259 duplicates if there is an unsorted section. Typically, this will
2260 only happen once, because we do all insertions before lookups. We
2261 then use bsearch to do a lookup. This also allows lookups to be
2262 fast. So we have fast insertion (O(log N) due to duplicate check),
2263 fast lookup (O(log N)) and one sort (O(N log N) expected time).
2264 Previously, all lookups were O(N) because of the use of the linked
2265 list and also all insertions were O(N) because of the check for
2266 duplicates. There are some complications here because the array
2267 size grows occasionally, which may add an O(N) factor, but this
2268 should be rare. Also, we free the excess array allocation, which
2269 requires a copy which is O(N), but this only happens once. */
2271 static struct elfNN_ia64_dyn_sym_info
*
2272 get_dyn_sym_info (struct elfNN_ia64_link_hash_table
*ia64_info
,
2273 struct elf_link_hash_entry
*h
, bfd
*abfd
,
2274 const Elf_Internal_Rela
*rel
, bfd_boolean create
)
2276 struct elfNN_ia64_dyn_sym_info
**info_p
, *info
, *dyn_i
, key
;
2277 unsigned int *count_p
, *sorted_count_p
, *size_p
;
2278 unsigned int count
, sorted_count
, size
;
2279 bfd_vma addend
= rel
? rel
->r_addend
: 0;
2284 struct elfNN_ia64_link_hash_entry
*global_h
;
2286 global_h
= (struct elfNN_ia64_link_hash_entry
*) h
;
2287 info_p
= &global_h
->info
;
2288 count_p
= &global_h
->count
;
2289 sorted_count_p
= &global_h
->sorted_count
;
2290 size_p
= &global_h
->size
;
2294 struct elfNN_ia64_local_hash_entry
*loc_h
;
2296 loc_h
= get_local_sym_hash (ia64_info
, abfd
, rel
, create
);
2299 BFD_ASSERT (!create
);
2303 info_p
= &loc_h
->info
;
2304 count_p
= &loc_h
->count
;
2305 sorted_count_p
= &loc_h
->sorted_count
;
2306 size_p
= &loc_h
->size
;
2310 sorted_count
= *sorted_count_p
;
2315 /* When we create the array, we don't check for duplicates,
2316 except in the previously sorted section if one exists, and
2317 against the last inserted entry. This allows insertions to
2323 /* Try bsearch first on the sorted section. */
2324 key
.addend
= addend
;
2325 dyn_i
= bsearch (&key
, info
, sorted_count
,
2326 sizeof (*info
), addend_compare
);
2334 /* Do a quick check for the last inserted entry. */
2335 dyn_i
= info
+ count
- 1;
2336 if (dyn_i
->addend
== addend
)
2344 /* It is the very first element. We create the array of size
2347 amt
= size
* sizeof (*info
);
2348 info
= bfd_malloc (amt
);
2350 else if (size
<= count
)
2352 /* We double the array size every time when we reach the
2355 amt
= size
* sizeof (*info
);
2356 info
= bfd_realloc (info
, amt
);
2367 /* Append the new one to the array. */
2368 dyn_i
= info
+ count
;
2369 memset (dyn_i
, 0, sizeof (*dyn_i
));
2370 dyn_i
->got_offset
= (bfd_vma
) -1;
2371 dyn_i
->addend
= addend
;
2373 /* We increment count only since the new ones are unsorted and
2374 may have duplicate. */
2379 /* It is a lookup without insertion. Sort array if part of the
2380 array isn't sorted. */
2381 if (count
!= sorted_count
)
2383 count
= sort_dyn_sym_info (info
, count
);
2385 *sorted_count_p
= count
;
2388 /* Free unused memory. */
2391 amt
= count
* sizeof (*info
);
2392 info
= bfd_malloc (amt
);
2395 memcpy (info
, *info_p
, amt
);
2402 key
.addend
= addend
;
2403 dyn_i
= bsearch (&key
, info
, count
,
2404 sizeof (*info
), addend_compare
);
2411 get_got (bfd
*abfd
, struct bfd_link_info
*info
,
2412 struct elfNN_ia64_link_hash_table
*ia64_info
)
2417 got
= ia64_info
->got_sec
;
2422 dynobj
= ia64_info
->root
.dynobj
;
2424 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2425 if (!_bfd_elf_create_got_section (dynobj
, info
))
2428 got
= bfd_get_section_by_name (dynobj
, ".got");
2430 ia64_info
->got_sec
= got
;
2432 /* The .got section is always aligned at 8 bytes. */
2433 if (!bfd_set_section_alignment (abfd
, got
, 3))
2436 flags
= bfd_get_section_flags (abfd
, got
);
2437 bfd_set_section_flags (abfd
, got
, SEC_SMALL_DATA
| flags
);
2443 /* Create function descriptor section (.opd). This section is called .opd
2444 because it contains "official procedure descriptors". The "official"
2445 refers to the fact that these descriptors are used when taking the address
2446 of a procedure, thus ensuring a unique address for each procedure. */
2449 get_fptr (bfd
*abfd
, struct bfd_link_info
*info
,
2450 struct elfNN_ia64_link_hash_table
*ia64_info
)
2455 fptr
= ia64_info
->fptr_sec
;
2458 dynobj
= ia64_info
->root
.dynobj
;
2460 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2462 fptr
= bfd_make_section_with_flags (dynobj
, ".opd",
2467 | (info
->pie
? 0 : SEC_READONLY
)
2468 | SEC_LINKER_CREATED
));
2470 || !bfd_set_section_alignment (abfd
, fptr
, 4))
2476 ia64_info
->fptr_sec
= fptr
;
2481 fptr_rel
= bfd_make_section_with_flags (dynobj
, ".rela.opd",
2482 (SEC_ALLOC
| SEC_LOAD
2485 | SEC_LINKER_CREATED
2487 if (fptr_rel
== NULL
2488 || !bfd_set_section_alignment (abfd
, fptr_rel
,
2495 ia64_info
->rel_fptr_sec
= fptr_rel
;
2503 get_pltoff (bfd
*abfd
, struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
2504 struct elfNN_ia64_link_hash_table
*ia64_info
)
2509 pltoff
= ia64_info
->pltoff_sec
;
2512 dynobj
= ia64_info
->root
.dynobj
;
2514 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2516 pltoff
= bfd_make_section_with_flags (dynobj
,
2517 ELF_STRING_ia64_pltoff
,
2523 | SEC_LINKER_CREATED
));
2525 || !bfd_set_section_alignment (abfd
, pltoff
, 4))
2531 ia64_info
->pltoff_sec
= pltoff
;
2538 get_reloc_section (bfd
*abfd
,
2539 struct elfNN_ia64_link_hash_table
*ia64_info
,
2540 asection
*sec
, bfd_boolean create
)
2542 const char *srel_name
;
2546 srel_name
= (bfd_elf_string_from_elf_section
2547 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
2548 elf_section_data(sec
)->rel_hdr
.sh_name
));
2549 if (srel_name
== NULL
)
2552 BFD_ASSERT ((CONST_STRNEQ (srel_name
, ".rela")
2553 && strcmp (bfd_get_section_name (abfd
, sec
),
2555 || (CONST_STRNEQ (srel_name
, ".rel")
2556 && strcmp (bfd_get_section_name (abfd
, sec
),
2557 srel_name
+4) == 0));
2559 dynobj
= ia64_info
->root
.dynobj
;
2561 ia64_info
->root
.dynobj
= dynobj
= abfd
;
2563 srel
= bfd_get_section_by_name (dynobj
, srel_name
);
2564 if (srel
== NULL
&& create
)
2566 srel
= bfd_make_section_with_flags (dynobj
, srel_name
,
2567 (SEC_ALLOC
| SEC_LOAD
2570 | SEC_LINKER_CREATED
2573 || !bfd_set_section_alignment (dynobj
, srel
,
2582 count_dyn_reloc (bfd
*abfd
, struct elfNN_ia64_dyn_sym_info
*dyn_i
,
2583 asection
*srel
, int type
, bfd_boolean reltext
)
2585 struct elfNN_ia64_dyn_reloc_entry
*rent
;
2587 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
2588 if (rent
->srel
== srel
&& rent
->type
== type
)
2593 rent
= ((struct elfNN_ia64_dyn_reloc_entry
*)
2594 bfd_alloc (abfd
, (bfd_size_type
) sizeof (*rent
)));
2598 rent
->next
= dyn_i
->reloc_entries
;
2602 dyn_i
->reloc_entries
= rent
;
2604 rent
->reltext
= reltext
;
2611 elfNN_ia64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
2613 const Elf_Internal_Rela
*relocs
)
2615 struct elfNN_ia64_link_hash_table
*ia64_info
;
2616 const Elf_Internal_Rela
*relend
;
2617 Elf_Internal_Shdr
*symtab_hdr
;
2618 const Elf_Internal_Rela
*rel
;
2619 asection
*got
, *fptr
, *srel
, *pltoff
;
2628 NEED_LTOFF_FPTR
= 128,
2634 struct elf_link_hash_entry
*h
;
2635 unsigned long r_symndx
;
2636 bfd_boolean maybe_dynamic
;
2638 if (info
->relocatable
)
2641 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2642 ia64_info
= elfNN_ia64_hash_table (info
);
2644 got
= fptr
= srel
= pltoff
= NULL
;
2646 relend
= relocs
+ sec
->reloc_count
;
2648 /* We scan relocations first to create dynamic relocation arrays. We
2649 modified get_dyn_sym_info to allow fast insertion and support fast
2650 lookup in the next loop. */
2651 for (rel
= relocs
; rel
< relend
; ++rel
)
2653 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2654 if (r_symndx
>= symtab_hdr
->sh_info
)
2656 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2657 h
= elf_sym_hashes (abfd
)[indx
];
2658 while (h
->root
.type
== bfd_link_hash_indirect
2659 || h
->root
.type
== bfd_link_hash_warning
)
2660 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2665 /* We can only get preliminary data on whether a symbol is
2666 locally or externally defined, as not all of the input files
2667 have yet been processed. Do something with what we know, as
2668 this may help reduce memory usage and processing time later. */
2669 maybe_dynamic
= (h
&& ((!info
->executable
2670 && (!SYMBOLIC_BIND (info
, h
)
2671 || info
->unresolved_syms_in_shared_libs
== RM_IGNORE
))
2673 || h
->root
.type
== bfd_link_hash_defweak
));
2676 switch (ELFNN_R_TYPE (rel
->r_info
))
2678 case R_IA64_TPREL64MSB
:
2679 case R_IA64_TPREL64LSB
:
2680 if (info
->shared
|| maybe_dynamic
)
2681 need_entry
= NEED_DYNREL
;
2684 case R_IA64_LTOFF_TPREL22
:
2685 need_entry
= NEED_TPREL
;
2687 info
->flags
|= DF_STATIC_TLS
;
2690 case R_IA64_DTPREL32MSB
:
2691 case R_IA64_DTPREL32LSB
:
2692 case R_IA64_DTPREL64MSB
:
2693 case R_IA64_DTPREL64LSB
:
2694 if (info
->shared
|| maybe_dynamic
)
2695 need_entry
= NEED_DYNREL
;
2698 case R_IA64_LTOFF_DTPREL22
:
2699 need_entry
= NEED_DTPREL
;
2702 case R_IA64_DTPMOD64MSB
:
2703 case R_IA64_DTPMOD64LSB
:
2704 if (info
->shared
|| maybe_dynamic
)
2705 need_entry
= NEED_DYNREL
;
2708 case R_IA64_LTOFF_DTPMOD22
:
2709 need_entry
= NEED_DTPMOD
;
2712 case R_IA64_LTOFF_FPTR22
:
2713 case R_IA64_LTOFF_FPTR64I
:
2714 case R_IA64_LTOFF_FPTR32MSB
:
2715 case R_IA64_LTOFF_FPTR32LSB
:
2716 case R_IA64_LTOFF_FPTR64MSB
:
2717 case R_IA64_LTOFF_FPTR64LSB
:
2718 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2721 case R_IA64_FPTR64I
:
2722 case R_IA64_FPTR32MSB
:
2723 case R_IA64_FPTR32LSB
:
2724 case R_IA64_FPTR64MSB
:
2725 case R_IA64_FPTR64LSB
:
2726 if (info
->shared
|| h
)
2727 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2729 need_entry
= NEED_FPTR
;
2732 case R_IA64_LTOFF22
:
2733 case R_IA64_LTOFF64I
:
2734 need_entry
= NEED_GOT
;
2737 case R_IA64_LTOFF22X
:
2738 need_entry
= NEED_GOTX
;
2741 case R_IA64_PLTOFF22
:
2742 case R_IA64_PLTOFF64I
:
2743 case R_IA64_PLTOFF64MSB
:
2744 case R_IA64_PLTOFF64LSB
:
2745 need_entry
= NEED_PLTOFF
;
2749 need_entry
|= NEED_MIN_PLT
;
2753 (*info
->callbacks
->warning
)
2754 (info
, _("@pltoff reloc against local symbol"), 0,
2755 abfd
, 0, (bfd_vma
) 0);
2759 case R_IA64_PCREL21B
:
2760 case R_IA64_PCREL60B
:
2761 /* Depending on where this symbol is defined, we may or may not
2762 need a full plt entry. Only skip if we know we'll not need
2763 the entry -- static or symbolic, and the symbol definition
2764 has already been seen. */
2765 if (maybe_dynamic
&& rel
->r_addend
== 0)
2766 need_entry
= NEED_FULL_PLT
;
2772 case R_IA64_DIR32MSB
:
2773 case R_IA64_DIR32LSB
:
2774 case R_IA64_DIR64MSB
:
2775 case R_IA64_DIR64LSB
:
2776 /* Shared objects will always need at least a REL relocation. */
2777 if (info
->shared
|| maybe_dynamic
)
2778 need_entry
= NEED_DYNREL
;
2781 case R_IA64_IPLTMSB
:
2782 case R_IA64_IPLTLSB
:
2783 /* Shared objects will always need at least a REL relocation. */
2784 if (info
->shared
|| maybe_dynamic
)
2785 need_entry
= NEED_DYNREL
;
2788 case R_IA64_PCREL22
:
2789 case R_IA64_PCREL64I
:
2790 case R_IA64_PCREL32MSB
:
2791 case R_IA64_PCREL32LSB
:
2792 case R_IA64_PCREL64MSB
:
2793 case R_IA64_PCREL64LSB
:
2795 need_entry
= NEED_DYNREL
;
2802 if ((need_entry
& NEED_FPTR
) != 0
2805 (*info
->callbacks
->warning
)
2806 (info
, _("non-zero addend in @fptr reloc"), 0,
2807 abfd
, 0, (bfd_vma
) 0);
2810 if (get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, TRUE
) == NULL
)
2814 /* Now, we only do lookup without insertion, which is very fast
2815 with the modified get_dyn_sym_info. */
2816 for (rel
= relocs
; rel
< relend
; ++rel
)
2818 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
2819 int dynrel_type
= R_IA64_NONE
;
2821 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
2822 if (r_symndx
>= symtab_hdr
->sh_info
)
2824 /* We're dealing with a global symbol -- find its hash entry
2825 and mark it as being referenced. */
2826 long indx
= r_symndx
- symtab_hdr
->sh_info
;
2827 h
= elf_sym_hashes (abfd
)[indx
];
2828 while (h
->root
.type
== bfd_link_hash_indirect
2829 || h
->root
.type
== bfd_link_hash_warning
)
2830 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2837 /* We can only get preliminary data on whether a symbol is
2838 locally or externally defined, as not all of the input files
2839 have yet been processed. Do something with what we know, as
2840 this may help reduce memory usage and processing time later. */
2841 maybe_dynamic
= (h
&& ((!info
->executable
2842 && (!SYMBOLIC_BIND (info
, h
)
2843 || info
->unresolved_syms_in_shared_libs
== RM_IGNORE
))
2845 || h
->root
.type
== bfd_link_hash_defweak
));
2848 switch (ELFNN_R_TYPE (rel
->r_info
))
2850 case R_IA64_TPREL64MSB
:
2851 case R_IA64_TPREL64LSB
:
2852 if (info
->shared
|| maybe_dynamic
)
2853 need_entry
= NEED_DYNREL
;
2854 dynrel_type
= R_IA64_TPREL64LSB
;
2856 info
->flags
|= DF_STATIC_TLS
;
2859 case R_IA64_LTOFF_TPREL22
:
2860 need_entry
= NEED_TPREL
;
2862 info
->flags
|= DF_STATIC_TLS
;
2865 case R_IA64_DTPREL32MSB
:
2866 case R_IA64_DTPREL32LSB
:
2867 case R_IA64_DTPREL64MSB
:
2868 case R_IA64_DTPREL64LSB
:
2869 if (info
->shared
|| maybe_dynamic
)
2870 need_entry
= NEED_DYNREL
;
2871 dynrel_type
= R_IA64_DTPRELNNLSB
;
2874 case R_IA64_LTOFF_DTPREL22
:
2875 need_entry
= NEED_DTPREL
;
2878 case R_IA64_DTPMOD64MSB
:
2879 case R_IA64_DTPMOD64LSB
:
2880 if (info
->shared
|| maybe_dynamic
)
2881 need_entry
= NEED_DYNREL
;
2882 dynrel_type
= R_IA64_DTPMOD64LSB
;
2885 case R_IA64_LTOFF_DTPMOD22
:
2886 need_entry
= NEED_DTPMOD
;
2889 case R_IA64_LTOFF_FPTR22
:
2890 case R_IA64_LTOFF_FPTR64I
:
2891 case R_IA64_LTOFF_FPTR32MSB
:
2892 case R_IA64_LTOFF_FPTR32LSB
:
2893 case R_IA64_LTOFF_FPTR64MSB
:
2894 case R_IA64_LTOFF_FPTR64LSB
:
2895 need_entry
= NEED_FPTR
| NEED_GOT
| NEED_LTOFF_FPTR
;
2898 case R_IA64_FPTR64I
:
2899 case R_IA64_FPTR32MSB
:
2900 case R_IA64_FPTR32LSB
:
2901 case R_IA64_FPTR64MSB
:
2902 case R_IA64_FPTR64LSB
:
2903 if (info
->shared
|| h
)
2904 need_entry
= NEED_FPTR
| NEED_DYNREL
;
2906 need_entry
= NEED_FPTR
;
2907 dynrel_type
= R_IA64_FPTRNNLSB
;
2910 case R_IA64_LTOFF22
:
2911 case R_IA64_LTOFF64I
:
2912 need_entry
= NEED_GOT
;
2915 case R_IA64_LTOFF22X
:
2916 need_entry
= NEED_GOTX
;
2919 case R_IA64_PLTOFF22
:
2920 case R_IA64_PLTOFF64I
:
2921 case R_IA64_PLTOFF64MSB
:
2922 case R_IA64_PLTOFF64LSB
:
2923 need_entry
= NEED_PLTOFF
;
2927 need_entry
|= NEED_MIN_PLT
;
2931 case R_IA64_PCREL21B
:
2932 case R_IA64_PCREL60B
:
2933 /* Depending on where this symbol is defined, we may or may not
2934 need a full plt entry. Only skip if we know we'll not need
2935 the entry -- static or symbolic, and the symbol definition
2936 has already been seen. */
2937 if (maybe_dynamic
&& rel
->r_addend
== 0)
2938 need_entry
= NEED_FULL_PLT
;
2944 case R_IA64_DIR32MSB
:
2945 case R_IA64_DIR32LSB
:
2946 case R_IA64_DIR64MSB
:
2947 case R_IA64_DIR64LSB
:
2948 /* Shared objects will always need at least a REL relocation. */
2949 if (info
->shared
|| maybe_dynamic
)
2950 need_entry
= NEED_DYNREL
;
2951 dynrel_type
= R_IA64_DIRNNLSB
;
2954 case R_IA64_IPLTMSB
:
2955 case R_IA64_IPLTLSB
:
2956 /* Shared objects will always need at least a REL relocation. */
2957 if (info
->shared
|| maybe_dynamic
)
2958 need_entry
= NEED_DYNREL
;
2959 dynrel_type
= R_IA64_IPLTLSB
;
2962 case R_IA64_PCREL22
:
2963 case R_IA64_PCREL64I
:
2964 case R_IA64_PCREL32MSB
:
2965 case R_IA64_PCREL32LSB
:
2966 case R_IA64_PCREL64MSB
:
2967 case R_IA64_PCREL64LSB
:
2969 need_entry
= NEED_DYNREL
;
2970 dynrel_type
= R_IA64_PCRELNNLSB
;
2977 dyn_i
= get_dyn_sym_info (ia64_info
, h
, abfd
, rel
, FALSE
);
2979 /* Record whether or not this is a local symbol. */
2982 /* Create what's needed. */
2983 if (need_entry
& (NEED_GOT
| NEED_GOTX
| NEED_TPREL
2984 | NEED_DTPMOD
| NEED_DTPREL
))
2988 got
= get_got (abfd
, info
, ia64_info
);
2992 if (need_entry
& NEED_GOT
)
2993 dyn_i
->want_got
= 1;
2994 if (need_entry
& NEED_GOTX
)
2995 dyn_i
->want_gotx
= 1;
2996 if (need_entry
& NEED_TPREL
)
2997 dyn_i
->want_tprel
= 1;
2998 if (need_entry
& NEED_DTPMOD
)
2999 dyn_i
->want_dtpmod
= 1;
3000 if (need_entry
& NEED_DTPREL
)
3001 dyn_i
->want_dtprel
= 1;
3003 if (need_entry
& NEED_FPTR
)
3007 fptr
= get_fptr (abfd
, info
, ia64_info
);
3012 /* FPTRs for shared libraries are allocated by the dynamic
3013 linker. Make sure this local symbol will appear in the
3014 dynamic symbol table. */
3015 if (!h
&& info
->shared
)
3017 if (! (bfd_elf_link_record_local_dynamic_symbol
3018 (info
, abfd
, (long) r_symndx
)))
3022 dyn_i
->want_fptr
= 1;
3024 if (need_entry
& NEED_LTOFF_FPTR
)
3025 dyn_i
->want_ltoff_fptr
= 1;
3026 if (need_entry
& (NEED_MIN_PLT
| NEED_FULL_PLT
))
3028 if (!ia64_info
->root
.dynobj
)
3029 ia64_info
->root
.dynobj
= abfd
;
3031 dyn_i
->want_plt
= 1;
3033 if (need_entry
& NEED_FULL_PLT
)
3034 dyn_i
->want_plt2
= 1;
3035 if (need_entry
& NEED_PLTOFF
)
3037 /* This is needed here, in case @pltoff is used in a non-shared
3041 pltoff
= get_pltoff (abfd
, info
, ia64_info
);
3046 dyn_i
->want_pltoff
= 1;
3048 if ((need_entry
& NEED_DYNREL
) && (sec
->flags
& SEC_ALLOC
))
3052 srel
= get_reloc_section (abfd
, ia64_info
, sec
, TRUE
);
3056 if (!count_dyn_reloc (abfd
, dyn_i
, srel
, dynrel_type
,
3057 (sec
->flags
& SEC_READONLY
) != 0))
3065 /* For cleanliness, and potentially faster dynamic loading, allocate
3066 external GOT entries first. */
3069 allocate_global_data_got (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3072 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3074 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
3075 && ! dyn_i
->want_fptr
3076 && elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3078 dyn_i
->got_offset
= x
->ofs
;
3081 if (dyn_i
->want_tprel
)
3083 dyn_i
->tprel_offset
= x
->ofs
;
3086 if (dyn_i
->want_dtpmod
)
3088 if (elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3090 dyn_i
->dtpmod_offset
= x
->ofs
;
3095 struct elfNN_ia64_link_hash_table
*ia64_info
;
3097 ia64_info
= elfNN_ia64_hash_table (x
->info
);
3098 if (ia64_info
->self_dtpmod_offset
== (bfd_vma
) -1)
3100 ia64_info
->self_dtpmod_offset
= x
->ofs
;
3103 dyn_i
->dtpmod_offset
= ia64_info
->self_dtpmod_offset
;
3106 if (dyn_i
->want_dtprel
)
3108 dyn_i
->dtprel_offset
= x
->ofs
;
3114 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
3117 allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3120 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3124 && elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, R_IA64_FPTRNNLSB
))
3126 dyn_i
->got_offset
= x
->ofs
;
3132 /* Lastly, allocate all the GOT entries for local data. */
3135 allocate_local_got (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3138 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3140 if ((dyn_i
->want_got
|| dyn_i
->want_gotx
)
3141 && !elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0))
3143 dyn_i
->got_offset
= x
->ofs
;
3149 /* Search for the index of a global symbol in it's defining object file. */
3152 global_sym_index (struct elf_link_hash_entry
*h
)
3154 struct elf_link_hash_entry
**p
;
3157 BFD_ASSERT (h
->root
.type
== bfd_link_hash_defined
3158 || h
->root
.type
== bfd_link_hash_defweak
);
3160 obj
= h
->root
.u
.def
.section
->owner
;
3161 for (p
= elf_sym_hashes (obj
); *p
!= h
; ++p
)
3164 return p
- elf_sym_hashes (obj
) + elf_tdata (obj
)->symtab_hdr
.sh_info
;
3167 /* Allocate function descriptors. We can do these for every function
3168 in a main executable that is not exported. */
3171 allocate_fptr (struct elfNN_ia64_dyn_sym_info
*dyn_i
, PTR data
)
3173 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3175 if (dyn_i
->want_fptr
)
3177 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3180 while (h
->root
.type
== bfd_link_hash_indirect
3181 || h
->root
.type
== bfd_link_hash_warning
)
3182 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3184 if (!x
->info
->executable
3186 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
3187 || (h
->root
.type
!= bfd_link_hash_undefweak
3188 && h
->root
.type
!= bfd_link_hash_undefined
)))
3190 if (h
&& h
->dynindx
== -1)
3192 BFD_ASSERT ((h
->root
.type
== bfd_link_hash_defined
)
3193 || (h
->root
.type
== bfd_link_hash_defweak
));
3195 if (!bfd_elf_link_record_local_dynamic_symbol
3196 (x
->info
, h
->root
.u
.def
.section
->owner
,
3197 global_sym_index (h
)))
3201 dyn_i
->want_fptr
= 0;
3203 else if (h
== NULL
|| h
->dynindx
== -1)
3205 dyn_i
->fptr_offset
= x
->ofs
;
3209 dyn_i
->want_fptr
= 0;
3214 /* Allocate all the minimal PLT entries. */
3217 allocate_plt_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3220 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3222 if (dyn_i
->want_plt
)
3224 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3227 while (h
->root
.type
== bfd_link_hash_indirect
3228 || h
->root
.type
== bfd_link_hash_warning
)
3229 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3231 /* ??? Versioned symbols seem to lose NEEDS_PLT. */
3232 if (elfNN_ia64_dynamic_symbol_p (h
, x
->info
, 0))
3234 bfd_size_type offset
= x
->ofs
;
3236 offset
= PLT_HEADER_SIZE
;
3237 dyn_i
->plt_offset
= offset
;
3238 x
->ofs
= offset
+ PLT_MIN_ENTRY_SIZE
;
3240 dyn_i
->want_pltoff
= 1;
3244 dyn_i
->want_plt
= 0;
3245 dyn_i
->want_plt2
= 0;
3251 /* Allocate all the full PLT entries. */
3254 allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3257 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3259 if (dyn_i
->want_plt2
)
3261 struct elf_link_hash_entry
*h
= dyn_i
->h
;
3262 bfd_size_type ofs
= x
->ofs
;
3264 dyn_i
->plt2_offset
= ofs
;
3265 x
->ofs
= ofs
+ PLT_FULL_ENTRY_SIZE
;
3267 while (h
->root
.type
== bfd_link_hash_indirect
3268 || h
->root
.type
== bfd_link_hash_warning
)
3269 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
3270 dyn_i
->h
->plt
.offset
= ofs
;
3275 /* Allocate all the PLTOFF entries requested by relocations and
3276 plt entries. We can't share space with allocated FPTR entries,
3277 because the latter are not necessarily addressable by the GP.
3278 ??? Relaxation might be able to determine that they are. */
3281 allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3284 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3286 if (dyn_i
->want_pltoff
)
3288 dyn_i
->pltoff_offset
= x
->ofs
;
3294 /* Allocate dynamic relocations for those symbols that turned out
3298 allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3301 struct elfNN_ia64_allocate_data
*x
= (struct elfNN_ia64_allocate_data
*)data
;
3302 struct elfNN_ia64_link_hash_table
*ia64_info
;
3303 struct elfNN_ia64_dyn_reloc_entry
*rent
;
3304 bfd_boolean dynamic_symbol
, shared
, resolved_zero
;
3306 ia64_info
= elfNN_ia64_hash_table (x
->info
);
3308 /* Note that this can't be used in relation to FPTR relocs below. */
3309 dynamic_symbol
= elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, x
->info
, 0);
3311 shared
= x
->info
->shared
;
3312 resolved_zero
= (dyn_i
->h
3313 && ELF_ST_VISIBILITY (dyn_i
->h
->other
)
3314 && dyn_i
->h
->root
.type
== bfd_link_hash_undefweak
);
3316 /* Take care of the GOT and PLT relocations. */
3319 && (dynamic_symbol
|| shared
)
3320 && (dyn_i
->want_got
|| dyn_i
->want_gotx
))
3321 || (dyn_i
->want_ltoff_fptr
3323 && dyn_i
->h
->dynindx
!= -1))
3325 if (!dyn_i
->want_ltoff_fptr
3328 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
3329 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
3331 if ((dynamic_symbol
|| shared
) && dyn_i
->want_tprel
)
3332 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
3333 if (dynamic_symbol
&& dyn_i
->want_dtpmod
)
3334 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
3335 if (dynamic_symbol
&& dyn_i
->want_dtprel
)
3336 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
3341 if (ia64_info
->rel_fptr_sec
&& dyn_i
->want_fptr
)
3343 if (dyn_i
->h
== NULL
|| dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
3344 ia64_info
->rel_fptr_sec
->size
+= sizeof (ElfNN_External_Rela
);
3347 if (!resolved_zero
&& dyn_i
->want_pltoff
)
3349 bfd_size_type t
= 0;
3351 /* Dynamic symbols get one IPLT relocation. Local symbols in
3352 shared libraries get two REL relocations. Local symbols in
3353 main applications get nothing. */
3355 t
= sizeof (ElfNN_External_Rela
);
3357 t
= 2 * sizeof (ElfNN_External_Rela
);
3359 ia64_info
->rel_pltoff_sec
->size
+= t
;
3362 /* Take care of the normal data relocations. */
3364 for (rent
= dyn_i
->reloc_entries
; rent
; rent
= rent
->next
)
3366 int count
= rent
->count
;
3370 case R_IA64_FPTR32LSB
:
3371 case R_IA64_FPTR64LSB
:
3372 /* Allocate one iff !want_fptr and not PIE, which by this point
3373 will be true only if we're actually allocating one statically
3374 in the main executable. Position independent executables
3375 need a relative reloc. */
3376 if (dyn_i
->want_fptr
&& !x
->info
->pie
)
3379 case R_IA64_PCREL32LSB
:
3380 case R_IA64_PCREL64LSB
:
3381 if (!dynamic_symbol
)
3384 case R_IA64_DIR32LSB
:
3385 case R_IA64_DIR64LSB
:
3386 if (!dynamic_symbol
&& !shared
)
3389 case R_IA64_IPLTLSB
:
3390 if (!dynamic_symbol
&& !shared
)
3392 /* Use two REL relocations for IPLT relocations
3393 against local symbols. */
3394 if (!dynamic_symbol
)
3397 case R_IA64_DTPREL32LSB
:
3398 case R_IA64_TPREL64LSB
:
3399 case R_IA64_DTPREL64LSB
:
3400 case R_IA64_DTPMOD64LSB
:
3406 ia64_info
->reltext
= 1;
3407 rent
->srel
->size
+= sizeof (ElfNN_External_Rela
) * count
;
3414 elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
3415 struct elf_link_hash_entry
*h
)
3417 /* ??? Undefined symbols with PLT entries should be re-defined
3418 to be the PLT entry. */
3420 /* If this is a weak symbol, and there is a real definition, the
3421 processor independent code will have arranged for us to see the
3422 real definition first, and we can just use the same value. */
3423 if (h
->u
.weakdef
!= NULL
)
3425 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
3426 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
3427 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
3428 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
3432 /* If this is a reference to a symbol defined by a dynamic object which
3433 is not a function, we might allocate the symbol in our .dynbss section
3434 and allocate a COPY dynamic relocation.
3436 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
3443 elfNN_ia64_size_dynamic_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
3444 struct bfd_link_info
*info
)
3446 struct elfNN_ia64_allocate_data data
;
3447 struct elfNN_ia64_link_hash_table
*ia64_info
;
3450 bfd_boolean relplt
= FALSE
;
3452 dynobj
= elf_hash_table(info
)->dynobj
;
3453 ia64_info
= elfNN_ia64_hash_table (info
);
3454 ia64_info
->self_dtpmod_offset
= (bfd_vma
) -1;
3455 BFD_ASSERT(dynobj
!= NULL
);
3458 /* Set the contents of the .interp section to the interpreter. */
3459 if (ia64_info
->root
.dynamic_sections_created
3460 && info
->executable
)
3462 sec
= bfd_get_section_by_name (dynobj
, ".interp");
3463 BFD_ASSERT (sec
!= NULL
);
3464 sec
->contents
= (bfd_byte
*) ELF_DYNAMIC_INTERPRETER
;
3465 sec
->size
= strlen (ELF_DYNAMIC_INTERPRETER
) + 1;
3468 /* Allocate the GOT entries. */
3470 if (ia64_info
->got_sec
)
3473 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_data_got
, &data
);
3474 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_global_fptr_got
, &data
);
3475 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_local_got
, &data
);
3476 ia64_info
->got_sec
->size
= data
.ofs
;
3479 /* Allocate the FPTR entries. */
3481 if (ia64_info
->fptr_sec
)
3484 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_fptr
, &data
);
3485 ia64_info
->fptr_sec
->size
= data
.ofs
;
3488 /* Now that we've seen all of the input files, we can decide which
3489 symbols need plt entries. Allocate the minimal PLT entries first.
3490 We do this even though dynamic_sections_created may be FALSE, because
3491 this has the side-effect of clearing want_plt and want_plt2. */
3494 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt_entries
, &data
);
3496 ia64_info
->minplt_entries
= 0;
3499 ia64_info
->minplt_entries
3500 = (data
.ofs
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
3503 /* Align the pointer for the plt2 entries. */
3504 data
.ofs
= (data
.ofs
+ 31) & (bfd_vma
) -32;
3506 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_plt2_entries
, &data
);
3507 if (data
.ofs
!= 0 || ia64_info
->root
.dynamic_sections_created
)
3509 /* FIXME: we always reserve the memory for dynamic linker even if
3510 there are no PLT entries since dynamic linker may assume the
3511 reserved memory always exists. */
3513 BFD_ASSERT (ia64_info
->root
.dynamic_sections_created
);
3515 ia64_info
->plt_sec
->size
= data
.ofs
;
3517 /* If we've got a .plt, we need some extra memory for the dynamic
3518 linker. We stuff these in .got.plt. */
3519 sec
= bfd_get_section_by_name (dynobj
, ".got.plt");
3520 sec
->size
= 8 * PLT_RESERVED_WORDS
;
3523 /* Allocate the PLTOFF entries. */
3525 if (ia64_info
->pltoff_sec
)
3528 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_pltoff_entries
, &data
);
3529 ia64_info
->pltoff_sec
->size
= data
.ofs
;
3532 if (ia64_info
->root
.dynamic_sections_created
)
3534 /* Allocate space for the dynamic relocations that turned out to be
3537 if (info
->shared
&& ia64_info
->self_dtpmod_offset
!= (bfd_vma
) -1)
3538 ia64_info
->rel_got_sec
->size
+= sizeof (ElfNN_External_Rela
);
3539 data
.only_got
= FALSE
;
3540 elfNN_ia64_dyn_sym_traverse (ia64_info
, allocate_dynrel_entries
, &data
);
3543 /* We have now determined the sizes of the various dynamic sections.
3544 Allocate memory for them. */
3545 for (sec
= dynobj
->sections
; sec
!= NULL
; sec
= sec
->next
)
3549 if (!(sec
->flags
& SEC_LINKER_CREATED
))
3552 /* If we don't need this section, strip it from the output file.
3553 There were several sections primarily related to dynamic
3554 linking that must be create before the linker maps input
3555 sections to output sections. The linker does that before
3556 bfd_elf_size_dynamic_sections is called, and it is that
3557 function which decides whether anything needs to go into
3560 strip
= (sec
->size
== 0);
3562 if (sec
== ia64_info
->got_sec
)
3564 else if (sec
== ia64_info
->rel_got_sec
)
3567 ia64_info
->rel_got_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
->fptr_sec
)
3576 ia64_info
->fptr_sec
= NULL
;
3578 else if (sec
== ia64_info
->rel_fptr_sec
)
3581 ia64_info
->rel_fptr_sec
= NULL
;
3583 /* We use the reloc_count field as a counter if we need to
3584 copy relocs into the output file. */
3585 sec
->reloc_count
= 0;
3587 else if (sec
== ia64_info
->plt_sec
)
3590 ia64_info
->plt_sec
= NULL
;
3592 else if (sec
== ia64_info
->pltoff_sec
)
3595 ia64_info
->pltoff_sec
= NULL
;
3597 else if (sec
== ia64_info
->rel_pltoff_sec
)
3600 ia64_info
->rel_pltoff_sec
= NULL
;
3604 /* We use the reloc_count field as a counter if we need to
3605 copy relocs into the output file. */
3606 sec
->reloc_count
= 0;
3613 /* It's OK to base decisions on the section name, because none
3614 of the dynobj section names depend upon the input files. */
3615 name
= bfd_get_section_name (dynobj
, sec
);
3617 if (strcmp (name
, ".got.plt") == 0)
3619 else if (CONST_STRNEQ (name
, ".rel"))
3623 /* We use the reloc_count field as a counter if we need to
3624 copy relocs into the output file. */
3625 sec
->reloc_count
= 0;
3633 sec
->flags
|= SEC_EXCLUDE
;
3636 /* Allocate memory for the section contents. */
3637 sec
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, sec
->size
);
3638 if (sec
->contents
== NULL
&& sec
->size
!= 0)
3643 if (elf_hash_table (info
)->dynamic_sections_created
)
3645 /* Add some entries to the .dynamic section. We fill in the values
3646 later (in finish_dynamic_sections) but we must add the entries now
3647 so that we get the correct size for the .dynamic section. */
3649 if (info
->executable
)
3651 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3653 #define add_dynamic_entry(TAG, VAL) \
3654 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3656 if (!add_dynamic_entry (DT_DEBUG
, 0))
3660 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE
, 0))
3662 if (!add_dynamic_entry (DT_PLTGOT
, 0))
3667 if (!add_dynamic_entry (DT_PLTRELSZ
, 0)
3668 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
3669 || !add_dynamic_entry (DT_JMPREL
, 0))
3673 if (!add_dynamic_entry (DT_RELA
, 0)
3674 || !add_dynamic_entry (DT_RELASZ
, 0)
3675 || !add_dynamic_entry (DT_RELAENT
, sizeof (ElfNN_External_Rela
)))
3678 if (ia64_info
->reltext
)
3680 if (!add_dynamic_entry (DT_TEXTREL
, 0))
3682 info
->flags
|= DF_TEXTREL
;
3686 /* ??? Perhaps force __gp local. */
3691 static bfd_reloc_status_type
3692 elfNN_ia64_install_value (bfd_byte
*hit_addr
, bfd_vma v
,
3693 unsigned int r_type
)
3695 const struct ia64_operand
*op
;
3696 int bigendian
= 0, shift
= 0;
3697 bfd_vma t0
, t1
, dword
;
3699 enum ia64_opnd opnd
;
3702 #ifdef BFD_HOST_U_64_BIT
3703 BFD_HOST_U_64_BIT val
= (BFD_HOST_U_64_BIT
) v
;
3708 opnd
= IA64_OPND_NIL
;
3713 return bfd_reloc_ok
;
3715 /* Instruction relocations. */
3718 case R_IA64_TPREL14
:
3719 case R_IA64_DTPREL14
:
3720 opnd
= IA64_OPND_IMM14
;
3723 case R_IA64_PCREL21F
: opnd
= IA64_OPND_TGT25
; break;
3724 case R_IA64_PCREL21M
: opnd
= IA64_OPND_TGT25b
; break;
3725 case R_IA64_PCREL60B
: opnd
= IA64_OPND_TGT64
; break;
3726 case R_IA64_PCREL21B
:
3727 case R_IA64_PCREL21BI
:
3728 opnd
= IA64_OPND_TGT25c
;
3732 case R_IA64_GPREL22
:
3733 case R_IA64_LTOFF22
:
3734 case R_IA64_LTOFF22X
:
3735 case R_IA64_PLTOFF22
:
3736 case R_IA64_PCREL22
:
3737 case R_IA64_LTOFF_FPTR22
:
3738 case R_IA64_TPREL22
:
3739 case R_IA64_DTPREL22
:
3740 case R_IA64_LTOFF_TPREL22
:
3741 case R_IA64_LTOFF_DTPMOD22
:
3742 case R_IA64_LTOFF_DTPREL22
:
3743 opnd
= IA64_OPND_IMM22
;
3747 case R_IA64_GPREL64I
:
3748 case R_IA64_LTOFF64I
:
3749 case R_IA64_PLTOFF64I
:
3750 case R_IA64_PCREL64I
:
3751 case R_IA64_FPTR64I
:
3752 case R_IA64_LTOFF_FPTR64I
:
3753 case R_IA64_TPREL64I
:
3754 case R_IA64_DTPREL64I
:
3755 opnd
= IA64_OPND_IMMU64
;
3758 /* Data relocations. */
3760 case R_IA64_DIR32MSB
:
3761 case R_IA64_GPREL32MSB
:
3762 case R_IA64_FPTR32MSB
:
3763 case R_IA64_PCREL32MSB
:
3764 case R_IA64_LTOFF_FPTR32MSB
:
3765 case R_IA64_SEGREL32MSB
:
3766 case R_IA64_SECREL32MSB
:
3767 case R_IA64_LTV32MSB
:
3768 case R_IA64_DTPREL32MSB
:
3769 size
= 4; bigendian
= 1;
3772 case R_IA64_DIR32LSB
:
3773 case R_IA64_GPREL32LSB
:
3774 case R_IA64_FPTR32LSB
:
3775 case R_IA64_PCREL32LSB
:
3776 case R_IA64_LTOFF_FPTR32LSB
:
3777 case R_IA64_SEGREL32LSB
:
3778 case R_IA64_SECREL32LSB
:
3779 case R_IA64_LTV32LSB
:
3780 case R_IA64_DTPREL32LSB
:
3781 size
= 4; bigendian
= 0;
3784 case R_IA64_DIR64MSB
:
3785 case R_IA64_GPREL64MSB
:
3786 case R_IA64_PLTOFF64MSB
:
3787 case R_IA64_FPTR64MSB
:
3788 case R_IA64_PCREL64MSB
:
3789 case R_IA64_LTOFF_FPTR64MSB
:
3790 case R_IA64_SEGREL64MSB
:
3791 case R_IA64_SECREL64MSB
:
3792 case R_IA64_LTV64MSB
:
3793 case R_IA64_TPREL64MSB
:
3794 case R_IA64_DTPMOD64MSB
:
3795 case R_IA64_DTPREL64MSB
:
3796 size
= 8; bigendian
= 1;
3799 case R_IA64_DIR64LSB
:
3800 case R_IA64_GPREL64LSB
:
3801 case R_IA64_PLTOFF64LSB
:
3802 case R_IA64_FPTR64LSB
:
3803 case R_IA64_PCREL64LSB
:
3804 case R_IA64_LTOFF_FPTR64LSB
:
3805 case R_IA64_SEGREL64LSB
:
3806 case R_IA64_SECREL64LSB
:
3807 case R_IA64_LTV64LSB
:
3808 case R_IA64_TPREL64LSB
:
3809 case R_IA64_DTPMOD64LSB
:
3810 case R_IA64_DTPREL64LSB
:
3811 size
= 8; bigendian
= 0;
3814 /* Unsupported / Dynamic relocations. */
3816 return bfd_reloc_notsupported
;
3821 case IA64_OPND_IMMU64
:
3822 hit_addr
-= (long) hit_addr
& 0x3;
3823 t0
= bfd_getl64 (hit_addr
);
3824 t1
= bfd_getl64 (hit_addr
+ 8);
3826 /* tmpl/s: bits 0.. 5 in t0
3827 slot 0: bits 5..45 in t0
3828 slot 1: bits 46..63 in t0, bits 0..22 in t1
3829 slot 2: bits 23..63 in t1 */
3831 /* First, clear the bits that form the 64 bit constant. */
3832 t0
&= ~(0x3ffffLL
<< 46);
3834 | (( (0x07fLL
<< 13) | (0x1ffLL
<< 27)
3835 | (0x01fLL
<< 22) | (0x001LL
<< 21)
3836 | (0x001LL
<< 36)) << 23));
3838 t0
|= ((val
>> 22) & 0x03ffffLL
) << 46; /* 18 lsbs of imm41 */
3839 t1
|= ((val
>> 40) & 0x7fffffLL
) << 0; /* 23 msbs of imm41 */
3840 t1
|= ( (((val
>> 0) & 0x07f) << 13) /* imm7b */
3841 | (((val
>> 7) & 0x1ff) << 27) /* imm9d */
3842 | (((val
>> 16) & 0x01f) << 22) /* imm5c */
3843 | (((val
>> 21) & 0x001) << 21) /* ic */
3844 | (((val
>> 63) & 0x001) << 36)) << 23; /* i */
3846 bfd_putl64 (t0
, hit_addr
);
3847 bfd_putl64 (t1
, hit_addr
+ 8);
3850 case IA64_OPND_TGT64
:
3851 hit_addr
-= (long) hit_addr
& 0x3;
3852 t0
= bfd_getl64 (hit_addr
);
3853 t1
= bfd_getl64 (hit_addr
+ 8);
3855 /* tmpl/s: bits 0.. 5 in t0
3856 slot 0: bits 5..45 in t0
3857 slot 1: bits 46..63 in t0, bits 0..22 in t1
3858 slot 2: bits 23..63 in t1 */
3860 /* First, clear the bits that form the 64 bit constant. */
3861 t0
&= ~(0x3ffffLL
<< 46);
3863 | ((1LL << 36 | 0xfffffLL
<< 13) << 23));
3866 t0
|= ((val
>> 20) & 0xffffLL
) << 2 << 46; /* 16 lsbs of imm39 */
3867 t1
|= ((val
>> 36) & 0x7fffffLL
) << 0; /* 23 msbs of imm39 */
3868 t1
|= ((((val
>> 0) & 0xfffffLL
) << 13) /* imm20b */
3869 | (((val
>> 59) & 0x1LL
) << 36)) << 23; /* i */
3871 bfd_putl64 (t0
, hit_addr
);
3872 bfd_putl64 (t1
, hit_addr
+ 8);
3876 switch ((long) hit_addr
& 0x3)
3878 case 0: shift
= 5; break;
3879 case 1: shift
= 14; hit_addr
+= 3; break;
3880 case 2: shift
= 23; hit_addr
+= 6; break;
3881 case 3: return bfd_reloc_notsupported
; /* shouldn't happen... */
3883 dword
= bfd_getl64 (hit_addr
);
3884 insn
= (dword
>> shift
) & 0x1ffffffffffLL
;
3886 op
= elf64_ia64_operands
+ opnd
;
3887 err
= (*op
->insert
) (op
, val
, &insn
);
3889 return bfd_reloc_overflow
;
3891 dword
&= ~(0x1ffffffffffLL
<< shift
);
3892 dword
|= (insn
<< shift
);
3893 bfd_putl64 (dword
, hit_addr
);
3897 /* A data relocation. */
3900 bfd_putb32 (val
, hit_addr
);
3902 bfd_putb64 (val
, hit_addr
);
3905 bfd_putl32 (val
, hit_addr
);
3907 bfd_putl64 (val
, hit_addr
);
3911 return bfd_reloc_ok
;
3915 elfNN_ia64_install_dyn_reloc (bfd
*abfd
, struct bfd_link_info
*info
,
3916 asection
*sec
, asection
*srel
,
3917 bfd_vma offset
, unsigned int type
,
3918 long dynindx
, bfd_vma addend
)
3920 Elf_Internal_Rela outrel
;
3923 BFD_ASSERT (dynindx
!= -1);
3924 outrel
.r_info
= ELFNN_R_INFO (dynindx
, type
);
3925 outrel
.r_addend
= addend
;
3926 outrel
.r_offset
= _bfd_elf_section_offset (abfd
, info
, sec
, offset
);
3927 if (outrel
.r_offset
>= (bfd_vma
) -2)
3929 /* Run for the hills. We shouldn't be outputting a relocation
3930 for this. So do what everyone else does and output a no-op. */
3931 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_NONE
);
3932 outrel
.r_addend
= 0;
3933 outrel
.r_offset
= 0;
3936 outrel
.r_offset
+= sec
->output_section
->vma
+ sec
->output_offset
;
3938 loc
= srel
->contents
;
3939 loc
+= srel
->reloc_count
++ * sizeof (ElfNN_External_Rela
);
3940 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
3941 BFD_ASSERT (sizeof (ElfNN_External_Rela
) * srel
->reloc_count
<= srel
->size
);
3944 /* Store an entry for target address TARGET_ADDR in the linkage table
3945 and return the gp-relative address of the linkage table entry. */
3948 set_got_entry (bfd
*abfd
, struct bfd_link_info
*info
,
3949 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
3950 long dynindx
, bfd_vma addend
, bfd_vma value
,
3951 unsigned int dyn_r_type
)
3953 struct elfNN_ia64_link_hash_table
*ia64_info
;
3958 ia64_info
= elfNN_ia64_hash_table (info
);
3959 got_sec
= ia64_info
->got_sec
;
3963 case R_IA64_TPREL64LSB
:
3964 done
= dyn_i
->tprel_done
;
3965 dyn_i
->tprel_done
= TRUE
;
3966 got_offset
= dyn_i
->tprel_offset
;
3968 case R_IA64_DTPMOD64LSB
:
3969 if (dyn_i
->dtpmod_offset
!= ia64_info
->self_dtpmod_offset
)
3971 done
= dyn_i
->dtpmod_done
;
3972 dyn_i
->dtpmod_done
= TRUE
;
3976 done
= ia64_info
->self_dtpmod_done
;
3977 ia64_info
->self_dtpmod_done
= TRUE
;
3980 got_offset
= dyn_i
->dtpmod_offset
;
3982 case R_IA64_DTPREL32LSB
:
3983 case R_IA64_DTPREL64LSB
:
3984 done
= dyn_i
->dtprel_done
;
3985 dyn_i
->dtprel_done
= TRUE
;
3986 got_offset
= dyn_i
->dtprel_offset
;
3989 done
= dyn_i
->got_done
;
3990 dyn_i
->got_done
= TRUE
;
3991 got_offset
= dyn_i
->got_offset
;
3995 BFD_ASSERT ((got_offset
& 7) == 0);
3999 /* Store the target address in the linkage table entry. */
4000 bfd_put_64 (abfd
, value
, got_sec
->contents
+ got_offset
);
4002 /* Install a dynamic relocation if needed. */
4005 || ELF_ST_VISIBILITY (dyn_i
->h
->other
) == STV_DEFAULT
4006 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
)
4007 && dyn_r_type
!= R_IA64_DTPREL32LSB
4008 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
4009 || elfNN_ia64_dynamic_symbol_p (dyn_i
->h
, info
, dyn_r_type
)
4011 && (dyn_r_type
== R_IA64_FPTR32LSB
4012 || dyn_r_type
== R_IA64_FPTR64LSB
)))
4013 && (!dyn_i
->want_ltoff_fptr
4016 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
))
4019 && dyn_r_type
!= R_IA64_TPREL64LSB
4020 && dyn_r_type
!= R_IA64_DTPMOD64LSB
4021 && dyn_r_type
!= R_IA64_DTPREL32LSB
4022 && dyn_r_type
!= R_IA64_DTPREL64LSB
)
4024 dyn_r_type
= R_IA64_RELNNLSB
;
4029 if (bfd_big_endian (abfd
))
4033 case R_IA64_REL32LSB
:
4034 dyn_r_type
= R_IA64_REL32MSB
;
4036 case R_IA64_DIR32LSB
:
4037 dyn_r_type
= R_IA64_DIR32MSB
;
4039 case R_IA64_FPTR32LSB
:
4040 dyn_r_type
= R_IA64_FPTR32MSB
;
4042 case R_IA64_DTPREL32LSB
:
4043 dyn_r_type
= R_IA64_DTPREL32MSB
;
4045 case R_IA64_REL64LSB
:
4046 dyn_r_type
= R_IA64_REL64MSB
;
4048 case R_IA64_DIR64LSB
:
4049 dyn_r_type
= R_IA64_DIR64MSB
;
4051 case R_IA64_FPTR64LSB
:
4052 dyn_r_type
= R_IA64_FPTR64MSB
;
4054 case R_IA64_TPREL64LSB
:
4055 dyn_r_type
= R_IA64_TPREL64MSB
;
4057 case R_IA64_DTPMOD64LSB
:
4058 dyn_r_type
= R_IA64_DTPMOD64MSB
;
4060 case R_IA64_DTPREL64LSB
:
4061 dyn_r_type
= R_IA64_DTPREL64MSB
;
4069 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, got_sec
,
4070 ia64_info
->rel_got_sec
,
4071 got_offset
, dyn_r_type
,
4076 /* Return the address of the linkage table entry. */
4077 value
= (got_sec
->output_section
->vma
4078 + got_sec
->output_offset
4084 /* Fill in a function descriptor consisting of the function's code
4085 address and its global pointer. Return the descriptor's address. */
4088 set_fptr_entry (bfd
*abfd
, struct bfd_link_info
*info
,
4089 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
4092 struct elfNN_ia64_link_hash_table
*ia64_info
;
4095 ia64_info
= elfNN_ia64_hash_table (info
);
4096 fptr_sec
= ia64_info
->fptr_sec
;
4098 if (!dyn_i
->fptr_done
)
4100 dyn_i
->fptr_done
= 1;
4102 /* Fill in the function descriptor. */
4103 bfd_put_64 (abfd
, value
, fptr_sec
->contents
+ dyn_i
->fptr_offset
);
4104 bfd_put_64 (abfd
, _bfd_get_gp_value (abfd
),
4105 fptr_sec
->contents
+ dyn_i
->fptr_offset
+ 8);
4106 if (ia64_info
->rel_fptr_sec
)
4108 Elf_Internal_Rela outrel
;
4111 if (bfd_little_endian (abfd
))
4112 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_IPLTLSB
);
4114 outrel
.r_info
= ELFNN_R_INFO (0, R_IA64_IPLTMSB
);
4115 outrel
.r_addend
= value
;
4116 outrel
.r_offset
= (fptr_sec
->output_section
->vma
4117 + fptr_sec
->output_offset
4118 + dyn_i
->fptr_offset
);
4119 loc
= ia64_info
->rel_fptr_sec
->contents
;
4120 loc
+= ia64_info
->rel_fptr_sec
->reloc_count
++
4121 * sizeof (ElfNN_External_Rela
);
4122 bfd_elfNN_swap_reloca_out (abfd
, &outrel
, loc
);
4126 /* Return the descriptor's address. */
4127 value
= (fptr_sec
->output_section
->vma
4128 + fptr_sec
->output_offset
4129 + dyn_i
->fptr_offset
);
4134 /* Fill in a PLTOFF entry consisting of the function's code address
4135 and its global pointer. Return the descriptor's address. */
4138 set_pltoff_entry (bfd
*abfd
, struct bfd_link_info
*info
,
4139 struct elfNN_ia64_dyn_sym_info
*dyn_i
,
4140 bfd_vma value
, bfd_boolean is_plt
)
4142 struct elfNN_ia64_link_hash_table
*ia64_info
;
4143 asection
*pltoff_sec
;
4145 ia64_info
= elfNN_ia64_hash_table (info
);
4146 pltoff_sec
= ia64_info
->pltoff_sec
;
4148 /* Don't do anything if this symbol uses a real PLT entry. In
4149 that case, we'll fill this in during finish_dynamic_symbol. */
4150 if ((! dyn_i
->want_plt
|| is_plt
)
4151 && !dyn_i
->pltoff_done
)
4153 bfd_vma gp
= _bfd_get_gp_value (abfd
);
4155 /* Fill in the function descriptor. */
4156 bfd_put_64 (abfd
, value
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
);
4157 bfd_put_64 (abfd
, gp
, pltoff_sec
->contents
+ dyn_i
->pltoff_offset
+ 8);
4159 /* Install dynamic relocations if needed. */
4163 || ELF_ST_VISIBILITY (dyn_i
->h
->other
) == STV_DEFAULT
4164 || dyn_i
->h
->root
.type
!= bfd_link_hash_undefweak
))
4166 unsigned int dyn_r_type
;
4168 if (bfd_big_endian (abfd
))
4169 dyn_r_type
= R_IA64_RELNNMSB
;
4171 dyn_r_type
= R_IA64_RELNNLSB
;
4173 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
4174 ia64_info
->rel_pltoff_sec
,
4175 dyn_i
->pltoff_offset
,
4176 dyn_r_type
, 0, value
);
4177 elfNN_ia64_install_dyn_reloc (abfd
, NULL
, pltoff_sec
,
4178 ia64_info
->rel_pltoff_sec
,
4179 dyn_i
->pltoff_offset
+ ARCH_SIZE
/ 8,
4183 dyn_i
->pltoff_done
= 1;
4186 /* Return the descriptor's address. */
4187 value
= (pltoff_sec
->output_section
->vma
4188 + pltoff_sec
->output_offset
4189 + dyn_i
->pltoff_offset
);
4194 /* Return the base VMA address which should be subtracted from real addresses
4195 when resolving @tprel() relocation.
4196 Main program TLS (whose template starts at PT_TLS p_vaddr)
4197 is assigned offset round(2 * size of pointer, PT_TLS p_align). */
4200 elfNN_ia64_tprel_base (struct bfd_link_info
*info
)
4202 asection
*tls_sec
= elf_hash_table (info
)->tls_sec
;
4203 return tls_sec
->vma
- align_power ((bfd_vma
) ARCH_SIZE
/ 4,
4204 tls_sec
->alignment_power
);
4207 /* Return the base VMA address which should be subtracted from real addresses
4208 when resolving @dtprel() relocation.
4209 This is PT_TLS segment p_vaddr. */
4212 elfNN_ia64_dtprel_base (struct bfd_link_info
*info
)
4214 return elf_hash_table (info
)->tls_sec
->vma
;
4217 /* Called through qsort to sort the .IA_64.unwind section during a
4218 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
4219 to the output bfd so we can do proper endianness frobbing. */
4221 static bfd
*elfNN_ia64_unwind_entry_compare_bfd
;
4224 elfNN_ia64_unwind_entry_compare (const PTR a
, const PTR b
)
4228 av
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, a
);
4229 bv
= bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd
, b
);
4231 return (av
< bv
? -1 : av
> bv
? 1 : 0);
4234 /* Make sure we've got ourselves a nice fat __gp value. */
4236 elfNN_ia64_choose_gp (bfd
*abfd
, struct bfd_link_info
*info
)
4238 bfd_vma min_vma
= (bfd_vma
) -1, max_vma
= 0;
4239 bfd_vma min_short_vma
= min_vma
, max_short_vma
= 0;
4240 struct elf_link_hash_entry
*gp
;
4243 struct elfNN_ia64_link_hash_table
*ia64_info
;
4245 ia64_info
= elfNN_ia64_hash_table (info
);
4247 /* Find the min and max vma of all sections marked short. Also collect
4248 min and max vma of any type, for use in selecting a nice gp. */
4249 for (os
= abfd
->sections
; os
; os
= os
->next
)
4253 if ((os
->flags
& SEC_ALLOC
) == 0)
4257 hi
= os
->vma
+ (os
->rawsize
? os
->rawsize
: os
->size
);
4265 if (os
->flags
& SEC_SMALL_DATA
)
4267 if (min_short_vma
> lo
)
4269 if (max_short_vma
< hi
)
4274 /* See if the user wants to force a value. */
4275 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
4279 && (gp
->root
.type
== bfd_link_hash_defined
4280 || gp
->root
.type
== bfd_link_hash_defweak
))
4282 asection
*gp_sec
= gp
->root
.u
.def
.section
;
4283 gp_val
= (gp
->root
.u
.def
.value
4284 + gp_sec
->output_section
->vma
4285 + gp_sec
->output_offset
);
4289 /* Pick a sensible value. */
4291 asection
*got_sec
= ia64_info
->got_sec
;
4293 /* Start with just the address of the .got. */
4295 gp_val
= got_sec
->output_section
->vma
;
4296 else if (max_short_vma
!= 0)
4297 gp_val
= min_short_vma
;
4298 else if (max_vma
- min_vma
< 0x200000)
4301 gp_val
= max_vma
- 0x200000 + 8;
4303 /* If it is possible to address the entire image, but we
4304 don't with the choice above, adjust. */
4305 if (max_vma
- min_vma
< 0x400000
4306 && (max_vma
- gp_val
>= 0x200000
4307 || gp_val
- min_vma
> 0x200000))
4308 gp_val
= min_vma
+ 0x200000;
4309 else if (max_short_vma
!= 0)
4311 /* If we don't cover all the short data, adjust. */
4312 if (max_short_vma
- gp_val
>= 0x200000)
4313 gp_val
= min_short_vma
+ 0x200000;
4315 /* If we're addressing stuff past the end, adjust back. */
4316 if (gp_val
> max_vma
)
4317 gp_val
= max_vma
- 0x200000 + 8;
4321 /* Validate whether all SHF_IA_64_SHORT sections are within
4322 range of the chosen GP. */
4324 if (max_short_vma
!= 0)
4326 if (max_short_vma
- min_short_vma
>= 0x400000)
4328 (*_bfd_error_handler
)
4329 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
4330 bfd_get_filename (abfd
),
4331 (unsigned long) (max_short_vma
- min_short_vma
));
4334 else if ((gp_val
> min_short_vma
4335 && gp_val
- min_short_vma
> 0x200000)
4336 || (gp_val
< max_short_vma
4337 && max_short_vma
- gp_val
>= 0x200000))
4339 (*_bfd_error_handler
)
4340 (_("%s: __gp does not cover short data segment"),
4341 bfd_get_filename (abfd
));
4346 _bfd_set_gp_value (abfd
, gp_val
);
4352 elfNN_ia64_final_link (bfd
*abfd
, struct bfd_link_info
*info
)
4354 struct elfNN_ia64_link_hash_table
*ia64_info
;
4355 asection
*unwind_output_sec
;
4357 ia64_info
= elfNN_ia64_hash_table (info
);
4359 /* Make sure we've got ourselves a nice fat __gp value. */
4360 if (!info
->relocatable
)
4363 struct elf_link_hash_entry
*gp
;
4365 /* We assume after gp is set, section size will only decrease. We
4366 need to adjust gp for it. */
4367 _bfd_set_gp_value (abfd
, 0);
4368 if (! elfNN_ia64_choose_gp (abfd
, info
))
4370 gp_val
= _bfd_get_gp_value (abfd
);
4372 gp
= elf_link_hash_lookup (elf_hash_table (info
), "__gp", FALSE
,
4376 gp
->root
.type
= bfd_link_hash_defined
;
4377 gp
->root
.u
.def
.value
= gp_val
;
4378 gp
->root
.u
.def
.section
= bfd_abs_section_ptr
;
4382 /* If we're producing a final executable, we need to sort the contents
4383 of the .IA_64.unwind section. Force this section to be relocated
4384 into memory rather than written immediately to the output file. */
4385 unwind_output_sec
= NULL
;
4386 if (!info
->relocatable
)
4388 asection
*s
= bfd_get_section_by_name (abfd
, ELF_STRING_ia64_unwind
);
4391 unwind_output_sec
= s
->output_section
;
4392 unwind_output_sec
->contents
4393 = bfd_malloc (unwind_output_sec
->size
);
4394 if (unwind_output_sec
->contents
== NULL
)
4399 /* Invoke the regular ELF backend linker to do all the work. */
4400 if (!bfd_elf_final_link (abfd
, info
))
4403 if (unwind_output_sec
)
4405 elfNN_ia64_unwind_entry_compare_bfd
= abfd
;
4406 qsort (unwind_output_sec
->contents
,
4407 (size_t) (unwind_output_sec
->size
/ 24),
4409 elfNN_ia64_unwind_entry_compare
);
4411 if (! bfd_set_section_contents (abfd
, unwind_output_sec
,
4412 unwind_output_sec
->contents
, (bfd_vma
) 0,
4413 unwind_output_sec
->size
))
4421 elfNN_ia64_relocate_section (bfd
*output_bfd
,
4422 struct bfd_link_info
*info
,
4424 asection
*input_section
,
4426 Elf_Internal_Rela
*relocs
,
4427 Elf_Internal_Sym
*local_syms
,
4428 asection
**local_sections
)
4430 struct elfNN_ia64_link_hash_table
*ia64_info
;
4431 Elf_Internal_Shdr
*symtab_hdr
;
4432 Elf_Internal_Rela
*rel
;
4433 Elf_Internal_Rela
*relend
;
4435 bfd_boolean ret_val
= TRUE
; /* for non-fatal errors */
4438 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
4439 ia64_info
= elfNN_ia64_hash_table (info
);
4441 /* Infect various flags from the input section to the output section. */
4442 if (info
->relocatable
)
4446 flags
= elf_section_data(input_section
)->this_hdr
.sh_flags
;
4447 flags
&= SHF_IA_64_NORECOV
;
4449 elf_section_data(input_section
->output_section
)
4450 ->this_hdr
.sh_flags
|= flags
;
4453 gp_val
= _bfd_get_gp_value (output_bfd
);
4454 srel
= get_reloc_section (input_bfd
, ia64_info
, input_section
, FALSE
);
4457 relend
= relocs
+ input_section
->reloc_count
;
4458 for (; rel
< relend
; ++rel
)
4460 struct elf_link_hash_entry
*h
;
4461 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
4462 bfd_reloc_status_type r
;
4463 reloc_howto_type
*howto
;
4464 unsigned long r_symndx
;
4465 Elf_Internal_Sym
*sym
;
4466 unsigned int r_type
;
4470 bfd_boolean dynamic_symbol_p
;
4471 bfd_boolean undef_weak_ref
;
4473 r_type
= ELFNN_R_TYPE (rel
->r_info
);
4474 if (r_type
> R_IA64_MAX_RELOC_CODE
)
4476 (*_bfd_error_handler
)
4477 (_("%B: unknown relocation type %d"),
4478 input_bfd
, (int) r_type
);
4479 bfd_set_error (bfd_error_bad_value
);
4484 howto
= lookup_howto (r_type
);
4485 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4489 undef_weak_ref
= FALSE
;
4491 if (r_symndx
< symtab_hdr
->sh_info
)
4493 /* Reloc against local symbol. */
4495 sym
= local_syms
+ r_symndx
;
4496 sym_sec
= local_sections
[r_symndx
];
4498 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &msec
, rel
);
4499 if (!info
->relocatable
4500 && (sym_sec
->flags
& SEC_MERGE
) != 0
4501 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
4502 && sym_sec
->sec_info_type
== ELF_INFO_TYPE_MERGE
)
4504 struct elfNN_ia64_local_hash_entry
*loc_h
;
4506 loc_h
= get_local_sym_hash (ia64_info
, input_bfd
, rel
, FALSE
);
4507 if (loc_h
&& ! loc_h
->sec_merge_done
)
4509 struct elfNN_ia64_dyn_sym_info
*dynent
;
4512 for (count
= loc_h
->count
, dynent
= loc_h
->info
;
4518 _bfd_merged_section_offset (output_bfd
, &msec
,
4519 elf_section_data (msec
)->
4523 dynent
->addend
-= sym
->st_value
;
4524 dynent
->addend
+= msec
->output_section
->vma
4525 + msec
->output_offset
4526 - sym_sec
->output_section
->vma
4527 - sym_sec
->output_offset
;
4530 /* We may have introduced duplicated entries. We need
4531 to remove them properly. */
4532 count
= sort_dyn_sym_info (loc_h
->info
, loc_h
->count
);
4533 if (count
!= loc_h
->count
)
4535 loc_h
->count
= count
;
4536 loc_h
->sorted_count
= count
;
4539 loc_h
->sec_merge_done
= 1;
4545 bfd_boolean unresolved_reloc
;
4547 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
4549 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
4550 r_symndx
, symtab_hdr
, sym_hashes
,
4552 unresolved_reloc
, warned
);
4554 if (h
->root
.type
== bfd_link_hash_undefweak
)
4555 undef_weak_ref
= TRUE
;
4560 /* For relocs against symbols from removed linkonce sections,
4561 or sections discarded by a linker script, we just want the
4562 section contents zeroed. Avoid any special processing. */
4563 if (sym_sec
!= NULL
&& elf_discarded_section (sym_sec
))
4565 _bfd_clear_contents (howto
, input_bfd
, contents
+ rel
->r_offset
);
4571 if (info
->relocatable
)
4574 hit_addr
= contents
+ rel
->r_offset
;
4575 value
+= rel
->r_addend
;
4576 dynamic_symbol_p
= elfNN_ia64_dynamic_symbol_p (h
, info
, r_type
);
4587 case R_IA64_DIR32MSB
:
4588 case R_IA64_DIR32LSB
:
4589 case R_IA64_DIR64MSB
:
4590 case R_IA64_DIR64LSB
:
4591 /* Install a dynamic relocation for this reloc. */
4592 if ((dynamic_symbol_p
|| info
->shared
)
4594 && (input_section
->flags
& SEC_ALLOC
) != 0)
4596 unsigned int dyn_r_type
;
4600 BFD_ASSERT (srel
!= NULL
);
4607 /* ??? People shouldn't be doing non-pic code in
4608 shared libraries nor dynamic executables. */
4609 (*_bfd_error_handler
)
4610 (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4612 h
? h
->root
.root
.string
4613 : bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4622 /* If we don't need dynamic symbol lookup, find a
4623 matching RELATIVE relocation. */
4624 dyn_r_type
= r_type
;
4625 if (dynamic_symbol_p
)
4627 dynindx
= h
->dynindx
;
4628 addend
= rel
->r_addend
;
4635 case R_IA64_DIR32MSB
:
4636 dyn_r_type
= R_IA64_REL32MSB
;
4638 case R_IA64_DIR32LSB
:
4639 dyn_r_type
= R_IA64_REL32LSB
;
4641 case R_IA64_DIR64MSB
:
4642 dyn_r_type
= R_IA64_REL64MSB
;
4644 case R_IA64_DIR64LSB
:
4645 dyn_r_type
= R_IA64_REL64LSB
;
4655 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4656 srel
, rel
->r_offset
, dyn_r_type
,
4661 case R_IA64_LTV32MSB
:
4662 case R_IA64_LTV32LSB
:
4663 case R_IA64_LTV64MSB
:
4664 case R_IA64_LTV64LSB
:
4665 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4668 case R_IA64_GPREL22
:
4669 case R_IA64_GPREL64I
:
4670 case R_IA64_GPREL32MSB
:
4671 case R_IA64_GPREL32LSB
:
4672 case R_IA64_GPREL64MSB
:
4673 case R_IA64_GPREL64LSB
:
4674 if (dynamic_symbol_p
)
4676 (*_bfd_error_handler
)
4677 (_("%B: @gprel relocation against dynamic symbol %s"),
4679 h
? h
->root
.root
.string
4680 : bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4686 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4689 case R_IA64_LTOFF22
:
4690 case R_IA64_LTOFF22X
:
4691 case R_IA64_LTOFF64I
:
4692 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4693 value
= set_got_entry (input_bfd
, info
, dyn_i
, (h
? h
->dynindx
: -1),
4694 rel
->r_addend
, value
, R_IA64_DIRNNLSB
);
4696 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4699 case R_IA64_PLTOFF22
:
4700 case R_IA64_PLTOFF64I
:
4701 case R_IA64_PLTOFF64MSB
:
4702 case R_IA64_PLTOFF64LSB
:
4703 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4704 value
= set_pltoff_entry (output_bfd
, info
, dyn_i
, value
, FALSE
);
4706 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4709 case R_IA64_FPTR64I
:
4710 case R_IA64_FPTR32MSB
:
4711 case R_IA64_FPTR32LSB
:
4712 case R_IA64_FPTR64MSB
:
4713 case R_IA64_FPTR64LSB
:
4714 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4715 if (dyn_i
->want_fptr
)
4717 if (!undef_weak_ref
)
4718 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4720 if (!dyn_i
->want_fptr
|| info
->pie
)
4723 unsigned int dyn_r_type
= r_type
;
4724 bfd_vma addend
= rel
->r_addend
;
4726 /* Otherwise, we expect the dynamic linker to create
4729 if (dyn_i
->want_fptr
)
4731 if (r_type
== R_IA64_FPTR64I
)
4733 /* We can't represent this without a dynamic symbol.
4734 Adjust the relocation to be against an output
4735 section symbol, which are always present in the
4736 dynamic symbol table. */
4737 /* ??? People shouldn't be doing non-pic code in
4738 shared libraries. Hork. */
4739 (*_bfd_error_handler
)
4740 (_("%B: linking non-pic code in a position independent executable"),
4747 dyn_r_type
= r_type
+ R_IA64_RELNNLSB
- R_IA64_FPTRNNLSB
;
4751 if (h
->dynindx
!= -1)
4752 dynindx
= h
->dynindx
;
4754 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4755 (info
, h
->root
.u
.def
.section
->owner
,
4756 global_sym_index (h
)));
4761 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4762 (info
, input_bfd
, (long) r_symndx
));
4766 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4767 srel
, rel
->r_offset
, dyn_r_type
,
4771 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4774 case R_IA64_LTOFF_FPTR22
:
4775 case R_IA64_LTOFF_FPTR64I
:
4776 case R_IA64_LTOFF_FPTR32MSB
:
4777 case R_IA64_LTOFF_FPTR32LSB
:
4778 case R_IA64_LTOFF_FPTR64MSB
:
4779 case R_IA64_LTOFF_FPTR64LSB
:
4783 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
4784 if (dyn_i
->want_fptr
)
4786 BFD_ASSERT (h
== NULL
|| h
->dynindx
== -1);
4787 if (!undef_weak_ref
)
4788 value
= set_fptr_entry (output_bfd
, info
, dyn_i
, value
);
4793 /* Otherwise, we expect the dynamic linker to create
4797 if (h
->dynindx
!= -1)
4798 dynindx
= h
->dynindx
;
4800 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4801 (info
, h
->root
.u
.def
.section
->owner
,
4802 global_sym_index (h
)));
4805 dynindx
= (_bfd_elf_link_lookup_local_dynindx
4806 (info
, input_bfd
, (long) r_symndx
));
4810 value
= set_got_entry (output_bfd
, info
, dyn_i
, dynindx
,
4811 rel
->r_addend
, value
, R_IA64_FPTRNNLSB
);
4813 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4817 case R_IA64_PCREL32MSB
:
4818 case R_IA64_PCREL32LSB
:
4819 case R_IA64_PCREL64MSB
:
4820 case R_IA64_PCREL64LSB
:
4821 /* Install a dynamic relocation for this reloc. */
4822 if (dynamic_symbol_p
&& r_symndx
!= 0)
4824 BFD_ASSERT (srel
!= NULL
);
4826 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4827 srel
, rel
->r_offset
, r_type
,
4828 h
->dynindx
, rel
->r_addend
);
4832 case R_IA64_PCREL21B
:
4833 case R_IA64_PCREL60B
:
4834 /* We should have created a PLT entry for any dynamic symbol. */
4837 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
4839 if (dyn_i
&& dyn_i
->want_plt2
)
4841 /* Should have caught this earlier. */
4842 BFD_ASSERT (rel
->r_addend
== 0);
4844 value
= (ia64_info
->plt_sec
->output_section
->vma
4845 + ia64_info
->plt_sec
->output_offset
4846 + dyn_i
->plt2_offset
);
4850 /* Since there's no PLT entry, Validate that this is
4852 BFD_ASSERT (undef_weak_ref
|| sym_sec
->output_section
!= NULL
);
4854 /* If the symbol is undef_weak, we shouldn't be trying
4855 to call it. There's every chance that we'd wind up
4856 with an out-of-range fixup here. Don't bother setting
4857 any value at all. */
4863 case R_IA64_PCREL21BI
:
4864 case R_IA64_PCREL21F
:
4865 case R_IA64_PCREL21M
:
4866 case R_IA64_PCREL22
:
4867 case R_IA64_PCREL64I
:
4868 /* The PCREL21BI reloc is specifically not intended for use with
4869 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4870 fixup code, and thus probably ought not be dynamic. The
4871 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4872 if (dynamic_symbol_p
)
4876 if (r_type
== R_IA64_PCREL21BI
)
4877 msg
= _("%B: @internal branch to dynamic symbol %s");
4878 else if (r_type
== R_IA64_PCREL21F
|| r_type
== R_IA64_PCREL21M
)
4879 msg
= _("%B: speculation fixup to dynamic symbol %s");
4881 msg
= _("%B: @pcrel relocation against dynamic symbol %s");
4882 (*_bfd_error_handler
) (msg
, input_bfd
,
4883 h
? h
->root
.root
.string
4884 : bfd_elf_sym_name (input_bfd
,
4894 /* Make pc-relative. */
4895 value
-= (input_section
->output_section
->vma
4896 + input_section
->output_offset
4897 + rel
->r_offset
) & ~ (bfd_vma
) 0x3;
4898 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4901 case R_IA64_SEGREL32MSB
:
4902 case R_IA64_SEGREL32LSB
:
4903 case R_IA64_SEGREL64MSB
:
4904 case R_IA64_SEGREL64LSB
:
4906 /* Find the segment that contains the output_section. */
4907 Elf_Internal_Phdr
*p
= _bfd_elf_find_segment_containing_section
4908 (output_bfd
, input_section
->output_section
);
4912 r
= bfd_reloc_notsupported
;
4916 /* The VMA of the segment is the vaddr of the associated
4918 if (value
> p
->p_vaddr
)
4919 value
-= p
->p_vaddr
;
4922 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4927 case R_IA64_SECREL32MSB
:
4928 case R_IA64_SECREL32LSB
:
4929 case R_IA64_SECREL64MSB
:
4930 case R_IA64_SECREL64LSB
:
4931 /* Make output-section relative to section where the symbol
4932 is defined. PR 475 */
4934 value
-= sym_sec
->output_section
->vma
;
4935 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4938 case R_IA64_IPLTMSB
:
4939 case R_IA64_IPLTLSB
:
4940 /* Install a dynamic relocation for this reloc. */
4941 if ((dynamic_symbol_p
|| info
->shared
)
4942 && (input_section
->flags
& SEC_ALLOC
) != 0)
4944 BFD_ASSERT (srel
!= NULL
);
4946 /* If we don't need dynamic symbol lookup, install two
4947 RELATIVE relocations. */
4948 if (!dynamic_symbol_p
)
4950 unsigned int dyn_r_type
;
4952 if (r_type
== R_IA64_IPLTMSB
)
4953 dyn_r_type
= R_IA64_REL64MSB
;
4955 dyn_r_type
= R_IA64_REL64LSB
;
4957 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4959 srel
, rel
->r_offset
,
4960 dyn_r_type
, 0, value
);
4961 elfNN_ia64_install_dyn_reloc (output_bfd
, info
,
4963 srel
, rel
->r_offset
+ 8,
4964 dyn_r_type
, 0, gp_val
);
4967 elfNN_ia64_install_dyn_reloc (output_bfd
, info
, input_section
,
4968 srel
, rel
->r_offset
, r_type
,
4969 h
->dynindx
, rel
->r_addend
);
4972 if (r_type
== R_IA64_IPLTMSB
)
4973 r_type
= R_IA64_DIR64MSB
;
4975 r_type
= R_IA64_DIR64LSB
;
4976 elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4977 r
= elfNN_ia64_install_value (hit_addr
+ 8, gp_val
, r_type
);
4980 case R_IA64_TPREL14
:
4981 case R_IA64_TPREL22
:
4982 case R_IA64_TPREL64I
:
4983 if (elf_hash_table (info
)->tls_sec
== NULL
)
4984 goto missing_tls_sec
;
4985 value
-= elfNN_ia64_tprel_base (info
);
4986 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
4989 case R_IA64_DTPREL14
:
4990 case R_IA64_DTPREL22
:
4991 case R_IA64_DTPREL64I
:
4992 case R_IA64_DTPREL32LSB
:
4993 case R_IA64_DTPREL32MSB
:
4994 case R_IA64_DTPREL64LSB
:
4995 case R_IA64_DTPREL64MSB
:
4996 if (elf_hash_table (info
)->tls_sec
== NULL
)
4997 goto missing_tls_sec
;
4998 value
-= elfNN_ia64_dtprel_base (info
);
4999 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5002 case R_IA64_LTOFF_TPREL22
:
5003 case R_IA64_LTOFF_DTPMOD22
:
5004 case R_IA64_LTOFF_DTPREL22
:
5007 long dynindx
= h
? h
->dynindx
: -1;
5008 bfd_vma r_addend
= rel
->r_addend
;
5013 case R_IA64_LTOFF_TPREL22
:
5014 if (!dynamic_symbol_p
)
5016 if (elf_hash_table (info
)->tls_sec
== NULL
)
5017 goto missing_tls_sec
;
5019 value
-= elfNN_ia64_tprel_base (info
);
5022 r_addend
+= value
- elfNN_ia64_dtprel_base (info
);
5026 got_r_type
= R_IA64_TPREL64LSB
;
5028 case R_IA64_LTOFF_DTPMOD22
:
5029 if (!dynamic_symbol_p
&& !info
->shared
)
5031 got_r_type
= R_IA64_DTPMOD64LSB
;
5033 case R_IA64_LTOFF_DTPREL22
:
5034 if (!dynamic_symbol_p
)
5036 if (elf_hash_table (info
)->tls_sec
== NULL
)
5037 goto missing_tls_sec
;
5038 value
-= elfNN_ia64_dtprel_base (info
);
5040 got_r_type
= R_IA64_DTPRELNNLSB
;
5043 dyn_i
= get_dyn_sym_info (ia64_info
, h
, input_bfd
, rel
, FALSE
);
5044 value
= set_got_entry (input_bfd
, info
, dyn_i
, dynindx
, r_addend
,
5047 r
= elfNN_ia64_install_value (hit_addr
, value
, r_type
);
5052 r
= bfd_reloc_notsupported
;
5061 case bfd_reloc_undefined
:
5062 /* This can happen for global table relative relocs if
5063 __gp is undefined. This is a panic situation so we
5064 don't try to continue. */
5065 (*info
->callbacks
->undefined_symbol
)
5066 (info
, "__gp", input_bfd
, input_section
, rel
->r_offset
, 1);
5069 case bfd_reloc_notsupported
:
5074 name
= h
->root
.root
.string
;
5076 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
5078 if (!(*info
->callbacks
->warning
) (info
, _("unsupported reloc"),
5080 input_section
, rel
->r_offset
))
5086 case bfd_reloc_dangerous
:
5087 case bfd_reloc_outofrange
:
5088 case bfd_reloc_overflow
:
5095 name
= h
->root
.root
.string
;
5097 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
5102 case R_IA64_TPREL14
:
5103 case R_IA64_TPREL22
:
5104 case R_IA64_TPREL64I
:
5105 case R_IA64_DTPREL14
:
5106 case R_IA64_DTPREL22
:
5107 case R_IA64_DTPREL64I
:
5108 case R_IA64_DTPREL32LSB
:
5109 case R_IA64_DTPREL32MSB
:
5110 case R_IA64_DTPREL64LSB
:
5111 case R_IA64_DTPREL64MSB
:
5112 case R_IA64_LTOFF_TPREL22
:
5113 case R_IA64_LTOFF_DTPMOD22
:
5114 case R_IA64_LTOFF_DTPREL22
:
5115 (*_bfd_error_handler
)
5116 (_("%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."),
5117 input_bfd
, input_section
, howto
->name
, name
,
5121 case R_IA64_PCREL21B
:
5122 case R_IA64_PCREL21BI
:
5123 case R_IA64_PCREL21M
:
5124 case R_IA64_PCREL21F
:
5125 if (is_elf_hash_table (info
->hash
))
5127 /* Relaxtion is always performed for ELF output.
5128 Overflow failures for those relocations mean
5129 that the section is too big to relax. */
5130 (*_bfd_error_handler
)
5131 (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
5132 input_bfd
, input_section
, howto
->name
, name
,
5133 rel
->r_offset
, input_section
->size
);
5137 if (!(*info
->callbacks
->reloc_overflow
) (info
,
5159 elfNN_ia64_finish_dynamic_symbol (bfd
*output_bfd
,
5160 struct bfd_link_info
*info
,
5161 struct elf_link_hash_entry
*h
,
5162 Elf_Internal_Sym
*sym
)
5164 struct elfNN_ia64_link_hash_table
*ia64_info
;
5165 struct elfNN_ia64_dyn_sym_info
*dyn_i
;
5167 ia64_info
= elfNN_ia64_hash_table (info
);
5168 dyn_i
= get_dyn_sym_info (ia64_info
, h
, NULL
, NULL
, FALSE
);
5170 /* Fill in the PLT data, if required. */
5171 if (dyn_i
&& dyn_i
->want_plt
)
5173 Elf_Internal_Rela outrel
;
5176 bfd_vma plt_addr
, pltoff_addr
, gp_val
, index
;
5178 gp_val
= _bfd_get_gp_value (output_bfd
);
5180 /* Initialize the minimal PLT entry. */
5182 index
= (dyn_i
->plt_offset
- PLT_HEADER_SIZE
) / PLT_MIN_ENTRY_SIZE
;
5183 plt_sec
= ia64_info
->plt_sec
;
5184 loc
= plt_sec
->contents
+ dyn_i
->plt_offset
;
5186 memcpy (loc
, plt_min_entry
, PLT_MIN_ENTRY_SIZE
);
5187 elfNN_ia64_install_value (loc
, index
, R_IA64_IMM22
);
5188 elfNN_ia64_install_value (loc
+2, -dyn_i
->plt_offset
, R_IA64_PCREL21B
);
5190 plt_addr
= (plt_sec
->output_section
->vma
5191 + plt_sec
->output_offset
5192 + dyn_i
->plt_offset
);
5193 pltoff_addr
= set_pltoff_entry (output_bfd
, info
, dyn_i
, plt_addr
, TRUE
);
5195 /* Initialize the FULL PLT entry, if needed. */
5196 if (dyn_i
->want_plt2
)
5198 loc
= plt_sec
->contents
+ dyn_i
->plt2_offset
;
5200 memcpy (loc
, plt_full_entry
, PLT_FULL_ENTRY_SIZE
);
5201 elfNN_ia64_install_value (loc
, pltoff_addr
- gp_val
, R_IA64_IMM22
);
5203 /* Mark the symbol as undefined, rather than as defined in the
5204 plt section. Leave the value alone. */
5205 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
5206 first place. But perhaps elflink.c did some for us. */
5207 if (!h
->def_regular
)
5208 sym
->st_shndx
= SHN_UNDEF
;
5211 /* Create the dynamic relocation. */
5212 outrel
.r_offset
= pltoff_addr
;
5213 if (bfd_little_endian (output_bfd
))
5214 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTLSB
);
5216 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, R_IA64_IPLTMSB
);
5217 outrel
.r_addend
= 0;
5219 /* This is fun. In the .IA_64.pltoff section, we've got entries
5220 that correspond both to real PLT entries, and those that
5221 happened to resolve to local symbols but need to be created
5222 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
5223 relocations for the real PLT should come at the end of the
5224 section, so that they can be indexed by plt entry at runtime.
5226 We emitted all of the relocations for the non-PLT @pltoff
5227 entries during relocate_section. So we can consider the
5228 existing sec->reloc_count to be the base of the array of
5231 loc
= ia64_info
->rel_pltoff_sec
->contents
;
5232 loc
+= ((ia64_info
->rel_pltoff_sec
->reloc_count
+ index
)
5233 * sizeof (ElfNN_External_Rela
));
5234 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
5237 /* Mark some specially defined symbols as absolute. */
5238 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
5239 || h
== ia64_info
->root
.hgot
5240 || h
== ia64_info
->root
.hplt
)
5241 sym
->st_shndx
= SHN_ABS
;
5247 elfNN_ia64_finish_dynamic_sections (bfd
*abfd
,
5248 struct bfd_link_info
*info
)
5250 struct elfNN_ia64_link_hash_table
*ia64_info
;
5253 ia64_info
= elfNN_ia64_hash_table (info
);
5254 dynobj
= ia64_info
->root
.dynobj
;
5256 if (elf_hash_table (info
)->dynamic_sections_created
)
5258 ElfNN_External_Dyn
*dyncon
, *dynconend
;
5259 asection
*sdyn
, *sgotplt
;
5262 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
5263 sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
5264 BFD_ASSERT (sdyn
!= NULL
);
5265 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
5266 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
5268 gp_val
= _bfd_get_gp_value (abfd
);
5270 for (; dyncon
< dynconend
; dyncon
++)
5272 Elf_Internal_Dyn dyn
;
5274 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
5279 dyn
.d_un
.d_ptr
= gp_val
;
5283 dyn
.d_un
.d_val
= (ia64_info
->minplt_entries
5284 * sizeof (ElfNN_External_Rela
));
5288 /* See the comment above in finish_dynamic_symbol. */
5289 dyn
.d_un
.d_ptr
= (ia64_info
->rel_pltoff_sec
->output_section
->vma
5290 + ia64_info
->rel_pltoff_sec
->output_offset
5291 + (ia64_info
->rel_pltoff_sec
->reloc_count
5292 * sizeof (ElfNN_External_Rela
)));
5295 case DT_IA_64_PLT_RESERVE
:
5296 dyn
.d_un
.d_ptr
= (sgotplt
->output_section
->vma
5297 + sgotplt
->output_offset
);
5301 /* Do not have RELASZ include JMPREL. This makes things
5302 easier on ld.so. This is not what the rest of BFD set up. */
5303 dyn
.d_un
.d_val
-= (ia64_info
->minplt_entries
5304 * sizeof (ElfNN_External_Rela
));
5308 bfd_elfNN_swap_dyn_out (abfd
, &dyn
, dyncon
);
5311 /* Initialize the PLT0 entry. */
5312 if (ia64_info
->plt_sec
)
5314 bfd_byte
*loc
= ia64_info
->plt_sec
->contents
;
5317 memcpy (loc
, plt_header
, PLT_HEADER_SIZE
);
5319 pltres
= (sgotplt
->output_section
->vma
5320 + sgotplt
->output_offset
5323 elfNN_ia64_install_value (loc
+1, pltres
, R_IA64_GPREL22
);
5330 /* ELF file flag handling: */
5332 /* Function to keep IA-64 specific file flags. */
5334 elfNN_ia64_set_private_flags (bfd
*abfd
, flagword flags
)
5336 BFD_ASSERT (!elf_flags_init (abfd
)
5337 || elf_elfheader (abfd
)->e_flags
== flags
);
5339 elf_elfheader (abfd
)->e_flags
= flags
;
5340 elf_flags_init (abfd
) = TRUE
;
5344 /* Merge backend specific data from an object file to the output
5345 object file when linking. */
5347 elfNN_ia64_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
5351 bfd_boolean ok
= TRUE
;
5353 /* Don't even pretend to support mixed-format linking. */
5354 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
5355 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
5358 in_flags
= elf_elfheader (ibfd
)->e_flags
;
5359 out_flags
= elf_elfheader (obfd
)->e_flags
;
5361 if (! elf_flags_init (obfd
))
5363 elf_flags_init (obfd
) = TRUE
;
5364 elf_elfheader (obfd
)->e_flags
= in_flags
;
5366 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
5367 && bfd_get_arch_info (obfd
)->the_default
)
5369 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
5370 bfd_get_mach (ibfd
));
5376 /* Check flag compatibility. */
5377 if (in_flags
== out_flags
)
5380 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
5381 if (!(in_flags
& EF_IA_64_REDUCEDFP
) && (out_flags
& EF_IA_64_REDUCEDFP
))
5382 elf_elfheader (obfd
)->e_flags
&= ~EF_IA_64_REDUCEDFP
;
5384 if ((in_flags
& EF_IA_64_TRAPNIL
) != (out_flags
& EF_IA_64_TRAPNIL
))
5386 (*_bfd_error_handler
)
5387 (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5390 bfd_set_error (bfd_error_bad_value
);
5393 if ((in_flags
& EF_IA_64_BE
) != (out_flags
& EF_IA_64_BE
))
5395 (*_bfd_error_handler
)
5396 (_("%B: linking big-endian files with little-endian files"),
5399 bfd_set_error (bfd_error_bad_value
);
5402 if ((in_flags
& EF_IA_64_ABI64
) != (out_flags
& EF_IA_64_ABI64
))
5404 (*_bfd_error_handler
)
5405 (_("%B: linking 64-bit files with 32-bit files"),
5408 bfd_set_error (bfd_error_bad_value
);
5411 if ((in_flags
& EF_IA_64_CONS_GP
) != (out_flags
& EF_IA_64_CONS_GP
))
5413 (*_bfd_error_handler
)
5414 (_("%B: linking constant-gp files with non-constant-gp files"),
5417 bfd_set_error (bfd_error_bad_value
);
5420 if ((in_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
)
5421 != (out_flags
& EF_IA_64_NOFUNCDESC_CONS_GP
))
5423 (*_bfd_error_handler
)
5424 (_("%B: linking auto-pic files with non-auto-pic files"),
5427 bfd_set_error (bfd_error_bad_value
);
5435 elfNN_ia64_print_private_bfd_data (bfd
*abfd
, PTR ptr
)
5437 FILE *file
= (FILE *) ptr
;
5438 flagword flags
= elf_elfheader (abfd
)->e_flags
;
5440 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
5442 fprintf (file
, "private flags = %s%s%s%s%s%s%s%s\n",
5443 (flags
& EF_IA_64_TRAPNIL
) ? "TRAPNIL, " : "",
5444 (flags
& EF_IA_64_EXT
) ? "EXT, " : "",
5445 (flags
& EF_IA_64_BE
) ? "BE, " : "LE, ",
5446 (flags
& EF_IA_64_REDUCEDFP
) ? "REDUCEDFP, " : "",
5447 (flags
& EF_IA_64_CONS_GP
) ? "CONS_GP, " : "",
5448 (flags
& EF_IA_64_NOFUNCDESC_CONS_GP
) ? "NOFUNCDESC_CONS_GP, " : "",
5449 (flags
& EF_IA_64_ABSOLUTE
) ? "ABSOLUTE, " : "",
5450 (flags
& EF_IA_64_ABI64
) ? "ABI64" : "ABI32");
5452 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
5456 static enum elf_reloc_type_class
5457 elfNN_ia64_reloc_type_class (const Elf_Internal_Rela
*rela
)
5459 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
5461 case R_IA64_REL32MSB
:
5462 case R_IA64_REL32LSB
:
5463 case R_IA64_REL64MSB
:
5464 case R_IA64_REL64LSB
:
5465 return reloc_class_relative
;
5466 case R_IA64_IPLTMSB
:
5467 case R_IA64_IPLTLSB
:
5468 return reloc_class_plt
;
5470 return reloc_class_copy
;
5472 return reloc_class_normal
;
5476 static const struct bfd_elf_special_section elfNN_ia64_special_sections
[] =
5478 { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_IA_64_SHORT
},
5479 { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_IA_64_SHORT
},
5480 { NULL
, 0, 0, 0, 0 }
5484 elfNN_ia64_object_p (bfd
*abfd
)
5487 asection
*group
, *unwi
, *unw
;
5490 char *unwi_name
, *unw_name
;
5493 if (abfd
->flags
& DYNAMIC
)
5496 /* Flags for fake group section. */
5497 flags
= (SEC_LINKER_CREATED
| SEC_GROUP
| SEC_LINK_ONCE
5500 /* We add a fake section group for each .gnu.linkonce.t.* section,
5501 which isn't in a section group, and its unwind sections. */
5502 for (sec
= abfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
5504 if (elf_sec_group (sec
) == NULL
5505 && ((sec
->flags
& (SEC_LINK_ONCE
| SEC_CODE
| SEC_GROUP
))
5506 == (SEC_LINK_ONCE
| SEC_CODE
))
5507 && CONST_STRNEQ (sec
->name
, ".gnu.linkonce.t."))
5509 name
= sec
->name
+ 16;
5511 amt
= strlen (name
) + sizeof (".gnu.linkonce.ia64unwi.");
5512 unwi_name
= bfd_alloc (abfd
, amt
);
5516 strcpy (stpcpy (unwi_name
, ".gnu.linkonce.ia64unwi."), name
);
5517 unwi
= bfd_get_section_by_name (abfd
, unwi_name
);
5519 amt
= strlen (name
) + sizeof (".gnu.linkonce.ia64unw.");
5520 unw_name
= bfd_alloc (abfd
, amt
);
5524 strcpy (stpcpy (unw_name
, ".gnu.linkonce.ia64unw."), name
);
5525 unw
= bfd_get_section_by_name (abfd
, unw_name
);
5527 /* We need to create a fake group section for it and its
5529 group
= bfd_make_section_anyway_with_flags (abfd
, name
,
5534 /* Move the fake group section to the beginning. */
5535 bfd_section_list_remove (abfd
, group
);
5536 bfd_section_list_prepend (abfd
, group
);
5538 elf_next_in_group (group
) = sec
;
5540 elf_group_name (sec
) = name
;
5541 elf_next_in_group (sec
) = sec
;
5542 elf_sec_group (sec
) = group
;
5546 elf_group_name (unwi
) = name
;
5547 elf_next_in_group (unwi
) = sec
;
5548 elf_next_in_group (sec
) = unwi
;
5549 elf_sec_group (unwi
) = group
;
5554 elf_group_name (unw
) = name
;
5557 elf_next_in_group (unw
) = elf_next_in_group (unwi
);
5558 elf_next_in_group (unwi
) = unw
;
5562 elf_next_in_group (unw
) = sec
;
5563 elf_next_in_group (sec
) = unw
;
5565 elf_sec_group (unw
) = group
;
5568 /* Fake SHT_GROUP section header. */
5569 elf_section_data (group
)->this_hdr
.bfd_section
= group
;
5570 elf_section_data (group
)->this_hdr
.sh_type
= SHT_GROUP
;
5577 elfNN_ia64_hpux_vec (const bfd_target
*vec
)
5579 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec
;
5580 return (vec
== & bfd_elfNN_ia64_hpux_big_vec
);
5584 elfNN_hpux_post_process_headers (bfd
*abfd
,
5585 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
5587 Elf_Internal_Ehdr
*i_ehdrp
= elf_elfheader (abfd
);
5589 i_ehdrp
->e_ident
[EI_OSABI
] = get_elf_backend_data (abfd
)->elf_osabi
;
5590 i_ehdrp
->e_ident
[EI_ABIVERSION
] = 1;
5594 elfNN_hpux_backend_section_from_bfd_section (bfd
*abfd ATTRIBUTE_UNUSED
,
5595 asection
*sec
, int *retval
)
5597 if (bfd_is_com_section (sec
))
5599 *retval
= SHN_IA_64_ANSI_COMMON
;
5606 elfNN_hpux_backend_symbol_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
5609 elf_symbol_type
*elfsym
= (elf_symbol_type
*) asym
;
5611 switch (elfsym
->internal_elf_sym
.st_shndx
)
5613 case SHN_IA_64_ANSI_COMMON
:
5614 asym
->section
= bfd_com_section_ptr
;
5615 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
5616 asym
->flags
&= ~BSF_GLOBAL
;
5622 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
5623 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
5624 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
5625 #define TARGET_BIG_NAME "elfNN-ia64-big"
5626 #define ELF_ARCH bfd_arch_ia64
5627 #define ELF_MACHINE_CODE EM_IA_64
5628 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
5629 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
5630 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
5631 #define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
5633 #define elf_backend_section_from_shdr \
5634 elfNN_ia64_section_from_shdr
5635 #define elf_backend_section_flags \
5636 elfNN_ia64_section_flags
5637 #define elf_backend_fake_sections \
5638 elfNN_ia64_fake_sections
5639 #define elf_backend_final_write_processing \
5640 elfNN_ia64_final_write_processing
5641 #define elf_backend_add_symbol_hook \
5642 elfNN_ia64_add_symbol_hook
5643 #define elf_backend_additional_program_headers \
5644 elfNN_ia64_additional_program_headers
5645 #define elf_backend_modify_segment_map \
5646 elfNN_ia64_modify_segment_map
5647 #define elf_backend_modify_program_headers \
5648 elfNN_ia64_modify_program_headers
5649 #define elf_info_to_howto \
5650 elfNN_ia64_info_to_howto
5652 #define bfd_elfNN_bfd_reloc_type_lookup \
5653 elfNN_ia64_reloc_type_lookup
5654 #define bfd_elfNN_bfd_reloc_name_lookup \
5655 elfNN_ia64_reloc_name_lookup
5656 #define bfd_elfNN_bfd_is_local_label_name \
5657 elfNN_ia64_is_local_label_name
5658 #define bfd_elfNN_bfd_relax_section \
5659 elfNN_ia64_relax_section
5661 #define elf_backend_object_p \
5664 /* Stuff for the BFD linker: */
5665 #define bfd_elfNN_bfd_link_hash_table_create \
5666 elfNN_ia64_hash_table_create
5667 #define bfd_elfNN_bfd_link_hash_table_free \
5668 elfNN_ia64_hash_table_free
5669 #define elf_backend_create_dynamic_sections \
5670 elfNN_ia64_create_dynamic_sections
5671 #define elf_backend_check_relocs \
5672 elfNN_ia64_check_relocs
5673 #define elf_backend_adjust_dynamic_symbol \
5674 elfNN_ia64_adjust_dynamic_symbol
5675 #define elf_backend_size_dynamic_sections \
5676 elfNN_ia64_size_dynamic_sections
5677 #define elf_backend_omit_section_dynsym \
5678 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
5679 #define elf_backend_relocate_section \
5680 elfNN_ia64_relocate_section
5681 #define elf_backend_finish_dynamic_symbol \
5682 elfNN_ia64_finish_dynamic_symbol
5683 #define elf_backend_finish_dynamic_sections \
5684 elfNN_ia64_finish_dynamic_sections
5685 #define bfd_elfNN_bfd_final_link \
5686 elfNN_ia64_final_link
5688 #define bfd_elfNN_bfd_merge_private_bfd_data \
5689 elfNN_ia64_merge_private_bfd_data
5690 #define bfd_elfNN_bfd_set_private_flags \
5691 elfNN_ia64_set_private_flags
5692 #define bfd_elfNN_bfd_print_private_bfd_data \
5693 elfNN_ia64_print_private_bfd_data
5695 #define elf_backend_plt_readonly 1
5696 #define elf_backend_want_plt_sym 0
5697 #define elf_backend_plt_alignment 5
5698 #define elf_backend_got_header_size 0
5699 #define elf_backend_want_got_plt 1
5700 #define elf_backend_may_use_rel_p 1
5701 #define elf_backend_may_use_rela_p 1
5702 #define elf_backend_default_use_rela_p 1
5703 #define elf_backend_want_dynbss 0
5704 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5705 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
5706 #define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
5707 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
5708 #define elf_backend_rela_normal 1
5709 #define elf_backend_special_sections elfNN_ia64_special_sections
5710 #define elf_backend_default_execstack 0
5712 /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5713 SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
5714 We don't want to flood users with so many error messages. We turn
5715 off the warning for now. It will be turned on later when the Intel
5716 compiler is fixed. */
5717 #define elf_backend_link_order_error_handler NULL
5719 #include "elfNN-target.h"
5721 /* HPUX-specific vectors. */
5723 #undef TARGET_LITTLE_SYM
5724 #undef TARGET_LITTLE_NAME
5725 #undef TARGET_BIG_SYM
5726 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
5727 #undef TARGET_BIG_NAME
5728 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
5730 /* These are HP-UX specific functions. */
5732 #undef elf_backend_post_process_headers
5733 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5735 #undef elf_backend_section_from_bfd_section
5736 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5738 #undef elf_backend_symbol_processing
5739 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5741 #undef elf_backend_want_p_paddr_set_to_zero
5742 #define elf_backend_want_p_paddr_set_to_zero 1
5744 #undef ELF_COMMONPAGESIZE
5746 #define ELF_OSABI ELFOSABI_HPUX
5749 #define elfNN_bed elfNN_ia64_hpux_bed
5751 #include "elfNN-target.h"
5753 #undef elf_backend_want_p_paddr_set_to_zero