1 /* X86-64 specific support for ELF
2 Copyright (C) 2000-2024 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka <jh@suse.cz>.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 #include "elfxx-x86.h"
24 #include "libiberty.h"
27 #include "opcode/i386.h"
34 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
35 #define MINUS_ONE (~ (bfd_vma) 0)
37 /* Since both 32-bit and 64-bit x86-64 encode relocation type in the
38 identical manner, we use ELF32_R_TYPE instead of ELF64_R_TYPE to get
39 relocation type. We also use ELF_ST_TYPE instead of ELF64_ST_TYPE
40 since they are the same. */
42 /* The relocation "howto" table. Order of fields:
43 type, rightshift, size, bitsize, pc_relative, bitpos, complain_on_overflow,
44 special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset. */
45 static reloc_howto_type x86_64_elf_howto_table
[] =
47 HOWTO(R_X86_64_NONE
, 0, 0, 0, false, 0, complain_overflow_dont
,
48 bfd_elf_generic_reloc
, "R_X86_64_NONE", false, 0, 0x00000000,
50 HOWTO(R_X86_64_64
, 0, 8, 64, false, 0, complain_overflow_dont
,
51 bfd_elf_generic_reloc
, "R_X86_64_64", false, 0, MINUS_ONE
,
53 HOWTO(R_X86_64_PC32
, 0, 4, 32, true, 0, complain_overflow_signed
,
54 bfd_elf_generic_reloc
, "R_X86_64_PC32", false, 0, 0xffffffff,
56 HOWTO(R_X86_64_GOT32
, 0, 4, 32, false, 0, complain_overflow_signed
,
57 bfd_elf_generic_reloc
, "R_X86_64_GOT32", false, 0, 0xffffffff,
59 HOWTO(R_X86_64_PLT32
, 0, 4, 32, true, 0, complain_overflow_signed
,
60 bfd_elf_generic_reloc
, "R_X86_64_PLT32", false, 0, 0xffffffff,
62 HOWTO(R_X86_64_COPY
, 0, 4, 32, false, 0, complain_overflow_bitfield
,
63 bfd_elf_generic_reloc
, "R_X86_64_COPY", false, 0, 0xffffffff,
65 HOWTO(R_X86_64_GLOB_DAT
, 0, 8, 64, false, 0, complain_overflow_dont
,
66 bfd_elf_generic_reloc
, "R_X86_64_GLOB_DAT", false, 0, MINUS_ONE
,
68 HOWTO(R_X86_64_JUMP_SLOT
, 0, 8, 64, false, 0, complain_overflow_dont
,
69 bfd_elf_generic_reloc
, "R_X86_64_JUMP_SLOT", false, 0, MINUS_ONE
,
71 HOWTO(R_X86_64_RELATIVE
, 0, 8, 64, false, 0, complain_overflow_dont
,
72 bfd_elf_generic_reloc
, "R_X86_64_RELATIVE", false, 0, MINUS_ONE
,
74 HOWTO(R_X86_64_GOTPCREL
, 0, 4, 32, true, 0, complain_overflow_signed
,
75 bfd_elf_generic_reloc
, "R_X86_64_GOTPCREL", false, 0, 0xffffffff,
77 HOWTO(R_X86_64_32
, 0, 4, 32, false, 0, complain_overflow_unsigned
,
78 bfd_elf_generic_reloc
, "R_X86_64_32", false, 0, 0xffffffff,
80 HOWTO(R_X86_64_32S
, 0, 4, 32, false, 0, complain_overflow_signed
,
81 bfd_elf_generic_reloc
, "R_X86_64_32S", false, 0, 0xffffffff,
83 HOWTO(R_X86_64_16
, 0, 2, 16, false, 0, complain_overflow_bitfield
,
84 bfd_elf_generic_reloc
, "R_X86_64_16", false, 0, 0xffff, false),
85 HOWTO(R_X86_64_PC16
, 0, 2, 16, true, 0, complain_overflow_bitfield
,
86 bfd_elf_generic_reloc
, "R_X86_64_PC16", false, 0, 0xffff, true),
87 HOWTO(R_X86_64_8
, 0, 1, 8, false, 0, complain_overflow_bitfield
,
88 bfd_elf_generic_reloc
, "R_X86_64_8", false, 0, 0xff, false),
89 HOWTO(R_X86_64_PC8
, 0, 1, 8, true, 0, complain_overflow_signed
,
90 bfd_elf_generic_reloc
, "R_X86_64_PC8", false, 0, 0xff, true),
91 HOWTO(R_X86_64_DTPMOD64
, 0, 8, 64, false, 0, complain_overflow_dont
,
92 bfd_elf_generic_reloc
, "R_X86_64_DTPMOD64", false, 0, MINUS_ONE
,
94 HOWTO(R_X86_64_DTPOFF64
, 0, 8, 64, false, 0, complain_overflow_dont
,
95 bfd_elf_generic_reloc
, "R_X86_64_DTPOFF64", false, 0, MINUS_ONE
,
97 HOWTO(R_X86_64_TPOFF64
, 0, 8, 64, false, 0, complain_overflow_dont
,
98 bfd_elf_generic_reloc
, "R_X86_64_TPOFF64", false, 0, MINUS_ONE
,
100 HOWTO(R_X86_64_TLSGD
, 0, 4, 32, true, 0, complain_overflow_signed
,
101 bfd_elf_generic_reloc
, "R_X86_64_TLSGD", false, 0, 0xffffffff,
103 HOWTO(R_X86_64_TLSLD
, 0, 4, 32, true, 0, complain_overflow_signed
,
104 bfd_elf_generic_reloc
, "R_X86_64_TLSLD", false, 0, 0xffffffff,
106 HOWTO(R_X86_64_DTPOFF32
, 0, 4, 32, false, 0, complain_overflow_signed
,
107 bfd_elf_generic_reloc
, "R_X86_64_DTPOFF32", false, 0, 0xffffffff,
109 HOWTO(R_X86_64_GOTTPOFF
, 0, 4, 32, true, 0, complain_overflow_signed
,
110 bfd_elf_generic_reloc
, "R_X86_64_GOTTPOFF", false, 0, 0xffffffff,
112 HOWTO(R_X86_64_TPOFF32
, 0, 4, 32, false, 0, complain_overflow_signed
,
113 bfd_elf_generic_reloc
, "R_X86_64_TPOFF32", false, 0, 0xffffffff,
115 HOWTO(R_X86_64_PC64
, 0, 8, 64, true, 0, complain_overflow_dont
,
116 bfd_elf_generic_reloc
, "R_X86_64_PC64", false, 0, MINUS_ONE
,
118 HOWTO(R_X86_64_GOTOFF64
, 0, 8, 64, false, 0, complain_overflow_dont
,
119 bfd_elf_generic_reloc
, "R_X86_64_GOTOFF64", false, 0, MINUS_ONE
,
121 HOWTO(R_X86_64_GOTPC32
, 0, 4, 32, true, 0, complain_overflow_signed
,
122 bfd_elf_generic_reloc
, "R_X86_64_GOTPC32", false, 0, 0xffffffff,
124 HOWTO(R_X86_64_GOT64
, 0, 8, 64, false, 0, complain_overflow_signed
,
125 bfd_elf_generic_reloc
, "R_X86_64_GOT64", false, 0, MINUS_ONE
,
127 HOWTO(R_X86_64_GOTPCREL64
, 0, 8, 64, true, 0, complain_overflow_signed
,
128 bfd_elf_generic_reloc
, "R_X86_64_GOTPCREL64", false, 0, MINUS_ONE
,
130 HOWTO(R_X86_64_GOTPC64
, 0, 8, 64, true, 0, complain_overflow_signed
,
131 bfd_elf_generic_reloc
, "R_X86_64_GOTPC64", false, 0, MINUS_ONE
,
133 HOWTO(R_X86_64_GOTPLT64
, 0, 8, 64, false, 0, complain_overflow_signed
,
134 bfd_elf_generic_reloc
, "R_X86_64_GOTPLT64", false, 0, MINUS_ONE
,
136 HOWTO(R_X86_64_PLTOFF64
, 0, 8, 64, false, 0, complain_overflow_signed
,
137 bfd_elf_generic_reloc
, "R_X86_64_PLTOFF64", false, 0, MINUS_ONE
,
139 HOWTO(R_X86_64_SIZE32
, 0, 4, 32, false, 0, complain_overflow_unsigned
,
140 bfd_elf_generic_reloc
, "R_X86_64_SIZE32", false, 0, 0xffffffff,
142 HOWTO(R_X86_64_SIZE64
, 0, 8, 64, false, 0, complain_overflow_dont
,
143 bfd_elf_generic_reloc
, "R_X86_64_SIZE64", false, 0, MINUS_ONE
,
145 HOWTO(R_X86_64_GOTPC32_TLSDESC
, 0, 4, 32, true, 0,
146 complain_overflow_bitfield
, bfd_elf_generic_reloc
,
147 "R_X86_64_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
148 HOWTO(R_X86_64_TLSDESC_CALL
, 0, 0, 0, false, 0,
149 complain_overflow_dont
, bfd_elf_generic_reloc
,
150 "R_X86_64_TLSDESC_CALL",
152 HOWTO(R_X86_64_TLSDESC
, 0, 8, 64, false, 0,
153 complain_overflow_dont
, bfd_elf_generic_reloc
,
154 "R_X86_64_TLSDESC", false, 0, MINUS_ONE
, false),
155 HOWTO(R_X86_64_IRELATIVE
, 0, 8, 64, false, 0, complain_overflow_dont
,
156 bfd_elf_generic_reloc
, "R_X86_64_IRELATIVE", false, 0, MINUS_ONE
,
158 HOWTO(R_X86_64_RELATIVE64
, 0, 8, 64, false, 0, complain_overflow_dont
,
159 bfd_elf_generic_reloc
, "R_X86_64_RELATIVE64", false, 0, MINUS_ONE
,
161 HOWTO(R_X86_64_PC32_BND
, 0, 4, 32, true, 0, complain_overflow_signed
,
162 bfd_elf_generic_reloc
, "R_X86_64_PC32_BND", false, 0, 0xffffffff,
164 HOWTO(R_X86_64_PLT32_BND
, 0, 4, 32, true, 0, complain_overflow_signed
,
165 bfd_elf_generic_reloc
, "R_X86_64_PLT32_BND", false, 0, 0xffffffff,
167 HOWTO(R_X86_64_GOTPCRELX
, 0, 4, 32, true, 0, complain_overflow_signed
,
168 bfd_elf_generic_reloc
, "R_X86_64_GOTPCRELX", false, 0, 0xffffffff,
170 HOWTO(R_X86_64_REX_GOTPCRELX
, 0, 4, 32, true, 0, complain_overflow_signed
,
171 bfd_elf_generic_reloc
, "R_X86_64_REX_GOTPCRELX", false, 0, 0xffffffff,
173 HOWTO(R_X86_64_CODE_4_GOTPCRELX
, 0, 4, 32, true, 0, complain_overflow_signed
,
174 bfd_elf_generic_reloc
, "R_X86_64_CODE_4_GOTPCRELX", false, 0, 0xffffffff,
176 HOWTO(R_X86_64_CODE_4_GOTTPOFF
, 0, 4, 32, true, 0, complain_overflow_signed
,
177 bfd_elf_generic_reloc
, "R_X86_64_CODE_4_GOTTPOFF", false, 0, 0xffffffff,
179 HOWTO(R_X86_64_CODE_4_GOTPC32_TLSDESC
, 0, 4, 32, true, 0,
180 complain_overflow_bitfield
, bfd_elf_generic_reloc
,
181 "R_X86_64_CODE_4_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
182 HOWTO(R_X86_64_CODE_5_GOTPCRELX
, 0, 4, 32, true, 0,
183 complain_overflow_signed
, bfd_elf_generic_reloc
,
184 "R_X86_64_CODE_5_GOTPCRELX", false, 0, 0xffffffff, true),
185 HOWTO(R_X86_64_CODE_5_GOTTPOFF
, 0, 4, 32, true, 0,
186 complain_overflow_signed
, bfd_elf_generic_reloc
,
187 "R_X86_64_CODE_5_GOTTPOFF", false, 0, 0xffffffff, true),
188 HOWTO(R_X86_64_CODE_5_GOTPC32_TLSDESC
, 0, 4, 32, true, 0,
189 complain_overflow_bitfield
, bfd_elf_generic_reloc
,
190 "R_X86_64_CODE_5_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
191 HOWTO(R_X86_64_CODE_6_GOTPCRELX
, 0, 4, 32, true, 0,
192 complain_overflow_signed
, bfd_elf_generic_reloc
,
193 "R_X86_64_CODE_6_GOTPCRELX", false, 0, 0xffffffff, true),
194 HOWTO(R_X86_64_CODE_6_GOTTPOFF
, 0, 4, 32, true, 0,
195 complain_overflow_signed
, bfd_elf_generic_reloc
,
196 "R_X86_64_CODE_6_GOTTPOFF", false, 0, 0xffffffff, true),
197 HOWTO(R_X86_64_CODE_6_GOTPC32_TLSDESC
, 0, 4, 32, true, 0,
198 complain_overflow_bitfield
, bfd_elf_generic_reloc
,
199 "R_X86_64_CODE_6_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
201 /* We have a gap in the reloc numbers here.
202 R_X86_64_standard counts the number up to this point, and
203 R_X86_64_vt_offset is the value to subtract from a reloc type of
204 R_X86_64_GNU_VT* to form an index into this table. */
205 #define R_X86_64_standard (R_X86_64_CODE_6_GOTPC32_TLSDESC + 1)
206 #define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
208 /* GNU extension to record C++ vtable hierarchy. */
209 HOWTO (R_X86_64_GNU_VTINHERIT
, 0, 8, 0, false, 0, complain_overflow_dont
,
210 NULL
, "R_X86_64_GNU_VTINHERIT", false, 0, 0, false),
212 /* GNU extension to record C++ vtable member usage. */
213 HOWTO (R_X86_64_GNU_VTENTRY
, 0, 8, 0, false, 0, complain_overflow_dont
,
214 _bfd_elf_rel_vtable_reloc_fn
, "R_X86_64_GNU_VTENTRY", false, 0, 0,
217 /* Use complain_overflow_bitfield on R_X86_64_32 for x32. */
218 HOWTO(R_X86_64_32
, 0, 4, 32, false, 0, complain_overflow_bitfield
,
219 bfd_elf_generic_reloc
, "R_X86_64_32", false, 0, 0xffffffff,
223 /* Map BFD relocs to the x86_64 elf relocs. */
226 bfd_reloc_code_real_type bfd_reloc_val
;
227 unsigned char elf_reloc_val
;
230 static const struct elf_reloc_map x86_64_reloc_map
[] =
232 { BFD_RELOC_NONE
, R_X86_64_NONE
, },
233 { BFD_RELOC_64
, R_X86_64_64
, },
234 { BFD_RELOC_32_PCREL
, R_X86_64_PC32
, },
235 { BFD_RELOC_X86_64_GOT32
, R_X86_64_GOT32
,},
236 { BFD_RELOC_X86_64_PLT32
, R_X86_64_PLT32
,},
237 { BFD_RELOC_X86_64_COPY
, R_X86_64_COPY
, },
238 { BFD_RELOC_X86_64_GLOB_DAT
, R_X86_64_GLOB_DAT
, },
239 { BFD_RELOC_X86_64_JUMP_SLOT
, R_X86_64_JUMP_SLOT
, },
240 { BFD_RELOC_X86_64_RELATIVE
, R_X86_64_RELATIVE
, },
241 { BFD_RELOC_X86_64_GOTPCREL
, R_X86_64_GOTPCREL
, },
242 { BFD_RELOC_32
, R_X86_64_32
, },
243 { BFD_RELOC_X86_64_32S
, R_X86_64_32S
, },
244 { BFD_RELOC_16
, R_X86_64_16
, },
245 { BFD_RELOC_16_PCREL
, R_X86_64_PC16
, },
246 { BFD_RELOC_8
, R_X86_64_8
, },
247 { BFD_RELOC_8_PCREL
, R_X86_64_PC8
, },
248 { BFD_RELOC_X86_64_DTPMOD64
, R_X86_64_DTPMOD64
, },
249 { BFD_RELOC_X86_64_DTPOFF64
, R_X86_64_DTPOFF64
, },
250 { BFD_RELOC_X86_64_TPOFF64
, R_X86_64_TPOFF64
, },
251 { BFD_RELOC_X86_64_TLSGD
, R_X86_64_TLSGD
, },
252 { BFD_RELOC_X86_64_TLSLD
, R_X86_64_TLSLD
, },
253 { BFD_RELOC_X86_64_DTPOFF32
, R_X86_64_DTPOFF32
, },
254 { BFD_RELOC_X86_64_GOTTPOFF
, R_X86_64_GOTTPOFF
, },
255 { BFD_RELOC_X86_64_TPOFF32
, R_X86_64_TPOFF32
, },
256 { BFD_RELOC_64_PCREL
, R_X86_64_PC64
, },
257 { BFD_RELOC_X86_64_GOTOFF64
, R_X86_64_GOTOFF64
, },
258 { BFD_RELOC_X86_64_GOTPC32
, R_X86_64_GOTPC32
, },
259 { BFD_RELOC_X86_64_GOT64
, R_X86_64_GOT64
, },
260 { BFD_RELOC_X86_64_GOTPCREL64
,R_X86_64_GOTPCREL64
, },
261 { BFD_RELOC_X86_64_GOTPC64
, R_X86_64_GOTPC64
, },
262 { BFD_RELOC_X86_64_GOTPLT64
, R_X86_64_GOTPLT64
, },
263 { BFD_RELOC_X86_64_PLTOFF64
, R_X86_64_PLTOFF64
, },
264 { BFD_RELOC_SIZE32
, R_X86_64_SIZE32
, },
265 { BFD_RELOC_SIZE64
, R_X86_64_SIZE64
, },
266 { BFD_RELOC_X86_64_GOTPC32_TLSDESC
, R_X86_64_GOTPC32_TLSDESC
, },
267 { BFD_RELOC_X86_64_TLSDESC_CALL
, R_X86_64_TLSDESC_CALL
, },
268 { BFD_RELOC_X86_64_TLSDESC
, R_X86_64_TLSDESC
, },
269 { BFD_RELOC_X86_64_IRELATIVE
, R_X86_64_IRELATIVE
, },
270 { BFD_RELOC_X86_64_PC32_BND
, R_X86_64_PC32_BND
, },
271 { BFD_RELOC_X86_64_PLT32_BND
, R_X86_64_PLT32_BND
, },
272 { BFD_RELOC_X86_64_GOTPCRELX
, R_X86_64_GOTPCRELX
, },
273 { BFD_RELOC_X86_64_REX_GOTPCRELX
, R_X86_64_REX_GOTPCRELX
, },
274 { BFD_RELOC_X86_64_CODE_4_GOTPCRELX
, R_X86_64_CODE_4_GOTPCRELX
, },
275 { BFD_RELOC_X86_64_CODE_4_GOTTPOFF
, R_X86_64_CODE_4_GOTTPOFF
, },
276 { BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC
, R_X86_64_CODE_4_GOTPC32_TLSDESC
, },
277 { BFD_RELOC_X86_64_CODE_5_GOTPCRELX
, R_X86_64_CODE_5_GOTPCRELX
, },
278 { BFD_RELOC_X86_64_CODE_5_GOTTPOFF
, R_X86_64_CODE_5_GOTTPOFF
, },
279 { BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC
, R_X86_64_CODE_5_GOTPC32_TLSDESC
, },
280 { BFD_RELOC_X86_64_CODE_6_GOTPCRELX
, R_X86_64_CODE_6_GOTPCRELX
, },
281 { BFD_RELOC_X86_64_CODE_6_GOTTPOFF
, R_X86_64_CODE_6_GOTTPOFF
, },
282 { BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC
, R_X86_64_CODE_6_GOTPC32_TLSDESC
, },
283 { BFD_RELOC_VTABLE_INHERIT
, R_X86_64_GNU_VTINHERIT
, },
284 { BFD_RELOC_VTABLE_ENTRY
, R_X86_64_GNU_VTENTRY
, },
287 static reloc_howto_type
*
288 elf_x86_64_rtype_to_howto (bfd
*abfd
, unsigned r_type
)
292 if (r_type
== (unsigned int) R_X86_64_32
)
297 i
= ARRAY_SIZE (x86_64_elf_howto_table
) - 1;
299 else if (r_type
< (unsigned int) R_X86_64_GNU_VTINHERIT
300 || r_type
>= (unsigned int) R_X86_64_max
)
302 if (r_type
>= (unsigned int) R_X86_64_standard
)
304 /* xgettext:c-format */
305 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
307 bfd_set_error (bfd_error_bad_value
);
313 i
= r_type
- (unsigned int) R_X86_64_vt_offset
;
314 BFD_ASSERT (x86_64_elf_howto_table
[i
].type
== r_type
);
315 return &x86_64_elf_howto_table
[i
];
318 /* Given a BFD reloc type, return a HOWTO structure. */
319 static reloc_howto_type
*
320 elf_x86_64_reloc_type_lookup (bfd
*abfd
,
321 bfd_reloc_code_real_type code
)
325 for (i
= 0; i
< sizeof (x86_64_reloc_map
) / sizeof (struct elf_reloc_map
);
328 if (x86_64_reloc_map
[i
].bfd_reloc_val
== code
)
329 return elf_x86_64_rtype_to_howto (abfd
,
330 x86_64_reloc_map
[i
].elf_reloc_val
);
335 static reloc_howto_type
*
336 elf_x86_64_reloc_name_lookup (bfd
*abfd
,
341 if (!ABI_64_P (abfd
) && strcasecmp (r_name
, "R_X86_64_32") == 0)
343 /* Get x32 R_X86_64_32. */
344 reloc_howto_type
*reloc
345 = &x86_64_elf_howto_table
[ARRAY_SIZE (x86_64_elf_howto_table
) - 1];
346 BFD_ASSERT (reloc
->type
== (unsigned int) R_X86_64_32
);
350 for (i
= 0; i
< ARRAY_SIZE (x86_64_elf_howto_table
); i
++)
351 if (x86_64_elf_howto_table
[i
].name
!= NULL
352 && strcasecmp (x86_64_elf_howto_table
[i
].name
, r_name
) == 0)
353 return &x86_64_elf_howto_table
[i
];
358 /* Given an x86_64 ELF reloc type, fill in an arelent structure. */
361 elf_x86_64_info_to_howto (bfd
*abfd
, arelent
*cache_ptr
,
362 Elf_Internal_Rela
*dst
)
366 r_type
= ELF32_R_TYPE (dst
->r_info
);
367 cache_ptr
->howto
= elf_x86_64_rtype_to_howto (abfd
, r_type
);
368 if (cache_ptr
->howto
== NULL
)
370 BFD_ASSERT (r_type
== cache_ptr
->howto
->type
|| cache_ptr
->howto
->type
== R_X86_64_NONE
);
374 /* Support for core dump NOTE sections. */
376 elf_x86_64_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
381 switch (note
->descsz
)
386 case 296: /* sizeof(istruct elf_prstatus) on Linux/x32 */
388 elf_tdata (abfd
)->core
->signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
391 elf_tdata (abfd
)->core
->lwpid
= bfd_get_32 (abfd
, note
->descdata
+ 24);
399 case 336: /* sizeof(istruct elf_prstatus) on Linux/x86_64 */
401 elf_tdata (abfd
)->core
->signal
402 = bfd_get_16 (abfd
, note
->descdata
+ 12);
405 elf_tdata (abfd
)->core
->lwpid
406 = bfd_get_32 (abfd
, note
->descdata
+ 32);
415 /* Make a ".reg/999" section. */
416 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
417 size
, note
->descpos
+ offset
);
421 elf_x86_64_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
423 switch (note
->descsz
)
429 /* sizeof (struct elf_external_linux_prpsinfo32_ugid16). */
430 elf_tdata (abfd
)->core
->pid
431 = bfd_get_32 (abfd
, note
->descdata
+ 12);
432 elf_tdata (abfd
)->core
->program
433 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 28, 16);
434 elf_tdata (abfd
)->core
->command
435 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 44, 80);
439 /* sizeof (struct elf_external_linux_prpsinfo32_ugid32). */
440 elf_tdata (abfd
)->core
->pid
441 = bfd_get_32 (abfd
, note
->descdata
+ 12);
442 elf_tdata (abfd
)->core
->program
443 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 32, 16);
444 elf_tdata (abfd
)->core
->command
445 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 48, 80);
449 /* sizeof (struct elf_prpsinfo) on Linux/x86_64. */
450 elf_tdata (abfd
)->core
->pid
451 = bfd_get_32 (abfd
, note
->descdata
+ 24);
452 elf_tdata (abfd
)->core
->program
453 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 40, 16);
454 elf_tdata (abfd
)->core
->command
455 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 56, 80);
458 /* Note that for some reason, a spurious space is tacked
459 onto the end of the args in some (at least one anyway)
460 implementations, so strip it off if it exists. */
463 char *command
= elf_tdata (abfd
)->core
->command
;
464 int n
= strlen (command
);
466 if (0 < n
&& command
[n
- 1] == ' ')
467 command
[n
- 1] = '\0';
474 # if GCC_VERSION >= 8000
475 # pragma GCC diagnostic push
476 # pragma GCC diagnostic ignored "-Wstringop-truncation"
479 elf_x86_64_write_core_note (bfd
*abfd
, char *buf
, int *bufsiz
,
482 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
484 const char *fname
, *psargs
;
495 va_start (ap
, note_type
);
496 fname
= va_arg (ap
, const char *);
497 psargs
= va_arg (ap
, const char *);
500 if (bed
->s
->elfclass
== ELFCLASS32
)
503 memset (&data
, 0, sizeof (data
));
504 strncpy (data
.pr_fname
, fname
, sizeof (data
.pr_fname
));
505 strncpy (data
.pr_psargs
, psargs
, sizeof (data
.pr_psargs
));
506 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE", note_type
,
507 &data
, sizeof (data
));
512 memset (&data
, 0, sizeof (data
));
513 strncpy (data
.pr_fname
, fname
, sizeof (data
.pr_fname
));
514 strncpy (data
.pr_psargs
, psargs
, sizeof (data
.pr_psargs
));
515 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE", note_type
,
516 &data
, sizeof (data
));
521 va_start (ap
, note_type
);
522 pid
= va_arg (ap
, long);
523 cursig
= va_arg (ap
, int);
524 gregs
= va_arg (ap
, const void *);
527 if (bed
->s
->elfclass
== ELFCLASS32
)
529 if (bed
->elf_machine_code
== EM_X86_64
)
531 prstatusx32_t prstat
;
532 memset (&prstat
, 0, sizeof (prstat
));
534 prstat
.pr_cursig
= cursig
;
535 memcpy (&prstat
.pr_reg
, gregs
, sizeof (prstat
.pr_reg
));
536 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE", note_type
,
537 &prstat
, sizeof (prstat
));
542 memset (&prstat
, 0, sizeof (prstat
));
544 prstat
.pr_cursig
= cursig
;
545 memcpy (&prstat
.pr_reg
, gregs
, sizeof (prstat
.pr_reg
));
546 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE", note_type
,
547 &prstat
, sizeof (prstat
));
553 memset (&prstat
, 0, sizeof (prstat
));
555 prstat
.pr_cursig
= cursig
;
556 memcpy (&prstat
.pr_reg
, gregs
, sizeof (prstat
.pr_reg
));
557 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE", note_type
,
558 &prstat
, sizeof (prstat
));
563 # if GCC_VERSION >= 8000
564 # pragma GCC diagnostic pop
568 /* Functions for the x86-64 ELF linker. */
570 /* The size in bytes of an entry in the global offset table. */
572 #define GOT_ENTRY_SIZE 8
574 /* The size in bytes of an entry in the lazy procedure linkage table. */
576 #define LAZY_PLT_ENTRY_SIZE 16
578 /* The size in bytes of an entry in the non-lazy procedure linkage
581 #define NON_LAZY_PLT_ENTRY_SIZE 8
583 /* The first entry in a lazy procedure linkage table looks like this.
584 See the SVR4 ABI i386 supplement and the x86-64 ABI to see how this
587 static const bfd_byte elf_x86_64_lazy_plt0_entry
[LAZY_PLT_ENTRY_SIZE
] =
589 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
590 0xff, 0x25, 16, 0, 0, 0, /* jmpq *GOT+16(%rip) */
591 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
594 /* Subsequent entries in a lazy procedure linkage table look like this. */
596 static const bfd_byte elf_x86_64_lazy_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
598 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
599 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
600 0x68, /* pushq immediate */
601 0, 0, 0, 0, /* replaced with index into relocation table. */
602 0xe9, /* jmp relative */
603 0, 0, 0, 0 /* replaced with offset to start of .plt0. */
606 /* The first entry in a lazy procedure linkage table with BND prefix
609 static const bfd_byte elf_x86_64_lazy_bnd_plt0_entry
[LAZY_PLT_ENTRY_SIZE
] =
611 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
612 0xf2, 0xff, 0x25, 16, 0, 0, 0, /* bnd jmpq *GOT+16(%rip) */
613 0x0f, 0x1f, 0 /* nopl (%rax) */
616 /* Subsequent entries for branches with BND prefx in a lazy procedure
617 linkage table look like this. */
619 static const bfd_byte elf_x86_64_lazy_bnd_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
621 0x68, 0, 0, 0, 0, /* pushq immediate */
622 0xf2, 0xe9, 0, 0, 0, 0, /* bnd jmpq relative */
623 0x0f, 0x1f, 0x44, 0, 0 /* nopl 0(%rax,%rax,1) */
626 /* The first entry in the IBT-enabled lazy procedure linkage table is the
627 the same as the lazy PLT with BND prefix so that bound registers are
628 preserved when control is passed to dynamic linker. Subsequent
629 entries for a IBT-enabled lazy procedure linkage table look like
632 static const bfd_byte elf_x86_64_lazy_bnd_ibt_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
634 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
635 0x68, 0, 0, 0, 0, /* pushq immediate */
636 0xf2, 0xe9, 0, 0, 0, 0, /* bnd jmpq relative */
640 /* The first entry in the IBT-enabled lazy procedure linkage table
641 is the same as the normal lazy PLT. Subsequent entries for an
642 IBT-enabled lazy procedure linkage table look like this. */
644 static const bfd_byte elf_x86_64_lazy_ibt_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
646 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
647 0x68, 0, 0, 0, 0, /* pushq immediate */
648 0xe9, 0, 0, 0, 0, /* jmpq relative */
649 0x66, 0x90 /* xchg %ax,%ax */
652 /* Entries in the non-lazey procedure linkage table look like this. */
654 static const bfd_byte elf_x86_64_non_lazy_plt_entry
[NON_LAZY_PLT_ENTRY_SIZE
] =
656 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
657 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
658 0x66, 0x90 /* xchg %ax,%ax */
661 /* Entries for branches with BND prefix in the non-lazey procedure
662 linkage table look like this. */
664 static const bfd_byte elf_x86_64_non_lazy_bnd_plt_entry
[NON_LAZY_PLT_ENTRY_SIZE
] =
666 0xf2, 0xff, 0x25, /* bnd jmpq *name@GOTPC(%rip) */
667 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
671 /* Entries for IBT-enabled branches with BND prefix in the non-lazey
672 procedure linkage table look like this. They have the same size as
673 the lazy PLT entry. */
675 static const bfd_byte elf_x86_64_non_lazy_bnd_ibt_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
677 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
678 0xf2, 0xff, 0x25, /* bnd jmpq *name@GOTPC(%rip) */
679 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
680 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopl 0x0(%rax,%rax,1) */
683 /* Entries for branches with IBT-enabled in the non-lazey procedure
684 linkage table look like this. They have the same size as the lazy
687 static const bfd_byte elf_x86_64_non_lazy_ibt_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
689 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
690 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
691 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
692 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
695 /* The TLSDESC entry in a lazy procedure linkage table. */
696 static const bfd_byte elf_x86_64_tlsdesc_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
698 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
699 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
700 0xff, 0x25, 16, 0, 0, 0 /* jmpq *GOT+TDG(%rip) */
703 /* .eh_frame covering the lazy .plt section. */
705 static const bfd_byte elf_x86_64_eh_frame_lazy_plt
[] =
707 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
708 0, 0, 0, 0, /* CIE ID */
710 'z', 'R', 0, /* Augmentation string */
711 1, /* Code alignment factor */
712 0x78, /* Data alignment factor */
713 16, /* Return address column */
714 1, /* Augmentation size */
715 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
716 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
717 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
718 DW_CFA_nop
, DW_CFA_nop
,
720 PLT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
721 PLT_CIE_LENGTH
+ 8, 0, 0, 0, /* CIE pointer */
722 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
723 0, 0, 0, 0, /* .plt size goes here */
724 0, /* Augmentation size */
725 DW_CFA_def_cfa_offset
, 16, /* DW_CFA_def_cfa_offset: 16 */
726 DW_CFA_advance_loc
+ 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
727 DW_CFA_def_cfa_offset
, 24, /* DW_CFA_def_cfa_offset: 24 */
728 DW_CFA_advance_loc
+ 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
729 DW_CFA_def_cfa_expression
, /* DW_CFA_def_cfa_expression */
730 11, /* Block length */
731 DW_OP_breg7
, 8, /* DW_OP_breg7 (rsp): 8 */
732 DW_OP_breg16
, 0, /* DW_OP_breg16 (rip): 0 */
733 DW_OP_lit15
, DW_OP_and
, DW_OP_lit11
, DW_OP_ge
,
734 DW_OP_lit3
, DW_OP_shl
, DW_OP_plus
,
735 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
738 /* .eh_frame covering the lazy BND .plt section. */
740 static const bfd_byte elf_x86_64_eh_frame_lazy_bnd_plt
[] =
742 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
743 0, 0, 0, 0, /* CIE ID */
745 'z', 'R', 0, /* Augmentation string */
746 1, /* Code alignment factor */
747 0x78, /* Data alignment factor */
748 16, /* Return address column */
749 1, /* Augmentation size */
750 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
751 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
752 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
753 DW_CFA_nop
, DW_CFA_nop
,
755 PLT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
756 PLT_CIE_LENGTH
+ 8, 0, 0, 0, /* CIE pointer */
757 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
758 0, 0, 0, 0, /* .plt size goes here */
759 0, /* Augmentation size */
760 DW_CFA_def_cfa_offset
, 16, /* DW_CFA_def_cfa_offset: 16 */
761 DW_CFA_advance_loc
+ 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
762 DW_CFA_def_cfa_offset
, 24, /* DW_CFA_def_cfa_offset: 24 */
763 DW_CFA_advance_loc
+ 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
764 DW_CFA_def_cfa_expression
, /* DW_CFA_def_cfa_expression */
765 11, /* Block length */
766 DW_OP_breg7
, 8, /* DW_OP_breg7 (rsp): 8 */
767 DW_OP_breg16
, 0, /* DW_OP_breg16 (rip): 0 */
768 DW_OP_lit15
, DW_OP_and
, DW_OP_lit5
, DW_OP_ge
,
769 DW_OP_lit3
, DW_OP_shl
, DW_OP_plus
,
770 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
773 /* .eh_frame covering the lazy .plt section with IBT-enabled and BND
776 static const bfd_byte elf_x86_64_eh_frame_lazy_bnd_ibt_plt
[] =
778 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
779 0, 0, 0, 0, /* CIE ID */
781 'z', 'R', 0, /* Augmentation string */
782 1, /* Code alignment factor */
783 0x78, /* Data alignment factor */
784 16, /* Return address column */
785 1, /* Augmentation size */
786 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
787 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
788 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
789 DW_CFA_nop
, DW_CFA_nop
,
791 PLT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
792 PLT_CIE_LENGTH
+ 8, 0, 0, 0, /* CIE pointer */
793 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
794 0, 0, 0, 0, /* .plt size goes here */
795 0, /* Augmentation size */
796 DW_CFA_def_cfa_offset
, 16, /* DW_CFA_def_cfa_offset: 16 */
797 DW_CFA_advance_loc
+ 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
798 DW_CFA_def_cfa_offset
, 24, /* DW_CFA_def_cfa_offset: 24 */
799 DW_CFA_advance_loc
+ 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
800 DW_CFA_def_cfa_expression
, /* DW_CFA_def_cfa_expression */
801 11, /* Block length */
802 DW_OP_breg7
, 8, /* DW_OP_breg7 (rsp): 8 */
803 DW_OP_breg16
, 0, /* DW_OP_breg16 (rip): 0 */
804 DW_OP_lit15
, DW_OP_and
, DW_OP_lit10
, DW_OP_ge
,
805 DW_OP_lit3
, DW_OP_shl
, DW_OP_plus
,
806 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
809 /* .eh_frame covering the lazy .plt section with IBT-enabled. */
811 static const bfd_byte elf_x86_64_eh_frame_lazy_ibt_plt
[] =
813 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
814 0, 0, 0, 0, /* CIE ID */
816 'z', 'R', 0, /* Augmentation string */
817 1, /* Code alignment factor */
818 0x78, /* Data alignment factor */
819 16, /* Return address column */
820 1, /* Augmentation size */
821 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
822 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
823 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
824 DW_CFA_nop
, DW_CFA_nop
,
826 PLT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
827 PLT_CIE_LENGTH
+ 8, 0, 0, 0, /* CIE pointer */
828 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
829 0, 0, 0, 0, /* .plt size goes here */
830 0, /* Augmentation size */
831 DW_CFA_def_cfa_offset
, 16, /* DW_CFA_def_cfa_offset: 16 */
832 DW_CFA_advance_loc
+ 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
833 DW_CFA_def_cfa_offset
, 24, /* DW_CFA_def_cfa_offset: 24 */
834 DW_CFA_advance_loc
+ 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
835 DW_CFA_def_cfa_expression
, /* DW_CFA_def_cfa_expression */
836 11, /* Block length */
837 DW_OP_breg7
, 8, /* DW_OP_breg7 (rsp): 8 */
838 DW_OP_breg16
, 0, /* DW_OP_breg16 (rip): 0 */
839 DW_OP_lit15
, DW_OP_and
, DW_OP_lit9
, DW_OP_ge
,
840 DW_OP_lit3
, DW_OP_shl
, DW_OP_plus
,
841 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
844 /* .eh_frame covering the non-lazy .plt section. */
846 static const bfd_byte elf_x86_64_eh_frame_non_lazy_plt
[] =
848 #define PLT_GOT_FDE_LENGTH 20
849 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
850 0, 0, 0, 0, /* CIE ID */
852 'z', 'R', 0, /* Augmentation string */
853 1, /* Code alignment factor */
854 0x78, /* Data alignment factor */
855 16, /* Return address column */
856 1, /* Augmentation size */
857 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
858 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
859 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
860 DW_CFA_nop
, DW_CFA_nop
,
862 PLT_GOT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
863 PLT_CIE_LENGTH
+ 8, 0, 0, 0, /* CIE pointer */
864 0, 0, 0, 0, /* the start of non-lazy .plt goes here */
865 0, 0, 0, 0, /* non-lazy .plt size goes here */
866 0, /* Augmentation size */
867 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
,
868 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
871 static const sframe_frame_row_entry elf_x86_64_sframe_null_fre
=
874 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
875 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP
, 1, SFRAME_FRE_OFFSET_1B
) /* FRE info. */
878 /* .sframe FRE covering the .plt section entry. */
879 static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre1
=
881 0, /* SFrame FRE start address. */
882 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
883 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP
, 1, SFRAME_FRE_OFFSET_1B
) /* FRE info. */
886 /* .sframe FRE covering the .plt section entry. */
887 static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre2
=
889 6, /* SFrame FRE start address. */
890 {24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
891 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP
, 1, SFRAME_FRE_OFFSET_1B
) /* FRE info. */
894 /* .sframe FRE covering the .plt section entry. */
895 static const sframe_frame_row_entry elf_x86_64_sframe_pltn_fre1
=
897 0, /* SFrame FRE start address. */
898 {8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
899 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP
, 1, SFRAME_FRE_OFFSET_1B
) /* FRE info. */
902 /* .sframe FRE covering the .plt section entry. */
903 static const sframe_frame_row_entry elf_x86_64_sframe_pltn_fre2
=
905 11, /* SFrame FRE start address. */
906 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
907 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP
, 1, SFRAME_FRE_OFFSET_1B
) /* FRE info. */
910 /* .sframe FRE covering the .plt section entry for IBT. */
911 static const sframe_frame_row_entry elf_x86_64_sframe_ibt_pltn_fre2
=
913 9, /* SFrame FRE start address. */
914 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
915 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP
, 1, SFRAME_FRE_OFFSET_1B
) /* FRE info. */
918 /* .sframe FRE covering the second .plt section entry. */
919 static const sframe_frame_row_entry elf_x86_64_sframe_sec_pltn_fre1
=
921 0, /* SFrame FRE start address. */
922 {8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
923 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP
, 1, SFRAME_FRE_OFFSET_1B
) /* FRE info. */
926 /* SFrame helper object for non-lazy PLT. */
927 static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_plt
=
930 2, /* Number of FREs for PLT0. */
931 /* Array of SFrame FREs for plt0. */
932 { &elf_x86_64_sframe_plt0_fre1
, &elf_x86_64_sframe_plt0_fre2
},
934 1, /* Number of FREs for PLTn. */
935 /* Array of SFrame FREs for plt. */
936 { &elf_x86_64_sframe_sec_pltn_fre1
, &elf_x86_64_sframe_null_fre
},
938 0, /* There is no second PLT necessary. */
939 { &elf_x86_64_sframe_null_fre
},
940 NON_LAZY_PLT_ENTRY_SIZE
,
941 1, /* Number of FREs for PLT GOT. */
942 /* Array of SFrame FREs for PLT GOT. */
943 { &elf_x86_64_sframe_null_fre
},
946 /* SFrame helper object for non-lazy IBT enabled PLT. */
947 static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_ibt_plt
=
950 2, /* Number of FREs for PLT0. */
951 /* Array of SFrame FREs for plt0. */
952 { &elf_x86_64_sframe_plt0_fre1
, &elf_x86_64_sframe_plt0_fre2
},
954 1, /* Number of FREs for PLTn. */
955 /* Array of SFrame FREs for plt. */
956 { &elf_x86_64_sframe_sec_pltn_fre1
, &elf_x86_64_sframe_null_fre
},
958 0, /* There is no second PLT necessary. */
959 { &elf_x86_64_sframe_null_fre
},
961 1, /* Number of FREs for PLT GOT. */
962 /* Array of SFrame FREs for PLT GOT. */
963 { &elf_x86_64_sframe_null_fre
},
966 /* SFrame helper object for lazy PLT. */
967 static const struct elf_x86_sframe_plt elf_x86_64_sframe_plt
=
970 2, /* Number of FREs for PLT0. */
971 /* Array of SFrame FREs for plt0. */
972 { &elf_x86_64_sframe_plt0_fre1
, &elf_x86_64_sframe_plt0_fre2
},
974 2, /* Number of FREs for PLTn. */
975 /* Array of SFrame FREs for plt. */
976 { &elf_x86_64_sframe_pltn_fre1
, &elf_x86_64_sframe_pltn_fre2
},
977 NON_LAZY_PLT_ENTRY_SIZE
,
978 1, /* Number of FREs for second PLT. */
979 /* Array of SFrame FREs for second PLT. */
980 { &elf_x86_64_sframe_sec_pltn_fre1
},
981 NON_LAZY_PLT_ENTRY_SIZE
,
982 1, /* Number of FREs for PLT GOT. */
983 /* Array of SFrame FREs for PLT GOT. */
984 { &elf_x86_64_sframe_null_fre
},
987 /* SFrame helper object for lazy PLT with IBT. */
988 static const struct elf_x86_sframe_plt elf_x86_64_sframe_ibt_plt
=
991 2, /* Number of FREs for PLT0. */
992 /* Array of SFrame FREs for plt0. */
993 { &elf_x86_64_sframe_plt0_fre1
, &elf_x86_64_sframe_plt0_fre2
},
995 2, /* Number of FREs for PLTn. */
996 /* Array of SFrame FREs for plt. */
997 { &elf_x86_64_sframe_pltn_fre1
, &elf_x86_64_sframe_ibt_pltn_fre2
},
999 1, /* Number of FREs for second PLT. */
1000 /* Array of SFrame FREs for second plt. */
1001 { &elf_x86_64_sframe_sec_pltn_fre1
},
1002 LAZY_PLT_ENTRY_SIZE
,
1003 1, /* Number of FREs for PLT GOT. */
1004 /* Array of SFrame FREs for PLT GOT. */
1005 { &elf_x86_64_sframe_null_fre
},
1008 /* These are the standard parameters. */
1009 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_plt
=
1011 elf_x86_64_lazy_plt0_entry
, /* plt0_entry */
1012 LAZY_PLT_ENTRY_SIZE
, /* plt0_entry_size */
1013 elf_x86_64_lazy_plt_entry
, /* plt_entry */
1014 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
1015 elf_x86_64_tlsdesc_plt_entry
, /* plt_tlsdesc_entry */
1016 LAZY_PLT_ENTRY_SIZE
, /* plt_tlsdesc_entry_size */
1017 6, /* plt_tlsdesc_got1_offset */
1018 12, /* plt_tlsdesc_got2_offset */
1019 10, /* plt_tlsdesc_got1_insn_end */
1020 16, /* plt_tlsdesc_got2_insn_end */
1021 2, /* plt0_got1_offset */
1022 8, /* plt0_got2_offset */
1023 12, /* plt0_got2_insn_end */
1024 2, /* plt_got_offset */
1025 7, /* plt_reloc_offset */
1026 12, /* plt_plt_offset */
1027 6, /* plt_got_insn_size */
1028 LAZY_PLT_ENTRY_SIZE
, /* plt_plt_insn_end */
1029 6, /* plt_lazy_offset */
1030 elf_x86_64_lazy_plt0_entry
, /* pic_plt0_entry */
1031 elf_x86_64_lazy_plt_entry
, /* pic_plt_entry */
1032 elf_x86_64_eh_frame_lazy_plt
, /* eh_frame_plt */
1033 sizeof (elf_x86_64_eh_frame_lazy_plt
) /* eh_frame_plt_size */
1036 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_plt
=
1038 elf_x86_64_non_lazy_plt_entry
, /* plt_entry */
1039 elf_x86_64_non_lazy_plt_entry
, /* pic_plt_entry */
1040 NON_LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
1041 2, /* plt_got_offset */
1042 6, /* plt_got_insn_size */
1043 elf_x86_64_eh_frame_non_lazy_plt
, /* eh_frame_plt */
1044 sizeof (elf_x86_64_eh_frame_non_lazy_plt
) /* eh_frame_plt_size */
1047 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_plt
=
1049 elf_x86_64_lazy_bnd_plt0_entry
, /* plt0_entry */
1050 LAZY_PLT_ENTRY_SIZE
, /* plt0_entry_size */
1051 elf_x86_64_lazy_bnd_plt_entry
, /* plt_entry */
1052 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
1053 elf_x86_64_tlsdesc_plt_entry
, /* plt_tlsdesc_entry */
1054 LAZY_PLT_ENTRY_SIZE
, /* plt_tlsdesc_entry_size */
1055 6, /* plt_tlsdesc_got1_offset */
1056 12, /* plt_tlsdesc_got2_offset */
1057 10, /* plt_tlsdesc_got1_insn_end */
1058 16, /* plt_tlsdesc_got2_insn_end */
1059 2, /* plt0_got1_offset */
1060 1+8, /* plt0_got2_offset */
1061 1+12, /* plt0_got2_insn_end */
1062 1+2, /* plt_got_offset */
1063 1, /* plt_reloc_offset */
1064 7, /* plt_plt_offset */
1065 1+6, /* plt_got_insn_size */
1066 11, /* plt_plt_insn_end */
1067 0, /* plt_lazy_offset */
1068 elf_x86_64_lazy_bnd_plt0_entry
, /* pic_plt0_entry */
1069 elf_x86_64_lazy_bnd_plt_entry
, /* pic_plt_entry */
1070 elf_x86_64_eh_frame_lazy_bnd_plt
, /* eh_frame_plt */
1071 sizeof (elf_x86_64_eh_frame_lazy_bnd_plt
) /* eh_frame_plt_size */
1074 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt
=
1076 elf_x86_64_non_lazy_bnd_plt_entry
, /* plt_entry */
1077 elf_x86_64_non_lazy_bnd_plt_entry
, /* pic_plt_entry */
1078 NON_LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
1079 1+2, /* plt_got_offset */
1080 1+6, /* plt_got_insn_size */
1081 elf_x86_64_eh_frame_non_lazy_plt
, /* eh_frame_plt */
1082 sizeof (elf_x86_64_eh_frame_non_lazy_plt
) /* eh_frame_plt_size */
1085 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_ibt_plt
=
1087 elf_x86_64_lazy_bnd_plt0_entry
, /* plt0_entry */
1088 LAZY_PLT_ENTRY_SIZE
, /* plt0_entry_size */
1089 elf_x86_64_lazy_bnd_ibt_plt_entry
, /* plt_entry */
1090 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
1091 elf_x86_64_tlsdesc_plt_entry
, /* plt_tlsdesc_entry */
1092 LAZY_PLT_ENTRY_SIZE
, /* plt_tlsdesc_entry_size */
1093 6, /* plt_tlsdesc_got1_offset */
1094 12, /* plt_tlsdesc_got2_offset */
1095 10, /* plt_tlsdesc_got1_insn_end */
1096 16, /* plt_tlsdesc_got2_insn_end */
1097 2, /* plt0_got1_offset */
1098 1+8, /* plt0_got2_offset */
1099 1+12, /* plt0_got2_insn_end */
1100 4+1+2, /* plt_got_offset */
1101 4+1, /* plt_reloc_offset */
1102 4+1+6, /* plt_plt_offset */
1103 4+1+6, /* plt_got_insn_size */
1104 4+1+5+5, /* plt_plt_insn_end */
1105 0, /* plt_lazy_offset */
1106 elf_x86_64_lazy_bnd_plt0_entry
, /* pic_plt0_entry */
1107 elf_x86_64_lazy_bnd_ibt_plt_entry
, /* pic_plt_entry */
1108 elf_x86_64_eh_frame_lazy_bnd_ibt_plt
, /* eh_frame_plt */
1109 sizeof (elf_x86_64_eh_frame_lazy_bnd_ibt_plt
) /* eh_frame_plt_size */
1112 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_ibt_plt
=
1114 elf_x86_64_lazy_plt0_entry
, /* plt0_entry */
1115 LAZY_PLT_ENTRY_SIZE
, /* plt0_entry_size */
1116 elf_x86_64_lazy_ibt_plt_entry
, /* plt_entry */
1117 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
1118 elf_x86_64_tlsdesc_plt_entry
, /* plt_tlsdesc_entry */
1119 LAZY_PLT_ENTRY_SIZE
, /* plt_tlsdesc_entry_size */
1120 6, /* plt_tlsdesc_got1_offset */
1121 12, /* plt_tlsdesc_got2_offset */
1122 10, /* plt_tlsdesc_got1_insn_end */
1123 16, /* plt_tlsdesc_got2_insn_end */
1124 2, /* plt0_got1_offset */
1125 8, /* plt0_got2_offset */
1126 12, /* plt0_got2_insn_end */
1127 4+2, /* plt_got_offset */
1128 4+1, /* plt_reloc_offset */
1129 4+6, /* plt_plt_offset */
1130 4+6, /* plt_got_insn_size */
1131 4+5+5, /* plt_plt_insn_end */
1132 0, /* plt_lazy_offset */
1133 elf_x86_64_lazy_plt0_entry
, /* pic_plt0_entry */
1134 elf_x86_64_lazy_ibt_plt_entry
, /* pic_plt_entry */
1135 elf_x86_64_eh_frame_lazy_ibt_plt
, /* eh_frame_plt */
1136 sizeof (elf_x86_64_eh_frame_lazy_ibt_plt
) /* eh_frame_plt_size */
1139 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_ibt_plt
=
1141 elf_x86_64_non_lazy_bnd_ibt_plt_entry
, /* plt_entry */
1142 elf_x86_64_non_lazy_bnd_ibt_plt_entry
, /* pic_plt_entry */
1143 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
1144 4+1+2, /* plt_got_offset */
1145 4+1+6, /* plt_got_insn_size */
1146 elf_x86_64_eh_frame_non_lazy_plt
, /* eh_frame_plt */
1147 sizeof (elf_x86_64_eh_frame_non_lazy_plt
) /* eh_frame_plt_size */
1150 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt
=
1152 elf_x86_64_non_lazy_ibt_plt_entry
, /* plt_entry */
1153 elf_x86_64_non_lazy_ibt_plt_entry
, /* pic_plt_entry */
1154 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
1155 4+2, /* plt_got_offset */
1156 4+6, /* plt_got_insn_size */
1157 elf_x86_64_eh_frame_non_lazy_plt
, /* eh_frame_plt */
1158 sizeof (elf_x86_64_eh_frame_non_lazy_plt
) /* eh_frame_plt_size */
1162 elf64_x86_64_elf_object_p (bfd
*abfd
)
1164 /* Set the right machine number for an x86-64 elf64 file. */
1165 bfd_default_set_arch_mach (abfd
, bfd_arch_i386
, bfd_mach_x86_64
);
1170 elf32_x86_64_elf_object_p (bfd
*abfd
)
1172 /* Set the right machine number for an x86-64 elf32 file. */
1173 bfd_default_set_arch_mach (abfd
, bfd_arch_i386
, bfd_mach_x64_32
);
1177 /* Return TRUE if the TLS access code sequence support transition
1180 static enum elf_x86_tls_error_type
1181 elf_x86_64_check_tls_transition (bfd
*abfd
,
1182 struct bfd_link_info
*info
,
1185 Elf_Internal_Shdr
*symtab_hdr
,
1186 struct elf_link_hash_entry
**sym_hashes
,
1187 unsigned int r_type
,
1188 const Elf_Internal_Rela
*rel
,
1189 const Elf_Internal_Rela
*relend
)
1192 unsigned long r_symndx
;
1193 bool largepic
= false;
1194 struct elf_link_hash_entry
*h
;
1196 struct elf_x86_link_hash_table
*htab
;
1200 htab
= elf_x86_hash_table (info
, X86_64_ELF_DATA
);
1201 offset
= rel
->r_offset
;
1204 case R_X86_64_TLSGD
:
1205 case R_X86_64_TLSLD
:
1206 if ((rel
+ 1) >= relend
)
1207 return elf_x86_tls_error_yes
;
1209 if (r_type
== R_X86_64_TLSGD
)
1211 /* Check transition from GD access model. For 64bit, only
1212 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
1213 .word 0x6666; rex64; call __tls_get_addr@PLT
1215 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
1217 call *__tls_get_addr@GOTPCREL(%rip)
1218 which may be converted to
1219 addr32 call __tls_get_addr
1220 can transit to different access model. For 32bit, only
1221 leaq foo@tlsgd(%rip), %rdi
1222 .word 0x6666; rex64; call __tls_get_addr@PLT
1224 leaq foo@tlsgd(%rip), %rdi
1226 call *__tls_get_addr@GOTPCREL(%rip)
1227 which may be converted to
1228 addr32 call __tls_get_addr
1229 can transit to different access model. For largepic,
1231 leaq foo@tlsgd(%rip), %rdi
1232 movabsq $__tls_get_addr@pltoff, %rax
1236 leaq foo@tlsgd(%rip), %rdi
1237 movabsq $__tls_get_addr@pltoff, %rax
1241 static const unsigned char leaq
[] = { 0x66, 0x48, 0x8d, 0x3d };
1243 if ((offset
+ 12) > sec
->size
)
1244 return elf_x86_tls_error_yes
;
1246 call
= contents
+ offset
+ 4;
1248 || !((call
[1] == 0x48
1256 && call
[3] == 0xe8)))
1258 if (!ABI_64_P (abfd
)
1259 || (offset
+ 19) > sec
->size
1261 || memcmp (call
- 7, leaq
+ 1, 3) != 0
1262 || memcmp (call
, "\x48\xb8", 2) != 0
1266 || !((call
[10] == 0x48 && call
[12] == 0xd8)
1267 || (call
[10] == 0x4c && call
[12] == 0xf8)))
1268 return elf_x86_tls_error_yes
;
1271 else if (ABI_64_P (abfd
))
1274 || memcmp (contents
+ offset
- 4, leaq
, 4) != 0)
1275 return elf_x86_tls_error_yes
;
1280 || memcmp (contents
+ offset
- 3, leaq
+ 1, 3) != 0)
1281 return elf_x86_tls_error_yes
;
1283 indirect_call
= call
[2] == 0xff;
1287 /* Check transition from LD access model. Only
1288 leaq foo@tlsld(%rip), %rdi;
1289 call __tls_get_addr@PLT
1291 leaq foo@tlsld(%rip), %rdi;
1292 call *__tls_get_addr@GOTPCREL(%rip)
1293 which may be converted to
1294 addr32 call __tls_get_addr
1295 can transit to different access model. For largepic
1297 leaq foo@tlsld(%rip), %rdi
1298 movabsq $__tls_get_addr@pltoff, %rax
1302 leaq foo@tlsld(%rip), %rdi
1303 movabsq $__tls_get_addr@pltoff, %rax
1307 static const unsigned char lea
[] = { 0x48, 0x8d, 0x3d };
1309 if (offset
< 3 || (offset
+ 9) > sec
->size
)
1310 return elf_x86_tls_error_yes
;
1312 if (memcmp (contents
+ offset
- 3, lea
, 3) != 0)
1313 return elf_x86_tls_error_yes
;
1315 call
= contents
+ offset
+ 4;
1316 if (!(call
[0] == 0xe8
1317 || (call
[0] == 0xff && call
[1] == 0x15)
1318 || (call
[0] == 0x67 && call
[1] == 0xe8)))
1320 if (!ABI_64_P (abfd
)
1321 || (offset
+ 19) > sec
->size
1322 || memcmp (call
, "\x48\xb8", 2) != 0
1326 || !((call
[10] == 0x48 && call
[12] == 0xd8)
1327 || (call
[10] == 0x4c && call
[12] == 0xf8)))
1328 return elf_x86_tls_error_yes
;
1331 indirect_call
= call
[0] == 0xff;
1334 r_symndx
= htab
->r_sym (rel
[1].r_info
);
1335 if (r_symndx
< symtab_hdr
->sh_info
)
1336 return elf_x86_tls_error_yes
;
1338 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1340 || !((struct elf_x86_link_hash_entry
*) h
)->tls_get_addr
)
1341 return elf_x86_tls_error_yes
;
1344 r_type
= (ELF32_R_TYPE (rel
[1].r_info
)
1345 & ~R_X86_64_converted_reloc_bit
);
1347 return (r_type
== R_X86_64_PLTOFF64
1348 ? elf_x86_tls_error_none
1349 : elf_x86_tls_error_yes
);
1350 else if (indirect_call
)
1351 return ((r_type
== R_X86_64_GOTPCRELX
1352 || r_type
== R_X86_64_GOTPCREL
)
1353 ? elf_x86_tls_error_none
1354 : elf_x86_tls_error_yes
);
1356 return ((r_type
== R_X86_64_PC32
1357 || r_type
== R_X86_64_PLT32
)
1358 ? elf_x86_tls_error_none
1359 : elf_x86_tls_error_yes
);
1362 case R_X86_64_CODE_4_GOTTPOFF
:
1363 /* Check transition from IE access model:
1364 mov foo@gottpoff(%rip), %reg
1365 add foo@gottpoff(%rip), %reg
1366 where reg is one of r16 to r31. */
1369 || (offset
+ 4) > sec
->size
1370 || contents
[offset
- 4] != 0xd5)
1371 return elf_x86_tls_error_yes
;
1373 goto check_gottpoff
;
1375 case R_X86_64_CODE_6_GOTTPOFF
:
1376 /* Check transition from IE access model:
1377 add %reg1, foo@gottpoff(%rip), %reg2
1378 where reg1/reg2 are one of r16 to r31. */
1381 || (offset
+ 4) > sec
->size
1382 || contents
[offset
- 6] != 0x62)
1383 return elf_x86_tls_error_yes
;
1385 val
= bfd_get_8 (abfd
, contents
+ offset
- 2);
1386 if (val
!= 0x01 && val
!= 0x03)
1387 return elf_x86_tls_error_add
;
1389 val
= bfd_get_8 (abfd
, contents
+ offset
- 1);
1390 return ((val
& 0xc7) == 5
1391 ? elf_x86_tls_error_none
1392 : elf_x86_tls_error_yes
);
1394 case R_X86_64_GOTTPOFF
:
1395 /* Check transition from IE access model:
1396 mov foo@gottpoff(%rip), %reg
1397 add foo@gottpoff(%rip), %reg
1400 /* Check REX prefix first. */
1401 if (offset
>= 3 && (offset
+ 4) <= sec
->size
)
1403 val
= bfd_get_8 (abfd
, contents
+ offset
- 3);
1404 if (val
!= 0x48 && val
!= 0x4c)
1406 /* X32 may have 0x44 REX prefix or no REX prefix. */
1407 if (ABI_64_P (abfd
))
1408 return elf_x86_tls_error_yes
;
1413 /* X32 may not have any REX prefix. */
1414 if (ABI_64_P (abfd
))
1415 return elf_x86_tls_error_yes
;
1416 if (offset
< 2 || (offset
+ 3) > sec
->size
)
1417 return elf_x86_tls_error_yes
;
1421 val
= bfd_get_8 (abfd
, contents
+ offset
- 2);
1422 if (val
!= 0x8b && val
!= 0x03)
1423 return elf_x86_tls_error_add_mov
;
1425 val
= bfd_get_8 (abfd
, contents
+ offset
- 1);
1426 return ((val
& 0xc7) == 5
1427 ? elf_x86_tls_error_none
1428 : elf_x86_tls_error_yes
);
1430 case R_X86_64_CODE_4_GOTPC32_TLSDESC
:
1431 /* Check transition from GDesc access model:
1432 lea x@tlsdesc(%rip), %reg
1433 where reg is one of r16 to r31. */
1436 || (offset
+ 4) > sec
->size
1437 || contents
[offset
- 4] != 0xd5)
1438 return elf_x86_tls_error_yes
;
1442 case R_X86_64_GOTPC32_TLSDESC
:
1443 /* Check transition from GDesc access model:
1444 leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
1445 rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
1447 Make sure it's a leaq adding rip to a 32-bit offset
1448 into any register, although it's probably almost always
1451 if (offset
< 3 || (offset
+ 4) > sec
->size
)
1452 return elf_x86_tls_error_yes
;
1454 val
= bfd_get_8 (abfd
, contents
+ offset
- 3);
1456 if (val
!= 0x48 && (ABI_64_P (abfd
) || val
!= 0x40))
1457 return elf_x86_tls_error_yes
;
1460 if (bfd_get_8 (abfd
, contents
+ offset
- 2) != 0x8d)
1461 return elf_x86_tls_error_lea
;
1463 val
= bfd_get_8 (abfd
, contents
+ offset
- 1);
1464 return ((val
& 0xc7) == 0x05
1465 ? elf_x86_tls_error_none
1466 : elf_x86_tls_error_yes
);
1468 case R_X86_64_TLSDESC_CALL
:
1469 /* It has been checked in elf_x86_64_tls_transition. */
1470 return elf_x86_tls_error_none
;
1477 /* Return TRUE if the TLS access transition is OK or no transition
1478 will be performed. Update R_TYPE if there is a transition. */
1481 elf_x86_64_tls_transition (struct bfd_link_info
*info
, bfd
*abfd
,
1482 asection
*sec
, bfd_byte
*contents
,
1483 Elf_Internal_Shdr
*symtab_hdr
,
1484 struct elf_link_hash_entry
**sym_hashes
,
1485 unsigned int *r_type
, int tls_type
,
1486 const Elf_Internal_Rela
*rel
,
1487 const Elf_Internal_Rela
*relend
,
1488 struct elf_link_hash_entry
*h
,
1489 Elf_Internal_Sym
*sym
,
1490 bool from_relocate_section
)
1492 unsigned int from_type
= *r_type
;
1493 unsigned int to_type
= from_type
;
1498 /* Skip TLS transition for functions. */
1500 && (h
->type
== STT_FUNC
1501 || h
->type
== STT_GNU_IFUNC
))
1506 case R_X86_64_TLSDESC_CALL
:
1507 /* Check valid GDesc call:
1508 call *x@tlscall(%rax) <--- LP64 mode.
1509 call *x@tlscall(%eax) <--- X32 mode.
1511 offset
= rel
->r_offset
;
1513 if (offset
+ 2 <= sec
->size
)
1515 unsigned int prefix
;
1516 call
= contents
+ offset
;
1518 if (!ABI_64_P (abfd
))
1520 /* Check for call *x@tlscall(%eax). */
1521 if (call
[0] == 0x67)
1524 if (offset
+ 3 > sec
->size
)
1529 /* Make sure that it's a call *x@tlscall(%rax). */
1531 && (call
[prefix
] != 0xff || call
[1 + prefix
] != 0x10))
1537 _bfd_x86_elf_link_report_tls_transition_error
1538 (info
, abfd
, sec
, symtab_hdr
, h
, sym
, rel
,
1539 "R_X86_64_TLSDESC_CALL", NULL
,
1540 elf_x86_tls_error_indirect_call
);
1546 case R_X86_64_TLSGD
:
1547 case R_X86_64_GOTPC32_TLSDESC
:
1548 case R_X86_64_CODE_4_GOTPC32_TLSDESC
:
1549 case R_X86_64_GOTTPOFF
:
1550 case R_X86_64_CODE_4_GOTTPOFF
:
1551 case R_X86_64_CODE_6_GOTTPOFF
:
1552 if (bfd_link_executable (info
))
1555 to_type
= R_X86_64_TPOFF32
;
1557 to_type
= R_X86_64_GOTTPOFF
;
1560 /* When we are called from elf_x86_64_relocate_section, there may
1561 be additional transitions based on TLS_TYPE. */
1562 if (from_relocate_section
)
1564 unsigned int new_to_type
= to_type
;
1566 if (TLS_TRANSITION_IE_TO_LE_P (info
, h
, tls_type
))
1567 new_to_type
= R_X86_64_TPOFF32
;
1569 if (to_type
== R_X86_64_TLSGD
1570 || to_type
== R_X86_64_GOTPC32_TLSDESC
1571 || to_type
== R_X86_64_CODE_4_GOTPC32_TLSDESC
1572 || to_type
== R_X86_64_TLSDESC_CALL
)
1574 if (tls_type
== GOT_TLS_IE
)
1575 new_to_type
= R_X86_64_GOTTPOFF
;
1578 /* We checked the transition before when we were called from
1579 elf_x86_64_scan_relocs. We only want to check the new
1580 transition which hasn't been checked before. */
1581 check
= (new_to_type
!= to_type
1582 && (from_type
== to_type
1583 || (from_type
== R_X86_64_CODE_4_GOTTPOFF
1584 && to_type
== R_X86_64_GOTTPOFF
)
1585 || (from_type
== R_X86_64_CODE_6_GOTTPOFF
1586 && to_type
== R_X86_64_GOTTPOFF
)));
1587 to_type
= new_to_type
;
1592 case R_X86_64_TLSLD
:
1593 if (bfd_link_executable (info
))
1594 to_type
= R_X86_64_TPOFF32
;
1601 /* Return TRUE if there is no transition. */
1602 if (from_type
== to_type
1603 || (from_type
== R_X86_64_CODE_4_GOTTPOFF
1604 && to_type
== R_X86_64_GOTTPOFF
)
1605 || (from_type
== R_X86_64_CODE_6_GOTTPOFF
1606 && to_type
== R_X86_64_GOTTPOFF
))
1609 /* Check if the transition can be performed. */
1610 enum elf_x86_tls_error_type tls_error
;
1612 && ((tls_error
= elf_x86_64_check_tls_transition (abfd
, info
, sec
,
1618 != elf_x86_tls_error_none
))
1621 reloc_howto_type
*from
, *to
;
1623 from
= elf_x86_64_rtype_to_howto (abfd
, from_type
);
1624 to
= elf_x86_64_rtype_to_howto (abfd
, to_type
);
1626 if (from
== NULL
|| to
== NULL
)
1629 _bfd_x86_elf_link_report_tls_transition_error
1630 (info
, abfd
, sec
, symtab_hdr
, h
, sym
, rel
, from
->name
,
1631 to
->name
, tls_error
);
1641 elf_x86_64_need_pic (struct bfd_link_info
*info
,
1642 bfd
*input_bfd
, asection
*sec
,
1643 struct elf_link_hash_entry
*h
,
1644 Elf_Internal_Shdr
*symtab_hdr
,
1645 Elf_Internal_Sym
*isym
,
1646 reloc_howto_type
*howto
)
1649 const char *und
= "";
1650 const char *pic
= "";
1656 name
= h
->root
.root
.string
;
1657 switch (ELF_ST_VISIBILITY (h
->other
))
1660 v
= _("hidden symbol ");
1663 v
= _("internal symbol ");
1666 v
= _("protected symbol ");
1669 if (((struct elf_x86_link_hash_entry
*) h
)->def_protected
)
1670 v
= _("protected symbol ");
1677 if (!SYMBOL_DEFINED_NON_SHARED_P (h
) && !h
->def_dynamic
)
1678 und
= _("undefined ");
1682 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, isym
, NULL
);
1686 if (bfd_link_dll (info
))
1688 object
= _("a shared object");
1690 pic
= _("; recompile with -fPIC");
1694 if (bfd_link_pie (info
))
1695 object
= _("a PIE object");
1697 object
= _("a PDE object");
1699 pic
= _("; recompile with -fPIE");
1702 /* xgettext:c-format */
1703 _bfd_error_handler (_("%pB: relocation %s against %s%s`%s' can "
1704 "not be used when making %s%s"),
1705 input_bfd
, howto
->name
, und
, v
, name
,
1707 bfd_set_error (bfd_error_bad_value
);
1708 sec
->check_relocs_failed
= 1;
1712 /* With the local symbol, foo, we convert
1713 mov foo@GOTPCREL(%rip), %reg
1717 call/jmp *foo@GOTPCREL(%rip)
1719 nop call foo/jmp foo nop
1720 When PIC is false, convert
1721 test %reg, foo@GOTPCREL(%rip)
1725 binop foo@GOTPCREL(%rip), %reg
1728 where binop is one of adc, add, and, cmp, or, sbb, sub, xor
1732 elf_x86_64_convert_load_reloc (bfd
*abfd
,
1734 unsigned int *r_type_p
,
1735 Elf_Internal_Rela
*irel
,
1736 struct elf_link_hash_entry
*h
,
1738 struct bfd_link_info
*link_info
)
1740 struct elf_x86_link_hash_table
*htab
;
1748 bfd_signed_vma raddend
;
1749 unsigned int opcode
;
1751 unsigned int r_type
= *r_type_p
;
1752 unsigned int r_symndx
;
1753 bfd_vma roff
= irel
->r_offset
;
1754 bfd_vma abs_relocation
;
1756 if (roff
< (r_type
== R_X86_64_CODE_4_GOTPCRELX
1757 ? 4 : (r_type
== R_X86_64_REX_GOTPCRELX
? 3 : 2)))
1760 raddend
= irel
->r_addend
;
1761 /* Addend for 32-bit PC-relative relocation must be -4. */
1765 htab
= elf_x86_hash_table (link_info
, X86_64_ELF_DATA
);
1766 is_pic
= bfd_link_pic (link_info
);
1768 if (r_type
== R_X86_64_CODE_4_GOTPCRELX
)
1770 /* Skip if this isn't a REX2 instruction. */
1771 opcode
= bfd_get_8 (abfd
, contents
+ roff
- 4);
1778 relocx
= (r_type
== R_X86_64_GOTPCRELX
1779 || r_type
== R_X86_64_REX_GOTPCRELX
);
1781 /* TRUE if --no-relax is used. */
1782 no_overflow
= link_info
->disable_target_specific_optimizations
> 1;
1784 r_symndx
= htab
->r_sym (irel
->r_info
);
1786 opcode
= bfd_get_8 (abfd
, contents
+ roff
- 2);
1788 /* Convert mov to lea since it has been done for a while. */
1791 /* Only convert R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX
1792 and R_X86_64_CODE_4_GOTPCRELX for call, jmp or one of adc,
1793 add, and, cmp, or, sbb, sub, test, xor instructions. */
1798 /* We convert only to R_X86_64_PC32:
1800 2. R_X86_64_GOTPCREL since we can't modify REX byte.
1801 3. no_overflow is true.
1804 to_reloc_pc32
= (opcode
== 0xff
1812 /* Get the symbol referred to by the reloc. */
1815 Elf_Internal_Sym
*isym
1816 = bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
, abfd
, r_symndx
);
1818 /* Skip relocation against undefined symbols. */
1819 if (isym
->st_shndx
== SHN_UNDEF
)
1823 if (isym
->st_shndx
== SHN_ABS
)
1825 tsec
= bfd_abs_section_ptr
;
1827 abs_relocation
= isym
->st_value
;
1829 else if (isym
->st_shndx
== SHN_COMMON
)
1830 tsec
= bfd_com_section_ptr
;
1831 else if (isym
->st_shndx
== SHN_X86_64_LCOMMON
)
1832 tsec
= &_bfd_elf_large_com_section
;
1834 tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1838 /* Undefined weak symbol is only bound locally in executable
1839 and its reference is resolved as 0 without relocation
1840 overflow. We can only perform this optimization for
1841 GOTPCRELX relocations since we need to modify REX byte.
1842 It is OK convert mov with R_X86_64_GOTPCREL to
1844 struct elf_x86_link_hash_entry
*eh
= elf_x86_hash_entry (h
);
1846 abs_symbol
= ABS_SYMBOL_P (h
);
1847 abs_relocation
= h
->root
.u
.def
.value
;
1849 /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P. */
1850 local_ref
= SYMBOL_REFERENCES_LOCAL_P (link_info
, h
);
1851 if ((relocx
|| opcode
== 0x8b)
1852 && (h
->root
.type
== bfd_link_hash_undefweak
1858 /* Skip for branch instructions since R_X86_64_PC32
1865 /* For non-branch instructions, we can convert to
1866 R_X86_64_32/R_X86_64_32S since we know if there
1868 to_reloc_pc32
= false;
1871 /* Since we don't know the current PC when PIC is true,
1872 we can't convert to R_X86_64_PC32. */
1873 if (to_reloc_pc32
&& is_pic
)
1878 /* Avoid optimizing GOTPCREL relocations againt _DYNAMIC since
1879 ld.so may use its link-time address. */
1880 else if (h
->start_stop
1883 || h
->root
.type
== bfd_link_hash_defined
1884 || h
->root
.type
== bfd_link_hash_defweak
)
1885 && h
!= htab
->elf
.hdynamic
1888 /* bfd_link_hash_new or bfd_link_hash_undefined is
1889 set by an assignment in a linker script in
1890 bfd_elf_record_link_assignment. start_stop is set
1891 on __start_SECNAME/__stop_SECNAME which mark section
1896 && (h
->root
.type
== bfd_link_hash_new
1897 || h
->root
.type
== bfd_link_hash_undefined
1898 || ((h
->root
.type
== bfd_link_hash_defined
1899 || h
->root
.type
== bfd_link_hash_defweak
)
1900 && h
->root
.u
.def
.section
== bfd_und_section_ptr
))))
1902 /* Skip since R_X86_64_32/R_X86_64_32S may overflow. */
1907 tsec
= h
->root
.u
.def
.section
;
1913 /* Don't convert GOTPCREL relocation against large section. */
1914 if (elf_section_data (tsec
) != NULL
1915 && (elf_section_flags (tsec
) & SHF_X86_64_LARGE
) != 0)
1918 /* Skip since R_X86_64_PC32/R_X86_64_32/R_X86_64_32S may overflow. */
1925 /* We have "call/jmp *foo@GOTPCREL(%rip)". */
1930 /* Convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX to
1932 modrm
= bfd_get_8 (abfd
, contents
+ roff
- 1);
1935 /* Convert to "jmp foo nop". */
1938 nop_offset
= irel
->r_offset
+ 3;
1939 disp
= bfd_get_32 (abfd
, contents
+ irel
->r_offset
);
1940 irel
->r_offset
-= 1;
1941 bfd_put_32 (abfd
, disp
, contents
+ irel
->r_offset
);
1945 struct elf_x86_link_hash_entry
*eh
1946 = (struct elf_x86_link_hash_entry
*) h
;
1948 /* Convert to "nop call foo". ADDR_PREFIX_OPCODE
1951 /* To support TLS optimization, always use addr32 prefix for
1952 "call *__tls_get_addr@GOTPCREL(%rip)". */
1953 if (eh
&& eh
->tls_get_addr
)
1956 nop_offset
= irel
->r_offset
- 2;
1960 nop
= htab
->params
->call_nop_byte
;
1961 if (htab
->params
->call_nop_as_suffix
)
1963 nop_offset
= irel
->r_offset
+ 3;
1964 disp
= bfd_get_32 (abfd
, contents
+ irel
->r_offset
);
1965 irel
->r_offset
-= 1;
1966 bfd_put_32 (abfd
, disp
, contents
+ irel
->r_offset
);
1969 nop_offset
= irel
->r_offset
- 2;
1972 bfd_put_8 (abfd
, nop
, contents
+ nop_offset
);
1973 bfd_put_8 (abfd
, modrm
, contents
+ irel
->r_offset
- 1);
1974 r_type
= R_X86_64_PC32
;
1978 unsigned int rex
= 0;
1979 unsigned int rex_mask
= REX_R
;
1980 unsigned int rex2
= 0;
1981 unsigned int rex2_mask
= REX_R
| REX_R
<< 4;
1984 if (r_type
== R_X86_64_CODE_4_GOTPCRELX
)
1986 rex2
= bfd_get_8 (abfd
, contents
+ roff
- 3);
1987 rex_w
= (rex2
& REX_W
) != 0;
1989 else if (r_type
== R_X86_64_REX_GOTPCRELX
)
1991 rex
= bfd_get_8 (abfd
, contents
+ roff
- 3);
1992 rex_w
= (rex
& REX_W
) != 0;
1997 if (abs_symbol
&& local_ref
&& relocx
)
1998 to_reloc_pc32
= false;
2002 /* Convert "mov foo@GOTPCREL(%rip), %reg" to
2003 "lea foo(%rip), %reg". */
2005 r_type
= R_X86_64_PC32
;
2009 /* Convert "mov foo@GOTPCREL(%rip), %reg" to
2010 "mov $foo, %reg". */
2012 modrm
= bfd_get_8 (abfd
, contents
+ roff
- 1);
2013 modrm
= 0xc0 | (modrm
& 0x38) >> 3;
2014 if (rex_w
&& ABI_64_P (link_info
->output_bfd
))
2016 /* Keep the REX_W bit in REX byte for LP64. */
2017 r_type
= R_X86_64_32S
;
2018 goto rewrite_modrm_rex
;
2022 /* If the REX_W bit in REX byte isn't needed,
2023 use R_X86_64_32 and clear the W bit to avoid
2024 sign-extend imm32 to imm64. */
2025 r_type
= R_X86_64_32
;
2026 /* Clear the W bit in REX byte and REX2 payload. */
2029 goto rewrite_modrm_rex
;
2035 /* R_X86_64_PC32 isn't supported. */
2039 modrm
= bfd_get_8 (abfd
, contents
+ roff
- 1);
2042 /* Convert "test %reg, foo@GOTPCREL(%rip)" to
2043 "test $foo, %reg". */
2044 modrm
= 0xc0 | (modrm
& 0x38) >> 3;
2049 /* Convert "binop foo@GOTPCREL(%rip), %reg" to
2050 "binop $foo, %reg". */
2051 modrm
= 0xc0 | (modrm
& 0x38) >> 3 | (opcode
& 0x3c);
2055 /* Use R_X86_64_32 with 32-bit operand to avoid relocation
2056 overflow when sign-extending imm32 to imm64. */
2057 r_type
= rex_w
? R_X86_64_32S
: R_X86_64_32
;
2062 /* Check if R_X86_64_32S/R_X86_64_32 fits. */
2063 if (r_type
== R_X86_64_32S
)
2065 if ((abs_relocation
+ 0x80000000) > 0xffffffff)
2070 if (abs_relocation
> 0xffffffff)
2075 bfd_put_8 (abfd
, modrm
, contents
+ roff
- 1);
2079 /* Move the R bit to the B bit in REX byte. */
2080 rex
= (rex
& ~rex_mask
) | (rex
& REX_R
) >> 2;
2081 bfd_put_8 (abfd
, rex
, contents
+ roff
- 3);
2085 /* Move the R bits to the B bits in REX2 payload byte. */
2086 rex2
= ((rex2
& ~rex2_mask
)
2087 | (rex2
& (REX_R
| REX_R
<< 4)) >> 2);
2088 bfd_put_8 (abfd
, rex2
, contents
+ roff
- 3);
2091 /* No addend for R_X86_64_32/R_X86_64_32S relocations. */
2095 bfd_put_8 (abfd
, opcode
, contents
+ roff
- 2);
2099 irel
->r_info
= htab
->r_info (r_symndx
,
2100 r_type
| R_X86_64_converted_reloc_bit
);
2107 /* Look through the relocs for a section during the first phase, and
2108 calculate needed space in the global offset table, and procedure
2112 elf_x86_64_scan_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
2114 const Elf_Internal_Rela
*relocs
)
2116 struct elf_x86_link_hash_table
*htab
;
2117 Elf_Internal_Shdr
*symtab_hdr
;
2118 struct elf_link_hash_entry
**sym_hashes
;
2119 const Elf_Internal_Rela
*rel
;
2120 const Elf_Internal_Rela
*rel_end
;
2124 if (bfd_link_relocatable (info
))
2127 htab
= elf_x86_hash_table (info
, X86_64_ELF_DATA
);
2130 sec
->check_relocs_failed
= 1;
2134 BFD_ASSERT (is_x86_elf (abfd
, htab
));
2136 /* Get the section contents. */
2137 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
2138 contents
= elf_section_data (sec
)->this_hdr
.contents
;
2139 else if (!_bfd_elf_mmap_section_contents (abfd
, sec
, &contents
))
2141 sec
->check_relocs_failed
= 1;
2145 symtab_hdr
= &elf_symtab_hdr (abfd
);
2146 sym_hashes
= elf_sym_hashes (abfd
);
2150 rel_end
= relocs
+ sec
->reloc_count
;
2151 for (rel
= relocs
; rel
< rel_end
; rel
++)
2153 unsigned int r_type
;
2154 unsigned int r_symndx
;
2155 struct elf_link_hash_entry
*h
;
2156 struct elf_x86_link_hash_entry
*eh
;
2157 Elf_Internal_Sym
*isym
;
2160 bool converted_reloc
;
2163 r_symndx
= htab
->r_sym (rel
->r_info
);
2164 r_type
= ELF32_R_TYPE (rel
->r_info
);
2166 /* Don't check R_X86_64_NONE. */
2167 if (r_type
== R_X86_64_NONE
)
2170 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
2172 /* xgettext:c-format */
2173 _bfd_error_handler (_("%pB: bad symbol index: %d"),
2178 if (r_symndx
< symtab_hdr
->sh_info
)
2180 /* A local symbol. */
2181 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
,
2186 /* Check relocation against local STT_GNU_IFUNC symbol. */
2187 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
2189 h
= _bfd_elf_x86_get_local_sym_hash (htab
, abfd
, rel
,
2194 /* Fake a STT_GNU_IFUNC symbol. */
2195 h
->root
.root
.string
= bfd_elf_sym_name (abfd
, symtab_hdr
,
2197 h
->type
= STT_GNU_IFUNC
;
2200 h
->forced_local
= 1;
2201 h
->root
.type
= bfd_link_hash_defined
;
2209 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
2210 while (h
->root
.type
== bfd_link_hash_indirect
2211 || h
->root
.type
== bfd_link_hash_warning
)
2212 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2215 /* Check invalid x32 relocations. */
2216 if (!ABI_64_P (abfd
))
2222 case R_X86_64_DTPOFF64
:
2223 case R_X86_64_TPOFF64
:
2225 case R_X86_64_GOTOFF64
:
2226 case R_X86_64_GOT64
:
2227 case R_X86_64_GOTPCREL64
:
2228 case R_X86_64_GOTPC64
:
2229 case R_X86_64_GOTPLT64
:
2230 case R_X86_64_PLTOFF64
:
2233 name
= h
->root
.root
.string
;
2235 name
= bfd_elf_sym_name (abfd
, symtab_hdr
, isym
,
2238 /* xgettext:c-format */
2239 (_("%pB: relocation %s against symbol `%s' isn't "
2240 "supported in x32 mode"), abfd
,
2241 x86_64_elf_howto_table
[r_type
].name
, name
);
2242 bfd_set_error (bfd_error_bad_value
);
2248 eh
= (struct elf_x86_link_hash_entry
*) h
;
2252 /* It is referenced by a non-shared object. */
2256 converted_reloc
= false;
2257 if ((r_type
== R_X86_64_GOTPCREL
2258 || r_type
== R_X86_64_GOTPCRELX
2259 || r_type
== R_X86_64_REX_GOTPCRELX
2260 || r_type
== R_X86_64_CODE_4_GOTPCRELX
)
2261 && (h
== NULL
|| h
->type
!= STT_GNU_IFUNC
))
2263 Elf_Internal_Rela
*irel
= (Elf_Internal_Rela
*) rel
;
2264 if (!elf_x86_64_convert_load_reloc (abfd
, contents
, &r_type
,
2265 irel
, h
, &converted_reloc
,
2269 if (converted_reloc
)
2273 if (!_bfd_elf_x86_valid_reloc_p (sec
, info
, htab
, rel
, h
, isym
,
2274 symtab_hdr
, &no_dynreloc
))
2277 if (! elf_x86_64_tls_transition (info
, abfd
, sec
, contents
,
2278 symtab_hdr
, sym_hashes
,
2279 &r_type
, GOT_UNKNOWN
,
2280 rel
, rel_end
, h
, isym
, false))
2283 /* Check if _GLOBAL_OFFSET_TABLE_ is referenced. */
2284 if (h
== htab
->elf
.hgot
)
2285 htab
->got_referenced
= true;
2289 case R_X86_64_TLSLD
:
2290 htab
->tls_ld_or_ldm_got
.refcount
= 1;
2293 case R_X86_64_TPOFF32
:
2294 if (!bfd_link_executable (info
) && ABI_64_P (abfd
))
2295 return elf_x86_64_need_pic (info
, abfd
, sec
, h
, symtab_hdr
, isym
,
2296 &x86_64_elf_howto_table
[r_type
]);
2298 eh
->zero_undefweak
&= 0x2;
2301 case R_X86_64_GOTTPOFF
:
2302 case R_X86_64_CODE_4_GOTTPOFF
:
2303 case R_X86_64_CODE_6_GOTTPOFF
:
2304 if (!bfd_link_executable (info
))
2305 info
->flags
|= DF_STATIC_TLS
;
2308 case R_X86_64_GOT32
:
2309 case R_X86_64_GOTPCREL
:
2310 case R_X86_64_GOTPCRELX
:
2311 case R_X86_64_REX_GOTPCRELX
:
2312 case R_X86_64_CODE_4_GOTPCRELX
:
2313 case R_X86_64_TLSGD
:
2314 case R_X86_64_GOT64
:
2315 case R_X86_64_GOTPCREL64
:
2316 case R_X86_64_GOTPLT64
:
2317 case R_X86_64_GOTPC32_TLSDESC
:
2318 case R_X86_64_CODE_4_GOTPC32_TLSDESC
:
2319 case R_X86_64_TLSDESC_CALL
:
2320 /* This symbol requires a global offset table entry. */
2322 int tls_type
, old_tls_type
;
2327 tls_type
= GOT_NORMAL
;
2330 if (ABS_SYMBOL_P (h
))
2333 else if (isym
->st_shndx
== SHN_ABS
)
2336 case R_X86_64_TLSGD
:
2337 tls_type
= GOT_TLS_GD
;
2339 case R_X86_64_GOTTPOFF
:
2340 case R_X86_64_CODE_4_GOTTPOFF
:
2341 case R_X86_64_CODE_6_GOTTPOFF
:
2342 tls_type
= GOT_TLS_IE
;
2344 case R_X86_64_GOTPC32_TLSDESC
:
2345 case R_X86_64_CODE_4_GOTPC32_TLSDESC
:
2346 case R_X86_64_TLSDESC_CALL
:
2347 tls_type
= GOT_TLS_GDESC
;
2353 h
->got
.refcount
= 1;
2354 old_tls_type
= eh
->tls_type
;
2358 bfd_signed_vma
*local_got_refcounts
;
2360 if (!elf_x86_allocate_local_got_info (abfd
,
2361 symtab_hdr
->sh_info
))
2364 /* This is a global offset table entry for a local symbol. */
2365 local_got_refcounts
= elf_local_got_refcounts (abfd
);
2366 local_got_refcounts
[r_symndx
] = 1;
2368 = elf_x86_local_got_tls_type (abfd
) [r_symndx
];
2371 /* If a TLS symbol is accessed using IE at least once,
2372 there is no point to use dynamic model for it. */
2373 if (old_tls_type
!= tls_type
&& old_tls_type
!= GOT_UNKNOWN
2374 && (! GOT_TLS_GD_ANY_P (old_tls_type
)
2375 || tls_type
!= GOT_TLS_IE
))
2377 if (old_tls_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (tls_type
))
2378 tls_type
= old_tls_type
;
2379 else if (GOT_TLS_GD_ANY_P (old_tls_type
)
2380 && GOT_TLS_GD_ANY_P (tls_type
))
2381 tls_type
|= old_tls_type
;
2385 name
= h
->root
.root
.string
;
2387 name
= bfd_elf_sym_name (abfd
, symtab_hdr
,
2390 /* xgettext:c-format */
2391 (_("%pB: '%s' accessed both as normal and"
2392 " thread local symbol"),
2394 bfd_set_error (bfd_error_bad_value
);
2399 if (old_tls_type
!= tls_type
)
2402 eh
->tls_type
= tls_type
;
2404 elf_x86_local_got_tls_type (abfd
) [r_symndx
] = tls_type
;
2409 case R_X86_64_GOTOFF64
:
2410 case R_X86_64_GOTPC32
:
2411 case R_X86_64_GOTPC64
:
2414 eh
->zero_undefweak
&= 0x2;
2417 case R_X86_64_PLT32
:
2418 /* This symbol requires a procedure linkage table entry. We
2419 actually build the entry in adjust_dynamic_symbol,
2420 because this might be a case of linking PIC code which is
2421 never referenced by a dynamic object, in which case we
2422 don't need to generate a procedure linkage table entry
2425 /* If this is a local symbol, we resolve it directly without
2426 creating a procedure linkage table entry. */
2430 eh
->zero_undefweak
&= 0x2;
2432 h
->plt
.refcount
= 1;
2435 case R_X86_64_PLTOFF64
:
2436 /* This tries to form the 'address' of a function relative
2437 to GOT. For global symbols we need a PLT entry. */
2441 h
->plt
.refcount
= 1;
2445 case R_X86_64_SIZE32
:
2446 case R_X86_64_SIZE64
:
2451 if (!ABI_64_P (abfd
))
2457 /* Check relocation overflow as these relocs may lead to
2458 run-time relocation overflow. Don't error out for
2459 sections we don't care about, such as debug sections or
2460 when relocation overflow check is disabled. */
2461 if (!htab
->params
->no_reloc_overflow_check
2463 && (bfd_link_pic (info
)
2464 || (bfd_link_executable (info
)
2468 && (sec
->flags
& SEC_READONLY
) == 0)))
2469 return elf_x86_64_need_pic (info
, abfd
, sec
, h
, symtab_hdr
, isym
,
2470 &x86_64_elf_howto_table
[r_type
]);
2479 if (eh
!= NULL
&& (sec
->flags
& SEC_CODE
) != 0)
2480 eh
->zero_undefweak
|= 0x2;
2481 /* We are called after all symbols have been resolved. Only
2482 relocation against STT_GNU_IFUNC symbol must go through
2485 && (bfd_link_executable (info
)
2486 || h
->type
== STT_GNU_IFUNC
))
2488 bool func_pointer_ref
= false;
2490 if (r_type
== R_X86_64_PC32
)
2492 /* Since something like ".long foo - ." may be used
2493 as pointer, make sure that PLT is used if foo is
2494 a function defined in a shared library. */
2495 if ((sec
->flags
& SEC_CODE
) == 0)
2497 h
->pointer_equality_needed
= 1;
2498 if (bfd_link_pie (info
)
2499 && h
->type
== STT_FUNC
2504 h
->plt
.refcount
= 1;
2508 else if (r_type
!= R_X86_64_PC64
)
2510 /* At run-time, R_X86_64_64 can be resolved for both
2511 x86-64 and x32. But R_X86_64_32 and R_X86_64_32S
2512 can only be resolved for x32. Function pointer
2513 reference doesn't need PLT for pointer equality. */
2514 if ((sec
->flags
& SEC_READONLY
) == 0
2515 && (r_type
== R_X86_64_64
2516 || (!ABI_64_P (abfd
)
2517 && (r_type
== R_X86_64_32
2518 || r_type
== R_X86_64_32S
))))
2519 func_pointer_ref
= true;
2521 /* IFUNC symbol needs pointer equality in PDE so that
2522 function pointer reference will be resolved to its
2523 PLT entry directly. */
2524 if (!func_pointer_ref
2525 || (bfd_link_pde (info
)
2526 && h
->type
== STT_GNU_IFUNC
))
2527 h
->pointer_equality_needed
= 1;
2530 if (!func_pointer_ref
)
2532 /* If this reloc is in a read-only section, we might
2533 need a copy reloc. We can't check reliably at this
2534 stage whether the section is read-only, as input
2535 sections have not yet been mapped to output sections.
2536 Tentatively set the flag for now, and correct in
2537 adjust_dynamic_symbol. */
2540 if (!elf_has_indirect_extern_access (sec
->owner
))
2541 eh
->non_got_ref_without_indirect_extern_access
= 1;
2543 /* We may need a .plt entry if the symbol is a function
2544 defined in a shared lib or is a function referenced
2545 from the code or read-only section. */
2547 || (sec
->flags
& (SEC_CODE
| SEC_READONLY
)) != 0)
2548 h
->plt
.refcount
= 1;
2550 if (htab
->elf
.target_os
!= is_solaris
2551 && h
->pointer_equality_needed
2552 && h
->type
== STT_FUNC
2553 && eh
->def_protected
2554 && !SYMBOL_DEFINED_NON_SHARED_P (h
)
2557 /* Disallow non-canonical reference to canonical
2558 protected function. */
2560 /* xgettext:c-format */
2561 (_("%pB: non-canonical reference to canonical "
2562 "protected function `%s' in %pB"),
2563 abfd
, h
->root
.root
.string
,
2564 h
->root
.u
.def
.section
->owner
);
2565 bfd_set_error (bfd_error_bad_value
);
2574 && NEED_DYNAMIC_RELOCATION_P (true, info
, true, h
, sec
,
2576 htab
->pointer_r_type
))
2578 struct elf_dyn_relocs
*p
;
2579 struct elf_dyn_relocs
**head
;
2581 /* If this is a global symbol, we count the number of
2582 relocations we need for this symbol. */
2584 head
= &h
->dyn_relocs
;
2587 /* Track dynamic relocs needed for local syms too.
2588 We really need local syms available to do this
2593 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
,
2598 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
2602 /* Beware of type punned pointers vs strict aliasing
2604 vpp
= &(elf_section_data (s
)->local_dynrel
);
2605 head
= (struct elf_dyn_relocs
**)vpp
;
2609 if (p
== NULL
|| p
->sec
!= sec
)
2611 size_t amt
= sizeof *p
;
2613 p
= ((struct elf_dyn_relocs
*)
2614 bfd_alloc (htab
->elf
.dynobj
, amt
));
2625 /* Count size relocation as PC-relative relocation. */
2626 if (X86_PCREL_TYPE_P (true, r_type
) || size_reloc
)
2631 case R_X86_64_CODE_5_GOTPCRELX
:
2632 case R_X86_64_CODE_5_GOTTPOFF
:
2633 case R_X86_64_CODE_5_GOTPC32_TLSDESC
:
2634 case R_X86_64_CODE_6_GOTPCRELX
:
2635 case R_X86_64_CODE_6_GOTPC32_TLSDESC
:
2637 /* These relocations are added only for completeness and
2640 name
= h
->root
.root
.string
;
2642 name
= bfd_elf_sym_name (abfd
, symtab_hdr
, isym
,
2645 /* xgettext:c-format */
2646 (_("%pB: unsupported relocation %s against symbol `%s'"),
2647 abfd
, x86_64_elf_howto_table
[r_type
].name
, name
);
2651 /* This relocation describes the C++ object vtable hierarchy.
2652 Reconstruct it for later use during GC. */
2653 case R_X86_64_GNU_VTINHERIT
:
2654 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
2658 /* This relocation describes which C++ vtable entries are actually
2659 used. Record for later use during GC. */
2660 case R_X86_64_GNU_VTENTRY
:
2661 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
2670 if (elf_section_data (sec
)->this_hdr
.contents
!= contents
)
2673 _bfd_elf_munmap_section_contents (sec
, contents
);
2676 /* Cache the section contents for elf_link_input_bfd if any
2677 load is converted or --no-keep-memory isn't used. */
2678 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2679 info
->cache_size
+= sec
->size
;
2683 /* Cache relocations if any load is converted. */
2684 if (elf_section_data (sec
)->relocs
!= relocs
&& converted
)
2685 elf_section_data (sec
)->relocs
= (Elf_Internal_Rela
*) relocs
;
2690 if (elf_section_data (sec
)->this_hdr
.contents
!= contents
)
2691 _bfd_elf_munmap_section_contents (sec
, contents
);
2692 sec
->check_relocs_failed
= 1;
2697 elf_x86_64_early_size_sections (bfd
*output_bfd
, struct bfd_link_info
*info
)
2701 /* Scan relocations after rel_from_abs has been set on __ehdr_start. */
2702 for (abfd
= info
->input_bfds
;
2703 abfd
!= (bfd
*) NULL
;
2704 abfd
= abfd
->link
.next
)
2705 if (bfd_get_flavour (abfd
) == bfd_target_elf_flavour
2706 && !_bfd_elf_link_iterate_on_relocs (abfd
, info
,
2707 elf_x86_64_scan_relocs
))
2710 return _bfd_x86_elf_early_size_sections (output_bfd
, info
);
2713 /* Return the relocation value for @tpoff relocation
2714 if STT_TLS virtual address is ADDRESS. */
2717 elf_x86_64_tpoff (struct bfd_link_info
*info
, bfd_vma address
)
2719 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
2720 const struct elf_backend_data
*bed
= get_elf_backend_data (info
->output_bfd
);
2721 bfd_vma static_tls_size
;
2723 /* If tls_segment is NULL, we should have signalled an error already. */
2724 if (htab
->tls_sec
== NULL
)
2727 /* Consider special static TLS alignment requirements. */
2728 static_tls_size
= BFD_ALIGN (htab
->tls_size
, bed
->static_tls_alignment
);
2729 return address
- static_tls_size
- htab
->tls_sec
->vma
;
2732 /* Relocate an x86_64 ELF section. */
2735 elf_x86_64_relocate_section (bfd
*output_bfd
,
2736 struct bfd_link_info
*info
,
2738 asection
*input_section
,
2740 Elf_Internal_Rela
*relocs
,
2741 Elf_Internal_Sym
*local_syms
,
2742 asection
**local_sections
)
2744 struct elf_x86_link_hash_table
*htab
;
2745 Elf_Internal_Shdr
*symtab_hdr
;
2746 struct elf_link_hash_entry
**sym_hashes
;
2747 bfd_vma
*local_got_offsets
;
2748 bfd_vma
*local_tlsdesc_gotents
;
2749 Elf_Internal_Rela
*rel
;
2750 Elf_Internal_Rela
*wrel
;
2751 Elf_Internal_Rela
*relend
;
2752 unsigned int plt_entry_size
;
2755 /* Skip if check_relocs or scan_relocs failed. */
2756 if (input_section
->check_relocs_failed
)
2759 htab
= elf_x86_hash_table (info
, X86_64_ELF_DATA
);
2763 if (!is_x86_elf (input_bfd
, htab
))
2765 bfd_set_error (bfd_error_wrong_format
);
2769 plt_entry_size
= htab
->plt
.plt_entry_size
;
2770 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
2771 sym_hashes
= elf_sym_hashes (input_bfd
);
2772 local_got_offsets
= elf_local_got_offsets (input_bfd
);
2773 local_tlsdesc_gotents
= elf_x86_local_tlsdesc_gotent (input_bfd
);
2775 _bfd_x86_elf_set_tls_module_base (info
);
2778 rel
= wrel
= relocs
;
2779 relend
= relocs
+ input_section
->reloc_count
;
2780 for (; rel
< relend
; wrel
++, rel
++)
2782 unsigned int r_type
, r_type_tls
;
2783 reloc_howto_type
*howto
;
2784 unsigned long r_symndx
;
2785 struct elf_link_hash_entry
*h
;
2786 struct elf_x86_link_hash_entry
*eh
;
2787 Elf_Internal_Sym
*sym
;
2789 bfd_vma off
, offplt
, plt_offset
;
2791 bool unresolved_reloc
;
2792 bfd_reloc_status_type r
;
2794 asection
*base_got
, *resolved_plt
;
2796 bool resolved_to_zero
;
2797 bool relative_reloc
;
2798 bool converted_reloc
;
2799 bool need_copy_reloc_in_pie
;
2800 bool no_copyreloc_p
;
2802 r_type
= ELF32_R_TYPE (rel
->r_info
);
2803 if (r_type
== (int) R_X86_64_GNU_VTINHERIT
2804 || r_type
== (int) R_X86_64_GNU_VTENTRY
)
2811 r_symndx
= htab
->r_sym (rel
->r_info
);
2812 converted_reloc
= (r_type
& R_X86_64_converted_reloc_bit
) != 0;
2813 if (converted_reloc
)
2815 r_type
&= ~R_X86_64_converted_reloc_bit
;
2816 rel
->r_info
= htab
->r_info (r_symndx
, r_type
);
2819 howto
= elf_x86_64_rtype_to_howto (input_bfd
, r_type
);
2821 return _bfd_unrecognized_reloc (input_bfd
, input_section
, r_type
);
2826 unresolved_reloc
= false;
2827 if (r_symndx
< symtab_hdr
->sh_info
)
2829 sym
= local_syms
+ r_symndx
;
2830 sec
= local_sections
[r_symndx
];
2832 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
,
2834 st_size
= sym
->st_size
;
2836 /* Relocate against local STT_GNU_IFUNC symbol. */
2837 if (!bfd_link_relocatable (info
)
2838 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
2840 h
= _bfd_elf_x86_get_local_sym_hash (htab
, input_bfd
,
2845 /* Set STT_GNU_IFUNC symbol value. */
2846 h
->root
.u
.def
.value
= sym
->st_value
;
2847 h
->root
.u
.def
.section
= sec
;
2852 bool warned ATTRIBUTE_UNUSED
;
2853 bool ignored ATTRIBUTE_UNUSED
;
2855 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
2856 r_symndx
, symtab_hdr
, sym_hashes
,
2858 unresolved_reloc
, warned
, ignored
);
2862 if (sec
!= NULL
&& discarded_section (sec
))
2864 _bfd_clear_contents (howto
, input_bfd
, input_section
,
2865 contents
, rel
->r_offset
);
2866 wrel
->r_offset
= rel
->r_offset
;
2870 /* For ld -r, remove relocations in debug sections against
2871 sections defined in discarded sections. Not done for
2872 eh_frame editing code expects to be present. */
2873 if (bfd_link_relocatable (info
)
2874 && (input_section
->flags
& SEC_DEBUGGING
))
2880 if (bfd_link_relocatable (info
))
2887 if (rel
->r_addend
== 0 && !ABI_64_P (output_bfd
))
2889 if (r_type
== R_X86_64_64
)
2891 /* For x32, treat R_X86_64_64 like R_X86_64_32 and
2892 zero-extend it to 64bit if addend is zero. */
2893 r_type
= R_X86_64_32
;
2894 memset (contents
+ rel
->r_offset
+ 4, 0, 4);
2896 else if (r_type
== R_X86_64_SIZE64
)
2898 /* For x32, treat R_X86_64_SIZE64 like R_X86_64_SIZE32 and
2899 zero-extend it to 64bit if addend is zero. */
2900 r_type
= R_X86_64_SIZE32
;
2901 memset (contents
+ rel
->r_offset
+ 4, 0, 4);
2905 eh
= (struct elf_x86_link_hash_entry
*) h
;
2907 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
2908 it here if it is defined in a non-shared object. */
2910 && h
->type
== STT_GNU_IFUNC
2916 if ((input_section
->flags
& SEC_ALLOC
) == 0)
2918 /* If this is a SHT_NOTE section without SHF_ALLOC, treat
2919 STT_GNU_IFUNC symbol as STT_FUNC. */
2920 if (elf_section_type (input_section
) == SHT_NOTE
)
2922 /* Dynamic relocs are not propagated for SEC_DEBUGGING
2923 sections because such sections are not SEC_ALLOC and
2924 thus ld.so will not process them. */
2925 if ((input_section
->flags
& SEC_DEBUGGING
) != 0)
2935 case R_X86_64_GOTPCREL
:
2936 case R_X86_64_GOTPCRELX
:
2937 case R_X86_64_REX_GOTPCRELX
:
2938 case R_X86_64_CODE_4_GOTPCRELX
:
2939 case R_X86_64_GOTPCREL64
:
2940 base_got
= htab
->elf
.sgot
;
2941 off
= h
->got
.offset
;
2943 if (base_got
== NULL
)
2946 if (off
== (bfd_vma
) -1)
2948 /* We can't use h->got.offset here to save state, or
2949 even just remember the offset, as finish_dynamic_symbol
2950 would use that as offset into .got. */
2952 if (h
->plt
.offset
== (bfd_vma
) -1)
2955 if (htab
->elf
.splt
!= NULL
)
2957 plt_index
= (h
->plt
.offset
/ plt_entry_size
2958 - htab
->plt
.has_plt0
);
2959 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
2960 base_got
= htab
->elf
.sgotplt
;
2964 plt_index
= h
->plt
.offset
/ plt_entry_size
;
2965 off
= plt_index
* GOT_ENTRY_SIZE
;
2966 base_got
= htab
->elf
.igotplt
;
2969 if (h
->dynindx
== -1
2973 /* This references the local defitionion. We must
2974 initialize this entry in the global offset table.
2975 Since the offset must always be a multiple of 8,
2976 we use the least significant bit to record
2977 whether we have initialized it already.
2979 When doing a dynamic link, we create a .rela.got
2980 relocation entry to initialize the value. This
2981 is done in the finish_dynamic_symbol routine. */
2986 bfd_put_64 (output_bfd
, relocation
,
2987 base_got
->contents
+ off
);
2988 /* Note that this is harmless for the GOTPLT64
2989 case, as -1 | 1 still is -1. */
2995 relocation
= (base_got
->output_section
->vma
2996 + base_got
->output_offset
+ off
);
3001 if (h
->plt
.offset
== (bfd_vma
) -1)
3003 /* Handle static pointers of STT_GNU_IFUNC symbols. */
3004 if (r_type
== htab
->pointer_r_type
3005 && (input_section
->flags
& SEC_CODE
) == 0)
3006 goto do_ifunc_pointer
;
3007 goto bad_ifunc_reloc
;
3010 /* STT_GNU_IFUNC symbol must go through PLT. */
3011 if (htab
->elf
.splt
!= NULL
)
3013 if (htab
->plt_second
!= NULL
)
3015 resolved_plt
= htab
->plt_second
;
3016 plt_offset
= eh
->plt_second
.offset
;
3020 resolved_plt
= htab
->elf
.splt
;
3021 plt_offset
= h
->plt
.offset
;
3026 resolved_plt
= htab
->elf
.iplt
;
3027 plt_offset
= h
->plt
.offset
;
3030 relocation
= (resolved_plt
->output_section
->vma
3031 + resolved_plt
->output_offset
+ plt_offset
);
3037 if (h
->root
.root
.string
)
3038 name
= h
->root
.root
.string
;
3040 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
3043 /* xgettext:c-format */
3044 (_("%pB: relocation %s against STT_GNU_IFUNC "
3045 "symbol `%s' isn't supported"), input_bfd
,
3047 bfd_set_error (bfd_error_bad_value
);
3051 if (bfd_link_pic (info
))
3056 if (ABI_64_P (output_bfd
))
3061 if (rel
->r_addend
!= 0)
3063 if (h
->root
.root
.string
)
3064 name
= h
->root
.root
.string
;
3066 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
3069 /* xgettext:c-format */
3070 (_("%pB: relocation %s against STT_GNU_IFUNC "
3071 "symbol `%s' has non-zero addend: %" PRId64
),
3072 input_bfd
, howto
->name
, name
, (int64_t) rel
->r_addend
);
3073 bfd_set_error (bfd_error_bad_value
);
3077 /* Generate dynamic relcoation only when there is a
3078 non-GOT reference in a shared object or there is no
3080 if ((bfd_link_pic (info
) && h
->non_got_ref
)
3081 || h
->plt
.offset
== (bfd_vma
) -1)
3083 Elf_Internal_Rela outrel
;
3086 /* Need a dynamic relocation to get the real function
3088 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
3092 if (outrel
.r_offset
== (bfd_vma
) -1
3093 || outrel
.r_offset
== (bfd_vma
) -2)
3096 outrel
.r_offset
+= (input_section
->output_section
->vma
3097 + input_section
->output_offset
);
3099 if (POINTER_LOCAL_IFUNC_P (info
, h
))
3101 info
->callbacks
->minfo (_("Local IFUNC function `%s' in %pB\n"),
3102 h
->root
.root
.string
,
3103 h
->root
.u
.def
.section
->owner
);
3105 /* This symbol is resolved locally. */
3106 outrel
.r_info
= htab
->r_info (0, R_X86_64_IRELATIVE
);
3107 outrel
.r_addend
= (h
->root
.u
.def
.value
3108 + h
->root
.u
.def
.section
->output_section
->vma
3109 + h
->root
.u
.def
.section
->output_offset
);
3111 if (htab
->params
->report_relative_reloc
)
3112 _bfd_x86_elf_link_report_relative_reloc
3113 (info
, input_section
, h
, sym
,
3114 "R_X86_64_IRELATIVE", &outrel
);
3118 outrel
.r_info
= htab
->r_info (h
->dynindx
, r_type
);
3119 outrel
.r_addend
= 0;
3122 /* Dynamic relocations are stored in
3123 1. .rela.ifunc section in PIC object.
3124 2. .rela.got section in dynamic executable.
3125 3. .rela.iplt section in static executable. */
3126 if (bfd_link_pic (info
))
3127 sreloc
= htab
->elf
.irelifunc
;
3128 else if (htab
->elf
.splt
!= NULL
)
3129 sreloc
= htab
->elf
.srelgot
;
3131 sreloc
= htab
->elf
.irelplt
;
3132 elf_append_rela (output_bfd
, sreloc
, &outrel
);
3134 /* If this reloc is against an external symbol, we
3135 do not want to fiddle with the addend. Otherwise,
3136 we need to include the symbol value so that it
3137 becomes an addend for the dynamic reloc. For an
3138 internal symbol, we have updated addend. */
3144 case R_X86_64_PLT32
:
3150 resolved_to_zero
= (eh
!= NULL
3151 && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info
, eh
));
3153 /* When generating a shared object, the relocations handled here are
3154 copied into the output file to be resolved at run time. */
3157 case R_X86_64_GOT32
:
3158 case R_X86_64_GOT64
:
3159 /* Relocation is to the entry for this symbol in the global
3161 case R_X86_64_GOTPCREL
:
3162 case R_X86_64_GOTPCRELX
:
3163 case R_X86_64_REX_GOTPCRELX
:
3164 case R_X86_64_CODE_4_GOTPCRELX
:
3165 case R_X86_64_GOTPCREL64
:
3166 /* Use global offset table entry as symbol value. */
3167 case R_X86_64_GOTPLT64
:
3168 /* This is obsolete and treated the same as GOT64. */
3169 base_got
= htab
->elf
.sgot
;
3171 if (htab
->elf
.sgot
== NULL
)
3174 relative_reloc
= false;
3177 off
= h
->got
.offset
;
3179 && h
->plt
.offset
!= (bfd_vma
)-1
3180 && off
== (bfd_vma
)-1)
3182 /* We can't use h->got.offset here to save
3183 state, or even just remember the offset, as
3184 finish_dynamic_symbol would use that as offset into
3186 bfd_vma plt_index
= (h
->plt
.offset
/ plt_entry_size
3187 - htab
->plt
.has_plt0
);
3188 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
3189 base_got
= htab
->elf
.sgotplt
;
3192 if (RESOLVED_LOCALLY_P (info
, h
, htab
))
3194 /* We must initialize this entry in the global offset
3195 table. Since the offset must always be a multiple
3196 of 8, we use the least significant bit to record
3197 whether we have initialized it already.
3199 When doing a dynamic link, we create a .rela.got
3200 relocation entry to initialize the value. This is
3201 done in the finish_dynamic_symbol routine. */
3206 bfd_put_64 (output_bfd
, relocation
,
3207 base_got
->contents
+ off
);
3208 /* Note that this is harmless for the GOTPLT64 case,
3209 as -1 | 1 still is -1. */
3212 /* NB: Don't generate relative relocation here if
3213 it has been generated by DT_RELR. */
3214 if (!info
->enable_dt_relr
3215 && GENERATE_RELATIVE_RELOC_P (info
, h
))
3217 /* If this symbol isn't dynamic in PIC,
3218 generate R_X86_64_RELATIVE here. */
3219 eh
->no_finish_dynamic_symbol
= 1;
3220 relative_reloc
= true;
3225 unresolved_reloc
= false;
3229 if (local_got_offsets
== NULL
)
3232 off
= local_got_offsets
[r_symndx
];
3234 /* The offset must always be a multiple of 8. We use
3235 the least significant bit to record whether we have
3236 already generated the necessary reloc. */
3241 bfd_put_64 (output_bfd
, relocation
,
3242 base_got
->contents
+ off
);
3243 local_got_offsets
[r_symndx
] |= 1;
3245 /* NB: GOTPCREL relocations against local absolute
3246 symbol store relocation value in the GOT slot
3247 without relative relocation. Don't generate
3248 relative relocation here if it has been generated
3250 if (!info
->enable_dt_relr
3251 && bfd_link_pic (info
)
3252 && !(sym
->st_shndx
== SHN_ABS
3253 && (r_type
== R_X86_64_GOTPCREL
3254 || r_type
== R_X86_64_GOTPCRELX
3255 || r_type
== R_X86_64_REX_GOTPCRELX
3256 || r_type
== R_X86_64_CODE_4_GOTPCRELX
)))
3257 relative_reloc
= true;
3264 Elf_Internal_Rela outrel
;
3266 /* We need to generate a R_X86_64_RELATIVE reloc
3267 for the dynamic linker. */
3268 s
= htab
->elf
.srelgot
;
3272 outrel
.r_offset
= (base_got
->output_section
->vma
3273 + base_got
->output_offset
3275 outrel
.r_info
= htab
->r_info (0, R_X86_64_RELATIVE
);
3276 outrel
.r_addend
= relocation
;
3278 if (htab
->params
->report_relative_reloc
)
3279 _bfd_x86_elf_link_report_relative_reloc
3280 (info
, input_section
, h
, sym
, "R_X86_64_RELATIVE",
3283 elf_append_rela (output_bfd
, s
, &outrel
);
3286 if (off
>= (bfd_vma
) -2)
3289 relocation
= base_got
->output_section
->vma
3290 + base_got
->output_offset
+ off
;
3291 if (r_type
!= R_X86_64_GOTPCREL
3292 && r_type
!= R_X86_64_GOTPCRELX
3293 && r_type
!= R_X86_64_REX_GOTPCRELX
3294 && r_type
!= R_X86_64_CODE_4_GOTPCRELX
3295 && r_type
!= R_X86_64_GOTPCREL64
)
3296 relocation
-= htab
->elf
.sgotplt
->output_section
->vma
3297 - htab
->elf
.sgotplt
->output_offset
;
3301 case R_X86_64_GOTOFF64
:
3302 /* Relocation is relative to the start of the global offset
3305 /* Check to make sure it isn't a protected function or data
3306 symbol for shared library since it may not be local when
3307 used as function address or with copy relocation. We also
3308 need to make sure that a symbol is referenced locally. */
3309 if (bfd_link_pic (info
) && h
)
3311 if (!h
->def_regular
)
3315 switch (ELF_ST_VISIBILITY (h
->other
))
3318 v
= _("hidden symbol");
3321 v
= _("internal symbol");
3324 v
= _("protected symbol");
3332 /* xgettext:c-format */
3333 (_("%pB: relocation R_X86_64_GOTOFF64 against undefined %s"
3334 " `%s' can not be used when making a shared object"),
3335 input_bfd
, v
, h
->root
.root
.string
);
3336 bfd_set_error (bfd_error_bad_value
);
3339 else if (!bfd_link_executable (info
)
3340 && !SYMBOL_REFERENCES_LOCAL_P (info
, h
)
3341 && (h
->type
== STT_FUNC
3342 || h
->type
== STT_OBJECT
)
3343 && ELF_ST_VISIBILITY (h
->other
) == STV_PROTECTED
)
3346 /* xgettext:c-format */
3347 (_("%pB: relocation R_X86_64_GOTOFF64 against protected %s"
3348 " `%s' can not be used when making a shared object"),
3350 h
->type
== STT_FUNC
? "function" : "data",
3351 h
->root
.root
.string
);
3352 bfd_set_error (bfd_error_bad_value
);
3357 /* Note that sgot is not involved in this
3358 calculation. We always want the start of .got.plt. If we
3359 defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
3360 permitted by the ABI, we might have to change this
3362 relocation
-= htab
->elf
.sgotplt
->output_section
->vma
3363 + htab
->elf
.sgotplt
->output_offset
;
3366 case R_X86_64_GOTPC32
:
3367 case R_X86_64_GOTPC64
:
3368 /* Use global offset table as symbol value. */
3369 relocation
= htab
->elf
.sgotplt
->output_section
->vma
3370 + htab
->elf
.sgotplt
->output_offset
;
3371 unresolved_reloc
= false;
3374 case R_X86_64_PLTOFF64
:
3375 /* Relocation is PLT entry relative to GOT. For local
3376 symbols it's the symbol itself relative to GOT. */
3378 /* See PLT32 handling. */
3379 && (h
->plt
.offset
!= (bfd_vma
) -1
3380 || eh
->plt_got
.offset
!= (bfd_vma
) -1)
3381 && htab
->elf
.splt
!= NULL
)
3383 if (eh
->plt_got
.offset
!= (bfd_vma
) -1)
3385 /* Use the GOT PLT. */
3386 resolved_plt
= htab
->plt_got
;
3387 plt_offset
= eh
->plt_got
.offset
;
3389 else if (htab
->plt_second
!= NULL
)
3391 resolved_plt
= htab
->plt_second
;
3392 plt_offset
= eh
->plt_second
.offset
;
3396 resolved_plt
= htab
->elf
.splt
;
3397 plt_offset
= h
->plt
.offset
;
3400 relocation
= (resolved_plt
->output_section
->vma
3401 + resolved_plt
->output_offset
3403 unresolved_reloc
= false;
3406 relocation
-= htab
->elf
.sgotplt
->output_section
->vma
3407 + htab
->elf
.sgotplt
->output_offset
;
3410 case R_X86_64_PLT32
:
3411 /* Relocation is to the entry for this symbol in the
3412 procedure linkage table. */
3414 /* Resolve a PLT32 reloc against a local symbol directly,
3415 without using the procedure linkage table. */
3419 if ((h
->plt
.offset
== (bfd_vma
) -1
3420 && eh
->plt_got
.offset
== (bfd_vma
) -1)
3421 || htab
->elf
.splt
== NULL
)
3423 /* We didn't make a PLT entry for this symbol. This
3424 happens when statically linking PIC code, or when
3425 using -Bsymbolic. */
3430 if (h
->plt
.offset
!= (bfd_vma
) -1)
3432 if (htab
->plt_second
!= NULL
)
3434 resolved_plt
= htab
->plt_second
;
3435 plt_offset
= eh
->plt_second
.offset
;
3439 resolved_plt
= htab
->elf
.splt
;
3440 plt_offset
= h
->plt
.offset
;
3445 /* Use the GOT PLT. */
3446 resolved_plt
= htab
->plt_got
;
3447 plt_offset
= eh
->plt_got
.offset
;
3450 relocation
= (resolved_plt
->output_section
->vma
3451 + resolved_plt
->output_offset
3453 unresolved_reloc
= false;
3456 case R_X86_64_SIZE32
:
3457 case R_X86_64_SIZE64
:
3458 /* Set to symbol size. */
3459 relocation
= st_size
;
3465 /* Don't complain about -fPIC if the symbol is undefined when
3466 building executable unless it is unresolved weak symbol,
3467 references a dynamic definition in PIE or -z nocopyreloc
3470 = (info
->nocopyreloc
3472 && !h
->root
.linker_def
3473 && !h
->root
.ldscript_def
3474 && eh
->def_protected
));
3476 if ((input_section
->flags
& SEC_ALLOC
) != 0
3477 && (input_section
->flags
& SEC_READONLY
) != 0
3479 && ((bfd_link_executable (info
)
3480 && ((h
->root
.type
== bfd_link_hash_undefweak
3482 || !UNDEFINED_WEAK_RESOLVED_TO_ZERO (info
,
3484 || (bfd_link_pie (info
)
3485 && !SYMBOL_DEFINED_NON_SHARED_P (h
)
3489 && !(h
->root
.u
.def
.section
->flags
& SEC_CODE
))))
3490 || (bfd_link_pie (info
)
3491 && h
->root
.type
== bfd_link_hash_undefweak
)
3492 || bfd_link_dll (info
)))
3495 if (SYMBOL_REFERENCES_LOCAL_P (info
, h
))
3497 /* Symbol is referenced locally. Make sure it is
3499 fail
= !SYMBOL_DEFINED_NON_SHARED_P (h
);
3501 else if (bfd_link_pie (info
))
3503 /* We can only use PC-relative relocations in PIE
3504 from non-code sections. */
3505 if (h
->root
.type
== bfd_link_hash_undefweak
3506 || (h
->type
== STT_FUNC
3507 && (sec
->flags
& SEC_CODE
) != 0))
3510 else if (no_copyreloc_p
|| bfd_link_dll (info
))
3512 /* Symbol doesn't need copy reloc and isn't
3513 referenced locally. Don't allow PC-relative
3514 relocations against default and protected
3515 symbols since address of protected function
3516 and location of protected data may not be in
3517 the shared object. */
3518 fail
= (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
3519 || ELF_ST_VISIBILITY (h
->other
) == STV_PROTECTED
);
3523 return elf_x86_64_need_pic (info
, input_bfd
, input_section
,
3524 h
, NULL
, NULL
, howto
);
3526 /* Since x86-64 has PC-relative PLT, we can use PLT in PIE
3527 as function address. */
3529 && (input_section
->flags
& SEC_CODE
) == 0
3530 && bfd_link_pie (info
)
3531 && h
->type
== STT_FUNC
3542 /* FIXME: The ABI says the linker should make sure the value is
3543 the same when it's zeroextended to 64 bit. */
3546 if ((input_section
->flags
& SEC_ALLOC
) == 0)
3549 need_copy_reloc_in_pie
= (bfd_link_pie (info
)
3554 == bfd_link_hash_undefined
))
3555 && (X86_PCREL_TYPE_P (true, r_type
)
3556 || X86_SIZE_TYPE_P (true,
3559 if (GENERATE_DYNAMIC_RELOCATION_P (true, info
, eh
, r_type
, sec
,
3560 need_copy_reloc_in_pie
,
3561 resolved_to_zero
, false))
3563 Elf_Internal_Rela outrel
;
3564 bool skip
, relocate
;
3565 bool generate_dynamic_reloc
= true;
3567 const char *relative_reloc_name
= NULL
;
3569 /* When generating a shared object, these relocations
3570 are copied into the output file to be resolved at run
3576 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
3578 if (outrel
.r_offset
== (bfd_vma
) -1)
3580 else if (outrel
.r_offset
== (bfd_vma
) -2)
3581 skip
= true, relocate
= true;
3583 outrel
.r_offset
+= (input_section
->output_section
->vma
3584 + input_section
->output_offset
);
3587 memset (&outrel
, 0, sizeof outrel
);
3589 else if (COPY_INPUT_RELOC_P (true, info
, h
, r_type
))
3591 outrel
.r_info
= htab
->r_info (h
->dynindx
, r_type
);
3592 outrel
.r_addend
= rel
->r_addend
;
3596 /* This symbol is local, or marked to become local.
3597 When relocation overflow check is disabled, we
3598 convert R_X86_64_32 to dynamic R_X86_64_RELATIVE. */
3599 if (r_type
== htab
->pointer_r_type
3600 || (r_type
== R_X86_64_32
3601 && htab
->params
->no_reloc_overflow_check
))
3604 /* NB: Don't generate relative relocation here if
3605 it has been generated by DT_RELR. */
3606 if (info
->enable_dt_relr
)
3607 generate_dynamic_reloc
= false;
3611 htab
->r_info (0, R_X86_64_RELATIVE
);
3612 outrel
.r_addend
= relocation
+ rel
->r_addend
;
3613 relative_reloc_name
= "R_X86_64_RELATIVE";
3616 else if (r_type
== R_X86_64_64
3617 && !ABI_64_P (output_bfd
))
3620 outrel
.r_info
= htab
->r_info (0,
3621 R_X86_64_RELATIVE64
);
3622 outrel
.r_addend
= relocation
+ rel
->r_addend
;
3623 relative_reloc_name
= "R_X86_64_RELATIVE64";
3624 /* Check addend overflow. */
3625 if ((outrel
.r_addend
& 0x80000000)
3626 != (rel
->r_addend
& 0x80000000))
3629 int addend
= rel
->r_addend
;
3630 if (h
&& h
->root
.root
.string
)
3631 name
= h
->root
.root
.string
;
3633 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
3636 /* xgettext:c-format */
3637 (_("%pB: addend %s%#x in relocation %s against "
3638 "symbol `%s' at %#" PRIx64
3639 " in section `%pA' is out of range"),
3640 input_bfd
, addend
< 0 ? "-" : "", addend
,
3641 howto
->name
, name
, (uint64_t) rel
->r_offset
,
3643 bfd_set_error (bfd_error_bad_value
);
3651 if (bfd_is_abs_section (sec
))
3653 else if (sec
== NULL
|| sec
->owner
== NULL
)
3655 bfd_set_error (bfd_error_bad_value
);
3662 /* We are turning this relocation into one
3663 against a section symbol. It would be
3664 proper to subtract the symbol's value,
3665 osec->vma, from the emitted reloc addend,
3666 but ld.so expects buggy relocs. */
3667 osec
= sec
->output_section
;
3668 sindx
= elf_section_data (osec
)->dynindx
;
3671 asection
*oi
= htab
->elf
.text_index_section
;
3672 sindx
= elf_section_data (oi
)->dynindx
;
3674 BFD_ASSERT (sindx
!= 0);
3677 outrel
.r_info
= htab
->r_info (sindx
, r_type
);
3678 outrel
.r_addend
= relocation
+ rel
->r_addend
;
3682 if (generate_dynamic_reloc
)
3684 sreloc
= elf_section_data (input_section
)->sreloc
;
3686 if (sreloc
== NULL
|| sreloc
->contents
== NULL
)
3688 r
= bfd_reloc_notsupported
;
3689 goto check_relocation_error
;
3692 if (relative_reloc_name
3693 && htab
->params
->report_relative_reloc
)
3694 _bfd_x86_elf_link_report_relative_reloc
3695 (info
, input_section
, h
, sym
,
3696 relative_reloc_name
, &outrel
);
3698 elf_append_rela (output_bfd
, sreloc
, &outrel
);
3701 /* If this reloc is against an external symbol, we do
3702 not want to fiddle with the addend. Otherwise, we
3703 need to include the symbol value so that it becomes
3704 an addend for the dynamic reloc. */
3711 case R_X86_64_TLSGD
:
3712 case R_X86_64_GOTPC32_TLSDESC
:
3713 case R_X86_64_CODE_4_GOTPC32_TLSDESC
:
3714 case R_X86_64_TLSDESC_CALL
:
3715 case R_X86_64_GOTTPOFF
:
3716 case R_X86_64_CODE_4_GOTTPOFF
:
3717 case R_X86_64_CODE_6_GOTTPOFF
:
3718 tls_type
= GOT_UNKNOWN
;
3719 if (h
== NULL
&& local_got_offsets
)
3720 tls_type
= elf_x86_local_got_tls_type (input_bfd
) [r_symndx
];
3722 tls_type
= elf_x86_hash_entry (h
)->tls_type
;
3724 r_type_tls
= r_type
;
3725 if (! elf_x86_64_tls_transition (info
, input_bfd
,
3726 input_section
, contents
,
3727 symtab_hdr
, sym_hashes
,
3728 &r_type_tls
, tls_type
, rel
,
3729 relend
, h
, sym
, true))
3732 if (r_type_tls
== R_X86_64_TPOFF32
)
3734 bfd_vma roff
= rel
->r_offset
;
3736 if (roff
>= input_section
->size
)
3739 BFD_ASSERT (! unresolved_reloc
);
3741 if (r_type
== R_X86_64_TLSGD
)
3743 /* GD->LE transition. For 64bit, change
3744 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3745 .word 0x6666; rex64; call __tls_get_addr@PLT
3747 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3749 call *__tls_get_addr@GOTPCREL(%rip)
3750 which may be converted to
3751 addr32 call __tls_get_addr
3754 leaq foo@tpoff(%rax), %rax
3756 leaq foo@tlsgd(%rip), %rdi
3757 .word 0x6666; rex64; call __tls_get_addr@PLT
3759 leaq foo@tlsgd(%rip), %rdi
3761 call *__tls_get_addr@GOTPCREL(%rip)
3762 which may be converted to
3763 addr32 call __tls_get_addr
3766 leaq foo@tpoff(%rax), %rax
3767 For largepic, change:
3768 leaq foo@tlsgd(%rip), %rdi
3769 movabsq $__tls_get_addr@pltoff, %rax
3774 leaq foo@tpoff(%rax), %rax
3775 nopw 0x0(%rax,%rax,1) */
3777 if (ABI_64_P (output_bfd
))
3779 if (roff
+ 5 >= input_section
->size
)
3781 if (contents
[roff
+ 5] == 0xb8)
3784 || (roff
- 3 + 22) > input_section
->size
)
3787 info
->callbacks
->einfo
3788 (_("%F%P: corrupt input: %pB\n"),
3792 memcpy (contents
+ roff
- 3,
3793 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80"
3794 "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
3800 || (roff
- 4 + 16) > input_section
->size
)
3802 memcpy (contents
+ roff
- 4,
3803 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
3810 || (roff
- 3 + 15) > input_section
->size
)
3812 memcpy (contents
+ roff
- 3,
3813 "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
3817 if (roff
+ 8 + largepic
>= input_section
->size
)
3820 bfd_put_32 (output_bfd
,
3821 elf_x86_64_tpoff (info
, relocation
),
3822 contents
+ roff
+ 8 + largepic
);
3823 /* Skip R_X86_64_PC32, R_X86_64_PLT32,
3824 R_X86_64_GOTPCRELX and R_X86_64_PLTOFF64. */
3829 else if (r_type
== R_X86_64_GOTPC32_TLSDESC
)
3831 /* GDesc -> LE transition.
3832 It's originally something like:
3833 leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
3834 rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
3837 movq $x@tpoff, %rax <--- LP64 mode.
3838 rex movl $x@tpoff, %eax <--- X32 mode.
3841 unsigned int val
, type
;
3845 type
= bfd_get_8 (input_bfd
, contents
+ roff
- 3);
3846 val
= bfd_get_8 (input_bfd
, contents
+ roff
- 1);
3847 bfd_put_8 (output_bfd
,
3848 (type
& 0x48) | ((type
>> 2) & 1),
3849 contents
+ roff
- 3);
3850 bfd_put_8 (output_bfd
, 0xc7, contents
+ roff
- 2);
3851 bfd_put_8 (output_bfd
, 0xc0 | ((val
>> 3) & 7),
3852 contents
+ roff
- 1);
3853 bfd_put_32 (output_bfd
,
3854 elf_x86_64_tpoff (info
, relocation
),
3858 else if (r_type
== R_X86_64_CODE_4_GOTPC32_TLSDESC
)
3860 /* GDesc -> LE transition.
3861 It's originally something like:
3862 lea x@tlsdesc(%rip), %reg
3866 where reg is one of r16 to r31. */
3868 unsigned int val
, rex2
;
3869 unsigned int rex2_mask
= REX_R
| REX_R
<< 4;
3873 rex2
= bfd_get_8 (input_bfd
, contents
+ roff
- 3);
3874 val
= bfd_get_8 (input_bfd
, contents
+ roff
- 1);
3875 /* Move the R bits to the B bits in REX2 payload
3877 bfd_put_8 (output_bfd
,
3878 ((rex2
& ~rex2_mask
)
3879 | (rex2
& rex2_mask
) >> 2),
3880 contents
+ roff
- 3);
3881 bfd_put_8 (output_bfd
, 0xc7, contents
+ roff
- 2);
3882 bfd_put_8 (output_bfd
, 0xc0 | ((val
>> 3) & 7),
3883 contents
+ roff
- 1);
3884 bfd_put_32 (output_bfd
,
3885 elf_x86_64_tpoff (info
, relocation
),
3889 else if (r_type
== R_X86_64_TLSDESC_CALL
)
3891 /* GDesc -> LE transition.
3893 call *(%rax) <--- LP64 mode.
3894 call *(%eax) <--- X32 mode.
3896 xchg %ax,%ax <-- LP64 mode.
3897 nopl (%rax) <-- X32 mode.
3899 unsigned int prefix
= 0;
3900 if (!ABI_64_P (input_bfd
))
3902 /* Check for call *x@tlscall(%eax). */
3903 if (contents
[roff
] == 0x67)
3908 if (roff
+ 2 >= input_section
->size
)
3911 bfd_put_8 (output_bfd
, 0x0f, contents
+ roff
);
3912 bfd_put_8 (output_bfd
, 0x1f, contents
+ roff
+ 1);
3913 bfd_put_8 (output_bfd
, 0x00, contents
+ roff
+ 2);
3917 if (roff
+ 1 >= input_section
->size
)
3920 bfd_put_8 (output_bfd
, 0x66, contents
+ roff
);
3921 bfd_put_8 (output_bfd
, 0x90, contents
+ roff
+ 1);
3925 else if (r_type
== R_X86_64_GOTTPOFF
)
3927 /* IE->LE transition:
3928 For 64bit, originally it can be one of:
3929 movq foo@gottpoff(%rip), %reg
3930 addq foo@gottpoff(%rip), %reg
3933 leaq foo(%reg), %reg
3935 For 32bit, originally it can be one of:
3936 movq foo@gottpoff(%rip), %reg
3937 addl foo@gottpoff(%rip), %reg
3940 leal foo(%reg), %reg
3943 unsigned int val
, type
, reg
;
3946 val
= bfd_get_8 (input_bfd
, contents
+ roff
- 3);
3953 type
= bfd_get_8 (input_bfd
, contents
+ roff
- 2);
3954 reg
= bfd_get_8 (input_bfd
, contents
+ roff
- 1);
3963 bfd_put_8 (output_bfd
, 0x49,
3964 contents
+ roff
- 3);
3966 else if (!ABI_64_P (output_bfd
) && val
== 0x44)
3970 bfd_put_8 (output_bfd
, 0x41,
3971 contents
+ roff
- 3);
3973 bfd_put_8 (output_bfd
, 0xc7,
3974 contents
+ roff
- 2);
3975 bfd_put_8 (output_bfd
, 0xc0 | reg
,
3976 contents
+ roff
- 1);
3980 /* addq/addl -> addq/addl - addressing with %rsp/%r12
3986 bfd_put_8 (output_bfd
, 0x49,
3987 contents
+ roff
- 3);
3989 else if (!ABI_64_P (output_bfd
) && val
== 0x44)
3993 bfd_put_8 (output_bfd
, 0x41,
3994 contents
+ roff
- 3);
3996 bfd_put_8 (output_bfd
, 0x81,
3997 contents
+ roff
- 2);
3998 bfd_put_8 (output_bfd
, 0xc0 | reg
,
3999 contents
+ roff
- 1);
4003 /* addq/addl -> leaq/leal */
4008 bfd_put_8 (output_bfd
, 0x4d,
4009 contents
+ roff
- 3);
4011 else if (!ABI_64_P (output_bfd
) && val
== 0x44)
4015 bfd_put_8 (output_bfd
, 0x45,
4016 contents
+ roff
- 3);
4018 bfd_put_8 (output_bfd
, 0x8d,
4019 contents
+ roff
- 2);
4020 bfd_put_8 (output_bfd
, 0x80 | reg
| (reg
<< 3),
4021 contents
+ roff
- 1);
4023 bfd_put_32 (output_bfd
,
4024 elf_x86_64_tpoff (info
, relocation
),
4028 else if (r_type
== R_X86_64_CODE_4_GOTTPOFF
)
4030 /* IE->LE transition:
4031 Originally it can be one of:
4032 mov foo@gottpoff(%rip), %reg
4033 add foo@gottpoff(%rip), %reg
4035 mov $foo@tpoff, %reg
4036 add $foo@tpoff, %reg
4037 where reg is one of r16 to r31. */
4039 unsigned int rex2
, type
, reg
;
4040 unsigned int rex2_mask
= REX_R
| REX_R
<< 4;
4045 rex2
= bfd_get_8 (input_bfd
, contents
+ roff
- 3);
4046 type
= bfd_get_8 (input_bfd
, contents
+ roff
- 2);
4047 reg
= bfd_get_8 (input_bfd
, contents
+ roff
- 1);
4049 /* Move the R bits to the B bits in REX2 payload
4055 bfd_put_8 (output_bfd
,
4056 ((rex2
& ~rex2_mask
)
4057 | (rex2
& rex2_mask
) >> 2),
4058 contents
+ roff
- 3);
4059 bfd_put_8 (output_bfd
, type
,
4060 contents
+ roff
- 2);
4061 bfd_put_8 (output_bfd
, 0xc0 | reg
,
4062 contents
+ roff
- 1);
4063 bfd_put_32 (output_bfd
,
4064 elf_x86_64_tpoff (info
, relocation
),
4068 else if (r_type
== R_X86_64_CODE_6_GOTTPOFF
)
4070 /* IE->LE transition:
4072 add %reg1, foo@gottpoff(%rip), %reg2
4074 add foo@gottpoff(%rip), %reg1, %reg2
4076 add $foo@tpoff, %reg1, %reg2
4078 unsigned int reg
, byte1
;
4079 unsigned int updated_byte1
;
4084 /* Move the R bits to the B bits in EVEX payload
4086 byte1
= bfd_get_8 (input_bfd
, contents
+ roff
- 5);
4087 updated_byte1
= byte1
;
4089 /* Set the R bits since they is inverted. */
4090 updated_byte1
|= 1 << 7 | 1 << 4;
4092 /* Update the B bits from the R bits. */
4093 if ((byte1
& (1 << 7)) == 0)
4094 updated_byte1
&= ~(1 << 5);
4095 if ((byte1
& (1 << 4)) == 0)
4096 updated_byte1
|= 1 << 3;
4098 reg
= bfd_get_8 (input_bfd
, contents
+ roff
- 1);
4101 bfd_put_8 (output_bfd
, updated_byte1
,
4102 contents
+ roff
- 5);
4103 bfd_put_8 (output_bfd
, 0x81,
4104 contents
+ roff
- 2);
4105 bfd_put_8 (output_bfd
, 0xc0 | reg
,
4106 contents
+ roff
- 1);
4107 bfd_put_32 (output_bfd
,
4108 elf_x86_64_tpoff (info
, relocation
),
4116 if (htab
->elf
.sgot
== NULL
)
4121 off
= h
->got
.offset
;
4122 offplt
= elf_x86_hash_entry (h
)->tlsdesc_got
;
4126 if (local_got_offsets
== NULL
)
4129 off
= local_got_offsets
[r_symndx
];
4130 offplt
= local_tlsdesc_gotents
[r_symndx
];
4137 Elf_Internal_Rela outrel
;
4141 if (htab
->elf
.srelgot
== NULL
)
4144 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
4146 if (GOT_TLS_GDESC_P (tls_type
))
4148 outrel
.r_info
= htab
->r_info (indx
, R_X86_64_TLSDESC
);
4149 BFD_ASSERT (htab
->sgotplt_jump_table_size
+ offplt
4150 + 2 * GOT_ENTRY_SIZE
<= htab
->elf
.sgotplt
->size
);
4151 outrel
.r_offset
= (htab
->elf
.sgotplt
->output_section
->vma
4152 + htab
->elf
.sgotplt
->output_offset
4154 + htab
->sgotplt_jump_table_size
);
4155 sreloc
= htab
->elf
.srelplt
;
4157 outrel
.r_addend
= relocation
- _bfd_x86_elf_dtpoff_base (info
);
4159 outrel
.r_addend
= 0;
4160 elf_append_rela (output_bfd
, sreloc
, &outrel
);
4163 sreloc
= htab
->elf
.srelgot
;
4165 outrel
.r_offset
= (htab
->elf
.sgot
->output_section
->vma
4166 + htab
->elf
.sgot
->output_offset
+ off
);
4168 if (GOT_TLS_GD_P (tls_type
))
4169 dr_type
= R_X86_64_DTPMOD64
;
4170 else if (GOT_TLS_GDESC_P (tls_type
))
4173 dr_type
= R_X86_64_TPOFF64
;
4175 bfd_put_64 (output_bfd
, 0, htab
->elf
.sgot
->contents
+ off
);
4176 outrel
.r_addend
= 0;
4177 if ((dr_type
== R_X86_64_TPOFF64
4178 || dr_type
== R_X86_64_TLSDESC
) && indx
== 0)
4179 outrel
.r_addend
= relocation
- _bfd_x86_elf_dtpoff_base (info
);
4180 outrel
.r_info
= htab
->r_info (indx
, dr_type
);
4182 elf_append_rela (output_bfd
, sreloc
, &outrel
);
4184 if (GOT_TLS_GD_P (tls_type
))
4188 BFD_ASSERT (! unresolved_reloc
);
4189 bfd_put_64 (output_bfd
,
4190 relocation
- _bfd_x86_elf_dtpoff_base (info
),
4191 htab
->elf
.sgot
->contents
+ off
+ GOT_ENTRY_SIZE
);
4195 bfd_put_64 (output_bfd
, 0,
4196 htab
->elf
.sgot
->contents
+ off
+ GOT_ENTRY_SIZE
);
4197 outrel
.r_info
= htab
->r_info (indx
,
4199 outrel
.r_offset
+= GOT_ENTRY_SIZE
;
4200 elf_append_rela (output_bfd
, sreloc
,
4209 local_got_offsets
[r_symndx
] |= 1;
4212 if (off
>= (bfd_vma
) -2
4213 && ! GOT_TLS_GDESC_P (tls_type
))
4215 if (r_type_tls
== r_type
)
4217 if (r_type
== R_X86_64_GOTPC32_TLSDESC
4218 || r_type
== R_X86_64_CODE_4_GOTPC32_TLSDESC
4219 || r_type
== R_X86_64_TLSDESC_CALL
)
4220 relocation
= htab
->elf
.sgotplt
->output_section
->vma
4221 + htab
->elf
.sgotplt
->output_offset
4222 + offplt
+ htab
->sgotplt_jump_table_size
;
4224 relocation
= htab
->elf
.sgot
->output_section
->vma
4225 + htab
->elf
.sgot
->output_offset
+ off
;
4226 unresolved_reloc
= false;
4230 bfd_vma roff
= rel
->r_offset
;
4232 if (r_type
== R_X86_64_TLSGD
)
4234 /* GD->IE transition. For 64bit, change
4235 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
4236 .word 0x6666; rex64; call __tls_get_addr@PLT
4238 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
4240 call *__tls_get_addr@GOTPCREL(%rip
4241 which may be converted to
4242 addr32 call __tls_get_addr
4245 addq foo@gottpoff(%rip), %rax
4247 leaq foo@tlsgd(%rip), %rdi
4248 .word 0x6666; rex64; call __tls_get_addr@PLT
4250 leaq foo@tlsgd(%rip), %rdi
4252 call *__tls_get_addr@GOTPCREL(%rip)
4253 which may be converted to
4254 addr32 call __tls_get_addr
4257 addq foo@gottpoff(%rip), %rax
4258 For largepic, change:
4259 leaq foo@tlsgd(%rip), %rdi
4260 movabsq $__tls_get_addr@pltoff, %rax
4265 addq foo@gottpoff(%rax), %rax
4266 nopw 0x0(%rax,%rax,1) */
4268 if (ABI_64_P (output_bfd
))
4270 if (contents
[roff
+ 5] == 0xb8)
4273 || (roff
- 3 + 22) > input_section
->size
)
4275 memcpy (contents
+ roff
- 3,
4276 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05"
4277 "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
4283 || (roff
- 4 + 16) > input_section
->size
)
4285 memcpy (contents
+ roff
- 4,
4286 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
4293 || (roff
- 3 + 15) > input_section
->size
)
4295 memcpy (contents
+ roff
- 3,
4296 "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
4300 relocation
= (htab
->elf
.sgot
->output_section
->vma
4301 + htab
->elf
.sgot
->output_offset
+ off
4304 - input_section
->output_section
->vma
4305 - input_section
->output_offset
4307 bfd_put_32 (output_bfd
, relocation
,
4308 contents
+ roff
+ 8 + largepic
);
4309 /* Skip R_X86_64_PLT32/R_X86_64_PLTOFF64. */
4314 else if (r_type
== R_X86_64_GOTPC32_TLSDESC
4315 || r_type
== R_X86_64_CODE_4_GOTPC32_TLSDESC
)
4317 /* GDesc -> IE transition.
4318 It's originally something like:
4319 leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
4320 rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
4323 # before xchg %ax,%ax in LP64 mode.
4324 movq x@gottpoff(%rip), %rax
4325 # before nopl (%rax) in X32 mode.
4326 rex movl x@gottpoff(%rip), %eax
4329 /* Now modify the instruction as appropriate. To
4330 turn a lea into a mov in the form we use it, it
4331 suffices to change the second byte from 0x8d to
4335 bfd_put_8 (output_bfd
, 0x8b, contents
+ roff
- 2);
4337 bfd_put_32 (output_bfd
,
4338 htab
->elf
.sgot
->output_section
->vma
4339 + htab
->elf
.sgot
->output_offset
+ off
4341 - input_section
->output_section
->vma
4342 - input_section
->output_offset
4347 else if (r_type
== R_X86_64_TLSDESC_CALL
)
4349 /* GDesc -> IE transition.
4351 call *(%rax) <--- LP64 mode.
4352 call *(%eax) <--- X32 mode.
4355 xchg %ax, %ax <-- LP64 mode.
4356 nopl (%rax) <-- X32 mode.
4359 unsigned int prefix
= 0;
4360 if (!ABI_64_P (input_bfd
))
4362 /* Check for call *x@tlscall(%eax). */
4363 if (contents
[roff
] == 0x67)
4368 bfd_put_8 (output_bfd
, 0x0f, contents
+ roff
);
4369 bfd_put_8 (output_bfd
, 0x1f, contents
+ roff
+ 1);
4370 bfd_put_8 (output_bfd
, 0x00, contents
+ roff
+ 2);
4374 bfd_put_8 (output_bfd
, 0x66, contents
+ roff
);
4375 bfd_put_8 (output_bfd
, 0x90, contents
+ roff
+ 1);
4384 case R_X86_64_TLSLD
:
4385 if (! elf_x86_64_tls_transition (info
, input_bfd
,
4386 input_section
, contents
,
4387 symtab_hdr
, sym_hashes
,
4388 &r_type
, GOT_UNKNOWN
, rel
,
4389 relend
, h
, sym
, true))
4392 if (r_type
!= R_X86_64_TLSLD
)
4394 /* LD->LE transition:
4395 leaq foo@tlsld(%rip), %rdi
4396 call __tls_get_addr@PLT
4397 For 64bit, we change it into:
4398 .word 0x6666; .byte 0x66; movq %fs:0, %rax
4399 For 32bit, we change it into:
4400 nopl 0x0(%rax); movl %fs:0, %eax
4402 leaq foo@tlsld(%rip), %rdi;
4403 call *__tls_get_addr@GOTPCREL(%rip)
4404 which may be converted to
4405 addr32 call __tls_get_addr
4406 For 64bit, we change it into:
4407 .word 0x6666; .word 0x6666; movq %fs:0, %rax
4408 For 32bit, we change it into:
4409 nopw 0x0(%rax); movl %fs:0, %eax
4410 For largepic, change:
4411 leaq foo@tlsgd(%rip), %rdi
4412 movabsq $__tls_get_addr@pltoff, %rax
4416 data16 data16 data16 nopw %cs:0x0(%rax,%rax,1)
4419 BFD_ASSERT (r_type
== R_X86_64_TPOFF32
);
4420 if (ABI_64_P (output_bfd
))
4422 if ((rel
->r_offset
+ 5) >= input_section
->size
)
4424 if (contents
[rel
->r_offset
+ 5] == 0xb8)
4426 if (rel
->r_offset
< 3
4427 || (rel
->r_offset
- 3 + 22) > input_section
->size
)
4429 memcpy (contents
+ rel
->r_offset
- 3,
4430 "\x66\x66\x66\x66\x2e\x0f\x1f\x84\0\0\0\0\0"
4431 "\x64\x48\x8b\x04\x25\0\0\0", 22);
4433 else if (contents
[rel
->r_offset
+ 4] == 0xff
4434 || contents
[rel
->r_offset
+ 4] == 0x67)
4436 if (rel
->r_offset
< 3
4437 || (rel
->r_offset
- 3 + 13) > input_section
->size
)
4439 memcpy (contents
+ rel
->r_offset
- 3,
4440 "\x66\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0",
4446 if (rel
->r_offset
< 3
4447 || (rel
->r_offset
- 3 + 12) > input_section
->size
)
4449 memcpy (contents
+ rel
->r_offset
- 3,
4450 "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
4455 if ((rel
->r_offset
+ 4) >= input_section
->size
)
4457 if (contents
[rel
->r_offset
+ 4] == 0xff)
4459 if (rel
->r_offset
< 3
4460 || (rel
->r_offset
- 3 + 13) > input_section
->size
)
4462 memcpy (contents
+ rel
->r_offset
- 3,
4463 "\x66\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0",
4468 if (rel
->r_offset
< 3
4469 || (rel
->r_offset
- 3 + 12) > input_section
->size
)
4471 memcpy (contents
+ rel
->r_offset
- 3,
4472 "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
4475 /* Skip R_X86_64_PC32, R_X86_64_PLT32, R_X86_64_GOTPCRELX
4476 and R_X86_64_PLTOFF64. */
4482 if (htab
->elf
.sgot
== NULL
)
4485 off
= htab
->tls_ld_or_ldm_got
.offset
;
4490 Elf_Internal_Rela outrel
;
4492 if (htab
->elf
.srelgot
== NULL
)
4495 outrel
.r_offset
= (htab
->elf
.sgot
->output_section
->vma
4496 + htab
->elf
.sgot
->output_offset
+ off
);
4498 bfd_put_64 (output_bfd
, 0,
4499 htab
->elf
.sgot
->contents
+ off
);
4500 bfd_put_64 (output_bfd
, 0,
4501 htab
->elf
.sgot
->contents
+ off
+ GOT_ENTRY_SIZE
);
4502 outrel
.r_info
= htab
->r_info (0, R_X86_64_DTPMOD64
);
4503 outrel
.r_addend
= 0;
4504 elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
4506 htab
->tls_ld_or_ldm_got
.offset
|= 1;
4508 relocation
= htab
->elf
.sgot
->output_section
->vma
4509 + htab
->elf
.sgot
->output_offset
+ off
;
4510 unresolved_reloc
= false;
4513 case R_X86_64_DTPOFF32
:
4514 if (!bfd_link_executable (info
)
4515 || (input_section
->flags
& SEC_CODE
) == 0)
4516 relocation
-= _bfd_x86_elf_dtpoff_base (info
);
4518 relocation
= elf_x86_64_tpoff (info
, relocation
);
4521 case R_X86_64_TPOFF32
:
4522 case R_X86_64_TPOFF64
:
4523 BFD_ASSERT (bfd_link_executable (info
));
4524 relocation
= elf_x86_64_tpoff (info
, relocation
);
4527 case R_X86_64_DTPOFF64
:
4528 BFD_ASSERT ((input_section
->flags
& SEC_CODE
) == 0);
4529 relocation
-= _bfd_x86_elf_dtpoff_base (info
);
4536 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
4537 because such sections are not SEC_ALLOC and thus ld.so will
4538 not process them. */
4539 if (unresolved_reloc
4540 && !((input_section
->flags
& SEC_DEBUGGING
) != 0
4542 && _bfd_elf_section_offset (output_bfd
, info
, input_section
,
4543 rel
->r_offset
) != (bfd_vma
) -1)
4548 sec
= h
->root
.u
.def
.section
;
4549 if ((info
->nocopyreloc
|| eh
->def_protected
)
4550 && !(h
->root
.u
.def
.section
->flags
& SEC_CODE
))
4551 return elf_x86_64_need_pic (info
, input_bfd
, input_section
,
4552 h
, NULL
, NULL
, howto
);
4557 /* xgettext:c-format */
4558 (_("%pB(%pA+%#" PRIx64
"): "
4559 "unresolvable %s relocation against symbol `%s'"),
4562 (uint64_t) rel
->r_offset
,
4564 h
->root
.root
.string
);
4570 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
4571 contents
, rel
->r_offset
,
4572 relocation
, rel
->r_addend
);
4574 check_relocation_error
:
4575 if (r
!= bfd_reloc_ok
)
4580 name
= h
->root
.root
.string
;
4583 name
= bfd_elf_string_from_elf_section (input_bfd
,
4584 symtab_hdr
->sh_link
,
4589 name
= bfd_section_name (sec
);
4592 if (r
== bfd_reloc_overflow
)
4594 if (converted_reloc
)
4596 info
->callbacks
->einfo
4597 ("%X%H:", input_bfd
, input_section
, rel
->r_offset
);
4598 info
->callbacks
->einfo
4599 (_(" failed to convert GOTPCREL relocation against "
4600 "'%s'; relink with --no-relax\n"),
4605 (*info
->callbacks
->reloc_overflow
)
4606 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
,
4607 (bfd_vma
) 0, input_bfd
, input_section
, rel
->r_offset
);
4612 /* xgettext:c-format */
4613 (_("%pB(%pA+%#" PRIx64
"): reloc against `%s': error %d"),
4614 input_bfd
, input_section
,
4615 (uint64_t) rel
->r_offset
, name
, (int) r
);
4626 Elf_Internal_Shdr
*rel_hdr
;
4627 size_t deleted
= rel
- wrel
;
4629 rel_hdr
= _bfd_elf_single_rel_hdr (input_section
->output_section
);
4630 rel_hdr
->sh_size
-= rel_hdr
->sh_entsize
* deleted
;
4631 if (rel_hdr
->sh_size
== 0)
4633 /* It is too late to remove an empty reloc section. Leave
4635 ??? What is wrong with an empty section??? */
4636 rel_hdr
->sh_size
= rel_hdr
->sh_entsize
;
4639 rel_hdr
= _bfd_elf_single_rel_hdr (input_section
);
4640 rel_hdr
->sh_size
-= rel_hdr
->sh_entsize
* deleted
;
4641 input_section
->reloc_count
-= deleted
;
4647 /* Finish up dynamic symbol handling. We set the contents of various
4648 dynamic sections here. */
4651 elf_x86_64_finish_dynamic_symbol (bfd
*output_bfd
,
4652 struct bfd_link_info
*info
,
4653 struct elf_link_hash_entry
*h
,
4654 Elf_Internal_Sym
*sym
)
4656 struct elf_x86_link_hash_table
*htab
;
4657 bool use_plt_second
;
4658 struct elf_x86_link_hash_entry
*eh
;
4659 bool local_undefweak
;
4661 htab
= elf_x86_hash_table (info
, X86_64_ELF_DATA
);
4663 /* Use the second PLT section only if there is .plt section. */
4664 use_plt_second
= htab
->elf
.splt
!= NULL
&& htab
->plt_second
!= NULL
;
4666 eh
= (struct elf_x86_link_hash_entry
*) h
;
4667 if (eh
->no_finish_dynamic_symbol
)
4670 /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for
4671 resolved undefined weak symbols in executable so that their
4672 references have value 0 at run-time. */
4673 local_undefweak
= UNDEFINED_WEAK_RESOLVED_TO_ZERO (info
, eh
);
4675 if (h
->plt
.offset
!= (bfd_vma
) -1)
4678 bfd_vma got_offset
, plt_offset
;
4679 Elf_Internal_Rela rela
;
4681 asection
*plt
, *gotplt
, *relplt
, *resolved_plt
;
4682 const struct elf_backend_data
*bed
;
4683 bfd_vma plt_got_pcrel_offset
;
4685 /* When building a static executable, use .iplt, .igot.plt and
4686 .rela.iplt sections for STT_GNU_IFUNC symbols. */
4687 if (htab
->elf
.splt
!= NULL
)
4689 plt
= htab
->elf
.splt
;
4690 gotplt
= htab
->elf
.sgotplt
;
4691 relplt
= htab
->elf
.srelplt
;
4695 plt
= htab
->elf
.iplt
;
4696 gotplt
= htab
->elf
.igotplt
;
4697 relplt
= htab
->elf
.irelplt
;
4700 VERIFY_PLT_ENTRY (info
, h
, plt
, gotplt
, relplt
, local_undefweak
)
4702 /* Get the index in the procedure linkage table which
4703 corresponds to this symbol. This is the index of this symbol
4704 in all the symbols for which we are making plt entries. The
4705 first entry in the procedure linkage table is reserved.
4707 Get the offset into the .got table of the entry that
4708 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
4709 bytes. The first three are reserved for the dynamic linker.
4711 For static executables, we don't reserve anything. */
4713 if (plt
== htab
->elf
.splt
)
4715 got_offset
= (h
->plt
.offset
/ htab
->plt
.plt_entry_size
4716 - htab
->plt
.has_plt0
);
4717 got_offset
= (got_offset
+ 3) * GOT_ENTRY_SIZE
;
4721 got_offset
= h
->plt
.offset
/ htab
->plt
.plt_entry_size
;
4722 got_offset
= got_offset
* GOT_ENTRY_SIZE
;
4725 /* Fill in the entry in the procedure linkage table. */
4726 memcpy (plt
->contents
+ h
->plt
.offset
, htab
->plt
.plt_entry
,
4727 htab
->plt
.plt_entry_size
);
4730 memcpy (htab
->plt_second
->contents
+ eh
->plt_second
.offset
,
4731 htab
->non_lazy_plt
->plt_entry
,
4732 htab
->non_lazy_plt
->plt_entry_size
);
4734 resolved_plt
= htab
->plt_second
;
4735 plt_offset
= eh
->plt_second
.offset
;
4740 plt_offset
= h
->plt
.offset
;
4743 /* Insert the relocation positions of the plt section. */
4745 /* Put offset the PC-relative instruction referring to the GOT entry,
4746 subtracting the size of that instruction. */
4747 plt_got_pcrel_offset
= (gotplt
->output_section
->vma
4748 + gotplt
->output_offset
4750 - resolved_plt
->output_section
->vma
4751 - resolved_plt
->output_offset
4753 - htab
->plt
.plt_got_insn_size
);
4755 /* Check PC-relative offset overflow in PLT entry. */
4756 if ((plt_got_pcrel_offset
+ 0x80000000) > 0xffffffff)
4757 /* xgettext:c-format */
4758 info
->callbacks
->einfo (_("%F%pB: PC-relative offset overflow in PLT entry for `%s'\n"),
4759 output_bfd
, h
->root
.root
.string
);
4761 bfd_put_32 (output_bfd
, plt_got_pcrel_offset
,
4762 (resolved_plt
->contents
+ plt_offset
4763 + htab
->plt
.plt_got_offset
));
4765 /* Fill in the entry in the global offset table, initially this
4766 points to the second part of the PLT entry. Leave the entry
4767 as zero for undefined weak symbol in PIE. No PLT relocation
4768 against undefined weak symbol in PIE. */
4769 if (!local_undefweak
)
4771 if (htab
->plt
.has_plt0
)
4772 bfd_put_64 (output_bfd
, (plt
->output_section
->vma
4773 + plt
->output_offset
4775 + htab
->lazy_plt
->plt_lazy_offset
),
4776 gotplt
->contents
+ got_offset
);
4778 /* Fill in the entry in the .rela.plt section. */
4779 rela
.r_offset
= (gotplt
->output_section
->vma
4780 + gotplt
->output_offset
4782 if (PLT_LOCAL_IFUNC_P (info
, h
))
4784 info
->callbacks
->minfo (_("Local IFUNC function `%s' in %pB\n"),
4785 h
->root
.root
.string
,
4786 h
->root
.u
.def
.section
->owner
);
4788 /* If an STT_GNU_IFUNC symbol is locally defined, generate
4789 R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT. */
4790 rela
.r_info
= htab
->r_info (0, R_X86_64_IRELATIVE
);
4791 rela
.r_addend
= (h
->root
.u
.def
.value
4792 + h
->root
.u
.def
.section
->output_section
->vma
4793 + h
->root
.u
.def
.section
->output_offset
);
4795 if (htab
->params
->report_relative_reloc
)
4796 _bfd_x86_elf_link_report_relative_reloc
4797 (info
, relplt
, h
, sym
, "R_X86_64_IRELATIVE", &rela
);
4799 /* R_X86_64_IRELATIVE comes last. */
4800 plt_index
= htab
->next_irelative_index
--;
4804 rela
.r_info
= htab
->r_info (h
->dynindx
, R_X86_64_JUMP_SLOT
);
4805 if (htab
->params
->mark_plt
)
4806 rela
.r_addend
= (resolved_plt
->output_section
->vma
4808 + htab
->plt
.plt_indirect_branch_offset
);
4811 plt_index
= htab
->next_jump_slot_index
++;
4814 /* Don't fill the second and third slots in PLT entry for
4815 static executables nor without PLT0. */
4816 if (plt
== htab
->elf
.splt
&& htab
->plt
.has_plt0
)
4819 = h
->plt
.offset
+ htab
->lazy_plt
->plt_plt_insn_end
;
4821 /* Put relocation index. */
4822 bfd_put_32 (output_bfd
, plt_index
,
4823 (plt
->contents
+ h
->plt
.offset
4824 + htab
->lazy_plt
->plt_reloc_offset
));
4826 /* Put offset for jmp .PLT0 and check for overflow. We don't
4827 check relocation index for overflow since branch displacement
4828 will overflow first. */
4829 if (plt0_offset
> 0x80000000)
4830 /* xgettext:c-format */
4831 info
->callbacks
->einfo (_("%F%pB: branch displacement overflow in PLT entry for `%s'\n"),
4832 output_bfd
, h
->root
.root
.string
);
4833 bfd_put_32 (output_bfd
, - plt0_offset
,
4834 (plt
->contents
+ h
->plt
.offset
4835 + htab
->lazy_plt
->plt_plt_offset
));
4838 bed
= get_elf_backend_data (output_bfd
);
4839 loc
= relplt
->contents
+ plt_index
* bed
->s
->sizeof_rela
;
4840 bed
->s
->swap_reloca_out (output_bfd
, &rela
, loc
);
4843 else if (eh
->plt_got
.offset
!= (bfd_vma
) -1)
4845 bfd_vma got_offset
, plt_offset
;
4846 asection
*plt
, *got
;
4848 int32_t got_pcrel_offset
;
4850 /* Set the entry in the GOT procedure linkage table. */
4851 plt
= htab
->plt_got
;
4852 got
= htab
->elf
.sgot
;
4853 got_offset
= h
->got
.offset
;
4855 if (got_offset
== (bfd_vma
) -1
4856 || (h
->type
== STT_GNU_IFUNC
&& h
->def_regular
)
4861 /* Use the non-lazy PLT entry template for the GOT PLT since they
4862 are the identical. */
4863 /* Fill in the entry in the GOT procedure linkage table. */
4864 plt_offset
= eh
->plt_got
.offset
;
4865 memcpy (plt
->contents
+ plt_offset
,
4866 htab
->non_lazy_plt
->plt_entry
,
4867 htab
->non_lazy_plt
->plt_entry_size
);
4869 /* Put offset the PC-relative instruction referring to the GOT
4870 entry, subtracting the size of that instruction. */
4871 got_pcrel_offset
= (got
->output_section
->vma
4872 + got
->output_offset
4874 - plt
->output_section
->vma
4875 - plt
->output_offset
4877 - htab
->non_lazy_plt
->plt_got_insn_size
);
4879 /* Check PC-relative offset overflow in GOT PLT entry. */
4880 got_after_plt
= got
->output_section
->vma
> plt
->output_section
->vma
;
4881 if ((got_after_plt
&& got_pcrel_offset
< 0)
4882 || (!got_after_plt
&& got_pcrel_offset
> 0))
4883 /* xgettext:c-format */
4884 info
->callbacks
->einfo (_("%F%pB: PC-relative offset overflow in GOT PLT entry for `%s'\n"),
4885 output_bfd
, h
->root
.root
.string
);
4887 bfd_put_32 (output_bfd
, got_pcrel_offset
,
4888 (plt
->contents
+ plt_offset
4889 + htab
->non_lazy_plt
->plt_got_offset
));
4892 if (!local_undefweak
4894 && (h
->plt
.offset
!= (bfd_vma
) -1
4895 || eh
->plt_got
.offset
!= (bfd_vma
) -1))
4897 /* Mark the symbol as undefined, rather than as defined in
4898 the .plt section. Leave the value if there were any
4899 relocations where pointer equality matters (this is a clue
4900 for the dynamic linker, to make function pointer
4901 comparisons work between an application and shared
4902 library), otherwise set it to zero. If a function is only
4903 called from a binary, there is no need to slow down
4904 shared libraries because of that. */
4905 sym
->st_shndx
= SHN_UNDEF
;
4906 if (!h
->pointer_equality_needed
)
4910 _bfd_x86_elf_link_fixup_ifunc_symbol (info
, htab
, h
, sym
);
4912 /* Don't generate dynamic GOT relocation against undefined weak
4913 symbol in executable. */
4914 if (h
->got
.offset
!= (bfd_vma
) -1
4915 && ! GOT_TLS_GD_ANY_P (elf_x86_hash_entry (h
)->tls_type
)
4916 && elf_x86_hash_entry (h
)->tls_type
!= GOT_TLS_IE
4917 && !local_undefweak
)
4919 Elf_Internal_Rela rela
;
4920 asection
*relgot
= htab
->elf
.srelgot
;
4921 const char *relative_reloc_name
= NULL
;
4922 bool generate_dynamic_reloc
= true;
4924 /* This symbol has an entry in the global offset table. Set it
4926 if (htab
->elf
.sgot
== NULL
|| htab
->elf
.srelgot
== NULL
)
4929 rela
.r_offset
= (htab
->elf
.sgot
->output_section
->vma
4930 + htab
->elf
.sgot
->output_offset
4931 + (h
->got
.offset
&~ (bfd_vma
) 1));
4933 /* If this is a static link, or it is a -Bsymbolic link and the
4934 symbol is defined locally or was forced to be local because
4935 of a version file, we just want to emit a RELATIVE reloc.
4936 The entry in the global offset table will already have been
4937 initialized in the relocate_section function. */
4939 && h
->type
== STT_GNU_IFUNC
)
4941 if (h
->plt
.offset
== (bfd_vma
) -1)
4943 /* STT_GNU_IFUNC is referenced without PLT. */
4944 if (htab
->elf
.splt
== NULL
)
4946 /* use .rel[a].iplt section to store .got relocations
4947 in static executable. */
4948 relgot
= htab
->elf
.irelplt
;
4950 if (SYMBOL_REFERENCES_LOCAL_P (info
, h
))
4952 info
->callbacks
->minfo (_("Local IFUNC function `%s' in %pB\n"),
4953 h
->root
.root
.string
,
4954 h
->root
.u
.def
.section
->owner
);
4956 rela
.r_info
= htab
->r_info (0,
4957 R_X86_64_IRELATIVE
);
4958 rela
.r_addend
= (h
->root
.u
.def
.value
4959 + h
->root
.u
.def
.section
->output_section
->vma
4960 + h
->root
.u
.def
.section
->output_offset
);
4961 relative_reloc_name
= "R_X86_64_IRELATIVE";
4966 else if (bfd_link_pic (info
))
4968 /* Generate R_X86_64_GLOB_DAT. */
4976 if (!h
->pointer_equality_needed
)
4979 /* For non-shared object, we can't use .got.plt, which
4980 contains the real function addres if we need pointer
4981 equality. We load the GOT entry with the PLT entry. */
4982 if (htab
->plt_second
!= NULL
)
4984 plt
= htab
->plt_second
;
4985 plt_offset
= eh
->plt_second
.offset
;
4989 plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
4990 plt_offset
= h
->plt
.offset
;
4992 bfd_put_64 (output_bfd
, (plt
->output_section
->vma
4993 + plt
->output_offset
4995 htab
->elf
.sgot
->contents
+ h
->got
.offset
);
4999 else if (bfd_link_pic (info
)
5000 && SYMBOL_REFERENCES_LOCAL_P (info
, h
))
5002 if (!SYMBOL_DEFINED_NON_SHARED_P (h
))
5004 BFD_ASSERT((h
->got
.offset
& 1) != 0);
5005 if (info
->enable_dt_relr
)
5006 generate_dynamic_reloc
= false;
5009 rela
.r_info
= htab
->r_info (0, R_X86_64_RELATIVE
);
5010 rela
.r_addend
= (h
->root
.u
.def
.value
5011 + h
->root
.u
.def
.section
->output_section
->vma
5012 + h
->root
.u
.def
.section
->output_offset
);
5013 relative_reloc_name
= "R_X86_64_RELATIVE";
5018 BFD_ASSERT((h
->got
.offset
& 1) == 0);
5020 bfd_put_64 (output_bfd
, (bfd_vma
) 0,
5021 htab
->elf
.sgot
->contents
+ h
->got
.offset
);
5022 rela
.r_info
= htab
->r_info (h
->dynindx
, R_X86_64_GLOB_DAT
);
5026 if (generate_dynamic_reloc
)
5028 if (relative_reloc_name
!= NULL
5029 && htab
->params
->report_relative_reloc
)
5030 _bfd_x86_elf_link_report_relative_reloc
5031 (info
, relgot
, h
, sym
, relative_reloc_name
, &rela
);
5033 elf_append_rela (output_bfd
, relgot
, &rela
);
5039 Elf_Internal_Rela rela
;
5042 /* This symbol needs a copy reloc. Set it up. */
5043 VERIFY_COPY_RELOC (h
, htab
)
5045 rela
.r_offset
= (h
->root
.u
.def
.value
5046 + h
->root
.u
.def
.section
->output_section
->vma
5047 + h
->root
.u
.def
.section
->output_offset
);
5048 rela
.r_info
= htab
->r_info (h
->dynindx
, R_X86_64_COPY
);
5050 if (h
->root
.u
.def
.section
== htab
->elf
.sdynrelro
)
5051 s
= htab
->elf
.sreldynrelro
;
5053 s
= htab
->elf
.srelbss
;
5054 elf_append_rela (output_bfd
, s
, &rela
);
5060 /* Finish up local dynamic symbol handling. We set the contents of
5061 various dynamic sections here. */
5064 elf_x86_64_finish_local_dynamic_symbol (void **slot
, void *inf
)
5066 struct elf_link_hash_entry
*h
5067 = (struct elf_link_hash_entry
*) *slot
;
5068 struct bfd_link_info
*info
5069 = (struct bfd_link_info
*) inf
;
5071 return elf_x86_64_finish_dynamic_symbol (info
->output_bfd
,
5075 /* Finish up undefined weak symbol handling in PIE. Fill its PLT entry
5076 here since undefined weak symbol may not be dynamic and may not be
5077 called for elf_x86_64_finish_dynamic_symbol. */
5080 elf_x86_64_pie_finish_undefweak_symbol (struct bfd_hash_entry
*bh
,
5083 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) bh
;
5084 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
5086 if (h
->root
.type
!= bfd_link_hash_undefweak
5087 || h
->dynindx
!= -1)
5090 return elf_x86_64_finish_dynamic_symbol (info
->output_bfd
,
5094 /* Used to decide how to sort relocs in an optimal manner for the
5095 dynamic linker, before writing them out. */
5097 static enum elf_reloc_type_class
5098 elf_x86_64_reloc_type_class (const struct bfd_link_info
*info
,
5099 const asection
*rel_sec ATTRIBUTE_UNUSED
,
5100 const Elf_Internal_Rela
*rela
)
5102 bfd
*abfd
= info
->output_bfd
;
5103 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
5104 struct elf_x86_link_hash_table
*htab
5105 = elf_x86_hash_table (info
, X86_64_ELF_DATA
);
5107 if (htab
->elf
.dynsym
!= NULL
5108 && htab
->elf
.dynsym
->contents
!= NULL
)
5110 /* Check relocation against STT_GNU_IFUNC symbol if there are
5112 unsigned long r_symndx
= htab
->r_sym (rela
->r_info
);
5113 if (r_symndx
!= STN_UNDEF
)
5115 Elf_Internal_Sym sym
;
5116 if (!bed
->s
->swap_symbol_in (abfd
,
5117 (htab
->elf
.dynsym
->contents
5118 + r_symndx
* bed
->s
->sizeof_sym
),
5122 if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
5123 return reloc_class_ifunc
;
5127 switch ((int) ELF32_R_TYPE (rela
->r_info
))
5129 case R_X86_64_IRELATIVE
:
5130 return reloc_class_ifunc
;
5131 case R_X86_64_RELATIVE
:
5132 case R_X86_64_RELATIVE64
:
5133 return reloc_class_relative
;
5134 case R_X86_64_JUMP_SLOT
:
5135 return reloc_class_plt
;
5137 return reloc_class_copy
;
5139 return reloc_class_normal
;
5143 /* Finish up the dynamic sections. */
5146 elf_x86_64_finish_dynamic_sections (bfd
*output_bfd
,
5147 struct bfd_link_info
*info
)
5149 struct elf_x86_link_hash_table
*htab
;
5151 htab
= _bfd_x86_elf_finish_dynamic_sections (output_bfd
, info
);
5155 if (! htab
->elf
.dynamic_sections_created
)
5158 if (htab
->elf
.splt
&& htab
->elf
.splt
->size
> 0)
5160 if (bfd_is_abs_section (htab
->elf
.splt
->output_section
))
5162 info
->callbacks
->einfo
5163 (_("%F%P: discarded output section: `%pA'\n"),
5168 elf_section_data (htab
->elf
.splt
->output_section
)
5169 ->this_hdr
.sh_entsize
= htab
->plt
.plt_entry_size
;
5171 if (htab
->plt
.has_plt0
)
5173 /* Fill in the special first entry in the procedure linkage
5175 memcpy (htab
->elf
.splt
->contents
,
5176 htab
->lazy_plt
->plt0_entry
,
5177 htab
->lazy_plt
->plt0_entry_size
);
5178 /* Add offset for pushq GOT+8(%rip), since the instruction
5179 uses 6 bytes subtract this value. */
5180 bfd_put_32 (output_bfd
,
5181 (htab
->elf
.sgotplt
->output_section
->vma
5182 + htab
->elf
.sgotplt
->output_offset
5184 - htab
->elf
.splt
->output_section
->vma
5185 - htab
->elf
.splt
->output_offset
5187 (htab
->elf
.splt
->contents
5188 + htab
->lazy_plt
->plt0_got1_offset
));
5189 /* Add offset for the PC-relative instruction accessing
5190 GOT+16, subtracting the offset to the end of that
5192 bfd_put_32 (output_bfd
,
5193 (htab
->elf
.sgotplt
->output_section
->vma
5194 + htab
->elf
.sgotplt
->output_offset
5196 - htab
->elf
.splt
->output_section
->vma
5197 - htab
->elf
.splt
->output_offset
5198 - htab
->lazy_plt
->plt0_got2_insn_end
),
5199 (htab
->elf
.splt
->contents
5200 + htab
->lazy_plt
->plt0_got2_offset
));
5203 if (htab
->elf
.tlsdesc_plt
)
5205 bfd_put_64 (output_bfd
, (bfd_vma
) 0,
5206 htab
->elf
.sgot
->contents
+ htab
->elf
.tlsdesc_got
);
5208 memcpy (htab
->elf
.splt
->contents
+ htab
->elf
.tlsdesc_plt
,
5209 htab
->lazy_plt
->plt_tlsdesc_entry
,
5210 htab
->lazy_plt
->plt_tlsdesc_entry_size
);
5212 /* Add offset for pushq GOT+8(%rip), since ENDBR64 uses 4
5213 bytes and the instruction uses 6 bytes, subtract these
5215 bfd_put_32 (output_bfd
,
5216 (htab
->elf
.sgotplt
->output_section
->vma
5217 + htab
->elf
.sgotplt
->output_offset
5219 - htab
->elf
.splt
->output_section
->vma
5220 - htab
->elf
.splt
->output_offset
5221 - htab
->elf
.tlsdesc_plt
5222 - htab
->lazy_plt
->plt_tlsdesc_got1_insn_end
),
5223 (htab
->elf
.splt
->contents
5224 + htab
->elf
.tlsdesc_plt
5225 + htab
->lazy_plt
->plt_tlsdesc_got1_offset
));
5226 /* Add offset for indirect branch via GOT+TDG, where TDG
5227 stands for htab->tlsdesc_got, subtracting the offset
5228 to the end of that instruction. */
5229 bfd_put_32 (output_bfd
,
5230 (htab
->elf
.sgot
->output_section
->vma
5231 + htab
->elf
.sgot
->output_offset
5232 + htab
->elf
.tlsdesc_got
5233 - htab
->elf
.splt
->output_section
->vma
5234 - htab
->elf
.splt
->output_offset
5235 - htab
->elf
.tlsdesc_plt
5236 - htab
->lazy_plt
->plt_tlsdesc_got2_insn_end
),
5237 (htab
->elf
.splt
->contents
5238 + htab
->elf
.tlsdesc_plt
5239 + htab
->lazy_plt
->plt_tlsdesc_got2_offset
));
5243 /* Fill PLT entries for undefined weak symbols in PIE. */
5244 if (bfd_link_pie (info
))
5245 bfd_hash_traverse (&info
->hash
->table
,
5246 elf_x86_64_pie_finish_undefweak_symbol
,
5252 /* Fill PLT/GOT entries and allocate dynamic relocations for local
5253 STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table.
5254 It has to be done before elf_link_sort_relocs is called so that
5255 dynamic relocations are properly sorted. */
5258 elf_x86_64_output_arch_local_syms
5259 (bfd
*output_bfd ATTRIBUTE_UNUSED
,
5260 struct bfd_link_info
*info
,
5261 void *flaginfo ATTRIBUTE_UNUSED
,
5262 int (*func
) (void *, const char *,
5265 struct elf_link_hash_entry
*) ATTRIBUTE_UNUSED
)
5267 struct elf_x86_link_hash_table
*htab
5268 = elf_x86_hash_table (info
, X86_64_ELF_DATA
);
5272 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
5273 htab_traverse (htab
->loc_hash_table
,
5274 elf_x86_64_finish_local_dynamic_symbol
,
5280 /* Similar to _bfd_elf_get_synthetic_symtab. Support PLTs with all
5281 dynamic relocations. */
5284 elf_x86_64_get_synthetic_symtab (bfd
*abfd
,
5285 long symcount ATTRIBUTE_UNUSED
,
5286 asymbol
**syms ATTRIBUTE_UNUSED
,
5293 bfd_byte
*plt_contents
;
5295 const struct elf_x86_lazy_plt_layout
*lazy_plt
;
5296 const struct elf_x86_non_lazy_plt_layout
*non_lazy_plt
;
5297 const struct elf_x86_lazy_plt_layout
*lazy_bnd_plt
;
5298 const struct elf_x86_non_lazy_plt_layout
*non_lazy_bnd_plt
;
5299 const struct elf_x86_lazy_plt_layout
*lazy_bnd_ibt_plt
;
5300 const struct elf_x86_non_lazy_plt_layout
*non_lazy_bnd_ibt_plt
;
5301 const struct elf_x86_lazy_plt_layout
*lazy_ibt_plt
;
5302 const struct elf_x86_non_lazy_plt_layout
*non_lazy_ibt_plt
;
5304 enum elf_x86_plt_type plt_type
;
5305 struct elf_x86_plt plts
[] =
5307 { ".plt", NULL
, NULL
, plt_unknown
, 0, 0, 0, 0 },
5308 { ".plt.got", NULL
, NULL
, plt_non_lazy
, 0, 0, 0, 0 },
5309 { ".plt.sec", NULL
, NULL
, plt_second
, 0, 0, 0, 0 },
5310 { ".plt.bnd", NULL
, NULL
, plt_second
, 0, 0, 0, 0 },
5311 { NULL
, NULL
, NULL
, plt_non_lazy
, 0, 0, 0, 0 }
5316 if ((abfd
->flags
& (DYNAMIC
| EXEC_P
)) == 0)
5319 if (dynsymcount
<= 0)
5322 relsize
= bfd_get_dynamic_reloc_upper_bound (abfd
);
5326 lazy_plt
= &elf_x86_64_lazy_plt
;
5327 non_lazy_plt
= &elf_x86_64_non_lazy_plt
;
5328 lazy_ibt_plt
= &elf_x86_64_lazy_ibt_plt
;
5329 non_lazy_ibt_plt
= &elf_x86_64_non_lazy_ibt_plt
;
5330 if (ABI_64_P (abfd
))
5332 lazy_bnd_ibt_plt
= &elf_x86_64_lazy_bnd_ibt_plt
;
5333 non_lazy_bnd_ibt_plt
= &elf_x86_64_non_lazy_bnd_ibt_plt
;
5334 lazy_bnd_plt
= &elf_x86_64_lazy_bnd_plt
;
5335 non_lazy_bnd_plt
= &elf_x86_64_non_lazy_bnd_plt
;
5339 lazy_bnd_ibt_plt
= NULL
;
5340 non_lazy_bnd_ibt_plt
= NULL
;
5341 lazy_bnd_plt
= NULL
;
5342 non_lazy_bnd_plt
= NULL
;
5346 for (j
= 0; plts
[j
].name
!= NULL
; j
++)
5348 plt
= bfd_get_section_by_name (abfd
, plts
[j
].name
);
5351 || (plt
->flags
& SEC_HAS_CONTENTS
) == 0)
5354 /* Get the PLT section contents. */
5355 if (!_bfd_elf_mmap_section_contents (abfd
, plt
, &plt_contents
))
5358 /* Check what kind of PLT it is. */
5359 plt_type
= plt_unknown
;
5360 if (plts
[j
].type
== plt_unknown
5361 && (plt
->size
>= (lazy_plt
->plt_entry_size
5362 + lazy_plt
->plt_entry_size
)))
5364 /* Match lazy PLT first. Need to check the first two
5366 if ((memcmp (plt_contents
, lazy_plt
->plt0_entry
,
5367 lazy_plt
->plt0_got1_offset
) == 0)
5368 && (memcmp (plt_contents
+ 6, lazy_plt
->plt0_entry
+ 6,
5371 if (memcmp (plt_contents
+ lazy_ibt_plt
->plt_entry_size
,
5372 lazy_ibt_plt
->plt_entry
,
5373 lazy_ibt_plt
->plt_got_offset
) == 0)
5375 /* The fist entry in the lazy IBT PLT is the same as
5377 plt_type
= plt_lazy
| plt_second
;
5378 lazy_plt
= lazy_ibt_plt
;
5381 plt_type
= plt_lazy
;
5383 else if (lazy_bnd_plt
!= NULL
5384 && (memcmp (plt_contents
, lazy_bnd_plt
->plt0_entry
,
5385 lazy_bnd_plt
->plt0_got1_offset
) == 0)
5386 && (memcmp (plt_contents
+ 6,
5387 lazy_bnd_plt
->plt0_entry
+ 6, 3) == 0))
5389 plt_type
= plt_lazy
| plt_second
;
5390 /* The fist entry in the lazy BND IBT PLT is the same as
5391 the lazy BND PLT. */
5392 if (memcmp (plt_contents
5393 + lazy_bnd_ibt_plt
->plt_entry_size
,
5394 lazy_bnd_ibt_plt
->plt_entry
,
5395 lazy_bnd_ibt_plt
->plt_got_offset
) == 0)
5396 lazy_plt
= lazy_bnd_ibt_plt
;
5398 lazy_plt
= lazy_bnd_plt
;
5402 if (non_lazy_plt
!= NULL
5403 && (plt_type
== plt_unknown
|| plt_type
== plt_non_lazy
)
5404 && plt
->size
>= non_lazy_plt
->plt_entry_size
)
5406 /* Match non-lazy PLT. */
5407 if (memcmp (plt_contents
, non_lazy_plt
->plt_entry
,
5408 non_lazy_plt
->plt_got_offset
) == 0)
5409 plt_type
= plt_non_lazy
;
5412 if (plt_type
== plt_unknown
|| plt_type
== plt_second
)
5414 if (plt
->size
>= non_lazy_ibt_plt
->plt_entry_size
5415 && (memcmp (plt_contents
,
5416 non_lazy_ibt_plt
->plt_entry
,
5417 non_lazy_ibt_plt
->plt_got_offset
) == 0))
5419 /* Match IBT PLT. */
5420 plt_type
= plt_second
;
5421 non_lazy_plt
= non_lazy_ibt_plt
;
5423 else if (non_lazy_bnd_plt
!= NULL
)
5425 if (plt
->size
>= non_lazy_bnd_plt
->plt_entry_size
5426 && (memcmp (plt_contents
, non_lazy_bnd_plt
->plt_entry
,
5427 non_lazy_bnd_plt
->plt_got_offset
) == 0))
5429 /* Match BND PLT. */
5430 plt_type
= plt_second
;
5431 non_lazy_plt
= non_lazy_bnd_plt
;
5433 else if (plt
->size
>= non_lazy_bnd_ibt_plt
->plt_entry_size
5434 && (memcmp (plt_contents
,
5435 non_lazy_bnd_ibt_plt
->plt_entry
,
5436 non_lazy_bnd_ibt_plt
->plt_got_offset
)
5439 /* Match BND IBT PLT. */
5440 plt_type
= plt_second
;
5441 non_lazy_plt
= non_lazy_bnd_ibt_plt
;
5446 if (plt_type
== plt_unknown
)
5448 _bfd_elf_munmap_section_contents (plt
, plt_contents
);
5453 plts
[j
].type
= plt_type
;
5455 if ((plt_type
& plt_lazy
))
5457 plts
[j
].plt_got_offset
= lazy_plt
->plt_got_offset
;
5458 plts
[j
].plt_got_insn_size
= lazy_plt
->plt_got_insn_size
;
5459 plts
[j
].plt_entry_size
= lazy_plt
->plt_entry_size
;
5460 /* Skip PLT0 in lazy PLT. */
5465 plts
[j
].plt_got_offset
= non_lazy_plt
->plt_got_offset
;
5466 plts
[j
].plt_got_insn_size
= non_lazy_plt
->plt_got_insn_size
;
5467 plts
[j
].plt_entry_size
= non_lazy_plt
->plt_entry_size
;
5471 /* Skip lazy PLT when the second PLT is used. */
5472 if (plt_type
== (plt_lazy
| plt_second
))
5476 n
= plt
->size
/ plts
[j
].plt_entry_size
;
5481 plts
[j
].contents
= plt_contents
;
5484 return _bfd_x86_elf_get_synthetic_symtab (abfd
, count
, relsize
,
5485 (bfd_vma
) 0, plts
, dynsyms
,
5489 /* Handle an x86-64 specific section when reading an object file. This
5490 is called when elfcode.h finds a section with an unknown type. */
5493 elf_x86_64_section_from_shdr (bfd
*abfd
, Elf_Internal_Shdr
*hdr
,
5494 const char *name
, int shindex
)
5496 if (hdr
->sh_type
!= SHT_X86_64_UNWIND
)
5499 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
5505 /* Hook called by the linker routine which adds symbols from an object
5506 file. We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
5510 elf_x86_64_add_symbol_hook (bfd
*abfd
,
5511 struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
5512 Elf_Internal_Sym
*sym
,
5513 const char **namep ATTRIBUTE_UNUSED
,
5514 flagword
*flagsp ATTRIBUTE_UNUSED
,
5520 switch (sym
->st_shndx
)
5522 case SHN_X86_64_LCOMMON
:
5523 lcomm
= bfd_get_section_by_name (abfd
, "LARGE_COMMON");
5526 lcomm
= bfd_make_section_with_flags (abfd
,
5530 | SEC_LINKER_CREATED
));
5533 elf_section_flags (lcomm
) |= SHF_X86_64_LARGE
;
5536 *valp
= sym
->st_size
;
5544 /* Given a BFD section, try to locate the corresponding ELF section
5548 elf_x86_64_elf_section_from_bfd_section (bfd
*abfd ATTRIBUTE_UNUSED
,
5549 asection
*sec
, int *index_return
)
5551 if (sec
== &_bfd_elf_large_com_section
)
5553 *index_return
= SHN_X86_64_LCOMMON
;
5559 /* Process a symbol. */
5562 elf_x86_64_symbol_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
5565 elf_symbol_type
*elfsym
= (elf_symbol_type
*) asym
;
5567 switch (elfsym
->internal_elf_sym
.st_shndx
)
5569 case SHN_X86_64_LCOMMON
:
5570 asym
->section
= &_bfd_elf_large_com_section
;
5571 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
5572 /* Common symbol doesn't set BSF_GLOBAL. */
5573 asym
->flags
&= ~BSF_GLOBAL
;
5579 elf_x86_64_common_definition (Elf_Internal_Sym
*sym
)
5581 return (sym
->st_shndx
== SHN_COMMON
5582 || sym
->st_shndx
== SHN_X86_64_LCOMMON
);
5586 elf_x86_64_common_section_index (asection
*sec
)
5588 if ((elf_section_flags (sec
) & SHF_X86_64_LARGE
) == 0)
5591 return SHN_X86_64_LCOMMON
;
5595 elf_x86_64_common_section (asection
*sec
)
5597 if ((elf_section_flags (sec
) & SHF_X86_64_LARGE
) == 0)
5598 return bfd_com_section_ptr
;
5600 return &_bfd_elf_large_com_section
;
5604 elf_x86_64_merge_symbol (struct elf_link_hash_entry
*h
,
5605 const Elf_Internal_Sym
*sym
,
5610 const asection
*oldsec
)
5612 /* A normal common symbol and a large common symbol result in a
5613 normal common symbol. We turn the large common symbol into a
5616 && h
->root
.type
== bfd_link_hash_common
5618 && bfd_is_com_section (*psec
)
5621 if (sym
->st_shndx
== SHN_COMMON
5622 && (elf_section_flags (oldsec
) & SHF_X86_64_LARGE
) != 0)
5624 h
->root
.u
.c
.p
->section
5625 = bfd_make_section_old_way (oldbfd
, "COMMON");
5626 h
->root
.u
.c
.p
->section
->flags
= SEC_ALLOC
;
5628 else if (sym
->st_shndx
== SHN_X86_64_LCOMMON
5629 && (elf_section_flags (oldsec
) & SHF_X86_64_LARGE
) == 0)
5630 *psec
= bfd_com_section_ptr
;
5637 elf_x86_64_section_flags (const Elf_Internal_Shdr
*hdr
)
5639 if ((hdr
->sh_flags
& SHF_X86_64_LARGE
) != 0)
5640 hdr
->bfd_section
->flags
|= SEC_ELF_LARGE
;
5646 elf_x86_64_fake_sections (bfd
*abfd ATTRIBUTE_UNUSED
,
5647 Elf_Internal_Shdr
*hdr
, asection
*sec
)
5649 if (sec
->flags
& SEC_ELF_LARGE
)
5650 hdr
->sh_flags
|= SHF_X86_64_LARGE
;
5656 elf_x86_64_copy_private_section_data (bfd
*ibfd
, asection
*isec
,
5657 bfd
*obfd
, asection
*osec
)
5659 if (!_bfd_elf_copy_private_section_data (ibfd
, isec
, obfd
, osec
))
5662 /* objcopy --set-section-flags without "large" drops SHF_X86_64_LARGE. */
5664 elf_section_flags (osec
) &= ~SHF_X86_64_LARGE
;
5670 elf_x86_64_additional_program_headers (bfd
*abfd
,
5671 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
5676 /* Check to see if we need a large readonly segment. */
5677 s
= bfd_get_section_by_name (abfd
, ".lrodata");
5678 if (s
&& (s
->flags
& SEC_LOAD
))
5681 /* Check to see if we need a large data segment. Since .lbss sections
5682 is placed right after the .bss section, there should be no need for
5683 a large data segment just because of .lbss. */
5684 s
= bfd_get_section_by_name (abfd
, ".ldata");
5685 if (s
&& (s
->flags
& SEC_LOAD
))
5691 /* Return TRUE iff relocations for INPUT are compatible with OUTPUT. */
5694 elf_x86_64_relocs_compatible (const bfd_target
*input
,
5695 const bfd_target
*output
)
5697 return ((xvec_get_elf_backend_data (input
)->s
->elfclass
5698 == xvec_get_elf_backend_data (output
)->s
->elfclass
)
5699 && _bfd_elf_relocs_compatible (input
, output
));
5702 /* Set up x86-64 GNU properties. Return the first relocatable ELF input
5703 with GNU properties if found. Otherwise, return NULL. */
5706 elf_x86_64_link_setup_gnu_properties (struct bfd_link_info
*info
)
5708 struct elf_x86_init_table init_table
;
5709 const struct elf_backend_data
*bed
;
5710 struct elf_x86_link_hash_table
*htab
;
5712 if ((int) R_X86_64_standard
>= (int) R_X86_64_converted_reloc_bit
5713 || (int) R_X86_64_max
<= (int) R_X86_64_converted_reloc_bit
5714 || ((int) (R_X86_64_GNU_VTINHERIT
| R_X86_64_converted_reloc_bit
)
5715 != (int) R_X86_64_GNU_VTINHERIT
)
5716 || ((int) (R_X86_64_GNU_VTENTRY
| R_X86_64_converted_reloc_bit
)
5717 != (int) R_X86_64_GNU_VTENTRY
))
5720 /* This is unused for x86-64. */
5721 init_table
.plt0_pad_byte
= 0x90;
5723 bed
= get_elf_backend_data (info
->output_bfd
);
5724 htab
= elf_x86_hash_table (info
, bed
->target_id
);
5728 init_table
.lazy_plt
= &elf_x86_64_lazy_plt
;
5729 init_table
.non_lazy_plt
= &elf_x86_64_non_lazy_plt
;
5731 init_table
.lazy_ibt_plt
= &elf_x86_64_lazy_ibt_plt
;
5732 init_table
.non_lazy_ibt_plt
= &elf_x86_64_non_lazy_ibt_plt
;
5734 if (ABI_64_P (info
->output_bfd
))
5736 init_table
.sframe_lazy_plt
= &elf_x86_64_sframe_plt
;
5737 init_table
.sframe_non_lazy_plt
= &elf_x86_64_sframe_non_lazy_plt
;
5738 init_table
.sframe_lazy_ibt_plt
= &elf_x86_64_sframe_ibt_plt
;
5739 init_table
.sframe_non_lazy_ibt_plt
= &elf_x86_64_sframe_non_lazy_ibt_plt
;
5743 /* SFrame is not supported for non AMD64. */
5744 init_table
.sframe_lazy_plt
= NULL
;
5745 init_table
.sframe_non_lazy_plt
= NULL
;
5748 if (ABI_64_P (info
->output_bfd
))
5750 init_table
.r_info
= elf64_r_info
;
5751 init_table
.r_sym
= elf64_r_sym
;
5755 init_table
.r_info
= elf32_r_info
;
5756 init_table
.r_sym
= elf32_r_sym
;
5759 return _bfd_x86_elf_link_setup_gnu_properties (info
, &init_table
);
5763 elf_x86_64_add_glibc_version_dependency
5764 (struct elf_find_verdep_info
*rinfo
)
5767 const char *version
[3] = { NULL
, NULL
, NULL
};
5768 struct elf_x86_link_hash_table
*htab
;
5770 if (rinfo
->info
->enable_dt_relr
)
5772 version
[i
] = "GLIBC_ABI_DT_RELR";
5776 htab
= elf_x86_hash_table (rinfo
->info
, X86_64_ELF_DATA
);
5777 if (htab
!= NULL
&& htab
->params
->mark_plt
)
5779 version
[i
] = "GLIBC_2.36";
5784 _bfd_elf_link_add_glibc_version_dependency (rinfo
, version
);
5787 static const struct bfd_elf_special_section
5788 elf_x86_64_special_sections
[]=
5790 { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_X86_64_LARGE
},
5791 { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS
, SHF_ALLOC
+ SHF_X86_64_LARGE
},
5792 { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS
, SHF_ALLOC
+ SHF_EXECINSTR
+ SHF_X86_64_LARGE
},
5793 { STRING_COMMA_LEN (".lbss"), -2, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_X86_64_LARGE
},
5794 { STRING_COMMA_LEN (".ldata"), -2, SHT_PROGBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_X86_64_LARGE
},
5795 { STRING_COMMA_LEN (".lrodata"), -2, SHT_PROGBITS
, SHF_ALLOC
+ SHF_X86_64_LARGE
},
5796 { NULL
, 0, 0, 0, 0 }
5799 #define TARGET_LITTLE_SYM x86_64_elf64_vec
5800 #define TARGET_LITTLE_NAME "elf64-x86-64"
5801 #define ELF_ARCH bfd_arch_i386
5802 #define ELF_TARGET_ID X86_64_ELF_DATA
5803 #define ELF_MACHINE_CODE EM_X86_64
5804 #define ELF_MAXPAGESIZE 0x1000
5805 #define ELF_COMMONPAGESIZE 0x1000
5807 #define elf_backend_can_gc_sections 1
5808 #define elf_backend_can_refcount 1
5809 #define elf_backend_want_got_plt 1
5810 #define elf_backend_plt_readonly 1
5811 #define elf_backend_want_plt_sym 0
5812 #define elf_backend_got_header_size (GOT_ENTRY_SIZE*3)
5813 #define elf_backend_rela_normal 1
5814 #define elf_backend_plt_alignment 4
5815 #define elf_backend_caches_rawsize 1
5816 #define elf_backend_dtrel_excludes_plt 1
5817 #define elf_backend_want_dynrelro 1
5819 #define elf_info_to_howto elf_x86_64_info_to_howto
5821 #define bfd_elf64_bfd_copy_private_section_data \
5822 elf_x86_64_copy_private_section_data
5823 #define bfd_elf64_bfd_reloc_type_lookup elf_x86_64_reloc_type_lookup
5824 #define bfd_elf64_bfd_reloc_name_lookup \
5825 elf_x86_64_reloc_name_lookup
5827 #define elf_backend_relocs_compatible elf_x86_64_relocs_compatible
5828 #define elf_backend_early_size_sections elf_x86_64_early_size_sections
5829 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
5830 #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections
5831 #define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol
5832 #define elf_backend_output_arch_local_syms elf_x86_64_output_arch_local_syms
5833 #define elf_backend_grok_prstatus elf_x86_64_grok_prstatus
5834 #define elf_backend_grok_psinfo elf_x86_64_grok_psinfo
5836 #define elf_backend_write_core_note elf_x86_64_write_core_note
5838 #define elf_backend_reloc_type_class elf_x86_64_reloc_type_class
5839 #define elf_backend_relocate_section elf_x86_64_relocate_section
5840 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
5841 #define elf_backend_object_p elf64_x86_64_elf_object_p
5842 #define bfd_elf64_get_synthetic_symtab elf_x86_64_get_synthetic_symtab
5844 #define elf_backend_section_from_shdr \
5845 elf_x86_64_section_from_shdr
5847 #define elf_backend_section_from_bfd_section \
5848 elf_x86_64_elf_section_from_bfd_section
5849 #define elf_backend_add_symbol_hook \
5850 elf_x86_64_add_symbol_hook
5851 #define elf_backend_symbol_processing \
5852 elf_x86_64_symbol_processing
5853 #define elf_backend_common_section_index \
5854 elf_x86_64_common_section_index
5855 #define elf_backend_common_section \
5856 elf_x86_64_common_section
5857 #define elf_backend_common_definition \
5858 elf_x86_64_common_definition
5859 #define elf_backend_merge_symbol \
5860 elf_x86_64_merge_symbol
5861 #define elf_backend_special_sections \
5862 elf_x86_64_special_sections
5863 #define elf_backend_section_flags elf_x86_64_section_flags
5864 #define elf_backend_fake_sections elf_x86_64_fake_sections
5865 #define elf_backend_additional_program_headers \
5866 elf_x86_64_additional_program_headers
5867 #define elf_backend_setup_gnu_properties \
5868 elf_x86_64_link_setup_gnu_properties
5869 #define elf_backend_hide_symbol \
5870 _bfd_x86_elf_hide_symbol
5871 #define elf_backend_add_glibc_version_dependency \
5872 elf_x86_64_add_glibc_version_dependency
5875 #define elf64_bed elf64_x86_64_bed
5877 #include "elf64-target.h"
5879 /* CloudABI support. */
5881 #undef TARGET_LITTLE_SYM
5882 #define TARGET_LITTLE_SYM x86_64_elf64_cloudabi_vec
5883 #undef TARGET_LITTLE_NAME
5884 #define TARGET_LITTLE_NAME "elf64-x86-64-cloudabi"
5887 #define ELF_OSABI ELFOSABI_CLOUDABI
5890 #define elf64_bed elf64_x86_64_cloudabi_bed
5892 #include "elf64-target.h"
5894 /* FreeBSD support. */
5896 #undef TARGET_LITTLE_SYM
5897 #define TARGET_LITTLE_SYM x86_64_elf64_fbsd_vec
5898 #undef TARGET_LITTLE_NAME
5899 #define TARGET_LITTLE_NAME "elf64-x86-64-freebsd"
5902 #define ELF_OSABI ELFOSABI_FREEBSD
5905 #define elf64_bed elf64_x86_64_fbsd_bed
5907 #include "elf64-target.h"
5909 /* Solaris 2 support. */
5911 #undef TARGET_LITTLE_SYM
5912 #define TARGET_LITTLE_SYM x86_64_elf64_sol2_vec
5913 #undef TARGET_LITTLE_NAME
5914 #define TARGET_LITTLE_NAME "elf64-x86-64-sol2"
5916 #undef ELF_TARGET_OS
5917 #define ELF_TARGET_OS is_solaris
5919 /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
5920 objects won't be recognized. */
5924 #define elf64_bed elf64_x86_64_sol2_bed
5926 /* The 64-bit static TLS arena size is rounded to the nearest 16-byte
5928 #undef elf_backend_static_tls_alignment
5929 #define elf_backend_static_tls_alignment 16
5931 /* The Solaris 2 ABI requires a plt symbol on all platforms.
5933 Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
5935 #undef elf_backend_want_plt_sym
5936 #define elf_backend_want_plt_sym 1
5938 #undef elf_backend_strtab_flags
5939 #define elf_backend_strtab_flags SHF_STRINGS
5942 elf64_x86_64_copy_solaris_special_section_fields (const bfd
*ibfd ATTRIBUTE_UNUSED
,
5943 bfd
*obfd ATTRIBUTE_UNUSED
,
5944 const Elf_Internal_Shdr
*isection ATTRIBUTE_UNUSED
,
5945 Elf_Internal_Shdr
*osection ATTRIBUTE_UNUSED
)
5947 /* PR 19938: FIXME: Need to add code for setting the sh_info
5948 and sh_link fields of Solaris specific section types. */
5952 #undef elf_backend_copy_special_section_fields
5953 #define elf_backend_copy_special_section_fields elf64_x86_64_copy_solaris_special_section_fields
5955 #include "elf64-target.h"
5957 /* Restore defaults. */
5959 #undef elf_backend_static_tls_alignment
5960 #undef elf_backend_want_plt_sym
5961 #define elf_backend_want_plt_sym 0
5962 #undef elf_backend_strtab_flags
5963 #undef elf_backend_copy_special_section_fields
5965 /* 32bit x86-64 support. */
5967 #undef TARGET_LITTLE_SYM
5968 #define TARGET_LITTLE_SYM x86_64_elf32_vec
5969 #undef TARGET_LITTLE_NAME
5970 #define TARGET_LITTLE_NAME "elf32-x86-64"
5972 #define elf32_bed elf32_x86_64_bed
5975 #define ELF_ARCH bfd_arch_i386
5977 #undef ELF_MACHINE_CODE
5978 #define ELF_MACHINE_CODE EM_X86_64
5980 #undef ELF_TARGET_OS
5983 #define bfd_elf32_bfd_copy_private_section_data \
5984 elf_x86_64_copy_private_section_data
5985 #define bfd_elf32_bfd_reloc_type_lookup \
5986 elf_x86_64_reloc_type_lookup
5987 #define bfd_elf32_bfd_reloc_name_lookup \
5988 elf_x86_64_reloc_name_lookup
5989 #define bfd_elf32_get_synthetic_symtab \
5990 elf_x86_64_get_synthetic_symtab
5992 #undef elf_backend_object_p
5993 #define elf_backend_object_p \
5994 elf32_x86_64_elf_object_p
5996 #undef elf_backend_bfd_from_remote_memory
5997 #define elf_backend_bfd_from_remote_memory \
5998 _bfd_elf32_bfd_from_remote_memory
6000 #undef elf_backend_size_info
6001 #define elf_backend_size_info \
6002 _bfd_elf32_size_info
6004 #include "elf32-target.h"