Automatic date update in version.in
[binutils-gdb.git] / bfd / elf64-x86-64.c
blob83399ea8928856df7e7421f848b73a253b57773f
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"
23 #include "dwarf2.h"
24 #include "libiberty.h"
25 #include "sframe.h"
27 #include "opcode/i386.h"
29 #ifdef CORE_HEADER
30 #include <stdarg.h>
31 #include CORE_HEADER
32 #endif
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,
49 false),
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,
52 false),
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,
55 true),
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,
58 false),
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,
61 true),
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,
64 false),
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,
67 false),
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,
70 false),
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,
73 false),
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,
76 true),
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,
79 false),
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,
82 false),
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,
93 false),
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,
96 false),
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,
99 false),
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,
102 true),
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,
105 true),
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,
108 false),
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,
111 true),
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,
114 false),
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,
117 true),
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,
120 false),
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,
123 true),
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,
126 false),
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,
129 true),
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,
132 true),
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,
135 false),
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,
138 false),
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,
141 false),
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,
144 false),
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",
151 false, 0, 0, false),
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,
157 false),
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,
160 false),
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,
163 true),
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,
166 true),
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,
169 true),
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,
172 true),
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,
175 true),
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,
178 true),
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,
215 false),
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,
220 false)
223 /* Map BFD relocs to the x86_64 elf relocs. */
224 struct elf_reloc_map
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)
290 unsigned i;
292 if (r_type == (unsigned int) R_X86_64_32)
294 if (ABI_64_P (abfd))
295 i = r_type;
296 else
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"),
306 abfd, r_type);
307 bfd_set_error (bfd_error_bad_value);
308 return NULL;
310 i = r_type;
312 else
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)
323 unsigned int i;
325 for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map);
326 i++)
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);
332 return NULL;
335 static reloc_howto_type *
336 elf_x86_64_reloc_name_lookup (bfd *abfd,
337 const char *r_name)
339 unsigned int i;
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);
347 return reloc;
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];
355 return NULL;
358 /* Given an x86_64 ELF reloc type, fill in an arelent structure. */
360 static bool
361 elf_x86_64_info_to_howto (bfd *abfd, arelent *cache_ptr,
362 Elf_Internal_Rela *dst)
364 unsigned r_type;
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)
369 return false;
370 BFD_ASSERT (r_type == cache_ptr->howto->type || cache_ptr->howto->type == R_X86_64_NONE);
371 return true;
374 /* Support for core dump NOTE sections. */
375 static bool
376 elf_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
378 int offset;
379 size_t size;
381 switch (note->descsz)
383 default:
384 return false;
386 case 296: /* sizeof(istruct elf_prstatus) on Linux/x32 */
387 /* pr_cursig */
388 elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
390 /* pr_pid */
391 elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
393 /* pr_reg */
394 offset = 72;
395 size = 216;
397 break;
399 case 336: /* sizeof(istruct elf_prstatus) on Linux/x86_64 */
400 /* pr_cursig */
401 elf_tdata (abfd)->core->signal
402 = bfd_get_16 (abfd, note->descdata + 12);
404 /* pr_pid */
405 elf_tdata (abfd)->core->lwpid
406 = bfd_get_32 (abfd, note->descdata + 32);
408 /* pr_reg */
409 offset = 112;
410 size = 216;
412 break;
415 /* Make a ".reg/999" section. */
416 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
417 size, note->descpos + offset);
420 static bool
421 elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
423 switch (note->descsz)
425 default:
426 return false;
428 case 124:
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);
436 break;
438 case 128:
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);
446 break;
448 case 136:
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';
470 return true;
473 #ifdef CORE_HEADER
474 # if GCC_VERSION >= 8000
475 # pragma GCC diagnostic push
476 # pragma GCC diagnostic ignored "-Wstringop-truncation"
477 # endif
478 static char *
479 elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
480 int note_type, ...)
482 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
483 va_list ap;
484 const char *fname, *psargs;
485 long pid;
486 int cursig;
487 const void *gregs;
489 switch (note_type)
491 default:
492 return NULL;
494 case NT_PRPSINFO:
495 va_start (ap, note_type);
496 fname = va_arg (ap, const char *);
497 psargs = va_arg (ap, const char *);
498 va_end (ap);
500 if (bed->s->elfclass == ELFCLASS32)
502 prpsinfo32_t data;
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));
509 else
511 prpsinfo64_t 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));
518 /* NOTREACHED */
520 case NT_PRSTATUS:
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 *);
525 va_end (ap);
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));
533 prstat.pr_pid = pid;
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));
539 else
541 prstatus32_t prstat;
542 memset (&prstat, 0, sizeof (prstat));
543 prstat.pr_pid = pid;
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));
550 else
552 prstatus64_t prstat;
553 memset (&prstat, 0, sizeof (prstat));
554 prstat.pr_pid = pid;
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));
561 /* NOTREACHED */
563 # if GCC_VERSION >= 8000
564 # pragma GCC diagnostic pop
565 # endif
566 #endif
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
579 table. */
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
585 works. */
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
607 like this. */
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
630 this. */
632 static const bfd_byte elf_x86_64_lazy_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 */
637 0x90 /* nop */
640 /* The first entry in the x32 IBT-enabled lazy procedure linkage table
641 is the same as the normal lazy PLT. Subsequent entries for an
642 x32 IBT-enabled lazy procedure linkage table look like this. */
644 static const bfd_byte elf_x32_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. */
668 0x90 /* nop */
671 /* Entries for branches with IBT-enabled in the non-lazey procedure
672 linkage table look like this. They have the same size as the lazy
673 PLT entry. */
675 static const bfd_byte elf_x86_64_non_lazy_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 x32 non-lazey procedure
684 linkage table look like this. They have the same size as the lazy
685 PLT entry. */
687 static const bfd_byte elf_x32_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 */
709 1, /* CIE version */
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 */
744 1, /* CIE version */
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. */
775 static const bfd_byte elf_x86_64_eh_frame_lazy_ibt_plt[] =
777 PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
778 0, 0, 0, 0, /* CIE ID */
779 1, /* CIE version */
780 'z', 'R', 0, /* Augmentation string */
781 1, /* Code alignment factor */
782 0x78, /* Data alignment factor */
783 16, /* Return address column */
784 1, /* Augmentation size */
785 DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
786 DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
787 DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
788 DW_CFA_nop, DW_CFA_nop,
790 PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
791 PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
792 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
793 0, 0, 0, 0, /* .plt size goes here */
794 0, /* Augmentation size */
795 DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */
796 DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
797 DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */
798 DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
799 DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
800 11, /* Block length */
801 DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */
802 DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */
803 DW_OP_lit15, DW_OP_and, DW_OP_lit10, DW_OP_ge,
804 DW_OP_lit3, DW_OP_shl, DW_OP_plus,
805 DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
808 /* .eh_frame covering the x32 lazy .plt section with IBT-enabled. */
810 static const bfd_byte elf_x32_eh_frame_lazy_ibt_plt[] =
812 PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
813 0, 0, 0, 0, /* CIE ID */
814 1, /* CIE version */
815 'z', 'R', 0, /* Augmentation string */
816 1, /* Code alignment factor */
817 0x78, /* Data alignment factor */
818 16, /* Return address column */
819 1, /* Augmentation size */
820 DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
821 DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
822 DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
823 DW_CFA_nop, DW_CFA_nop,
825 PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
826 PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
827 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
828 0, 0, 0, 0, /* .plt size goes here */
829 0, /* Augmentation size */
830 DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */
831 DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
832 DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */
833 DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
834 DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
835 11, /* Block length */
836 DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */
837 DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */
838 DW_OP_lit15, DW_OP_and, DW_OP_lit9, DW_OP_ge,
839 DW_OP_lit3, DW_OP_shl, DW_OP_plus,
840 DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
843 /* .eh_frame covering the non-lazy .plt section. */
845 static const bfd_byte elf_x86_64_eh_frame_non_lazy_plt[] =
847 #define PLT_GOT_FDE_LENGTH 20
848 PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
849 0, 0, 0, 0, /* CIE ID */
850 1, /* CIE version */
851 'z', 'R', 0, /* Augmentation string */
852 1, /* Code alignment factor */
853 0x78, /* Data alignment factor */
854 16, /* Return address column */
855 1, /* Augmentation size */
856 DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
857 DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
858 DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
859 DW_CFA_nop, DW_CFA_nop,
861 PLT_GOT_FDE_LENGTH, 0, 0, 0, /* FDE length */
862 PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
863 0, 0, 0, 0, /* the start of non-lazy .plt goes here */
864 0, 0, 0, 0, /* non-lazy .plt size goes here */
865 0, /* Augmentation size */
866 DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop,
867 DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
870 static const sframe_frame_row_entry elf_x86_64_sframe_null_fre =
873 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
874 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
877 /* .sframe FRE covering the .plt section entry. */
878 static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre1 =
880 0, /* SFrame FRE start address. */
881 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
882 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
885 /* .sframe FRE covering the .plt section entry. */
886 static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre2 =
888 6, /* SFrame FRE start address. */
889 {24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
890 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
893 /* .sframe FRE covering the .plt section entry. */
894 static const sframe_frame_row_entry elf_x86_64_sframe_pltn_fre1 =
896 0, /* SFrame FRE start address. */
897 {8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
898 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
901 /* .sframe FRE covering the .plt section entry. */
902 static const sframe_frame_row_entry elf_x86_64_sframe_pltn_fre2 =
904 11, /* SFrame FRE start address. */
905 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
906 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
909 /* .sframe FRE covering the second .plt section entry. */
910 static const sframe_frame_row_entry elf_x86_64_sframe_sec_pltn_fre1 =
912 0, /* SFrame FRE start address. */
913 {8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
914 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
917 /* SFrame helper object for non-lazy PLT. Also used for IBT enabled PLT. */
918 static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_plt =
920 LAZY_PLT_ENTRY_SIZE,
921 2, /* Number of FREs for PLT0. */
922 /* Array of SFrame FREs for plt0. */
923 { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 },
924 LAZY_PLT_ENTRY_SIZE,
925 1, /* Number of FREs for PLTn. */
926 /* Array of SFrame FREs for plt. */
927 { &elf_x86_64_sframe_sec_pltn_fre1, &elf_x86_64_sframe_null_fre },
929 0, /* There is no second PLT necessary. */
930 { &elf_x86_64_sframe_null_fre }
933 /* SFrame helper object for lazy PLT. Also used for IBT enabled PLT. */
934 static const struct elf_x86_sframe_plt elf_x86_64_sframe_plt =
936 LAZY_PLT_ENTRY_SIZE,
937 2, /* Number of FREs for PLT0. */
938 /* Array of SFrame FREs for plt0. */
939 { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 },
940 LAZY_PLT_ENTRY_SIZE,
941 2, /* Number of FREs for PLTn. */
942 /* Array of SFrame FREs for plt. */
943 { &elf_x86_64_sframe_pltn_fre1, &elf_x86_64_sframe_pltn_fre2 },
944 NON_LAZY_PLT_ENTRY_SIZE,
945 1, /* Number of FREs for PLTn for second PLT. */
946 /* FREs for second plt (stack trace info for .plt.got is
947 identical). Used when IBT or non-lazy PLT is in effect. */
948 { &elf_x86_64_sframe_sec_pltn_fre1 }
951 /* These are the standard parameters. */
952 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_plt =
954 elf_x86_64_lazy_plt0_entry, /* plt0_entry */
955 LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */
956 elf_x86_64_lazy_plt_entry, /* plt_entry */
957 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
958 elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */
959 LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */
960 6, /* plt_tlsdesc_got1_offset */
961 12, /* plt_tlsdesc_got2_offset */
962 10, /* plt_tlsdesc_got1_insn_end */
963 16, /* plt_tlsdesc_got2_insn_end */
964 2, /* plt0_got1_offset */
965 8, /* plt0_got2_offset */
966 12, /* plt0_got2_insn_end */
967 2, /* plt_got_offset */
968 7, /* plt_reloc_offset */
969 12, /* plt_plt_offset */
970 6, /* plt_got_insn_size */
971 LAZY_PLT_ENTRY_SIZE, /* plt_plt_insn_end */
972 6, /* plt_lazy_offset */
973 elf_x86_64_lazy_plt0_entry, /* pic_plt0_entry */
974 elf_x86_64_lazy_plt_entry, /* pic_plt_entry */
975 elf_x86_64_eh_frame_lazy_plt, /* eh_frame_plt */
976 sizeof (elf_x86_64_eh_frame_lazy_plt) /* eh_frame_plt_size */
979 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_plt =
981 elf_x86_64_non_lazy_plt_entry, /* plt_entry */
982 elf_x86_64_non_lazy_plt_entry, /* pic_plt_entry */
983 NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
984 2, /* plt_got_offset */
985 6, /* plt_got_insn_size */
986 elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */
987 sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
990 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_plt =
992 elf_x86_64_lazy_bnd_plt0_entry, /* plt0_entry */
993 LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */
994 elf_x86_64_lazy_bnd_plt_entry, /* plt_entry */
995 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
996 elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */
997 LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */
998 6, /* plt_tlsdesc_got1_offset */
999 12, /* plt_tlsdesc_got2_offset */
1000 10, /* plt_tlsdesc_got1_insn_end */
1001 16, /* plt_tlsdesc_got2_insn_end */
1002 2, /* plt0_got1_offset */
1003 1+8, /* plt0_got2_offset */
1004 1+12, /* plt0_got2_insn_end */
1005 1+2, /* plt_got_offset */
1006 1, /* plt_reloc_offset */
1007 7, /* plt_plt_offset */
1008 1+6, /* plt_got_insn_size */
1009 11, /* plt_plt_insn_end */
1010 0, /* plt_lazy_offset */
1011 elf_x86_64_lazy_bnd_plt0_entry, /* pic_plt0_entry */
1012 elf_x86_64_lazy_bnd_plt_entry, /* pic_plt_entry */
1013 elf_x86_64_eh_frame_lazy_bnd_plt, /* eh_frame_plt */
1014 sizeof (elf_x86_64_eh_frame_lazy_bnd_plt) /* eh_frame_plt_size */
1017 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt =
1019 elf_x86_64_non_lazy_bnd_plt_entry, /* plt_entry */
1020 elf_x86_64_non_lazy_bnd_plt_entry, /* pic_plt_entry */
1021 NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1022 1+2, /* plt_got_offset */
1023 1+6, /* plt_got_insn_size */
1024 elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */
1025 sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
1028 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_ibt_plt =
1030 elf_x86_64_lazy_bnd_plt0_entry, /* plt0_entry */
1031 LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */
1032 elf_x86_64_lazy_ibt_plt_entry, /* plt_entry */
1033 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1034 elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */
1035 LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */
1036 6, /* plt_tlsdesc_got1_offset */
1037 12, /* plt_tlsdesc_got2_offset */
1038 10, /* plt_tlsdesc_got1_insn_end */
1039 16, /* plt_tlsdesc_got2_insn_end */
1040 2, /* plt0_got1_offset */
1041 1+8, /* plt0_got2_offset */
1042 1+12, /* plt0_got2_insn_end */
1043 4+1+2, /* plt_got_offset */
1044 4+1, /* plt_reloc_offset */
1045 4+1+6, /* plt_plt_offset */
1046 4+1+6, /* plt_got_insn_size */
1047 4+1+5+5, /* plt_plt_insn_end */
1048 0, /* plt_lazy_offset */
1049 elf_x86_64_lazy_bnd_plt0_entry, /* pic_plt0_entry */
1050 elf_x86_64_lazy_ibt_plt_entry, /* pic_plt_entry */
1051 elf_x86_64_eh_frame_lazy_ibt_plt, /* eh_frame_plt */
1052 sizeof (elf_x86_64_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
1055 static const struct elf_x86_lazy_plt_layout elf_x32_lazy_ibt_plt =
1057 elf_x86_64_lazy_plt0_entry, /* plt0_entry */
1058 LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */
1059 elf_x32_lazy_ibt_plt_entry, /* plt_entry */
1060 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1061 elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */
1062 LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */
1063 6, /* plt_tlsdesc_got1_offset */
1064 12, /* plt_tlsdesc_got2_offset */
1065 10, /* plt_tlsdesc_got1_insn_end */
1066 16, /* plt_tlsdesc_got2_insn_end */
1067 2, /* plt0_got1_offset */
1068 8, /* plt0_got2_offset */
1069 12, /* plt0_got2_insn_end */
1070 4+2, /* plt_got_offset */
1071 4+1, /* plt_reloc_offset */
1072 4+6, /* plt_plt_offset */
1073 4+6, /* plt_got_insn_size */
1074 4+5+5, /* plt_plt_insn_end */
1075 0, /* plt_lazy_offset */
1076 elf_x86_64_lazy_plt0_entry, /* pic_plt0_entry */
1077 elf_x32_lazy_ibt_plt_entry, /* pic_plt_entry */
1078 elf_x32_eh_frame_lazy_ibt_plt, /* eh_frame_plt */
1079 sizeof (elf_x32_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
1082 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt =
1084 elf_x86_64_non_lazy_ibt_plt_entry, /* plt_entry */
1085 elf_x86_64_non_lazy_ibt_plt_entry, /* pic_plt_entry */
1086 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1087 4+1+2, /* plt_got_offset */
1088 4+1+6, /* plt_got_insn_size */
1089 elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */
1090 sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
1093 static const struct elf_x86_non_lazy_plt_layout elf_x32_non_lazy_ibt_plt =
1095 elf_x32_non_lazy_ibt_plt_entry, /* plt_entry */
1096 elf_x32_non_lazy_ibt_plt_entry, /* pic_plt_entry */
1097 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1098 4+2, /* plt_got_offset */
1099 4+6, /* plt_got_insn_size */
1100 elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */
1101 sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
1104 static bool
1105 elf64_x86_64_elf_object_p (bfd *abfd)
1107 /* Set the right machine number for an x86-64 elf64 file. */
1108 bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
1109 return true;
1112 static bool
1113 elf32_x86_64_elf_object_p (bfd *abfd)
1115 /* Set the right machine number for an x86-64 elf32 file. */
1116 bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x64_32);
1117 return true;
1120 /* Return TRUE if the TLS access code sequence support transition
1121 from R_TYPE. */
1123 static enum elf_x86_tls_error_type
1124 elf_x86_64_check_tls_transition (bfd *abfd,
1125 struct bfd_link_info *info,
1126 asection *sec,
1127 bfd_byte *contents,
1128 Elf_Internal_Shdr *symtab_hdr,
1129 struct elf_link_hash_entry **sym_hashes,
1130 unsigned int r_type,
1131 const Elf_Internal_Rela *rel,
1132 const Elf_Internal_Rela *relend)
1134 unsigned int val;
1135 unsigned long r_symndx;
1136 bool largepic = false;
1137 struct elf_link_hash_entry *h;
1138 bfd_vma offset;
1139 struct elf_x86_link_hash_table *htab;
1140 bfd_byte *call;
1141 bool indirect_call;
1143 htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
1144 offset = rel->r_offset;
1145 switch (r_type)
1147 case R_X86_64_TLSGD:
1148 case R_X86_64_TLSLD:
1149 if ((rel + 1) >= relend)
1150 return elf_x86_tls_error_yes;
1152 if (r_type == R_X86_64_TLSGD)
1154 /* Check transition from GD access model. For 64bit, only
1155 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
1156 .word 0x6666; rex64; call __tls_get_addr@PLT
1158 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
1159 .byte 0x66; rex64
1160 call *__tls_get_addr@GOTPCREL(%rip)
1161 which may be converted to
1162 addr32 call __tls_get_addr
1163 can transit to different access model. For 32bit, only
1164 leaq foo@tlsgd(%rip), %rdi
1165 .word 0x6666; rex64; call __tls_get_addr@PLT
1167 leaq foo@tlsgd(%rip), %rdi
1168 .byte 0x66; rex64
1169 call *__tls_get_addr@GOTPCREL(%rip)
1170 which may be converted to
1171 addr32 call __tls_get_addr
1172 can transit to different access model. For largepic,
1173 we also support:
1174 leaq foo@tlsgd(%rip), %rdi
1175 movabsq $__tls_get_addr@pltoff, %rax
1176 addq $r15, %rax
1177 call *%rax
1179 leaq foo@tlsgd(%rip), %rdi
1180 movabsq $__tls_get_addr@pltoff, %rax
1181 addq $rbx, %rax
1182 call *%rax */
1184 static const unsigned char leaq[] = { 0x66, 0x48, 0x8d, 0x3d };
1186 if ((offset + 12) > sec->size)
1187 return elf_x86_tls_error_yes;
1189 call = contents + offset + 4;
1190 if (call[0] != 0x66
1191 || !((call[1] == 0x48
1192 && call[2] == 0xff
1193 && call[3] == 0x15)
1194 || (call[1] == 0x48
1195 && call[2] == 0x67
1196 && call[3] == 0xe8)
1197 || (call[1] == 0x66
1198 && call[2] == 0x48
1199 && call[3] == 0xe8)))
1201 if (!ABI_64_P (abfd)
1202 || (offset + 19) > sec->size
1203 || offset < 3
1204 || memcmp (call - 7, leaq + 1, 3) != 0
1205 || memcmp (call, "\x48\xb8", 2) != 0
1206 || call[11] != 0x01
1207 || call[13] != 0xff
1208 || call[14] != 0xd0
1209 || !((call[10] == 0x48 && call[12] == 0xd8)
1210 || (call[10] == 0x4c && call[12] == 0xf8)))
1211 return elf_x86_tls_error_yes;
1212 largepic = true;
1214 else if (ABI_64_P (abfd))
1216 if (offset < 4
1217 || memcmp (contents + offset - 4, leaq, 4) != 0)
1218 return elf_x86_tls_error_yes;
1220 else
1222 if (offset < 3
1223 || memcmp (contents + offset - 3, leaq + 1, 3) != 0)
1224 return elf_x86_tls_error_yes;
1226 indirect_call = call[2] == 0xff;
1228 else
1230 /* Check transition from LD access model. Only
1231 leaq foo@tlsld(%rip), %rdi;
1232 call __tls_get_addr@PLT
1234 leaq foo@tlsld(%rip), %rdi;
1235 call *__tls_get_addr@GOTPCREL(%rip)
1236 which may be converted to
1237 addr32 call __tls_get_addr
1238 can transit to different access model. For largepic
1239 we also support:
1240 leaq foo@tlsld(%rip), %rdi
1241 movabsq $__tls_get_addr@pltoff, %rax
1242 addq $r15, %rax
1243 call *%rax
1245 leaq foo@tlsld(%rip), %rdi
1246 movabsq $__tls_get_addr@pltoff, %rax
1247 addq $rbx, %rax
1248 call *%rax */
1250 static const unsigned char lea[] = { 0x48, 0x8d, 0x3d };
1252 if (offset < 3 || (offset + 9) > sec->size)
1253 return elf_x86_tls_error_yes;
1255 if (memcmp (contents + offset - 3, lea, 3) != 0)
1256 return elf_x86_tls_error_yes;
1258 call = contents + offset + 4;
1259 if (!(call[0] == 0xe8
1260 || (call[0] == 0xff && call[1] == 0x15)
1261 || (call[0] == 0x67 && call[1] == 0xe8)))
1263 if (!ABI_64_P (abfd)
1264 || (offset + 19) > sec->size
1265 || memcmp (call, "\x48\xb8", 2) != 0
1266 || call[11] != 0x01
1267 || call[13] != 0xff
1268 || call[14] != 0xd0
1269 || !((call[10] == 0x48 && call[12] == 0xd8)
1270 || (call[10] == 0x4c && call[12] == 0xf8)))
1271 return elf_x86_tls_error_yes;
1272 largepic = true;
1274 indirect_call = call[0] == 0xff;
1277 r_symndx = htab->r_sym (rel[1].r_info);
1278 if (r_symndx < symtab_hdr->sh_info)
1279 return elf_x86_tls_error_yes;
1281 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1282 if (h == NULL
1283 || !((struct elf_x86_link_hash_entry *) h)->tls_get_addr)
1284 return elf_x86_tls_error_yes;
1285 else
1287 r_type = (ELF32_R_TYPE (rel[1].r_info)
1288 & ~R_X86_64_converted_reloc_bit);
1289 if (largepic)
1290 return (r_type == R_X86_64_PLTOFF64
1291 ? elf_x86_tls_error_none
1292 : elf_x86_tls_error_yes);
1293 else if (indirect_call)
1294 return ((r_type == R_X86_64_GOTPCRELX
1295 || r_type == R_X86_64_GOTPCREL)
1296 ? elf_x86_tls_error_none
1297 : elf_x86_tls_error_yes);
1298 else
1299 return ((r_type == R_X86_64_PC32
1300 || r_type == R_X86_64_PLT32)
1301 ? elf_x86_tls_error_none
1302 : elf_x86_tls_error_yes);
1305 case R_X86_64_CODE_4_GOTTPOFF:
1306 /* Check transition from IE access model:
1307 mov foo@gottpoff(%rip), %reg
1308 add foo@gottpoff(%rip), %reg
1309 where reg is one of r16 to r31. */
1311 if (offset < 4
1312 || (offset + 4) > sec->size
1313 || contents[offset - 4] != 0xd5)
1314 return elf_x86_tls_error_yes;
1316 goto check_gottpoff;
1318 case R_X86_64_CODE_6_GOTTPOFF:
1319 /* Check transition from IE access model:
1320 add %reg1, foo@gottpoff(%rip), %reg2
1321 where reg1/reg2 are one of r16 to r31. */
1323 if (offset < 6
1324 || (offset + 4) > sec->size
1325 || contents[offset - 6] != 0x62)
1326 return elf_x86_tls_error_yes;
1328 val = bfd_get_8 (abfd, contents + offset - 2);
1329 if (val != 0x01 && val != 0x03)
1330 return elf_x86_tls_error_add;
1332 val = bfd_get_8 (abfd, contents + offset - 1);
1333 return ((val & 0xc7) == 5
1334 ? elf_x86_tls_error_none
1335 : elf_x86_tls_error_yes);
1337 case R_X86_64_GOTTPOFF:
1338 /* Check transition from IE access model:
1339 mov foo@gottpoff(%rip), %reg
1340 add foo@gottpoff(%rip), %reg
1343 /* Check REX prefix first. */
1344 if (offset >= 3 && (offset + 4) <= sec->size)
1346 val = bfd_get_8 (abfd, contents + offset - 3);
1347 if (val != 0x48 && val != 0x4c)
1349 /* X32 may have 0x44 REX prefix or no REX prefix. */
1350 if (ABI_64_P (abfd))
1351 return elf_x86_tls_error_yes;
1354 else
1356 /* X32 may not have any REX prefix. */
1357 if (ABI_64_P (abfd))
1358 return elf_x86_tls_error_yes;
1359 if (offset < 2 || (offset + 3) > sec->size)
1360 return elf_x86_tls_error_yes;
1363 check_gottpoff:
1364 val = bfd_get_8 (abfd, contents + offset - 2);
1365 if (val != 0x8b && val != 0x03)
1366 return elf_x86_tls_error_add_mov;
1368 val = bfd_get_8 (abfd, contents + offset - 1);
1369 return ((val & 0xc7) == 5
1370 ? elf_x86_tls_error_none
1371 : elf_x86_tls_error_yes);
1373 case R_X86_64_CODE_4_GOTPC32_TLSDESC:
1374 /* Check transition from GDesc access model:
1375 lea x@tlsdesc(%rip), %reg
1376 where reg is one of r16 to r31. */
1378 if (offset < 4
1379 || (offset + 4) > sec->size
1380 || contents[offset - 4] != 0xd5)
1381 return elf_x86_tls_error_yes;
1383 goto check_tlsdesc;
1385 case R_X86_64_GOTPC32_TLSDESC:
1386 /* Check transition from GDesc access model:
1387 leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
1388 rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
1390 Make sure it's a leaq adding rip to a 32-bit offset
1391 into any register, although it's probably almost always
1392 going to be rax. */
1394 if (offset < 3 || (offset + 4) > sec->size)
1395 return elf_x86_tls_error_yes;
1397 val = bfd_get_8 (abfd, contents + offset - 3);
1398 val &= 0xfb;
1399 if (val != 0x48 && (ABI_64_P (abfd) || val != 0x40))
1400 return elf_x86_tls_error_yes;
1402 check_tlsdesc:
1403 if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
1404 return elf_x86_tls_error_lea;
1406 val = bfd_get_8 (abfd, contents + offset - 1);
1407 return ((val & 0xc7) == 0x05
1408 ? elf_x86_tls_error_none
1409 : elf_x86_tls_error_yes);
1411 case R_X86_64_TLSDESC_CALL:
1412 /* Check transition from GDesc access model:
1413 call *x@tlsdesc(%rax) <--- LP64 mode.
1414 call *x@tlsdesc(%eax) <--- X32 mode.
1416 if (offset + 2 <= sec->size)
1418 unsigned int prefix;
1419 call = contents + offset;
1420 prefix = 0;
1421 if (!ABI_64_P (abfd))
1423 /* Check for call *x@tlsdesc(%eax). */
1424 if (call[0] == 0x67)
1426 prefix = 1;
1427 if (offset + 3 > sec->size)
1428 return elf_x86_tls_error_yes;
1431 /* Make sure that it's a call *x@tlsdesc(%rax). */
1432 return (call[prefix] == 0xff && call[1 + prefix] == 0x10
1433 ? elf_x86_tls_error_none
1434 : elf_x86_tls_error_indirect_call);
1437 return elf_x86_tls_error_yes;
1439 default:
1440 abort ();
1444 /* Return TRUE if the TLS access transition is OK or no transition
1445 will be performed. Update R_TYPE if there is a transition. */
1447 static bool
1448 elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
1449 asection *sec, bfd_byte *contents,
1450 Elf_Internal_Shdr *symtab_hdr,
1451 struct elf_link_hash_entry **sym_hashes,
1452 unsigned int *r_type, int tls_type,
1453 const Elf_Internal_Rela *rel,
1454 const Elf_Internal_Rela *relend,
1455 struct elf_link_hash_entry *h,
1456 Elf_Internal_Sym *sym,
1457 bool from_relocate_section)
1459 unsigned int from_type = *r_type;
1460 unsigned int to_type = from_type;
1461 bool check = true;
1463 /* Skip TLS transition for functions. */
1464 if (h != NULL
1465 && (h->type == STT_FUNC
1466 || h->type == STT_GNU_IFUNC))
1467 return true;
1469 switch (from_type)
1471 case R_X86_64_TLSGD:
1472 case R_X86_64_GOTPC32_TLSDESC:
1473 case R_X86_64_CODE_4_GOTPC32_TLSDESC:
1474 case R_X86_64_TLSDESC_CALL:
1475 case R_X86_64_GOTTPOFF:
1476 case R_X86_64_CODE_4_GOTTPOFF:
1477 case R_X86_64_CODE_6_GOTTPOFF:
1478 if (bfd_link_executable (info))
1480 if (h == NULL)
1481 to_type = R_X86_64_TPOFF32;
1482 else
1483 to_type = R_X86_64_GOTTPOFF;
1486 /* When we are called from elf_x86_64_relocate_section, there may
1487 be additional transitions based on TLS_TYPE. */
1488 if (from_relocate_section)
1490 unsigned int new_to_type = to_type;
1492 if (TLS_TRANSITION_IE_TO_LE_P (info, h, tls_type))
1493 new_to_type = R_X86_64_TPOFF32;
1495 if (to_type == R_X86_64_TLSGD
1496 || to_type == R_X86_64_GOTPC32_TLSDESC
1497 || to_type == R_X86_64_CODE_4_GOTPC32_TLSDESC
1498 || to_type == R_X86_64_TLSDESC_CALL)
1500 if (tls_type == GOT_TLS_IE)
1501 new_to_type = R_X86_64_GOTTPOFF;
1504 /* We checked the transition before when we were called from
1505 elf_x86_64_scan_relocs. We only want to check the new
1506 transition which hasn't been checked before. */
1507 check = (new_to_type != to_type
1508 && (from_type == to_type
1509 || (from_type == R_X86_64_CODE_4_GOTTPOFF
1510 && to_type == R_X86_64_GOTTPOFF)
1511 || (from_type == R_X86_64_CODE_6_GOTTPOFF
1512 && to_type == R_X86_64_GOTTPOFF)));
1513 to_type = new_to_type;
1516 break;
1518 case R_X86_64_TLSLD:
1519 if (bfd_link_executable (info))
1520 to_type = R_X86_64_TPOFF32;
1521 break;
1523 default:
1524 return true;
1527 /* Return TRUE if there is no transition. */
1528 if (from_type == to_type
1529 || (from_type == R_X86_64_CODE_4_GOTTPOFF
1530 && to_type == R_X86_64_GOTTPOFF)
1531 || (from_type == R_X86_64_CODE_6_GOTTPOFF
1532 && to_type == R_X86_64_GOTTPOFF))
1533 return true;
1535 /* Check if the transition can be performed. */
1536 enum elf_x86_tls_error_type tls_error;
1537 if (check
1538 && ((tls_error = elf_x86_64_check_tls_transition (abfd, info, sec,
1539 contents,
1540 symtab_hdr,
1541 sym_hashes,
1542 from_type, rel,
1543 relend))
1544 != elf_x86_tls_error_none))
1547 reloc_howto_type *from, *to;
1549 from = elf_x86_64_rtype_to_howto (abfd, from_type);
1550 to = elf_x86_64_rtype_to_howto (abfd, to_type);
1552 if (from == NULL || to == NULL)
1553 return false;
1555 _bfd_x86_elf_link_report_tls_transition_error
1556 (info, abfd, sec, symtab_hdr, h, sym, rel, from->name,
1557 to->name, tls_error);
1559 return false;
1562 *r_type = to_type;
1563 return true;
1566 static bool
1567 elf_x86_64_need_pic (struct bfd_link_info *info,
1568 bfd *input_bfd, asection *sec,
1569 struct elf_link_hash_entry *h,
1570 Elf_Internal_Shdr *symtab_hdr,
1571 Elf_Internal_Sym *isym,
1572 reloc_howto_type *howto)
1574 const char *v = "";
1575 const char *und = "";
1576 const char *pic = "";
1577 const char *object;
1579 const char *name;
1580 if (h)
1582 name = h->root.root.string;
1583 switch (ELF_ST_VISIBILITY (h->other))
1585 case STV_HIDDEN:
1586 v = _("hidden symbol ");
1587 break;
1588 case STV_INTERNAL:
1589 v = _("internal symbol ");
1590 break;
1591 case STV_PROTECTED:
1592 v = _("protected symbol ");
1593 break;
1594 default:
1595 if (((struct elf_x86_link_hash_entry *) h)->def_protected)
1596 v = _("protected symbol ");
1597 else
1598 v = _("symbol ");
1599 pic = NULL;
1600 break;
1603 if (!SYMBOL_DEFINED_NON_SHARED_P (h) && !h->def_dynamic)
1604 und = _("undefined ");
1606 else
1608 name = bfd_elf_sym_name (input_bfd, symtab_hdr, isym, NULL);
1609 pic = NULL;
1612 if (bfd_link_dll (info))
1614 object = _("a shared object");
1615 if (!pic)
1616 pic = _("; recompile with -fPIC");
1618 else
1620 if (bfd_link_pie (info))
1621 object = _("a PIE object");
1622 else
1623 object = _("a PDE object");
1624 if (!pic)
1625 pic = _("; recompile with -fPIE");
1628 /* xgettext:c-format */
1629 _bfd_error_handler (_("%pB: relocation %s against %s%s`%s' can "
1630 "not be used when making %s%s"),
1631 input_bfd, howto->name, und, v, name,
1632 object, pic);
1633 bfd_set_error (bfd_error_bad_value);
1634 sec->check_relocs_failed = 1;
1635 return false;
1638 /* With the local symbol, foo, we convert
1639 mov foo@GOTPCREL(%rip), %reg
1641 lea foo(%rip), %reg
1642 and convert
1643 call/jmp *foo@GOTPCREL(%rip)
1645 nop call foo/jmp foo nop
1646 When PIC is false, convert
1647 test %reg, foo@GOTPCREL(%rip)
1649 test $foo, %reg
1650 and convert
1651 binop foo@GOTPCREL(%rip), %reg
1653 binop $foo, %reg
1654 where binop is one of adc, add, and, cmp, or, sbb, sub, xor
1655 instructions. */
1657 static bool
1658 elf_x86_64_convert_load_reloc (bfd *abfd,
1659 bfd_byte *contents,
1660 unsigned int *r_type_p,
1661 Elf_Internal_Rela *irel,
1662 struct elf_link_hash_entry *h,
1663 bool *converted,
1664 struct bfd_link_info *link_info)
1666 struct elf_x86_link_hash_table *htab;
1667 bool is_pic;
1668 bool no_overflow;
1669 bool relocx;
1670 bool to_reloc_pc32;
1671 bool abs_symbol;
1672 bool local_ref;
1673 asection *tsec;
1674 bfd_signed_vma raddend;
1675 unsigned int opcode;
1676 unsigned int modrm;
1677 unsigned int r_type = *r_type_p;
1678 unsigned int r_symndx;
1679 bfd_vma roff = irel->r_offset;
1680 bfd_vma abs_relocation;
1682 if (roff < (r_type == R_X86_64_CODE_4_GOTPCRELX
1683 ? 4 : (r_type == R_X86_64_REX_GOTPCRELX ? 3 : 2)))
1684 return true;
1686 raddend = irel->r_addend;
1687 /* Addend for 32-bit PC-relative relocation must be -4. */
1688 if (raddend != -4)
1689 return true;
1691 htab = elf_x86_hash_table (link_info, X86_64_ELF_DATA);
1692 is_pic = bfd_link_pic (link_info);
1694 if (r_type == R_X86_64_CODE_4_GOTPCRELX)
1696 /* Skip if this isn't a REX2 instruction. */
1697 opcode = bfd_get_8 (abfd, contents + roff - 4);
1698 if (opcode != 0xd5)
1699 return true;
1701 relocx = true;
1703 else
1704 relocx = (r_type == R_X86_64_GOTPCRELX
1705 || r_type == R_X86_64_REX_GOTPCRELX);
1707 /* TRUE if --no-relax is used. */
1708 no_overflow = link_info->disable_target_specific_optimizations > 1;
1710 r_symndx = htab->r_sym (irel->r_info);
1712 opcode = bfd_get_8 (abfd, contents + roff - 2);
1714 /* Convert mov to lea since it has been done for a while. */
1715 if (opcode != 0x8b)
1717 /* Only convert R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX
1718 and R_X86_64_CODE_4_GOTPCRELX for call, jmp or one of adc,
1719 add, and, cmp, or, sbb, sub, test, xor instructions. */
1720 if (!relocx)
1721 return true;
1724 /* We convert only to R_X86_64_PC32:
1725 1. Branch.
1726 2. R_X86_64_GOTPCREL since we can't modify REX byte.
1727 3. no_overflow is true.
1728 4. PIC.
1730 to_reloc_pc32 = (opcode == 0xff
1731 || !relocx
1732 || no_overflow
1733 || is_pic);
1735 abs_symbol = false;
1736 abs_relocation = 0;
1738 /* Get the symbol referred to by the reloc. */
1739 if (h == NULL)
1741 Elf_Internal_Sym *isym
1742 = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
1744 /* Skip relocation against undefined symbols. */
1745 if (isym->st_shndx == SHN_UNDEF)
1746 return true;
1748 local_ref = true;
1749 if (isym->st_shndx == SHN_ABS)
1751 tsec = bfd_abs_section_ptr;
1752 abs_symbol = true;
1753 abs_relocation = isym->st_value;
1755 else if (isym->st_shndx == SHN_COMMON)
1756 tsec = bfd_com_section_ptr;
1757 else if (isym->st_shndx == SHN_X86_64_LCOMMON)
1758 tsec = &_bfd_elf_large_com_section;
1759 else
1760 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1762 else
1764 /* Undefined weak symbol is only bound locally in executable
1765 and its reference is resolved as 0 without relocation
1766 overflow. We can only perform this optimization for
1767 GOTPCRELX relocations since we need to modify REX byte.
1768 It is OK convert mov with R_X86_64_GOTPCREL to
1769 R_X86_64_PC32. */
1770 struct elf_x86_link_hash_entry *eh = elf_x86_hash_entry (h);
1772 abs_symbol = ABS_SYMBOL_P (h);
1773 abs_relocation = h->root.u.def.value;
1775 /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P. */
1776 local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h);
1777 if ((relocx || opcode == 0x8b)
1778 && (h->root.type == bfd_link_hash_undefweak
1779 && !eh->linker_def
1780 && local_ref))
1782 if (opcode == 0xff)
1784 /* Skip for branch instructions since R_X86_64_PC32
1785 may overflow. */
1786 if (no_overflow)
1787 return true;
1789 else if (relocx)
1791 /* For non-branch instructions, we can convert to
1792 R_X86_64_32/R_X86_64_32S since we know if there
1793 is a REX byte. */
1794 to_reloc_pc32 = false;
1797 /* Since we don't know the current PC when PIC is true,
1798 we can't convert to R_X86_64_PC32. */
1799 if (to_reloc_pc32 && is_pic)
1800 return true;
1802 goto convert;
1804 /* Avoid optimizing GOTPCREL relocations againt _DYNAMIC since
1805 ld.so may use its link-time address. */
1806 else if (h->start_stop
1807 || eh->linker_def
1808 || ((h->def_regular
1809 || h->root.type == bfd_link_hash_defined
1810 || h->root.type == bfd_link_hash_defweak)
1811 && h != htab->elf.hdynamic
1812 && local_ref))
1814 /* bfd_link_hash_new or bfd_link_hash_undefined is
1815 set by an assignment in a linker script in
1816 bfd_elf_record_link_assignment. start_stop is set
1817 on __start_SECNAME/__stop_SECNAME which mark section
1818 SECNAME. */
1819 if (h->start_stop
1820 || eh->linker_def
1821 || (h->def_regular
1822 && (h->root.type == bfd_link_hash_new
1823 || h->root.type == bfd_link_hash_undefined
1824 || ((h->root.type == bfd_link_hash_defined
1825 || h->root.type == bfd_link_hash_defweak)
1826 && h->root.u.def.section == bfd_und_section_ptr))))
1828 /* Skip since R_X86_64_32/R_X86_64_32S may overflow. */
1829 if (no_overflow)
1830 return true;
1831 goto convert;
1833 tsec = h->root.u.def.section;
1835 else
1836 return true;
1839 /* Don't convert GOTPCREL relocation against large section. */
1840 if (elf_section_data (tsec) != NULL
1841 && (elf_section_flags (tsec) & SHF_X86_64_LARGE) != 0)
1842 return true;
1844 /* Skip since R_X86_64_PC32/R_X86_64_32/R_X86_64_32S may overflow. */
1845 if (no_overflow)
1846 return true;
1848 convert:
1849 if (opcode == 0xff)
1851 /* We have "call/jmp *foo@GOTPCREL(%rip)". */
1852 unsigned int nop;
1853 unsigned int disp;
1854 bfd_vma nop_offset;
1856 /* Convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX to
1857 R_X86_64_PC32. */
1858 modrm = bfd_get_8 (abfd, contents + roff - 1);
1859 if (modrm == 0x25)
1861 /* Convert to "jmp foo nop". */
1862 modrm = 0xe9;
1863 nop = NOP_OPCODE;
1864 nop_offset = irel->r_offset + 3;
1865 disp = bfd_get_32 (abfd, contents + irel->r_offset);
1866 irel->r_offset -= 1;
1867 bfd_put_32 (abfd, disp, contents + irel->r_offset);
1869 else
1871 struct elf_x86_link_hash_entry *eh
1872 = (struct elf_x86_link_hash_entry *) h;
1874 /* Convert to "nop call foo". ADDR_PREFIX_OPCODE
1875 is a nop prefix. */
1876 modrm = 0xe8;
1877 /* To support TLS optimization, always use addr32 prefix for
1878 "call *__tls_get_addr@GOTPCREL(%rip)". */
1879 if (eh && eh->tls_get_addr)
1881 nop = 0x67;
1882 nop_offset = irel->r_offset - 2;
1884 else
1886 nop = htab->params->call_nop_byte;
1887 if (htab->params->call_nop_as_suffix)
1889 nop_offset = irel->r_offset + 3;
1890 disp = bfd_get_32 (abfd, contents + irel->r_offset);
1891 irel->r_offset -= 1;
1892 bfd_put_32 (abfd, disp, contents + irel->r_offset);
1894 else
1895 nop_offset = irel->r_offset - 2;
1898 bfd_put_8 (abfd, nop, contents + nop_offset);
1899 bfd_put_8 (abfd, modrm, contents + irel->r_offset - 1);
1900 r_type = R_X86_64_PC32;
1902 else
1904 unsigned int rex = 0;
1905 unsigned int rex_mask = REX_R;
1906 unsigned int rex2 = 0;
1907 unsigned int rex2_mask = REX_R | REX_R << 4;
1908 bool rex_w = false;
1910 if (r_type == R_X86_64_CODE_4_GOTPCRELX)
1912 rex2 = bfd_get_8 (abfd, contents + roff - 3);
1913 rex_w = (rex2 & REX_W) != 0;
1915 else if (r_type == R_X86_64_REX_GOTPCRELX)
1917 rex = bfd_get_8 (abfd, contents + roff - 3);
1918 rex_w = (rex & REX_W) != 0;
1921 if (opcode == 0x8b)
1923 if (abs_symbol && local_ref && relocx)
1924 to_reloc_pc32 = false;
1926 if (to_reloc_pc32)
1928 /* Convert "mov foo@GOTPCREL(%rip), %reg" to
1929 "lea foo(%rip), %reg". */
1930 opcode = 0x8d;
1931 r_type = R_X86_64_PC32;
1933 else
1935 /* Convert "mov foo@GOTPCREL(%rip), %reg" to
1936 "mov $foo, %reg". */
1937 opcode = 0xc7;
1938 modrm = bfd_get_8 (abfd, contents + roff - 1);
1939 modrm = 0xc0 | (modrm & 0x38) >> 3;
1940 if (rex_w && ABI_64_P (link_info->output_bfd))
1942 /* Keep the REX_W bit in REX byte for LP64. */
1943 r_type = R_X86_64_32S;
1944 goto rewrite_modrm_rex;
1946 else
1948 /* If the REX_W bit in REX byte isn't needed,
1949 use R_X86_64_32 and clear the W bit to avoid
1950 sign-extend imm32 to imm64. */
1951 r_type = R_X86_64_32;
1952 /* Clear the W bit in REX byte and REX2 payload. */
1953 rex_mask |= REX_W;
1954 rex2_mask |= REX_W;
1955 goto rewrite_modrm_rex;
1959 else
1961 /* R_X86_64_PC32 isn't supported. */
1962 if (to_reloc_pc32)
1963 return true;
1965 modrm = bfd_get_8 (abfd, contents + roff - 1);
1966 if (opcode == 0x85)
1968 /* Convert "test %reg, foo@GOTPCREL(%rip)" to
1969 "test $foo, %reg". */
1970 modrm = 0xc0 | (modrm & 0x38) >> 3;
1971 opcode = 0xf7;
1973 else
1975 /* Convert "binop foo@GOTPCREL(%rip), %reg" to
1976 "binop $foo, %reg". */
1977 modrm = 0xc0 | (modrm & 0x38) >> 3 | (opcode & 0x3c);
1978 opcode = 0x81;
1981 /* Use R_X86_64_32 with 32-bit operand to avoid relocation
1982 overflow when sign-extending imm32 to imm64. */
1983 r_type = rex_w ? R_X86_64_32S : R_X86_64_32;
1985 rewrite_modrm_rex:
1986 if (abs_relocation)
1988 /* Check if R_X86_64_32S/R_X86_64_32 fits. */
1989 if (r_type == R_X86_64_32S)
1991 if ((abs_relocation + 0x80000000) > 0xffffffff)
1992 return true;
1994 else
1996 if (abs_relocation > 0xffffffff)
1997 return true;
2001 bfd_put_8 (abfd, modrm, contents + roff - 1);
2003 if (rex)
2005 /* Move the R bit to the B bit in REX byte. */
2006 rex = (rex & ~rex_mask) | (rex & REX_R) >> 2;
2007 bfd_put_8 (abfd, rex, contents + roff - 3);
2009 else if (rex2)
2011 /* Move the R bits to the B bits in REX2 payload byte. */
2012 rex2 = ((rex2 & ~rex2_mask)
2013 | (rex2 & (REX_R | REX_R << 4)) >> 2);
2014 bfd_put_8 (abfd, rex2, contents + roff - 3);
2017 /* No addend for R_X86_64_32/R_X86_64_32S relocations. */
2018 irel->r_addend = 0;
2021 bfd_put_8 (abfd, opcode, contents + roff - 2);
2024 *r_type_p = r_type;
2025 irel->r_info = htab->r_info (r_symndx,
2026 r_type | R_X86_64_converted_reloc_bit);
2028 *converted = true;
2030 return true;
2033 /* Look through the relocs for a section during the first phase, and
2034 calculate needed space in the global offset table, and procedure
2035 linkage table. */
2037 static bool
2038 elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
2039 asection *sec,
2040 const Elf_Internal_Rela *relocs)
2042 struct elf_x86_link_hash_table *htab;
2043 Elf_Internal_Shdr *symtab_hdr;
2044 struct elf_link_hash_entry **sym_hashes;
2045 const Elf_Internal_Rela *rel;
2046 const Elf_Internal_Rela *rel_end;
2047 bfd_byte *contents;
2048 bool converted;
2050 if (bfd_link_relocatable (info))
2051 return true;
2053 htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
2054 if (htab == NULL)
2056 sec->check_relocs_failed = 1;
2057 return false;
2060 BFD_ASSERT (is_x86_elf (abfd, htab));
2062 /* Get the section contents. */
2063 if (elf_section_data (sec)->this_hdr.contents != NULL)
2064 contents = elf_section_data (sec)->this_hdr.contents;
2065 else if (!_bfd_elf_mmap_section_contents (abfd, sec, &contents))
2067 sec->check_relocs_failed = 1;
2068 return false;
2071 symtab_hdr = &elf_symtab_hdr (abfd);
2072 sym_hashes = elf_sym_hashes (abfd);
2074 converted = false;
2076 rel_end = relocs + sec->reloc_count;
2077 for (rel = relocs; rel < rel_end; rel++)
2079 unsigned int r_type;
2080 unsigned int r_symndx;
2081 struct elf_link_hash_entry *h;
2082 struct elf_x86_link_hash_entry *eh;
2083 Elf_Internal_Sym *isym;
2084 const char *name;
2085 bool size_reloc;
2086 bool converted_reloc;
2087 bool no_dynreloc;
2089 r_symndx = htab->r_sym (rel->r_info);
2090 r_type = ELF32_R_TYPE (rel->r_info);
2092 /* Don't check R_X86_64_NONE. */
2093 if (r_type == R_X86_64_NONE)
2094 continue;
2096 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
2098 /* xgettext:c-format */
2099 _bfd_error_handler (_("%pB: bad symbol index: %d"),
2100 abfd, r_symndx);
2101 goto error_return;
2104 if (r_symndx < symtab_hdr->sh_info)
2106 /* A local symbol. */
2107 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
2108 abfd, r_symndx);
2109 if (isym == NULL)
2110 goto error_return;
2112 /* Check relocation against local STT_GNU_IFUNC symbol. */
2113 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
2115 h = _bfd_elf_x86_get_local_sym_hash (htab, abfd, rel,
2116 true);
2117 if (h == NULL)
2118 goto error_return;
2120 /* Fake a STT_GNU_IFUNC symbol. */
2121 h->root.root.string = bfd_elf_sym_name (abfd, symtab_hdr,
2122 isym, NULL);
2123 h->type = STT_GNU_IFUNC;
2124 h->def_regular = 1;
2125 h->ref_regular = 1;
2126 h->forced_local = 1;
2127 h->root.type = bfd_link_hash_defined;
2129 else
2130 h = NULL;
2132 else
2134 isym = NULL;
2135 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2136 while (h->root.type == bfd_link_hash_indirect
2137 || h->root.type == bfd_link_hash_warning)
2138 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2141 /* Check invalid x32 relocations. */
2142 if (!ABI_64_P (abfd))
2143 switch (r_type)
2145 default:
2146 break;
2148 case R_X86_64_DTPOFF64:
2149 case R_X86_64_TPOFF64:
2150 case R_X86_64_PC64:
2151 case R_X86_64_GOTOFF64:
2152 case R_X86_64_GOT64:
2153 case R_X86_64_GOTPCREL64:
2154 case R_X86_64_GOTPC64:
2155 case R_X86_64_GOTPLT64:
2156 case R_X86_64_PLTOFF64:
2158 if (h)
2159 name = h->root.root.string;
2160 else
2161 name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
2162 NULL);
2163 _bfd_error_handler
2164 /* xgettext:c-format */
2165 (_("%pB: relocation %s against symbol `%s' isn't "
2166 "supported in x32 mode"), abfd,
2167 x86_64_elf_howto_table[r_type].name, name);
2168 bfd_set_error (bfd_error_bad_value);
2169 goto error_return;
2171 break;
2174 eh = (struct elf_x86_link_hash_entry *) h;
2176 if (h != NULL)
2178 /* It is referenced by a non-shared object. */
2179 h->ref_regular = 1;
2182 converted_reloc = false;
2183 if ((r_type == R_X86_64_GOTPCREL
2184 || r_type == R_X86_64_GOTPCRELX
2185 || r_type == R_X86_64_REX_GOTPCRELX
2186 || r_type == R_X86_64_CODE_4_GOTPCRELX)
2187 && (h == NULL || h->type != STT_GNU_IFUNC))
2189 Elf_Internal_Rela *irel = (Elf_Internal_Rela *) rel;
2190 if (!elf_x86_64_convert_load_reloc (abfd, contents, &r_type,
2191 irel, h, &converted_reloc,
2192 info))
2193 goto error_return;
2195 if (converted_reloc)
2196 converted = true;
2199 if (!_bfd_elf_x86_valid_reloc_p (sec, info, htab, rel, h, isym,
2200 symtab_hdr, &no_dynreloc))
2201 return false;
2203 if (! elf_x86_64_tls_transition (info, abfd, sec, contents,
2204 symtab_hdr, sym_hashes,
2205 &r_type, GOT_UNKNOWN,
2206 rel, rel_end, h, isym, false))
2207 goto error_return;
2209 /* Check if _GLOBAL_OFFSET_TABLE_ is referenced. */
2210 if (h == htab->elf.hgot)
2211 htab->got_referenced = true;
2213 switch (r_type)
2215 case R_X86_64_TLSLD:
2216 htab->tls_ld_or_ldm_got.refcount = 1;
2217 goto create_got;
2219 case R_X86_64_TPOFF32:
2220 if (!bfd_link_executable (info) && ABI_64_P (abfd))
2221 return elf_x86_64_need_pic (info, abfd, sec, h, symtab_hdr, isym,
2222 &x86_64_elf_howto_table[r_type]);
2223 if (eh != NULL)
2224 eh->zero_undefweak &= 0x2;
2225 break;
2227 case R_X86_64_GOTTPOFF:
2228 case R_X86_64_CODE_4_GOTTPOFF:
2229 case R_X86_64_CODE_6_GOTTPOFF:
2230 if (!bfd_link_executable (info))
2231 info->flags |= DF_STATIC_TLS;
2232 /* Fall through */
2234 case R_X86_64_GOT32:
2235 case R_X86_64_GOTPCREL:
2236 case R_X86_64_GOTPCRELX:
2237 case R_X86_64_REX_GOTPCRELX:
2238 case R_X86_64_CODE_4_GOTPCRELX:
2239 case R_X86_64_TLSGD:
2240 case R_X86_64_GOT64:
2241 case R_X86_64_GOTPCREL64:
2242 case R_X86_64_GOTPLT64:
2243 case R_X86_64_GOTPC32_TLSDESC:
2244 case R_X86_64_CODE_4_GOTPC32_TLSDESC:
2245 case R_X86_64_TLSDESC_CALL:
2246 /* This symbol requires a global offset table entry. */
2248 int tls_type, old_tls_type;
2250 switch (r_type)
2252 default:
2253 tls_type = GOT_NORMAL;
2254 if (h)
2256 if (ABS_SYMBOL_P (h))
2257 tls_type = GOT_ABS;
2259 else if (isym->st_shndx == SHN_ABS)
2260 tls_type = GOT_ABS;
2261 break;
2262 case R_X86_64_TLSGD:
2263 tls_type = GOT_TLS_GD;
2264 break;
2265 case R_X86_64_GOTTPOFF:
2266 case R_X86_64_CODE_4_GOTTPOFF:
2267 case R_X86_64_CODE_6_GOTTPOFF:
2268 tls_type = GOT_TLS_IE;
2269 break;
2270 case R_X86_64_GOTPC32_TLSDESC:
2271 case R_X86_64_CODE_4_GOTPC32_TLSDESC:
2272 case R_X86_64_TLSDESC_CALL:
2273 tls_type = GOT_TLS_GDESC;
2274 break;
2277 if (h != NULL)
2279 h->got.refcount = 1;
2280 old_tls_type = eh->tls_type;
2282 else
2284 bfd_signed_vma *local_got_refcounts;
2286 if (!elf_x86_allocate_local_got_info (abfd,
2287 symtab_hdr->sh_info))
2288 goto error_return;
2290 /* This is a global offset table entry for a local symbol. */
2291 local_got_refcounts = elf_local_got_refcounts (abfd);
2292 local_got_refcounts[r_symndx] = 1;
2293 old_tls_type
2294 = elf_x86_local_got_tls_type (abfd) [r_symndx];
2297 /* If a TLS symbol is accessed using IE at least once,
2298 there is no point to use dynamic model for it. */
2299 if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
2300 && (! GOT_TLS_GD_ANY_P (old_tls_type)
2301 || tls_type != GOT_TLS_IE))
2303 if (old_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (tls_type))
2304 tls_type = old_tls_type;
2305 else if (GOT_TLS_GD_ANY_P (old_tls_type)
2306 && GOT_TLS_GD_ANY_P (tls_type))
2307 tls_type |= old_tls_type;
2308 else
2310 if (h)
2311 name = h->root.root.string;
2312 else
2313 name = bfd_elf_sym_name (abfd, symtab_hdr,
2314 isym, NULL);
2315 _bfd_error_handler
2316 /* xgettext:c-format */
2317 (_("%pB: '%s' accessed both as normal and"
2318 " thread local symbol"),
2319 abfd, name);
2320 bfd_set_error (bfd_error_bad_value);
2321 goto error_return;
2325 if (old_tls_type != tls_type)
2327 if (eh != NULL)
2328 eh->tls_type = tls_type;
2329 else
2330 elf_x86_local_got_tls_type (abfd) [r_symndx] = tls_type;
2333 /* Fall through */
2335 case R_X86_64_GOTOFF64:
2336 case R_X86_64_GOTPC32:
2337 case R_X86_64_GOTPC64:
2338 create_got:
2339 if (eh != NULL)
2340 eh->zero_undefweak &= 0x2;
2341 break;
2343 case R_X86_64_PLT32:
2344 /* This symbol requires a procedure linkage table entry. We
2345 actually build the entry in adjust_dynamic_symbol,
2346 because this might be a case of linking PIC code which is
2347 never referenced by a dynamic object, in which case we
2348 don't need to generate a procedure linkage table entry
2349 after all. */
2351 /* If this is a local symbol, we resolve it directly without
2352 creating a procedure linkage table entry. */
2353 if (h == NULL)
2354 continue;
2356 eh->zero_undefweak &= 0x2;
2357 h->needs_plt = 1;
2358 h->plt.refcount = 1;
2359 break;
2361 case R_X86_64_PLTOFF64:
2362 /* This tries to form the 'address' of a function relative
2363 to GOT. For global symbols we need a PLT entry. */
2364 if (h != NULL)
2366 h->needs_plt = 1;
2367 h->plt.refcount = 1;
2369 goto create_got;
2371 case R_X86_64_SIZE32:
2372 case R_X86_64_SIZE64:
2373 size_reloc = true;
2374 goto do_size;
2376 case R_X86_64_32:
2377 if (!ABI_64_P (abfd))
2378 goto pointer;
2379 /* Fall through. */
2380 case R_X86_64_8:
2381 case R_X86_64_16:
2382 case R_X86_64_32S:
2383 /* Check relocation overflow as these relocs may lead to
2384 run-time relocation overflow. Don't error out for
2385 sections we don't care about, such as debug sections or
2386 when relocation overflow check is disabled. */
2387 if (!htab->params->no_reloc_overflow_check
2388 && !converted_reloc
2389 && (bfd_link_pic (info)
2390 || (bfd_link_executable (info)
2391 && h != NULL
2392 && !h->def_regular
2393 && h->def_dynamic
2394 && (sec->flags & SEC_READONLY) == 0)))
2395 return elf_x86_64_need_pic (info, abfd, sec, h, symtab_hdr, isym,
2396 &x86_64_elf_howto_table[r_type]);
2397 /* Fall through. */
2399 case R_X86_64_PC8:
2400 case R_X86_64_PC16:
2401 case R_X86_64_PC32:
2402 case R_X86_64_PC64:
2403 case R_X86_64_64:
2404 pointer:
2405 if (eh != NULL && (sec->flags & SEC_CODE) != 0)
2406 eh->zero_undefweak |= 0x2;
2407 /* We are called after all symbols have been resolved. Only
2408 relocation against STT_GNU_IFUNC symbol must go through
2409 PLT. */
2410 if (h != NULL
2411 && (bfd_link_executable (info)
2412 || h->type == STT_GNU_IFUNC))
2414 bool func_pointer_ref = false;
2416 if (r_type == R_X86_64_PC32)
2418 /* Since something like ".long foo - ." may be used
2419 as pointer, make sure that PLT is used if foo is
2420 a function defined in a shared library. */
2421 if ((sec->flags & SEC_CODE) == 0)
2423 h->pointer_equality_needed = 1;
2424 if (bfd_link_pie (info)
2425 && h->type == STT_FUNC
2426 && !h->def_regular
2427 && h->def_dynamic)
2429 h->needs_plt = 1;
2430 h->plt.refcount = 1;
2434 else if (r_type != R_X86_64_PC64)
2436 /* At run-time, R_X86_64_64 can be resolved for both
2437 x86-64 and x32. But R_X86_64_32 and R_X86_64_32S
2438 can only be resolved for x32. Function pointer
2439 reference doesn't need PLT for pointer equality. */
2440 if ((sec->flags & SEC_READONLY) == 0
2441 && (r_type == R_X86_64_64
2442 || (!ABI_64_P (abfd)
2443 && (r_type == R_X86_64_32
2444 || r_type == R_X86_64_32S))))
2445 func_pointer_ref = true;
2447 /* IFUNC symbol needs pointer equality in PDE so that
2448 function pointer reference will be resolved to its
2449 PLT entry directly. */
2450 if (!func_pointer_ref
2451 || (bfd_link_pde (info)
2452 && h->type == STT_GNU_IFUNC))
2453 h->pointer_equality_needed = 1;
2456 if (!func_pointer_ref)
2458 /* If this reloc is in a read-only section, we might
2459 need a copy reloc. We can't check reliably at this
2460 stage whether the section is read-only, as input
2461 sections have not yet been mapped to output sections.
2462 Tentatively set the flag for now, and correct in
2463 adjust_dynamic_symbol. */
2464 h->non_got_ref = 1;
2466 if (!elf_has_indirect_extern_access (sec->owner))
2467 eh->non_got_ref_without_indirect_extern_access = 1;
2469 /* We may need a .plt entry if the symbol is a function
2470 defined in a shared lib or is a function referenced
2471 from the code or read-only section. */
2472 if (!h->def_regular
2473 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
2474 h->plt.refcount = 1;
2476 if (htab->elf.target_os != is_solaris
2477 && h->pointer_equality_needed
2478 && h->type == STT_FUNC
2479 && eh->def_protected
2480 && !SYMBOL_DEFINED_NON_SHARED_P (h)
2481 && h->def_dynamic)
2483 /* Disallow non-canonical reference to canonical
2484 protected function. */
2485 _bfd_error_handler
2486 /* xgettext:c-format */
2487 (_("%pB: non-canonical reference to canonical "
2488 "protected function `%s' in %pB"),
2489 abfd, h->root.root.string,
2490 h->root.u.def.section->owner);
2491 bfd_set_error (bfd_error_bad_value);
2492 goto error_return;
2497 size_reloc = false;
2498 do_size:
2499 if (!no_dynreloc
2500 && NEED_DYNAMIC_RELOCATION_P (true, info, true, h, sec,
2501 r_type,
2502 htab->pointer_r_type))
2504 struct elf_dyn_relocs *p;
2505 struct elf_dyn_relocs **head;
2507 /* If this is a global symbol, we count the number of
2508 relocations we need for this symbol. */
2509 if (h != NULL)
2510 head = &h->dyn_relocs;
2511 else
2513 /* Track dynamic relocs needed for local syms too.
2514 We really need local syms available to do this
2515 easily. Oh well. */
2516 asection *s;
2517 void **vpp;
2519 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
2520 abfd, r_symndx);
2521 if (isym == NULL)
2522 goto error_return;
2524 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2525 if (s == NULL)
2526 s = sec;
2528 /* Beware of type punned pointers vs strict aliasing
2529 rules. */
2530 vpp = &(elf_section_data (s)->local_dynrel);
2531 head = (struct elf_dyn_relocs **)vpp;
2534 p = *head;
2535 if (p == NULL || p->sec != sec)
2537 size_t amt = sizeof *p;
2539 p = ((struct elf_dyn_relocs *)
2540 bfd_alloc (htab->elf.dynobj, amt));
2541 if (p == NULL)
2542 goto error_return;
2543 p->next = *head;
2544 *head = p;
2545 p->sec = sec;
2546 p->count = 0;
2547 p->pc_count = 0;
2550 p->count += 1;
2551 /* Count size relocation as PC-relative relocation. */
2552 if (X86_PCREL_TYPE_P (true, r_type) || size_reloc)
2553 p->pc_count += 1;
2555 break;
2557 case R_X86_64_CODE_5_GOTPCRELX:
2558 case R_X86_64_CODE_5_GOTTPOFF:
2559 case R_X86_64_CODE_5_GOTPC32_TLSDESC:
2560 case R_X86_64_CODE_6_GOTPCRELX:
2561 case R_X86_64_CODE_6_GOTPC32_TLSDESC:
2563 /* These relocations are added only for completeness and
2564 aren't be used. */
2565 if (h)
2566 name = h->root.root.string;
2567 else
2568 name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
2569 NULL);
2570 _bfd_error_handler
2571 /* xgettext:c-format */
2572 (_("%pB: unsupported relocation %s against symbol `%s'"),
2573 abfd, x86_64_elf_howto_table[r_type].name, name);
2575 break;
2577 /* This relocation describes the C++ object vtable hierarchy.
2578 Reconstruct it for later use during GC. */
2579 case R_X86_64_GNU_VTINHERIT:
2580 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2581 goto error_return;
2582 break;
2584 /* This relocation describes which C++ vtable entries are actually
2585 used. Record for later use during GC. */
2586 case R_X86_64_GNU_VTENTRY:
2587 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2588 goto error_return;
2589 break;
2591 default:
2592 break;
2596 if (elf_section_data (sec)->this_hdr.contents != contents)
2598 if (!converted)
2599 _bfd_elf_munmap_section_contents (sec, contents);
2600 else
2602 /* Cache the section contents for elf_link_input_bfd if any
2603 load is converted or --no-keep-memory isn't used. */
2604 elf_section_data (sec)->this_hdr.contents = contents;
2605 info->cache_size += sec->size;
2609 /* Cache relocations if any load is converted. */
2610 if (elf_section_data (sec)->relocs != relocs && converted)
2611 elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
2613 return true;
2615 error_return:
2616 if (elf_section_data (sec)->this_hdr.contents != contents)
2617 _bfd_elf_munmap_section_contents (sec, contents);
2618 sec->check_relocs_failed = 1;
2619 return false;
2622 static bool
2623 elf_x86_64_early_size_sections (bfd *output_bfd, struct bfd_link_info *info)
2625 bfd *abfd;
2627 /* Scan relocations after rel_from_abs has been set on __ehdr_start. */
2628 for (abfd = info->input_bfds;
2629 abfd != (bfd *) NULL;
2630 abfd = abfd->link.next)
2631 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
2632 && !_bfd_elf_link_iterate_on_relocs (abfd, info,
2633 elf_x86_64_scan_relocs))
2634 return false;
2636 return _bfd_x86_elf_early_size_sections (output_bfd, info);
2639 /* Return the relocation value for @tpoff relocation
2640 if STT_TLS virtual address is ADDRESS. */
2642 static bfd_vma
2643 elf_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
2645 struct elf_link_hash_table *htab = elf_hash_table (info);
2646 const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
2647 bfd_vma static_tls_size;
2649 /* If tls_segment is NULL, we should have signalled an error already. */
2650 if (htab->tls_sec == NULL)
2651 return 0;
2653 /* Consider special static TLS alignment requirements. */
2654 static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment);
2655 return address - static_tls_size - htab->tls_sec->vma;
2658 /* Relocate an x86_64 ELF section. */
2660 static int
2661 elf_x86_64_relocate_section (bfd *output_bfd,
2662 struct bfd_link_info *info,
2663 bfd *input_bfd,
2664 asection *input_section,
2665 bfd_byte *contents,
2666 Elf_Internal_Rela *relocs,
2667 Elf_Internal_Sym *local_syms,
2668 asection **local_sections)
2670 struct elf_x86_link_hash_table *htab;
2671 Elf_Internal_Shdr *symtab_hdr;
2672 struct elf_link_hash_entry **sym_hashes;
2673 bfd_vma *local_got_offsets;
2674 bfd_vma *local_tlsdesc_gotents;
2675 Elf_Internal_Rela *rel;
2676 Elf_Internal_Rela *wrel;
2677 Elf_Internal_Rela *relend;
2678 unsigned int plt_entry_size;
2679 bool status;
2681 /* Skip if check_relocs or scan_relocs failed. */
2682 if (input_section->check_relocs_failed)
2683 return false;
2685 htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
2686 if (htab == NULL)
2687 return false;
2689 if (!is_x86_elf (input_bfd, htab))
2691 bfd_set_error (bfd_error_wrong_format);
2692 return false;
2695 plt_entry_size = htab->plt.plt_entry_size;
2696 symtab_hdr = &elf_symtab_hdr (input_bfd);
2697 sym_hashes = elf_sym_hashes (input_bfd);
2698 local_got_offsets = elf_local_got_offsets (input_bfd);
2699 local_tlsdesc_gotents = elf_x86_local_tlsdesc_gotent (input_bfd);
2701 _bfd_x86_elf_set_tls_module_base (info);
2703 status = true;
2704 rel = wrel = relocs;
2705 relend = relocs + input_section->reloc_count;
2706 for (; rel < relend; wrel++, rel++)
2708 unsigned int r_type, r_type_tls;
2709 reloc_howto_type *howto;
2710 unsigned long r_symndx;
2711 struct elf_link_hash_entry *h;
2712 struct elf_x86_link_hash_entry *eh;
2713 Elf_Internal_Sym *sym;
2714 asection *sec;
2715 bfd_vma off, offplt, plt_offset;
2716 bfd_vma relocation;
2717 bool unresolved_reloc;
2718 bfd_reloc_status_type r;
2719 int tls_type;
2720 asection *base_got, *resolved_plt;
2721 bfd_vma st_size;
2722 bool resolved_to_zero;
2723 bool relative_reloc;
2724 bool converted_reloc;
2725 bool need_copy_reloc_in_pie;
2726 bool no_copyreloc_p;
2728 r_type = ELF32_R_TYPE (rel->r_info);
2729 if (r_type == (int) R_X86_64_GNU_VTINHERIT
2730 || r_type == (int) R_X86_64_GNU_VTENTRY)
2732 if (wrel != rel)
2733 *wrel = *rel;
2734 continue;
2737 r_symndx = htab->r_sym (rel->r_info);
2738 converted_reloc = (r_type & R_X86_64_converted_reloc_bit) != 0;
2739 if (converted_reloc)
2741 r_type &= ~R_X86_64_converted_reloc_bit;
2742 rel->r_info = htab->r_info (r_symndx, r_type);
2745 howto = elf_x86_64_rtype_to_howto (input_bfd, r_type);
2746 if (howto == NULL)
2747 return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
2749 h = NULL;
2750 sym = NULL;
2751 sec = NULL;
2752 unresolved_reloc = false;
2753 if (r_symndx < symtab_hdr->sh_info)
2755 sym = local_syms + r_symndx;
2756 sec = local_sections[r_symndx];
2758 relocation = _bfd_elf_rela_local_sym (output_bfd, sym,
2759 &sec, rel);
2760 st_size = sym->st_size;
2762 /* Relocate against local STT_GNU_IFUNC symbol. */
2763 if (!bfd_link_relocatable (info)
2764 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2766 h = _bfd_elf_x86_get_local_sym_hash (htab, input_bfd,
2767 rel, false);
2768 if (h == NULL)
2769 abort ();
2771 /* Set STT_GNU_IFUNC symbol value. */
2772 h->root.u.def.value = sym->st_value;
2773 h->root.u.def.section = sec;
2776 else
2778 bool warned ATTRIBUTE_UNUSED;
2779 bool ignored ATTRIBUTE_UNUSED;
2781 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2782 r_symndx, symtab_hdr, sym_hashes,
2783 h, sec, relocation,
2784 unresolved_reloc, warned, ignored);
2785 st_size = h->size;
2788 if (sec != NULL && discarded_section (sec))
2790 _bfd_clear_contents (howto, input_bfd, input_section,
2791 contents, rel->r_offset);
2792 wrel->r_offset = rel->r_offset;
2793 wrel->r_info = 0;
2794 wrel->r_addend = 0;
2796 /* For ld -r, remove relocations in debug sections against
2797 sections defined in discarded sections. Not done for
2798 eh_frame editing code expects to be present. */
2799 if (bfd_link_relocatable (info)
2800 && (input_section->flags & SEC_DEBUGGING))
2801 wrel--;
2803 continue;
2806 if (bfd_link_relocatable (info))
2808 if (wrel != rel)
2809 *wrel = *rel;
2810 continue;
2813 if (rel->r_addend == 0 && !ABI_64_P (output_bfd))
2815 if (r_type == R_X86_64_64)
2817 /* For x32, treat R_X86_64_64 like R_X86_64_32 and
2818 zero-extend it to 64bit if addend is zero. */
2819 r_type = R_X86_64_32;
2820 memset (contents + rel->r_offset + 4, 0, 4);
2822 else if (r_type == R_X86_64_SIZE64)
2824 /* For x32, treat R_X86_64_SIZE64 like R_X86_64_SIZE32 and
2825 zero-extend it to 64bit if addend is zero. */
2826 r_type = R_X86_64_SIZE32;
2827 memset (contents + rel->r_offset + 4, 0, 4);
2831 eh = (struct elf_x86_link_hash_entry *) h;
2833 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
2834 it here if it is defined in a non-shared object. */
2835 if (h != NULL
2836 && h->type == STT_GNU_IFUNC
2837 && h->def_regular)
2839 bfd_vma plt_index;
2840 const char *name;
2842 if ((input_section->flags & SEC_ALLOC) == 0)
2844 /* If this is a SHT_NOTE section without SHF_ALLOC, treat
2845 STT_GNU_IFUNC symbol as STT_FUNC. */
2846 if (elf_section_type (input_section) == SHT_NOTE)
2847 goto skip_ifunc;
2848 /* Dynamic relocs are not propagated for SEC_DEBUGGING
2849 sections because such sections are not SEC_ALLOC and
2850 thus ld.so will not process them. */
2851 if ((input_section->flags & SEC_DEBUGGING) != 0)
2852 continue;
2853 abort ();
2856 switch (r_type)
2858 default:
2859 break;
2861 case R_X86_64_GOTPCREL:
2862 case R_X86_64_GOTPCRELX:
2863 case R_X86_64_REX_GOTPCRELX:
2864 case R_X86_64_CODE_4_GOTPCRELX:
2865 case R_X86_64_GOTPCREL64:
2866 base_got = htab->elf.sgot;
2867 off = h->got.offset;
2869 if (base_got == NULL)
2870 abort ();
2872 if (off == (bfd_vma) -1)
2874 /* We can't use h->got.offset here to save state, or
2875 even just remember the offset, as finish_dynamic_symbol
2876 would use that as offset into .got. */
2878 if (h->plt.offset == (bfd_vma) -1)
2879 abort ();
2881 if (htab->elf.splt != NULL)
2883 plt_index = (h->plt.offset / plt_entry_size
2884 - htab->plt.has_plt0);
2885 off = (plt_index + 3) * GOT_ENTRY_SIZE;
2886 base_got = htab->elf.sgotplt;
2888 else
2890 plt_index = h->plt.offset / plt_entry_size;
2891 off = plt_index * GOT_ENTRY_SIZE;
2892 base_got = htab->elf.igotplt;
2895 if (h->dynindx == -1
2896 || h->forced_local
2897 || info->symbolic)
2899 /* This references the local defitionion. We must
2900 initialize this entry in the global offset table.
2901 Since the offset must always be a multiple of 8,
2902 we use the least significant bit to record
2903 whether we have initialized it already.
2905 When doing a dynamic link, we create a .rela.got
2906 relocation entry to initialize the value. This
2907 is done in the finish_dynamic_symbol routine. */
2908 if ((off & 1) != 0)
2909 off &= ~1;
2910 else
2912 bfd_put_64 (output_bfd, relocation,
2913 base_got->contents + off);
2914 /* Note that this is harmless for the GOTPLT64
2915 case, as -1 | 1 still is -1. */
2916 h->got.offset |= 1;
2921 relocation = (base_got->output_section->vma
2922 + base_got->output_offset + off);
2924 goto do_relocation;
2927 if (h->plt.offset == (bfd_vma) -1)
2929 /* Handle static pointers of STT_GNU_IFUNC symbols. */
2930 if (r_type == htab->pointer_r_type
2931 && (input_section->flags & SEC_CODE) == 0)
2932 goto do_ifunc_pointer;
2933 goto bad_ifunc_reloc;
2936 /* STT_GNU_IFUNC symbol must go through PLT. */
2937 if (htab->elf.splt != NULL)
2939 if (htab->plt_second != NULL)
2941 resolved_plt = htab->plt_second;
2942 plt_offset = eh->plt_second.offset;
2944 else
2946 resolved_plt = htab->elf.splt;
2947 plt_offset = h->plt.offset;
2950 else
2952 resolved_plt = htab->elf.iplt;
2953 plt_offset = h->plt.offset;
2956 relocation = (resolved_plt->output_section->vma
2957 + resolved_plt->output_offset + plt_offset);
2959 switch (r_type)
2961 default:
2962 bad_ifunc_reloc:
2963 if (h->root.root.string)
2964 name = h->root.root.string;
2965 else
2966 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
2967 NULL);
2968 _bfd_error_handler
2969 /* xgettext:c-format */
2970 (_("%pB: relocation %s against STT_GNU_IFUNC "
2971 "symbol `%s' isn't supported"), input_bfd,
2972 howto->name, name);
2973 bfd_set_error (bfd_error_bad_value);
2974 return false;
2976 case R_X86_64_32S:
2977 if (bfd_link_pic (info))
2978 abort ();
2979 goto do_relocation;
2981 case R_X86_64_32:
2982 if (ABI_64_P (output_bfd))
2983 goto do_relocation;
2984 /* FALLTHROUGH */
2985 case R_X86_64_64:
2986 do_ifunc_pointer:
2987 if (rel->r_addend != 0)
2989 if (h->root.root.string)
2990 name = h->root.root.string;
2991 else
2992 name = bfd_elf_sym_name (input_bfd, symtab_hdr,
2993 sym, NULL);
2994 _bfd_error_handler
2995 /* xgettext:c-format */
2996 (_("%pB: relocation %s against STT_GNU_IFUNC "
2997 "symbol `%s' has non-zero addend: %" PRId64),
2998 input_bfd, howto->name, name, (int64_t) rel->r_addend);
2999 bfd_set_error (bfd_error_bad_value);
3000 return false;
3003 /* Generate dynamic relcoation only when there is a
3004 non-GOT reference in a shared object or there is no
3005 PLT. */
3006 if ((bfd_link_pic (info) && h->non_got_ref)
3007 || h->plt.offset == (bfd_vma) -1)
3009 Elf_Internal_Rela outrel;
3010 asection *sreloc;
3012 /* Need a dynamic relocation to get the real function
3013 address. */
3014 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
3015 info,
3016 input_section,
3017 rel->r_offset);
3018 if (outrel.r_offset == (bfd_vma) -1
3019 || outrel.r_offset == (bfd_vma) -2)
3020 abort ();
3022 outrel.r_offset += (input_section->output_section->vma
3023 + input_section->output_offset);
3025 if (POINTER_LOCAL_IFUNC_P (info, h))
3027 info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
3028 h->root.root.string,
3029 h->root.u.def.section->owner);
3031 /* This symbol is resolved locally. */
3032 outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
3033 outrel.r_addend = (h->root.u.def.value
3034 + h->root.u.def.section->output_section->vma
3035 + h->root.u.def.section->output_offset);
3037 if (htab->params->report_relative_reloc)
3038 _bfd_x86_elf_link_report_relative_reloc
3039 (info, input_section, h, sym,
3040 "R_X86_64_IRELATIVE", &outrel);
3042 else
3044 outrel.r_info = htab->r_info (h->dynindx, r_type);
3045 outrel.r_addend = 0;
3048 /* Dynamic relocations are stored in
3049 1. .rela.ifunc section in PIC object.
3050 2. .rela.got section in dynamic executable.
3051 3. .rela.iplt section in static executable. */
3052 if (bfd_link_pic (info))
3053 sreloc = htab->elf.irelifunc;
3054 else if (htab->elf.splt != NULL)
3055 sreloc = htab->elf.srelgot;
3056 else
3057 sreloc = htab->elf.irelplt;
3058 elf_append_rela (output_bfd, sreloc, &outrel);
3060 /* If this reloc is against an external symbol, we
3061 do not want to fiddle with the addend. Otherwise,
3062 we need to include the symbol value so that it
3063 becomes an addend for the dynamic reloc. For an
3064 internal symbol, we have updated addend. */
3065 continue;
3067 /* FALLTHROUGH */
3068 case R_X86_64_PC32:
3069 case R_X86_64_PC64:
3070 case R_X86_64_PLT32:
3071 goto do_relocation;
3075 skip_ifunc:
3076 resolved_to_zero = (eh != NULL
3077 && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
3079 /* When generating a shared object, the relocations handled here are
3080 copied into the output file to be resolved at run time. */
3081 switch (r_type)
3083 case R_X86_64_GOT32:
3084 case R_X86_64_GOT64:
3085 /* Relocation is to the entry for this symbol in the global
3086 offset table. */
3087 case R_X86_64_GOTPCREL:
3088 case R_X86_64_GOTPCRELX:
3089 case R_X86_64_REX_GOTPCRELX:
3090 case R_X86_64_CODE_4_GOTPCRELX:
3091 case R_X86_64_GOTPCREL64:
3092 /* Use global offset table entry as symbol value. */
3093 case R_X86_64_GOTPLT64:
3094 /* This is obsolete and treated the same as GOT64. */
3095 base_got = htab->elf.sgot;
3097 if (htab->elf.sgot == NULL)
3098 abort ();
3100 relative_reloc = false;
3101 if (h != NULL)
3103 off = h->got.offset;
3104 if (h->needs_plt
3105 && h->plt.offset != (bfd_vma)-1
3106 && off == (bfd_vma)-1)
3108 /* We can't use h->got.offset here to save
3109 state, or even just remember the offset, as
3110 finish_dynamic_symbol would use that as offset into
3111 .got. */
3112 bfd_vma plt_index = (h->plt.offset / plt_entry_size
3113 - htab->plt.has_plt0);
3114 off = (plt_index + 3) * GOT_ENTRY_SIZE;
3115 base_got = htab->elf.sgotplt;
3118 if (RESOLVED_LOCALLY_P (info, h, htab))
3120 /* We must initialize this entry in the global offset
3121 table. Since the offset must always be a multiple
3122 of 8, we use the least significant bit to record
3123 whether we have initialized it already.
3125 When doing a dynamic link, we create a .rela.got
3126 relocation entry to initialize the value. This is
3127 done in the finish_dynamic_symbol routine. */
3128 if ((off & 1) != 0)
3129 off &= ~1;
3130 else
3132 bfd_put_64 (output_bfd, relocation,
3133 base_got->contents + off);
3134 /* Note that this is harmless for the GOTPLT64 case,
3135 as -1 | 1 still is -1. */
3136 h->got.offset |= 1;
3138 /* NB: Don't generate relative relocation here if
3139 it has been generated by DT_RELR. */
3140 if (!info->enable_dt_relr
3141 && GENERATE_RELATIVE_RELOC_P (info, h))
3143 /* If this symbol isn't dynamic in PIC,
3144 generate R_X86_64_RELATIVE here. */
3145 eh->no_finish_dynamic_symbol = 1;
3146 relative_reloc = true;
3150 else
3151 unresolved_reloc = false;
3153 else
3155 if (local_got_offsets == NULL)
3156 abort ();
3158 off = local_got_offsets[r_symndx];
3160 /* The offset must always be a multiple of 8. We use
3161 the least significant bit to record whether we have
3162 already generated the necessary reloc. */
3163 if ((off & 1) != 0)
3164 off &= ~1;
3165 else
3167 bfd_put_64 (output_bfd, relocation,
3168 base_got->contents + off);
3169 local_got_offsets[r_symndx] |= 1;
3171 /* NB: GOTPCREL relocations against local absolute
3172 symbol store relocation value in the GOT slot
3173 without relative relocation. Don't generate
3174 relative relocation here if it has been generated
3175 by DT_RELR. */
3176 if (!info->enable_dt_relr
3177 && bfd_link_pic (info)
3178 && !(sym->st_shndx == SHN_ABS
3179 && (r_type == R_X86_64_GOTPCREL
3180 || r_type == R_X86_64_GOTPCRELX
3181 || r_type == R_X86_64_REX_GOTPCRELX
3182 || r_type == R_X86_64_CODE_4_GOTPCRELX)))
3183 relative_reloc = true;
3187 if (relative_reloc)
3189 asection *s;
3190 Elf_Internal_Rela outrel;
3192 /* We need to generate a R_X86_64_RELATIVE reloc
3193 for the dynamic linker. */
3194 s = htab->elf.srelgot;
3195 if (s == NULL)
3196 abort ();
3198 outrel.r_offset = (base_got->output_section->vma
3199 + base_got->output_offset
3200 + off);
3201 outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
3202 outrel.r_addend = relocation;
3204 if (htab->params->report_relative_reloc)
3205 _bfd_x86_elf_link_report_relative_reloc
3206 (info, input_section, h, sym, "R_X86_64_RELATIVE",
3207 &outrel);
3209 elf_append_rela (output_bfd, s, &outrel);
3212 if (off >= (bfd_vma) -2)
3213 abort ();
3215 relocation = base_got->output_section->vma
3216 + base_got->output_offset + off;
3217 if (r_type != R_X86_64_GOTPCREL
3218 && r_type != R_X86_64_GOTPCRELX
3219 && r_type != R_X86_64_REX_GOTPCRELX
3220 && r_type != R_X86_64_CODE_4_GOTPCRELX
3221 && r_type != R_X86_64_GOTPCREL64)
3222 relocation -= htab->elf.sgotplt->output_section->vma
3223 - htab->elf.sgotplt->output_offset;
3225 break;
3227 case R_X86_64_GOTOFF64:
3228 /* Relocation is relative to the start of the global offset
3229 table. */
3231 /* Check to make sure it isn't a protected function or data
3232 symbol for shared library since it may not be local when
3233 used as function address or with copy relocation. We also
3234 need to make sure that a symbol is referenced locally. */
3235 if (bfd_link_pic (info) && h)
3237 if (!h->def_regular)
3239 const char *v;
3241 switch (ELF_ST_VISIBILITY (h->other))
3243 case STV_HIDDEN:
3244 v = _("hidden symbol");
3245 break;
3246 case STV_INTERNAL:
3247 v = _("internal symbol");
3248 break;
3249 case STV_PROTECTED:
3250 v = _("protected symbol");
3251 break;
3252 default:
3253 v = _("symbol");
3254 break;
3257 _bfd_error_handler
3258 /* xgettext:c-format */
3259 (_("%pB: relocation R_X86_64_GOTOFF64 against undefined %s"
3260 " `%s' can not be used when making a shared object"),
3261 input_bfd, v, h->root.root.string);
3262 bfd_set_error (bfd_error_bad_value);
3263 return false;
3265 else if (!bfd_link_executable (info)
3266 && !SYMBOL_REFERENCES_LOCAL_P (info, h)
3267 && (h->type == STT_FUNC
3268 || h->type == STT_OBJECT)
3269 && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
3271 _bfd_error_handler
3272 /* xgettext:c-format */
3273 (_("%pB: relocation R_X86_64_GOTOFF64 against protected %s"
3274 " `%s' can not be used when making a shared object"),
3275 input_bfd,
3276 h->type == STT_FUNC ? "function" : "data",
3277 h->root.root.string);
3278 bfd_set_error (bfd_error_bad_value);
3279 return false;
3283 /* Note that sgot is not involved in this
3284 calculation. We always want the start of .got.plt. If we
3285 defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
3286 permitted by the ABI, we might have to change this
3287 calculation. */
3288 relocation -= htab->elf.sgotplt->output_section->vma
3289 + htab->elf.sgotplt->output_offset;
3290 break;
3292 case R_X86_64_GOTPC32:
3293 case R_X86_64_GOTPC64:
3294 /* Use global offset table as symbol value. */
3295 relocation = htab->elf.sgotplt->output_section->vma
3296 + htab->elf.sgotplt->output_offset;
3297 unresolved_reloc = false;
3298 break;
3300 case R_X86_64_PLTOFF64:
3301 /* Relocation is PLT entry relative to GOT. For local
3302 symbols it's the symbol itself relative to GOT. */
3303 if (h != NULL
3304 /* See PLT32 handling. */
3305 && (h->plt.offset != (bfd_vma) -1
3306 || eh->plt_got.offset != (bfd_vma) -1)
3307 && htab->elf.splt != NULL)
3309 if (eh->plt_got.offset != (bfd_vma) -1)
3311 /* Use the GOT PLT. */
3312 resolved_plt = htab->plt_got;
3313 plt_offset = eh->plt_got.offset;
3315 else if (htab->plt_second != NULL)
3317 resolved_plt = htab->plt_second;
3318 plt_offset = eh->plt_second.offset;
3320 else
3322 resolved_plt = htab->elf.splt;
3323 plt_offset = h->plt.offset;
3326 relocation = (resolved_plt->output_section->vma
3327 + resolved_plt->output_offset
3328 + plt_offset);
3329 unresolved_reloc = false;
3332 relocation -= htab->elf.sgotplt->output_section->vma
3333 + htab->elf.sgotplt->output_offset;
3334 break;
3336 case R_X86_64_PLT32:
3337 /* Relocation is to the entry for this symbol in the
3338 procedure linkage table. */
3340 /* Resolve a PLT32 reloc against a local symbol directly,
3341 without using the procedure linkage table. */
3342 if (h == NULL)
3343 break;
3345 if ((h->plt.offset == (bfd_vma) -1
3346 && eh->plt_got.offset == (bfd_vma) -1)
3347 || htab->elf.splt == NULL)
3349 /* We didn't make a PLT entry for this symbol. This
3350 happens when statically linking PIC code, or when
3351 using -Bsymbolic. */
3352 break;
3355 use_plt:
3356 if (h->plt.offset != (bfd_vma) -1)
3358 if (htab->plt_second != NULL)
3360 resolved_plt = htab->plt_second;
3361 plt_offset = eh->plt_second.offset;
3363 else
3365 resolved_plt = htab->elf.splt;
3366 plt_offset = h->plt.offset;
3369 else
3371 /* Use the GOT PLT. */
3372 resolved_plt = htab->plt_got;
3373 plt_offset = eh->plt_got.offset;
3376 relocation = (resolved_plt->output_section->vma
3377 + resolved_plt->output_offset
3378 + plt_offset);
3379 unresolved_reloc = false;
3380 break;
3382 case R_X86_64_SIZE32:
3383 case R_X86_64_SIZE64:
3384 /* Set to symbol size. */
3385 relocation = st_size;
3386 goto direct;
3388 case R_X86_64_PC8:
3389 case R_X86_64_PC16:
3390 case R_X86_64_PC32:
3391 /* Don't complain about -fPIC if the symbol is undefined when
3392 building executable unless it is unresolved weak symbol,
3393 references a dynamic definition in PIE or -z nocopyreloc
3394 is used. */
3395 no_copyreloc_p
3396 = (info->nocopyreloc
3397 || (h != NULL
3398 && !h->root.linker_def
3399 && !h->root.ldscript_def
3400 && eh->def_protected));
3402 if ((input_section->flags & SEC_ALLOC) != 0
3403 && (input_section->flags & SEC_READONLY) != 0
3404 && h != NULL
3405 && ((bfd_link_executable (info)
3406 && ((h->root.type == bfd_link_hash_undefweak
3407 && (eh == NULL
3408 || !UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
3409 eh)))
3410 || (bfd_link_pie (info)
3411 && !SYMBOL_DEFINED_NON_SHARED_P (h)
3412 && h->def_dynamic)
3413 || (no_copyreloc_p
3414 && h->def_dynamic
3415 && !(h->root.u.def.section->flags & SEC_CODE))))
3416 || (bfd_link_pie (info)
3417 && h->root.type == bfd_link_hash_undefweak)
3418 || bfd_link_dll (info)))
3420 bool fail = false;
3421 if (SYMBOL_REFERENCES_LOCAL_P (info, h))
3423 /* Symbol is referenced locally. Make sure it is
3424 defined locally. */
3425 fail = !SYMBOL_DEFINED_NON_SHARED_P (h);
3427 else if (bfd_link_pie (info))
3429 /* We can only use PC-relative relocations in PIE
3430 from non-code sections. */
3431 if (h->root.type == bfd_link_hash_undefweak
3432 || (h->type == STT_FUNC
3433 && (sec->flags & SEC_CODE) != 0))
3434 fail = true;
3436 else if (no_copyreloc_p || bfd_link_dll (info))
3438 /* Symbol doesn't need copy reloc and isn't
3439 referenced locally. Don't allow PC-relative
3440 relocations against default and protected
3441 symbols since address of protected function
3442 and location of protected data may not be in
3443 the shared object. */
3444 fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3445 || ELF_ST_VISIBILITY (h->other) == STV_PROTECTED);
3448 if (fail)
3449 return elf_x86_64_need_pic (info, input_bfd, input_section,
3450 h, NULL, NULL, howto);
3452 /* Since x86-64 has PC-relative PLT, we can use PLT in PIE
3453 as function address. */
3454 else if (h != NULL
3455 && (input_section->flags & SEC_CODE) == 0
3456 && bfd_link_pie (info)
3457 && h->type == STT_FUNC
3458 && !h->def_regular
3459 && h->def_dynamic)
3460 goto use_plt;
3461 /* Fall through. */
3463 case R_X86_64_8:
3464 case R_X86_64_16:
3465 case R_X86_64_32:
3466 case R_X86_64_PC64:
3467 case R_X86_64_64:
3468 /* FIXME: The ABI says the linker should make sure the value is
3469 the same when it's zeroextended to 64 bit. */
3471 direct:
3472 if ((input_section->flags & SEC_ALLOC) == 0)
3473 break;
3475 need_copy_reloc_in_pie = (bfd_link_pie (info)
3476 && h != NULL
3477 && (h->needs_copy
3478 || eh->needs_copy
3479 || (h->root.type
3480 == bfd_link_hash_undefined))
3481 && (X86_PCREL_TYPE_P (true, r_type)
3482 || X86_SIZE_TYPE_P (true,
3483 r_type)));
3485 if (GENERATE_DYNAMIC_RELOCATION_P (true, info, eh, r_type, sec,
3486 need_copy_reloc_in_pie,
3487 resolved_to_zero, false))
3489 Elf_Internal_Rela outrel;
3490 bool skip, relocate;
3491 bool generate_dynamic_reloc = true;
3492 asection *sreloc;
3493 const char *relative_reloc_name = NULL;
3495 /* When generating a shared object, these relocations
3496 are copied into the output file to be resolved at run
3497 time. */
3498 skip = false;
3499 relocate = false;
3501 outrel.r_offset =
3502 _bfd_elf_section_offset (output_bfd, info, input_section,
3503 rel->r_offset);
3504 if (outrel.r_offset == (bfd_vma) -1)
3505 skip = true;
3506 else if (outrel.r_offset == (bfd_vma) -2)
3507 skip = true, relocate = true;
3509 outrel.r_offset += (input_section->output_section->vma
3510 + input_section->output_offset);
3512 if (skip)
3513 memset (&outrel, 0, sizeof outrel);
3515 else if (COPY_INPUT_RELOC_P (true, info, h, r_type))
3517 outrel.r_info = htab->r_info (h->dynindx, r_type);
3518 outrel.r_addend = rel->r_addend;
3520 else
3522 /* This symbol is local, or marked to become local.
3523 When relocation overflow check is disabled, we
3524 convert R_X86_64_32 to dynamic R_X86_64_RELATIVE. */
3525 if (r_type == htab->pointer_r_type
3526 || (r_type == R_X86_64_32
3527 && htab->params->no_reloc_overflow_check))
3529 relocate = true;
3530 /* NB: Don't generate relative relocation here if
3531 it has been generated by DT_RELR. */
3532 if (info->enable_dt_relr)
3533 generate_dynamic_reloc = false;
3534 else
3536 outrel.r_info =
3537 htab->r_info (0, R_X86_64_RELATIVE);
3538 outrel.r_addend = relocation + rel->r_addend;
3539 relative_reloc_name = "R_X86_64_RELATIVE";
3542 else if (r_type == R_X86_64_64
3543 && !ABI_64_P (output_bfd))
3545 relocate = true;
3546 outrel.r_info = htab->r_info (0,
3547 R_X86_64_RELATIVE64);
3548 outrel.r_addend = relocation + rel->r_addend;
3549 relative_reloc_name = "R_X86_64_RELATIVE64";
3550 /* Check addend overflow. */
3551 if ((outrel.r_addend & 0x80000000)
3552 != (rel->r_addend & 0x80000000))
3554 const char *name;
3555 int addend = rel->r_addend;
3556 if (h && h->root.root.string)
3557 name = h->root.root.string;
3558 else
3559 name = bfd_elf_sym_name (input_bfd, symtab_hdr,
3560 sym, NULL);
3561 _bfd_error_handler
3562 /* xgettext:c-format */
3563 (_("%pB: addend %s%#x in relocation %s against "
3564 "symbol `%s' at %#" PRIx64
3565 " in section `%pA' is out of range"),
3566 input_bfd, addend < 0 ? "-" : "", addend,
3567 howto->name, name, (uint64_t) rel->r_offset,
3568 input_section);
3569 bfd_set_error (bfd_error_bad_value);
3570 return false;
3573 else
3575 long sindx;
3577 if (bfd_is_abs_section (sec))
3578 sindx = 0;
3579 else if (sec == NULL || sec->owner == NULL)
3581 bfd_set_error (bfd_error_bad_value);
3582 return false;
3584 else
3586 asection *osec;
3588 /* We are turning this relocation into one
3589 against a section symbol. It would be
3590 proper to subtract the symbol's value,
3591 osec->vma, from the emitted reloc addend,
3592 but ld.so expects buggy relocs. */
3593 osec = sec->output_section;
3594 sindx = elf_section_data (osec)->dynindx;
3595 if (sindx == 0)
3597 asection *oi = htab->elf.text_index_section;
3598 sindx = elf_section_data (oi)->dynindx;
3600 BFD_ASSERT (sindx != 0);
3603 outrel.r_info = htab->r_info (sindx, r_type);
3604 outrel.r_addend = relocation + rel->r_addend;
3608 if (generate_dynamic_reloc)
3610 sreloc = elf_section_data (input_section)->sreloc;
3612 if (sreloc == NULL || sreloc->contents == NULL)
3614 r = bfd_reloc_notsupported;
3615 goto check_relocation_error;
3618 if (relative_reloc_name
3619 && htab->params->report_relative_reloc)
3620 _bfd_x86_elf_link_report_relative_reloc
3621 (info, input_section, h, sym,
3622 relative_reloc_name, &outrel);
3624 elf_append_rela (output_bfd, sreloc, &outrel);
3627 /* If this reloc is against an external symbol, we do
3628 not want to fiddle with the addend. Otherwise, we
3629 need to include the symbol value so that it becomes
3630 an addend for the dynamic reloc. */
3631 if (! relocate)
3632 continue;
3635 break;
3637 case R_X86_64_TLSGD:
3638 case R_X86_64_GOTPC32_TLSDESC:
3639 case R_X86_64_CODE_4_GOTPC32_TLSDESC:
3640 case R_X86_64_TLSDESC_CALL:
3641 case R_X86_64_GOTTPOFF:
3642 case R_X86_64_CODE_4_GOTTPOFF:
3643 case R_X86_64_CODE_6_GOTTPOFF:
3644 tls_type = GOT_UNKNOWN;
3645 if (h == NULL && local_got_offsets)
3646 tls_type = elf_x86_local_got_tls_type (input_bfd) [r_symndx];
3647 else if (h != NULL)
3648 tls_type = elf_x86_hash_entry (h)->tls_type;
3650 r_type_tls = r_type;
3651 if (! elf_x86_64_tls_transition (info, input_bfd,
3652 input_section, contents,
3653 symtab_hdr, sym_hashes,
3654 &r_type_tls, tls_type, rel,
3655 relend, h, sym, true))
3656 return false;
3658 if (r_type_tls == R_X86_64_TPOFF32)
3660 bfd_vma roff = rel->r_offset;
3662 if (roff >= input_section->size)
3663 goto corrupt_input;
3665 BFD_ASSERT (! unresolved_reloc);
3667 if (r_type == R_X86_64_TLSGD)
3669 /* GD->LE transition. For 64bit, change
3670 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3671 .word 0x6666; rex64; call __tls_get_addr@PLT
3673 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3674 .byte 0x66; rex64
3675 call *__tls_get_addr@GOTPCREL(%rip)
3676 which may be converted to
3677 addr32 call __tls_get_addr
3678 into:
3679 movq %fs:0, %rax
3680 leaq foo@tpoff(%rax), %rax
3681 For 32bit, change
3682 leaq foo@tlsgd(%rip), %rdi
3683 .word 0x6666; rex64; call __tls_get_addr@PLT
3685 leaq foo@tlsgd(%rip), %rdi
3686 .byte 0x66; rex64
3687 call *__tls_get_addr@GOTPCREL(%rip)
3688 which may be converted to
3689 addr32 call __tls_get_addr
3690 into:
3691 movl %fs:0, %eax
3692 leaq foo@tpoff(%rax), %rax
3693 For largepic, change:
3694 leaq foo@tlsgd(%rip), %rdi
3695 movabsq $__tls_get_addr@pltoff, %rax
3696 addq %r15, %rax
3697 call *%rax
3698 into:
3699 movq %fs:0, %rax
3700 leaq foo@tpoff(%rax), %rax
3701 nopw 0x0(%rax,%rax,1) */
3702 int largepic = 0;
3703 if (ABI_64_P (output_bfd))
3705 if (roff + 5 >= input_section->size)
3706 goto corrupt_input;
3707 if (contents[roff + 5] == 0xb8)
3709 if (roff < 3
3710 || (roff - 3 + 22) > input_section->size)
3712 corrupt_input:
3713 info->callbacks->einfo
3714 (_("%F%P: corrupt input: %pB\n"),
3715 input_bfd);
3716 return false;
3718 memcpy (contents + roff - 3,
3719 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80"
3720 "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
3721 largepic = 1;
3723 else
3725 if (roff < 4
3726 || (roff - 4 + 16) > input_section->size)
3727 goto corrupt_input;
3728 memcpy (contents + roff - 4,
3729 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
3730 16);
3733 else
3735 if (roff < 3
3736 || (roff - 3 + 15) > input_section->size)
3737 goto corrupt_input;
3738 memcpy (contents + roff - 3,
3739 "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
3740 15);
3743 if (roff + 8 + largepic >= input_section->size)
3744 goto corrupt_input;
3746 bfd_put_32 (output_bfd,
3747 elf_x86_64_tpoff (info, relocation),
3748 contents + roff + 8 + largepic);
3749 /* Skip R_X86_64_PC32, R_X86_64_PLT32,
3750 R_X86_64_GOTPCRELX and R_X86_64_PLTOFF64. */
3751 rel++;
3752 wrel++;
3753 continue;
3755 else if (r_type == R_X86_64_GOTPC32_TLSDESC)
3757 /* GDesc -> LE transition.
3758 It's originally something like:
3759 leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
3760 rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
3762 Change it to:
3763 movq $x@tpoff, %rax <--- LP64 mode.
3764 rex movl $x@tpoff, %eax <--- X32 mode.
3767 unsigned int val, type;
3769 if (roff < 3)
3770 goto corrupt_input;
3771 type = bfd_get_8 (input_bfd, contents + roff - 3);
3772 val = bfd_get_8 (input_bfd, contents + roff - 1);
3773 bfd_put_8 (output_bfd,
3774 (type & 0x48) | ((type >> 2) & 1),
3775 contents + roff - 3);
3776 bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
3777 bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
3778 contents + roff - 1);
3779 bfd_put_32 (output_bfd,
3780 elf_x86_64_tpoff (info, relocation),
3781 contents + roff);
3782 continue;
3784 else if (r_type == R_X86_64_CODE_4_GOTPC32_TLSDESC)
3786 /* GDesc -> LE transition.
3787 It's originally something like:
3788 lea x@tlsdesc(%rip), %reg
3790 Change it to:
3791 mov $x@tpoff, %reg
3792 where reg is one of r16 to r31. */
3794 unsigned int val, rex2;
3795 unsigned int rex2_mask = REX_R | REX_R << 4;
3797 if (roff < 4)
3798 goto corrupt_input;
3799 rex2 = bfd_get_8 (input_bfd, contents + roff - 3);
3800 val = bfd_get_8 (input_bfd, contents + roff - 1);
3801 /* Move the R bits to the B bits in REX2 payload
3802 byte. */
3803 bfd_put_8 (output_bfd,
3804 ((rex2 & ~rex2_mask)
3805 | (rex2 & rex2_mask) >> 2),
3806 contents + roff - 3);
3807 bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
3808 bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
3809 contents + roff - 1);
3810 bfd_put_32 (output_bfd,
3811 elf_x86_64_tpoff (info, relocation),
3812 contents + roff);
3813 continue;
3815 else if (r_type == R_X86_64_TLSDESC_CALL)
3817 /* GDesc -> LE transition.
3818 It's originally:
3819 call *(%rax) <--- LP64 mode.
3820 call *(%eax) <--- X32 mode.
3821 Turn it into:
3822 xchg %ax,%ax <-- LP64 mode.
3823 nopl (%rax) <-- X32 mode.
3825 unsigned int prefix = 0;
3826 if (!ABI_64_P (input_bfd))
3828 /* Check for call *x@tlsdesc(%eax). */
3829 if (contents[roff] == 0x67)
3830 prefix = 1;
3832 if (prefix)
3834 if (roff + 2 >= input_section->size)
3835 goto corrupt_input;
3837 bfd_put_8 (output_bfd, 0x0f, contents + roff);
3838 bfd_put_8 (output_bfd, 0x1f, contents + roff + 1);
3839 bfd_put_8 (output_bfd, 0x00, contents + roff + 2);
3841 else
3843 if (roff + 1 >= input_section->size)
3844 goto corrupt_input;
3846 bfd_put_8 (output_bfd, 0x66, contents + roff);
3847 bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
3849 continue;
3851 else if (r_type == R_X86_64_GOTTPOFF)
3853 /* IE->LE transition:
3854 For 64bit, originally it can be one of:
3855 movq foo@gottpoff(%rip), %reg
3856 addq foo@gottpoff(%rip), %reg
3857 We change it into:
3858 movq $foo, %reg
3859 leaq foo(%reg), %reg
3860 addq $foo, %reg.
3861 For 32bit, originally it can be one of:
3862 movq foo@gottpoff(%rip), %reg
3863 addl foo@gottpoff(%rip), %reg
3864 We change it into:
3865 movq $foo, %reg
3866 leal foo(%reg), %reg
3867 addl $foo, %reg. */
3869 unsigned int val, type, reg;
3871 if (roff >= 3)
3872 val = bfd_get_8 (input_bfd, contents + roff - 3);
3873 else
3875 if (roff < 2)
3876 goto corrupt_input;
3877 val = 0;
3879 type = bfd_get_8 (input_bfd, contents + roff - 2);
3880 reg = bfd_get_8 (input_bfd, contents + roff - 1);
3881 reg >>= 3;
3882 if (type == 0x8b)
3884 /* movq */
3885 if (val == 0x4c)
3887 if (roff < 3)
3888 goto corrupt_input;
3889 bfd_put_8 (output_bfd, 0x49,
3890 contents + roff - 3);
3892 else if (!ABI_64_P (output_bfd) && val == 0x44)
3894 if (roff < 3)
3895 goto corrupt_input;
3896 bfd_put_8 (output_bfd, 0x41,
3897 contents + roff - 3);
3899 bfd_put_8 (output_bfd, 0xc7,
3900 contents + roff - 2);
3901 bfd_put_8 (output_bfd, 0xc0 | reg,
3902 contents + roff - 1);
3904 else if (reg == 4)
3906 /* addq/addl -> addq/addl - addressing with %rsp/%r12
3907 is special */
3908 if (val == 0x4c)
3910 if (roff < 3)
3911 goto corrupt_input;
3912 bfd_put_8 (output_bfd, 0x49,
3913 contents + roff - 3);
3915 else if (!ABI_64_P (output_bfd) && val == 0x44)
3917 if (roff < 3)
3918 goto corrupt_input;
3919 bfd_put_8 (output_bfd, 0x41,
3920 contents + roff - 3);
3922 bfd_put_8 (output_bfd, 0x81,
3923 contents + roff - 2);
3924 bfd_put_8 (output_bfd, 0xc0 | reg,
3925 contents + roff - 1);
3927 else
3929 /* addq/addl -> leaq/leal */
3930 if (val == 0x4c)
3932 if (roff < 3)
3933 goto corrupt_input;
3934 bfd_put_8 (output_bfd, 0x4d,
3935 contents + roff - 3);
3937 else if (!ABI_64_P (output_bfd) && val == 0x44)
3939 if (roff < 3)
3940 goto corrupt_input;
3941 bfd_put_8 (output_bfd, 0x45,
3942 contents + roff - 3);
3944 bfd_put_8 (output_bfd, 0x8d,
3945 contents + roff - 2);
3946 bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
3947 contents + roff - 1);
3949 bfd_put_32 (output_bfd,
3950 elf_x86_64_tpoff (info, relocation),
3951 contents + roff);
3952 continue;
3954 else if (r_type == R_X86_64_CODE_4_GOTTPOFF)
3956 /* IE->LE transition:
3957 Originally it can be one of:
3958 mov foo@gottpoff(%rip), %reg
3959 add foo@gottpoff(%rip), %reg
3960 We change it into:
3961 mov $foo@tpoff, %reg
3962 add $foo@tpoff, %reg
3963 where reg is one of r16 to r31. */
3965 unsigned int rex2, type, reg;
3966 unsigned int rex2_mask = REX_R | REX_R << 4;
3968 if (roff < 4)
3969 goto corrupt_input;
3971 rex2 = bfd_get_8 (input_bfd, contents + roff - 3);
3972 type = bfd_get_8 (input_bfd, contents + roff - 2);
3973 reg = bfd_get_8 (input_bfd, contents + roff - 1);
3974 reg >>= 3;
3975 /* Move the R bits to the B bits in REX2 payload
3976 byte. */
3977 if (type == 0x8b)
3978 type = 0xc7;
3979 else
3980 type = 0x81;
3981 bfd_put_8 (output_bfd,
3982 ((rex2 & ~rex2_mask)
3983 | (rex2 & rex2_mask) >> 2),
3984 contents + roff - 3);
3985 bfd_put_8 (output_bfd, type,
3986 contents + roff - 2);
3987 bfd_put_8 (output_bfd, 0xc0 | reg,
3988 contents + roff - 1);
3989 bfd_put_32 (output_bfd,
3990 elf_x86_64_tpoff (info, relocation),
3991 contents + roff);
3992 continue;
3994 else if (r_type == R_X86_64_CODE_6_GOTTPOFF)
3996 /* IE->LE transition:
3997 Originally it is
3998 add %reg1, foo@gottpoff(%rip), %reg2
4000 add foo@gottpoff(%rip), %reg1, %reg2
4001 We change it into:
4002 add $foo@tpoff, %reg1, %reg2
4004 unsigned int reg, byte1;
4005 unsigned int updated_byte1;
4007 if (roff < 6)
4008 goto corrupt_input;
4010 /* Move the R bits to the B bits in EVEX payload
4011 byte 1. */
4012 byte1 = bfd_get_8 (input_bfd, contents + roff - 5);
4013 updated_byte1 = byte1;
4015 /* Set the R bits since they is inverted. */
4016 updated_byte1 |= 1 << 7 | 1 << 4;
4018 /* Update the B bits from the R bits. */
4019 if ((byte1 & (1 << 7)) == 0)
4020 updated_byte1 &= ~(1 << 5);
4021 if ((byte1 & (1 << 4)) == 0)
4022 updated_byte1 |= 1 << 3;
4024 reg = bfd_get_8 (input_bfd, contents + roff - 1);
4025 reg >>= 3;
4027 bfd_put_8 (output_bfd, updated_byte1,
4028 contents + roff - 5);
4029 bfd_put_8 (output_bfd, 0x81,
4030 contents + roff - 2);
4031 bfd_put_8 (output_bfd, 0xc0 | reg,
4032 contents + roff - 1);
4033 bfd_put_32 (output_bfd,
4034 elf_x86_64_tpoff (info, relocation),
4035 contents + roff);
4036 continue;
4038 else
4039 BFD_ASSERT (false);
4042 if (htab->elf.sgot == NULL)
4043 abort ();
4045 if (h != NULL)
4047 off = h->got.offset;
4048 offplt = elf_x86_hash_entry (h)->tlsdesc_got;
4050 else
4052 if (local_got_offsets == NULL)
4053 abort ();
4055 off = local_got_offsets[r_symndx];
4056 offplt = local_tlsdesc_gotents[r_symndx];
4059 if ((off & 1) != 0)
4060 off &= ~1;
4061 else
4063 Elf_Internal_Rela outrel;
4064 int dr_type, indx;
4065 asection *sreloc;
4067 if (htab->elf.srelgot == NULL)
4068 abort ();
4070 indx = h && h->dynindx != -1 ? h->dynindx : 0;
4072 if (GOT_TLS_GDESC_P (tls_type))
4074 outrel.r_info = htab->r_info (indx, R_X86_64_TLSDESC);
4075 BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
4076 + 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size);
4077 outrel.r_offset = (htab->elf.sgotplt->output_section->vma
4078 + htab->elf.sgotplt->output_offset
4079 + offplt
4080 + htab->sgotplt_jump_table_size);
4081 sreloc = htab->elf.srelplt;
4082 if (indx == 0)
4083 outrel.r_addend = relocation - _bfd_x86_elf_dtpoff_base (info);
4084 else
4085 outrel.r_addend = 0;
4086 elf_append_rela (output_bfd, sreloc, &outrel);
4089 sreloc = htab->elf.srelgot;
4091 outrel.r_offset = (htab->elf.sgot->output_section->vma
4092 + htab->elf.sgot->output_offset + off);
4094 if (GOT_TLS_GD_P (tls_type))
4095 dr_type = R_X86_64_DTPMOD64;
4096 else if (GOT_TLS_GDESC_P (tls_type))
4097 goto dr_done;
4098 else
4099 dr_type = R_X86_64_TPOFF64;
4101 bfd_put_64 (output_bfd, 0, htab->elf.sgot->contents + off);
4102 outrel.r_addend = 0;
4103 if ((dr_type == R_X86_64_TPOFF64
4104 || dr_type == R_X86_64_TLSDESC) && indx == 0)
4105 outrel.r_addend = relocation - _bfd_x86_elf_dtpoff_base (info);
4106 outrel.r_info = htab->r_info (indx, dr_type);
4108 elf_append_rela (output_bfd, sreloc, &outrel);
4110 if (GOT_TLS_GD_P (tls_type))
4112 if (indx == 0)
4114 BFD_ASSERT (! unresolved_reloc);
4115 bfd_put_64 (output_bfd,
4116 relocation - _bfd_x86_elf_dtpoff_base (info),
4117 htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
4119 else
4121 bfd_put_64 (output_bfd, 0,
4122 htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
4123 outrel.r_info = htab->r_info (indx,
4124 R_X86_64_DTPOFF64);
4125 outrel.r_offset += GOT_ENTRY_SIZE;
4126 elf_append_rela (output_bfd, sreloc,
4127 &outrel);
4131 dr_done:
4132 if (h != NULL)
4133 h->got.offset |= 1;
4134 else
4135 local_got_offsets[r_symndx] |= 1;
4138 if (off >= (bfd_vma) -2
4139 && ! GOT_TLS_GDESC_P (tls_type))
4140 abort ();
4141 if (r_type_tls == r_type)
4143 if (r_type == R_X86_64_GOTPC32_TLSDESC
4144 || r_type == R_X86_64_CODE_4_GOTPC32_TLSDESC
4145 || r_type == R_X86_64_TLSDESC_CALL)
4146 relocation = htab->elf.sgotplt->output_section->vma
4147 + htab->elf.sgotplt->output_offset
4148 + offplt + htab->sgotplt_jump_table_size;
4149 else
4150 relocation = htab->elf.sgot->output_section->vma
4151 + htab->elf.sgot->output_offset + off;
4152 unresolved_reloc = false;
4154 else
4156 bfd_vma roff = rel->r_offset;
4158 if (r_type == R_X86_64_TLSGD)
4160 /* GD->IE transition. For 64bit, change
4161 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
4162 .word 0x6666; rex64; call __tls_get_addr@PLT
4164 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
4165 .byte 0x66; rex64
4166 call *__tls_get_addr@GOTPCREL(%rip
4167 which may be converted to
4168 addr32 call __tls_get_addr
4169 into:
4170 movq %fs:0, %rax
4171 addq foo@gottpoff(%rip), %rax
4172 For 32bit, change
4173 leaq foo@tlsgd(%rip), %rdi
4174 .word 0x6666; rex64; call __tls_get_addr@PLT
4176 leaq foo@tlsgd(%rip), %rdi
4177 .byte 0x66; rex64;
4178 call *__tls_get_addr@GOTPCREL(%rip)
4179 which may be converted to
4180 addr32 call __tls_get_addr
4181 into:
4182 movl %fs:0, %eax
4183 addq foo@gottpoff(%rip), %rax
4184 For largepic, change:
4185 leaq foo@tlsgd(%rip), %rdi
4186 movabsq $__tls_get_addr@pltoff, %rax
4187 addq %r15, %rax
4188 call *%rax
4189 into:
4190 movq %fs:0, %rax
4191 addq foo@gottpoff(%rax), %rax
4192 nopw 0x0(%rax,%rax,1) */
4193 int largepic = 0;
4194 if (ABI_64_P (output_bfd))
4196 if (contents[roff + 5] == 0xb8)
4198 if (roff < 3
4199 || (roff - 3 + 22) > input_section->size)
4200 goto corrupt_input;
4201 memcpy (contents + roff - 3,
4202 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05"
4203 "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
4204 largepic = 1;
4206 else
4208 if (roff < 4
4209 || (roff - 4 + 16) > input_section->size)
4210 goto corrupt_input;
4211 memcpy (contents + roff - 4,
4212 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
4213 16);
4216 else
4218 if (roff < 3
4219 || (roff - 3 + 15) > input_section->size)
4220 goto corrupt_input;
4221 memcpy (contents + roff - 3,
4222 "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
4223 15);
4226 relocation = (htab->elf.sgot->output_section->vma
4227 + htab->elf.sgot->output_offset + off
4228 - roff
4229 - largepic
4230 - input_section->output_section->vma
4231 - input_section->output_offset
4232 - 12);
4233 bfd_put_32 (output_bfd, relocation,
4234 contents + roff + 8 + largepic);
4235 /* Skip R_X86_64_PLT32/R_X86_64_PLTOFF64. */
4236 rel++;
4237 wrel++;
4238 continue;
4240 else if (r_type == R_X86_64_GOTPC32_TLSDESC
4241 || r_type == R_X86_64_CODE_4_GOTPC32_TLSDESC)
4243 /* GDesc -> IE transition.
4244 It's originally something like:
4245 leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
4246 rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
4248 Change it to:
4249 # before xchg %ax,%ax in LP64 mode.
4250 movq x@gottpoff(%rip), %rax
4251 # before nopl (%rax) in X32 mode.
4252 rex movl x@gottpoff(%rip), %eax
4255 /* Now modify the instruction as appropriate. To
4256 turn a lea into a mov in the form we use it, it
4257 suffices to change the second byte from 0x8d to
4258 0x8b. */
4259 if (roff < 2)
4260 goto corrupt_input;
4261 bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
4263 bfd_put_32 (output_bfd,
4264 htab->elf.sgot->output_section->vma
4265 + htab->elf.sgot->output_offset + off
4266 - rel->r_offset
4267 - input_section->output_section->vma
4268 - input_section->output_offset
4269 - 4,
4270 contents + roff);
4271 continue;
4273 else if (r_type == R_X86_64_TLSDESC_CALL)
4275 /* GDesc -> IE transition.
4276 It's originally:
4277 call *(%rax) <--- LP64 mode.
4278 call *(%eax) <--- X32 mode.
4280 Change it to:
4281 xchg %ax, %ax <-- LP64 mode.
4282 nopl (%rax) <-- X32 mode.
4285 unsigned int prefix = 0;
4286 if (!ABI_64_P (input_bfd))
4288 /* Check for call *x@tlsdesc(%eax). */
4289 if (contents[roff] == 0x67)
4290 prefix = 1;
4292 if (prefix)
4294 bfd_put_8 (output_bfd, 0x0f, contents + roff);
4295 bfd_put_8 (output_bfd, 0x1f, contents + roff + 1);
4296 bfd_put_8 (output_bfd, 0x00, contents + roff + 2);
4298 else
4300 bfd_put_8 (output_bfd, 0x66, contents + roff);
4301 bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
4303 continue;
4305 else
4306 BFD_ASSERT (false);
4308 break;
4310 case R_X86_64_TLSLD:
4311 if (! elf_x86_64_tls_transition (info, input_bfd,
4312 input_section, contents,
4313 symtab_hdr, sym_hashes,
4314 &r_type, GOT_UNKNOWN, rel,
4315 relend, h, sym, true))
4316 return false;
4318 if (r_type != R_X86_64_TLSLD)
4320 /* LD->LE transition:
4321 leaq foo@tlsld(%rip), %rdi
4322 call __tls_get_addr@PLT
4323 For 64bit, we change it into:
4324 .word 0x6666; .byte 0x66; movq %fs:0, %rax
4325 For 32bit, we change it into:
4326 nopl 0x0(%rax); movl %fs:0, %eax
4328 leaq foo@tlsld(%rip), %rdi;
4329 call *__tls_get_addr@GOTPCREL(%rip)
4330 which may be converted to
4331 addr32 call __tls_get_addr
4332 For 64bit, we change it into:
4333 .word 0x6666; .word 0x6666; movq %fs:0, %rax
4334 For 32bit, we change it into:
4335 nopw 0x0(%rax); movl %fs:0, %eax
4336 For largepic, change:
4337 leaq foo@tlsgd(%rip), %rdi
4338 movabsq $__tls_get_addr@pltoff, %rax
4339 addq %rbx, %rax
4340 call *%rax
4341 into
4342 data16 data16 data16 nopw %cs:0x0(%rax,%rax,1)
4343 movq %fs:0, %eax */
4345 BFD_ASSERT (r_type == R_X86_64_TPOFF32);
4346 if (ABI_64_P (output_bfd))
4348 if ((rel->r_offset + 5) >= input_section->size)
4349 goto corrupt_input;
4350 if (contents[rel->r_offset + 5] == 0xb8)
4352 if (rel->r_offset < 3
4353 || (rel->r_offset - 3 + 22) > input_section->size)
4354 goto corrupt_input;
4355 memcpy (contents + rel->r_offset - 3,
4356 "\x66\x66\x66\x66\x2e\x0f\x1f\x84\0\0\0\0\0"
4357 "\x64\x48\x8b\x04\x25\0\0\0", 22);
4359 else if (contents[rel->r_offset + 4] == 0xff
4360 || contents[rel->r_offset + 4] == 0x67)
4362 if (rel->r_offset < 3
4363 || (rel->r_offset - 3 + 13) > input_section->size)
4364 goto corrupt_input;
4365 memcpy (contents + rel->r_offset - 3,
4366 "\x66\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0",
4367 13);
4370 else
4372 if (rel->r_offset < 3
4373 || (rel->r_offset - 3 + 12) > input_section->size)
4374 goto corrupt_input;
4375 memcpy (contents + rel->r_offset - 3,
4376 "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
4379 else
4381 if ((rel->r_offset + 4) >= input_section->size)
4382 goto corrupt_input;
4383 if (contents[rel->r_offset + 4] == 0xff)
4385 if (rel->r_offset < 3
4386 || (rel->r_offset - 3 + 13) > input_section->size)
4387 goto corrupt_input;
4388 memcpy (contents + rel->r_offset - 3,
4389 "\x66\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0",
4390 13);
4392 else
4394 if (rel->r_offset < 3
4395 || (rel->r_offset - 3 + 12) > input_section->size)
4396 goto corrupt_input;
4397 memcpy (contents + rel->r_offset - 3,
4398 "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
4401 /* Skip R_X86_64_PC32, R_X86_64_PLT32, R_X86_64_GOTPCRELX
4402 and R_X86_64_PLTOFF64. */
4403 rel++;
4404 wrel++;
4405 continue;
4408 if (htab->elf.sgot == NULL)
4409 abort ();
4411 off = htab->tls_ld_or_ldm_got.offset;
4412 if (off & 1)
4413 off &= ~1;
4414 else
4416 Elf_Internal_Rela outrel;
4418 if (htab->elf.srelgot == NULL)
4419 abort ();
4421 outrel.r_offset = (htab->elf.sgot->output_section->vma
4422 + htab->elf.sgot->output_offset + off);
4424 bfd_put_64 (output_bfd, 0,
4425 htab->elf.sgot->contents + off);
4426 bfd_put_64 (output_bfd, 0,
4427 htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
4428 outrel.r_info = htab->r_info (0, R_X86_64_DTPMOD64);
4429 outrel.r_addend = 0;
4430 elf_append_rela (output_bfd, htab->elf.srelgot,
4431 &outrel);
4432 htab->tls_ld_or_ldm_got.offset |= 1;
4434 relocation = htab->elf.sgot->output_section->vma
4435 + htab->elf.sgot->output_offset + off;
4436 unresolved_reloc = false;
4437 break;
4439 case R_X86_64_DTPOFF32:
4440 if (!bfd_link_executable (info)
4441 || (input_section->flags & SEC_CODE) == 0)
4442 relocation -= _bfd_x86_elf_dtpoff_base (info);
4443 else
4444 relocation = elf_x86_64_tpoff (info, relocation);
4445 break;
4447 case R_X86_64_TPOFF32:
4448 case R_X86_64_TPOFF64:
4449 BFD_ASSERT (bfd_link_executable (info));
4450 relocation = elf_x86_64_tpoff (info, relocation);
4451 break;
4453 case R_X86_64_DTPOFF64:
4454 BFD_ASSERT ((input_section->flags & SEC_CODE) == 0);
4455 relocation -= _bfd_x86_elf_dtpoff_base (info);
4456 break;
4458 default:
4459 break;
4462 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
4463 because such sections are not SEC_ALLOC and thus ld.so will
4464 not process them. */
4465 if (unresolved_reloc
4466 && !((input_section->flags & SEC_DEBUGGING) != 0
4467 && h->def_dynamic)
4468 && _bfd_elf_section_offset (output_bfd, info, input_section,
4469 rel->r_offset) != (bfd_vma) -1)
4471 switch (r_type)
4473 case R_X86_64_32S:
4474 sec = h->root.u.def.section;
4475 if ((info->nocopyreloc || eh->def_protected)
4476 && !(h->root.u.def.section->flags & SEC_CODE))
4477 return elf_x86_64_need_pic (info, input_bfd, input_section,
4478 h, NULL, NULL, howto);
4479 /* Fall through. */
4481 default:
4482 _bfd_error_handler
4483 /* xgettext:c-format */
4484 (_("%pB(%pA+%#" PRIx64 "): "
4485 "unresolvable %s relocation against symbol `%s'"),
4486 input_bfd,
4487 input_section,
4488 (uint64_t) rel->r_offset,
4489 howto->name,
4490 h->root.root.string);
4491 return false;
4495 do_relocation:
4496 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
4497 contents, rel->r_offset,
4498 relocation, rel->r_addend);
4500 check_relocation_error:
4501 if (r != bfd_reloc_ok)
4503 const char *name;
4505 if (h != NULL)
4506 name = h->root.root.string;
4507 else
4509 name = bfd_elf_string_from_elf_section (input_bfd,
4510 symtab_hdr->sh_link,
4511 sym->st_name);
4512 if (name == NULL)
4513 return false;
4514 if (*name == '\0')
4515 name = bfd_section_name (sec);
4518 if (r == bfd_reloc_overflow)
4520 if (converted_reloc)
4522 info->callbacks->einfo
4523 ("%X%H:", input_bfd, input_section, rel->r_offset);
4524 info->callbacks->einfo
4525 (_(" failed to convert GOTPCREL relocation against "
4526 "'%s'; relink with --no-relax\n"),
4527 name);
4528 status = false;
4529 continue;
4531 (*info->callbacks->reloc_overflow)
4532 (info, (h ? &h->root : NULL), name, howto->name,
4533 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
4535 else
4537 _bfd_error_handler
4538 /* xgettext:c-format */
4539 (_("%pB(%pA+%#" PRIx64 "): reloc against `%s': error %d"),
4540 input_bfd, input_section,
4541 (uint64_t) rel->r_offset, name, (int) r);
4542 return false;
4546 if (wrel != rel)
4547 *wrel = *rel;
4550 if (wrel != rel)
4552 Elf_Internal_Shdr *rel_hdr;
4553 size_t deleted = rel - wrel;
4555 rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section);
4556 rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
4557 if (rel_hdr->sh_size == 0)
4559 /* It is too late to remove an empty reloc section. Leave
4560 one NONE reloc.
4561 ??? What is wrong with an empty section??? */
4562 rel_hdr->sh_size = rel_hdr->sh_entsize;
4563 deleted -= 1;
4565 rel_hdr = _bfd_elf_single_rel_hdr (input_section);
4566 rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
4567 input_section->reloc_count -= deleted;
4570 return status;
4573 /* Finish up dynamic symbol handling. We set the contents of various
4574 dynamic sections here. */
4576 static bool
4577 elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
4578 struct bfd_link_info *info,
4579 struct elf_link_hash_entry *h,
4580 Elf_Internal_Sym *sym)
4582 struct elf_x86_link_hash_table *htab;
4583 bool use_plt_second;
4584 struct elf_x86_link_hash_entry *eh;
4585 bool local_undefweak;
4587 htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
4589 /* Use the second PLT section only if there is .plt section. */
4590 use_plt_second = htab->elf.splt != NULL && htab->plt_second != NULL;
4592 eh = (struct elf_x86_link_hash_entry *) h;
4593 if (eh->no_finish_dynamic_symbol)
4594 abort ();
4596 /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for
4597 resolved undefined weak symbols in executable so that their
4598 references have value 0 at run-time. */
4599 local_undefweak = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
4601 if (h->plt.offset != (bfd_vma) -1)
4603 bfd_vma plt_index;
4604 bfd_vma got_offset, plt_offset;
4605 Elf_Internal_Rela rela;
4606 bfd_byte *loc;
4607 asection *plt, *gotplt, *relplt, *resolved_plt;
4608 const struct elf_backend_data *bed;
4609 bfd_vma plt_got_pcrel_offset;
4611 /* When building a static executable, use .iplt, .igot.plt and
4612 .rela.iplt sections for STT_GNU_IFUNC symbols. */
4613 if (htab->elf.splt != NULL)
4615 plt = htab->elf.splt;
4616 gotplt = htab->elf.sgotplt;
4617 relplt = htab->elf.srelplt;
4619 else
4621 plt = htab->elf.iplt;
4622 gotplt = htab->elf.igotplt;
4623 relplt = htab->elf.irelplt;
4626 VERIFY_PLT_ENTRY (info, h, plt, gotplt, relplt, local_undefweak)
4628 /* Get the index in the procedure linkage table which
4629 corresponds to this symbol. This is the index of this symbol
4630 in all the symbols for which we are making plt entries. The
4631 first entry in the procedure linkage table is reserved.
4633 Get the offset into the .got table of the entry that
4634 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
4635 bytes. The first three are reserved for the dynamic linker.
4637 For static executables, we don't reserve anything. */
4639 if (plt == htab->elf.splt)
4641 got_offset = (h->plt.offset / htab->plt.plt_entry_size
4642 - htab->plt.has_plt0);
4643 got_offset = (got_offset + 3) * GOT_ENTRY_SIZE;
4645 else
4647 got_offset = h->plt.offset / htab->plt.plt_entry_size;
4648 got_offset = got_offset * GOT_ENTRY_SIZE;
4651 /* Fill in the entry in the procedure linkage table. */
4652 memcpy (plt->contents + h->plt.offset, htab->plt.plt_entry,
4653 htab->plt.plt_entry_size);
4654 if (use_plt_second)
4656 memcpy (htab->plt_second->contents + eh->plt_second.offset,
4657 htab->non_lazy_plt->plt_entry,
4658 htab->non_lazy_plt->plt_entry_size);
4660 resolved_plt = htab->plt_second;
4661 plt_offset = eh->plt_second.offset;
4663 else
4665 resolved_plt = plt;
4666 plt_offset = h->plt.offset;
4669 /* Insert the relocation positions of the plt section. */
4671 /* Put offset the PC-relative instruction referring to the GOT entry,
4672 subtracting the size of that instruction. */
4673 plt_got_pcrel_offset = (gotplt->output_section->vma
4674 + gotplt->output_offset
4675 + got_offset
4676 - resolved_plt->output_section->vma
4677 - resolved_plt->output_offset
4678 - plt_offset
4679 - htab->plt.plt_got_insn_size);
4681 /* Check PC-relative offset overflow in PLT entry. */
4682 if ((plt_got_pcrel_offset + 0x80000000) > 0xffffffff)
4683 /* xgettext:c-format */
4684 info->callbacks->einfo (_("%F%pB: PC-relative offset overflow in PLT entry for `%s'\n"),
4685 output_bfd, h->root.root.string);
4687 bfd_put_32 (output_bfd, plt_got_pcrel_offset,
4688 (resolved_plt->contents + plt_offset
4689 + htab->plt.plt_got_offset));
4691 /* Fill in the entry in the global offset table, initially this
4692 points to the second part of the PLT entry. Leave the entry
4693 as zero for undefined weak symbol in PIE. No PLT relocation
4694 against undefined weak symbol in PIE. */
4695 if (!local_undefweak)
4697 if (htab->plt.has_plt0)
4698 bfd_put_64 (output_bfd, (plt->output_section->vma
4699 + plt->output_offset
4700 + h->plt.offset
4701 + htab->lazy_plt->plt_lazy_offset),
4702 gotplt->contents + got_offset);
4704 /* Fill in the entry in the .rela.plt section. */
4705 rela.r_offset = (gotplt->output_section->vma
4706 + gotplt->output_offset
4707 + got_offset);
4708 if (PLT_LOCAL_IFUNC_P (info, h))
4710 info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
4711 h->root.root.string,
4712 h->root.u.def.section->owner);
4714 /* If an STT_GNU_IFUNC symbol is locally defined, generate
4715 R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT. */
4716 rela.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
4717 rela.r_addend = (h->root.u.def.value
4718 + h->root.u.def.section->output_section->vma
4719 + h->root.u.def.section->output_offset);
4721 if (htab->params->report_relative_reloc)
4722 _bfd_x86_elf_link_report_relative_reloc
4723 (info, relplt, h, sym, "R_X86_64_IRELATIVE", &rela);
4725 /* R_X86_64_IRELATIVE comes last. */
4726 plt_index = htab->next_irelative_index--;
4728 else
4730 rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT);
4731 if (htab->params->mark_plt)
4732 rela.r_addend = (resolved_plt->output_section->vma
4733 + plt_offset
4734 + htab->plt.plt_indirect_branch_offset);
4735 else
4736 rela.r_addend = 0;
4737 plt_index = htab->next_jump_slot_index++;
4740 /* Don't fill the second and third slots in PLT entry for
4741 static executables nor without PLT0. */
4742 if (plt == htab->elf.splt && htab->plt.has_plt0)
4744 bfd_vma plt0_offset
4745 = h->plt.offset + htab->lazy_plt->plt_plt_insn_end;
4747 /* Put relocation index. */
4748 bfd_put_32 (output_bfd, plt_index,
4749 (plt->contents + h->plt.offset
4750 + htab->lazy_plt->plt_reloc_offset));
4752 /* Put offset for jmp .PLT0 and check for overflow. We don't
4753 check relocation index for overflow since branch displacement
4754 will overflow first. */
4755 if (plt0_offset > 0x80000000)
4756 /* xgettext:c-format */
4757 info->callbacks->einfo (_("%F%pB: branch displacement overflow in PLT entry for `%s'\n"),
4758 output_bfd, h->root.root.string);
4759 bfd_put_32 (output_bfd, - plt0_offset,
4760 (plt->contents + h->plt.offset
4761 + htab->lazy_plt->plt_plt_offset));
4764 bed = get_elf_backend_data (output_bfd);
4765 loc = relplt->contents + plt_index * bed->s->sizeof_rela;
4766 bed->s->swap_reloca_out (output_bfd, &rela, loc);
4769 else if (eh->plt_got.offset != (bfd_vma) -1)
4771 bfd_vma got_offset, plt_offset;
4772 asection *plt, *got;
4773 bool got_after_plt;
4774 int32_t got_pcrel_offset;
4776 /* Set the entry in the GOT procedure linkage table. */
4777 plt = htab->plt_got;
4778 got = htab->elf.sgot;
4779 got_offset = h->got.offset;
4781 if (got_offset == (bfd_vma) -1
4782 || (h->type == STT_GNU_IFUNC && h->def_regular)
4783 || plt == NULL
4784 || got == NULL)
4785 abort ();
4787 /* Use the non-lazy PLT entry template for the GOT PLT since they
4788 are the identical. */
4789 /* Fill in the entry in the GOT procedure linkage table. */
4790 plt_offset = eh->plt_got.offset;
4791 memcpy (plt->contents + plt_offset,
4792 htab->non_lazy_plt->plt_entry,
4793 htab->non_lazy_plt->plt_entry_size);
4795 /* Put offset the PC-relative instruction referring to the GOT
4796 entry, subtracting the size of that instruction. */
4797 got_pcrel_offset = (got->output_section->vma
4798 + got->output_offset
4799 + got_offset
4800 - plt->output_section->vma
4801 - plt->output_offset
4802 - plt_offset
4803 - htab->non_lazy_plt->plt_got_insn_size);
4805 /* Check PC-relative offset overflow in GOT PLT entry. */
4806 got_after_plt = got->output_section->vma > plt->output_section->vma;
4807 if ((got_after_plt && got_pcrel_offset < 0)
4808 || (!got_after_plt && got_pcrel_offset > 0))
4809 /* xgettext:c-format */
4810 info->callbacks->einfo (_("%F%pB: PC-relative offset overflow in GOT PLT entry for `%s'\n"),
4811 output_bfd, h->root.root.string);
4813 bfd_put_32 (output_bfd, got_pcrel_offset,
4814 (plt->contents + plt_offset
4815 + htab->non_lazy_plt->plt_got_offset));
4818 if (!local_undefweak
4819 && !h->def_regular
4820 && (h->plt.offset != (bfd_vma) -1
4821 || eh->plt_got.offset != (bfd_vma) -1))
4823 /* Mark the symbol as undefined, rather than as defined in
4824 the .plt section. Leave the value if there were any
4825 relocations where pointer equality matters (this is a clue
4826 for the dynamic linker, to make function pointer
4827 comparisons work between an application and shared
4828 library), otherwise set it to zero. If a function is only
4829 called from a binary, there is no need to slow down
4830 shared libraries because of that. */
4831 sym->st_shndx = SHN_UNDEF;
4832 if (!h->pointer_equality_needed)
4833 sym->st_value = 0;
4836 _bfd_x86_elf_link_fixup_ifunc_symbol (info, htab, h, sym);
4838 /* Don't generate dynamic GOT relocation against undefined weak
4839 symbol in executable. */
4840 if (h->got.offset != (bfd_vma) -1
4841 && ! GOT_TLS_GD_ANY_P (elf_x86_hash_entry (h)->tls_type)
4842 && elf_x86_hash_entry (h)->tls_type != GOT_TLS_IE
4843 && !local_undefweak)
4845 Elf_Internal_Rela rela;
4846 asection *relgot = htab->elf.srelgot;
4847 const char *relative_reloc_name = NULL;
4848 bool generate_dynamic_reloc = true;
4850 /* This symbol has an entry in the global offset table. Set it
4851 up. */
4852 if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
4853 abort ();
4855 rela.r_offset = (htab->elf.sgot->output_section->vma
4856 + htab->elf.sgot->output_offset
4857 + (h->got.offset &~ (bfd_vma) 1));
4859 /* If this is a static link, or it is a -Bsymbolic link and the
4860 symbol is defined locally or was forced to be local because
4861 of a version file, we just want to emit a RELATIVE reloc.
4862 The entry in the global offset table will already have been
4863 initialized in the relocate_section function. */
4864 if (h->def_regular
4865 && h->type == STT_GNU_IFUNC)
4867 if (h->plt.offset == (bfd_vma) -1)
4869 /* STT_GNU_IFUNC is referenced without PLT. */
4870 if (htab->elf.splt == NULL)
4872 /* use .rel[a].iplt section to store .got relocations
4873 in static executable. */
4874 relgot = htab->elf.irelplt;
4876 if (SYMBOL_REFERENCES_LOCAL_P (info, h))
4878 info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
4879 h->root.root.string,
4880 h->root.u.def.section->owner);
4882 rela.r_info = htab->r_info (0,
4883 R_X86_64_IRELATIVE);
4884 rela.r_addend = (h->root.u.def.value
4885 + h->root.u.def.section->output_section->vma
4886 + h->root.u.def.section->output_offset);
4887 relative_reloc_name = "R_X86_64_IRELATIVE";
4889 else
4890 goto do_glob_dat;
4892 else if (bfd_link_pic (info))
4894 /* Generate R_X86_64_GLOB_DAT. */
4895 goto do_glob_dat;
4897 else
4899 asection *plt;
4900 bfd_vma plt_offset;
4902 if (!h->pointer_equality_needed)
4903 abort ();
4905 /* For non-shared object, we can't use .got.plt, which
4906 contains the real function addres if we need pointer
4907 equality. We load the GOT entry with the PLT entry. */
4908 if (htab->plt_second != NULL)
4910 plt = htab->plt_second;
4911 plt_offset = eh->plt_second.offset;
4913 else
4915 plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
4916 plt_offset = h->plt.offset;
4918 bfd_put_64 (output_bfd, (plt->output_section->vma
4919 + plt->output_offset
4920 + plt_offset),
4921 htab->elf.sgot->contents + h->got.offset);
4922 return true;
4925 else if (bfd_link_pic (info)
4926 && SYMBOL_REFERENCES_LOCAL_P (info, h))
4928 if (!SYMBOL_DEFINED_NON_SHARED_P (h))
4929 return false;
4930 BFD_ASSERT((h->got.offset & 1) != 0);
4931 if (info->enable_dt_relr)
4932 generate_dynamic_reloc = false;
4933 else
4935 rela.r_info = htab->r_info (0, R_X86_64_RELATIVE);
4936 rela.r_addend = (h->root.u.def.value
4937 + h->root.u.def.section->output_section->vma
4938 + h->root.u.def.section->output_offset);
4939 relative_reloc_name = "R_X86_64_RELATIVE";
4942 else
4944 BFD_ASSERT((h->got.offset & 1) == 0);
4945 do_glob_dat:
4946 bfd_put_64 (output_bfd, (bfd_vma) 0,
4947 htab->elf.sgot->contents + h->got.offset);
4948 rela.r_info = htab->r_info (h->dynindx, R_X86_64_GLOB_DAT);
4949 rela.r_addend = 0;
4952 if (generate_dynamic_reloc)
4954 if (relative_reloc_name != NULL
4955 && htab->params->report_relative_reloc)
4956 _bfd_x86_elf_link_report_relative_reloc
4957 (info, relgot, h, sym, relative_reloc_name, &rela);
4959 elf_append_rela (output_bfd, relgot, &rela);
4963 if (h->needs_copy)
4965 Elf_Internal_Rela rela;
4966 asection *s;
4968 /* This symbol needs a copy reloc. Set it up. */
4969 VERIFY_COPY_RELOC (h, htab)
4971 rela.r_offset = (h->root.u.def.value
4972 + h->root.u.def.section->output_section->vma
4973 + h->root.u.def.section->output_offset);
4974 rela.r_info = htab->r_info (h->dynindx, R_X86_64_COPY);
4975 rela.r_addend = 0;
4976 if (h->root.u.def.section == htab->elf.sdynrelro)
4977 s = htab->elf.sreldynrelro;
4978 else
4979 s = htab->elf.srelbss;
4980 elf_append_rela (output_bfd, s, &rela);
4983 return true;
4986 /* Finish up local dynamic symbol handling. We set the contents of
4987 various dynamic sections here. */
4989 static int
4990 elf_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
4992 struct elf_link_hash_entry *h
4993 = (struct elf_link_hash_entry *) *slot;
4994 struct bfd_link_info *info
4995 = (struct bfd_link_info *) inf;
4997 return elf_x86_64_finish_dynamic_symbol (info->output_bfd,
4998 info, h, NULL);
5001 /* Finish up undefined weak symbol handling in PIE. Fill its PLT entry
5002 here since undefined weak symbol may not be dynamic and may not be
5003 called for elf_x86_64_finish_dynamic_symbol. */
5005 static bool
5006 elf_x86_64_pie_finish_undefweak_symbol (struct bfd_hash_entry *bh,
5007 void *inf)
5009 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh;
5010 struct bfd_link_info *info = (struct bfd_link_info *) inf;
5012 if (h->root.type != bfd_link_hash_undefweak
5013 || h->dynindx != -1)
5014 return true;
5016 return elf_x86_64_finish_dynamic_symbol (info->output_bfd,
5017 info, h, NULL);
5020 /* Used to decide how to sort relocs in an optimal manner for the
5021 dynamic linker, before writing them out. */
5023 static enum elf_reloc_type_class
5024 elf_x86_64_reloc_type_class (const struct bfd_link_info *info,
5025 const asection *rel_sec ATTRIBUTE_UNUSED,
5026 const Elf_Internal_Rela *rela)
5028 bfd *abfd = info->output_bfd;
5029 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
5030 struct elf_x86_link_hash_table *htab
5031 = elf_x86_hash_table (info, X86_64_ELF_DATA);
5033 if (htab->elf.dynsym != NULL
5034 && htab->elf.dynsym->contents != NULL)
5036 /* Check relocation against STT_GNU_IFUNC symbol if there are
5037 dynamic symbols. */
5038 unsigned long r_symndx = htab->r_sym (rela->r_info);
5039 if (r_symndx != STN_UNDEF)
5041 Elf_Internal_Sym sym;
5042 if (!bed->s->swap_symbol_in (abfd,
5043 (htab->elf.dynsym->contents
5044 + r_symndx * bed->s->sizeof_sym),
5045 0, &sym))
5046 abort ();
5048 if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
5049 return reloc_class_ifunc;
5053 switch ((int) ELF32_R_TYPE (rela->r_info))
5055 case R_X86_64_IRELATIVE:
5056 return reloc_class_ifunc;
5057 case R_X86_64_RELATIVE:
5058 case R_X86_64_RELATIVE64:
5059 return reloc_class_relative;
5060 case R_X86_64_JUMP_SLOT:
5061 return reloc_class_plt;
5062 case R_X86_64_COPY:
5063 return reloc_class_copy;
5064 default:
5065 return reloc_class_normal;
5069 /* Finish up the dynamic sections. */
5071 static bool
5072 elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
5073 struct bfd_link_info *info)
5075 struct elf_x86_link_hash_table *htab;
5077 htab = _bfd_x86_elf_finish_dynamic_sections (output_bfd, info);
5078 if (htab == NULL)
5079 return false;
5081 if (! htab->elf.dynamic_sections_created)
5082 return true;
5084 if (htab->elf.splt && htab->elf.splt->size > 0)
5086 if (bfd_is_abs_section (htab->elf.splt->output_section))
5088 info->callbacks->einfo
5089 (_("%F%P: discarded output section: `%pA'\n"),
5090 htab->elf.splt);
5091 return false;
5094 elf_section_data (htab->elf.splt->output_section)
5095 ->this_hdr.sh_entsize = htab->plt.plt_entry_size;
5097 if (htab->plt.has_plt0)
5099 /* Fill in the special first entry in the procedure linkage
5100 table. */
5101 memcpy (htab->elf.splt->contents,
5102 htab->lazy_plt->plt0_entry,
5103 htab->lazy_plt->plt0_entry_size);
5104 /* Add offset for pushq GOT+8(%rip), since the instruction
5105 uses 6 bytes subtract this value. */
5106 bfd_put_32 (output_bfd,
5107 (htab->elf.sgotplt->output_section->vma
5108 + htab->elf.sgotplt->output_offset
5110 - htab->elf.splt->output_section->vma
5111 - htab->elf.splt->output_offset
5112 - 6),
5113 (htab->elf.splt->contents
5114 + htab->lazy_plt->plt0_got1_offset));
5115 /* Add offset for the PC-relative instruction accessing
5116 GOT+16, subtracting the offset to the end of that
5117 instruction. */
5118 bfd_put_32 (output_bfd,
5119 (htab->elf.sgotplt->output_section->vma
5120 + htab->elf.sgotplt->output_offset
5121 + 16
5122 - htab->elf.splt->output_section->vma
5123 - htab->elf.splt->output_offset
5124 - htab->lazy_plt->plt0_got2_insn_end),
5125 (htab->elf.splt->contents
5126 + htab->lazy_plt->plt0_got2_offset));
5129 if (htab->elf.tlsdesc_plt)
5131 bfd_put_64 (output_bfd, (bfd_vma) 0,
5132 htab->elf.sgot->contents + htab->elf.tlsdesc_got);
5134 memcpy (htab->elf.splt->contents + htab->elf.tlsdesc_plt,
5135 htab->lazy_plt->plt_tlsdesc_entry,
5136 htab->lazy_plt->plt_tlsdesc_entry_size);
5138 /* Add offset for pushq GOT+8(%rip), since ENDBR64 uses 4
5139 bytes and the instruction uses 6 bytes, subtract these
5140 values. */
5141 bfd_put_32 (output_bfd,
5142 (htab->elf.sgotplt->output_section->vma
5143 + htab->elf.sgotplt->output_offset
5145 - htab->elf.splt->output_section->vma
5146 - htab->elf.splt->output_offset
5147 - htab->elf.tlsdesc_plt
5148 - htab->lazy_plt->plt_tlsdesc_got1_insn_end),
5149 (htab->elf.splt->contents
5150 + htab->elf.tlsdesc_plt
5151 + htab->lazy_plt->plt_tlsdesc_got1_offset));
5152 /* Add offset for indirect branch via GOT+TDG, where TDG
5153 stands for htab->tlsdesc_got, subtracting the offset
5154 to the end of that instruction. */
5155 bfd_put_32 (output_bfd,
5156 (htab->elf.sgot->output_section->vma
5157 + htab->elf.sgot->output_offset
5158 + htab->elf.tlsdesc_got
5159 - htab->elf.splt->output_section->vma
5160 - htab->elf.splt->output_offset
5161 - htab->elf.tlsdesc_plt
5162 - htab->lazy_plt->plt_tlsdesc_got2_insn_end),
5163 (htab->elf.splt->contents
5164 + htab->elf.tlsdesc_plt
5165 + htab->lazy_plt->plt_tlsdesc_got2_offset));
5169 /* Fill PLT entries for undefined weak symbols in PIE. */
5170 if (bfd_link_pie (info))
5171 bfd_hash_traverse (&info->hash->table,
5172 elf_x86_64_pie_finish_undefweak_symbol,
5173 info);
5175 return true;
5178 /* Fill PLT/GOT entries and allocate dynamic relocations for local
5179 STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table.
5180 It has to be done before elf_link_sort_relocs is called so that
5181 dynamic relocations are properly sorted. */
5183 static bool
5184 elf_x86_64_output_arch_local_syms
5185 (bfd *output_bfd ATTRIBUTE_UNUSED,
5186 struct bfd_link_info *info,
5187 void *flaginfo ATTRIBUTE_UNUSED,
5188 int (*func) (void *, const char *,
5189 Elf_Internal_Sym *,
5190 asection *,
5191 struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
5193 struct elf_x86_link_hash_table *htab
5194 = elf_x86_hash_table (info, X86_64_ELF_DATA);
5195 if (htab == NULL)
5196 return false;
5198 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
5199 htab_traverse (htab->loc_hash_table,
5200 elf_x86_64_finish_local_dynamic_symbol,
5201 info);
5203 return true;
5206 /* Similar to _bfd_elf_get_synthetic_symtab. Support PLTs with all
5207 dynamic relocations. */
5209 static long
5210 elf_x86_64_get_synthetic_symtab (bfd *abfd,
5211 long symcount ATTRIBUTE_UNUSED,
5212 asymbol **syms ATTRIBUTE_UNUSED,
5213 long dynsymcount,
5214 asymbol **dynsyms,
5215 asymbol **ret)
5217 long count, i, n;
5218 int j;
5219 bfd_byte *plt_contents;
5220 long relsize;
5221 const struct elf_x86_lazy_plt_layout *lazy_plt;
5222 const struct elf_x86_non_lazy_plt_layout *non_lazy_plt;
5223 const struct elf_x86_lazy_plt_layout *lazy_bnd_plt;
5224 const struct elf_x86_non_lazy_plt_layout *non_lazy_bnd_plt;
5225 const struct elf_x86_lazy_plt_layout *lazy_ibt_plt;
5226 const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt;
5227 const struct elf_x86_lazy_plt_layout *x32_lazy_ibt_plt;
5228 const struct elf_x86_non_lazy_plt_layout *x32_non_lazy_ibt_plt;
5229 asection *plt;
5230 enum elf_x86_plt_type plt_type;
5231 struct elf_x86_plt plts[] =
5233 { ".plt", NULL, NULL, plt_unknown, 0, 0, 0, 0 },
5234 { ".plt.got", NULL, NULL, plt_non_lazy, 0, 0, 0, 0 },
5235 { ".plt.sec", NULL, NULL, plt_second, 0, 0, 0, 0 },
5236 { ".plt.bnd", NULL, NULL, plt_second, 0, 0, 0, 0 },
5237 { NULL, NULL, NULL, plt_non_lazy, 0, 0, 0, 0 }
5240 *ret = NULL;
5242 if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
5243 return 0;
5245 if (dynsymcount <= 0)
5246 return 0;
5248 relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
5249 if (relsize <= 0)
5250 return -1;
5252 lazy_plt = &elf_x86_64_lazy_plt;
5253 non_lazy_plt = &elf_x86_64_non_lazy_plt;
5254 lazy_bnd_plt = &elf_x86_64_lazy_bnd_plt;
5255 non_lazy_bnd_plt = &elf_x86_64_non_lazy_bnd_plt;
5256 if (ABI_64_P (abfd))
5258 lazy_ibt_plt = &elf_x86_64_lazy_ibt_plt;
5259 non_lazy_ibt_plt = &elf_x86_64_non_lazy_ibt_plt;
5260 x32_lazy_ibt_plt = &elf_x32_lazy_ibt_plt;
5261 x32_non_lazy_ibt_plt = &elf_x32_non_lazy_ibt_plt;
5263 else
5265 lazy_ibt_plt = &elf_x32_lazy_ibt_plt;
5266 non_lazy_ibt_plt = &elf_x32_non_lazy_ibt_plt;
5267 x32_lazy_ibt_plt = NULL;
5268 x32_non_lazy_ibt_plt = NULL;
5271 count = 0;
5272 for (j = 0; plts[j].name != NULL; j++)
5274 plt = bfd_get_section_by_name (abfd, plts[j].name);
5275 if (plt == NULL
5276 || plt->size == 0
5277 || (plt->flags & SEC_HAS_CONTENTS) == 0)
5278 continue;
5280 /* Get the PLT section contents. */
5281 if (!_bfd_elf_mmap_section_contents (abfd, plt, &plt_contents))
5282 break;
5284 /* Check what kind of PLT it is. */
5285 plt_type = plt_unknown;
5286 if (plts[j].type == plt_unknown
5287 && (plt->size >= (lazy_plt->plt_entry_size
5288 + lazy_plt->plt_entry_size)))
5290 /* Match lazy PLT first. Need to check the first two
5291 instructions. */
5292 if ((memcmp (plt_contents, lazy_plt->plt0_entry,
5293 lazy_plt->plt0_got1_offset) == 0)
5294 && (memcmp (plt_contents + 6, lazy_plt->plt0_entry + 6,
5295 2) == 0))
5297 if (x32_lazy_ibt_plt != NULL
5298 && (memcmp (plt_contents
5299 + x32_lazy_ibt_plt->plt_entry_size,
5300 x32_lazy_ibt_plt->plt_entry,
5301 x32_lazy_ibt_plt->plt_got_offset) == 0))
5303 /* The fist entry in the x32 lazy IBT PLT is the same
5304 as the lazy PLT. */
5305 plt_type = plt_lazy | plt_second;
5306 lazy_plt = x32_lazy_ibt_plt;
5308 else
5309 plt_type = plt_lazy;
5311 else if (lazy_bnd_plt != NULL
5312 && (memcmp (plt_contents, lazy_bnd_plt->plt0_entry,
5313 lazy_bnd_plt->plt0_got1_offset) == 0)
5314 && (memcmp (plt_contents + 6,
5315 lazy_bnd_plt->plt0_entry + 6, 3) == 0))
5317 plt_type = plt_lazy | plt_second;
5318 /* The fist entry in the lazy IBT PLT is the same as the
5319 lazy BND PLT. */
5320 if ((memcmp (plt_contents + lazy_ibt_plt->plt_entry_size,
5321 lazy_ibt_plt->plt_entry,
5322 lazy_ibt_plt->plt_got_offset) == 0))
5323 lazy_plt = lazy_ibt_plt;
5324 else
5325 lazy_plt = lazy_bnd_plt;
5329 if (non_lazy_plt != NULL
5330 && (plt_type == plt_unknown || plt_type == plt_non_lazy)
5331 && plt->size >= non_lazy_plt->plt_entry_size)
5333 /* Match non-lazy PLT. */
5334 if (memcmp (plt_contents, non_lazy_plt->plt_entry,
5335 non_lazy_plt->plt_got_offset) == 0)
5336 plt_type = plt_non_lazy;
5339 if (plt_type == plt_unknown || plt_type == plt_second)
5341 if (non_lazy_bnd_plt != NULL
5342 && plt->size >= non_lazy_bnd_plt->plt_entry_size
5343 && (memcmp (plt_contents, non_lazy_bnd_plt->plt_entry,
5344 non_lazy_bnd_plt->plt_got_offset) == 0))
5346 /* Match BND PLT. */
5347 plt_type = plt_second;
5348 non_lazy_plt = non_lazy_bnd_plt;
5350 else if (non_lazy_ibt_plt != NULL
5351 && plt->size >= non_lazy_ibt_plt->plt_entry_size
5352 && (memcmp (plt_contents,
5353 non_lazy_ibt_plt->plt_entry,
5354 non_lazy_ibt_plt->plt_got_offset) == 0))
5356 /* Match IBT PLT. */
5357 plt_type = plt_second;
5358 non_lazy_plt = non_lazy_ibt_plt;
5360 else if (x32_non_lazy_ibt_plt != NULL
5361 && plt->size >= x32_non_lazy_ibt_plt->plt_entry_size
5362 && (memcmp (plt_contents,
5363 x32_non_lazy_ibt_plt->plt_entry,
5364 x32_non_lazy_ibt_plt->plt_got_offset) == 0))
5366 /* Match x32 IBT PLT. */
5367 plt_type = plt_second;
5368 non_lazy_plt = x32_non_lazy_ibt_plt;
5372 if (plt_type == plt_unknown)
5374 _bfd_elf_munmap_section_contents (plt, plt_contents);
5375 continue;
5378 plts[j].sec = plt;
5379 plts[j].type = plt_type;
5381 if ((plt_type & plt_lazy))
5383 plts[j].plt_got_offset = lazy_plt->plt_got_offset;
5384 plts[j].plt_got_insn_size = lazy_plt->plt_got_insn_size;
5385 plts[j].plt_entry_size = lazy_plt->plt_entry_size;
5386 /* Skip PLT0 in lazy PLT. */
5387 i = 1;
5389 else
5391 plts[j].plt_got_offset = non_lazy_plt->plt_got_offset;
5392 plts[j].plt_got_insn_size = non_lazy_plt->plt_got_insn_size;
5393 plts[j].plt_entry_size = non_lazy_plt->plt_entry_size;
5394 i = 0;
5397 /* Skip lazy PLT when the second PLT is used. */
5398 if (plt_type == (plt_lazy | plt_second))
5399 plts[j].count = 0;
5400 else
5402 n = plt->size / plts[j].plt_entry_size;
5403 plts[j].count = n;
5404 count += n - i;
5407 plts[j].contents = plt_contents;
5410 return _bfd_x86_elf_get_synthetic_symtab (abfd, count, relsize,
5411 (bfd_vma) 0, plts, dynsyms,
5412 ret);
5415 /* Handle an x86-64 specific section when reading an object file. This
5416 is called when elfcode.h finds a section with an unknown type. */
5418 static bool
5419 elf_x86_64_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
5420 const char *name, int shindex)
5422 if (hdr->sh_type != SHT_X86_64_UNWIND)
5423 return false;
5425 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
5426 return false;
5428 return true;
5431 /* Hook called by the linker routine which adds symbols from an object
5432 file. We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
5433 of .bss. */
5435 static bool
5436 elf_x86_64_add_symbol_hook (bfd *abfd,
5437 struct bfd_link_info *info ATTRIBUTE_UNUSED,
5438 Elf_Internal_Sym *sym,
5439 const char **namep ATTRIBUTE_UNUSED,
5440 flagword *flagsp ATTRIBUTE_UNUSED,
5441 asection **secp,
5442 bfd_vma *valp)
5444 asection *lcomm;
5446 switch (sym->st_shndx)
5448 case SHN_X86_64_LCOMMON:
5449 lcomm = bfd_get_section_by_name (abfd, "LARGE_COMMON");
5450 if (lcomm == NULL)
5452 lcomm = bfd_make_section_with_flags (abfd,
5453 "LARGE_COMMON",
5454 (SEC_ALLOC
5455 | SEC_IS_COMMON
5456 | SEC_LINKER_CREATED));
5457 if (lcomm == NULL)
5458 return false;
5459 elf_section_flags (lcomm) |= SHF_X86_64_LARGE;
5461 *secp = lcomm;
5462 *valp = sym->st_size;
5463 return true;
5466 return true;
5470 /* Given a BFD section, try to locate the corresponding ELF section
5471 index. */
5473 static bool
5474 elf_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
5475 asection *sec, int *index_return)
5477 if (sec == &_bfd_elf_large_com_section)
5479 *index_return = SHN_X86_64_LCOMMON;
5480 return true;
5482 return false;
5485 /* Process a symbol. */
5487 static void
5488 elf_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5489 asymbol *asym)
5491 elf_symbol_type *elfsym = (elf_symbol_type *) asym;
5493 switch (elfsym->internal_elf_sym.st_shndx)
5495 case SHN_X86_64_LCOMMON:
5496 asym->section = &_bfd_elf_large_com_section;
5497 asym->value = elfsym->internal_elf_sym.st_size;
5498 /* Common symbol doesn't set BSF_GLOBAL. */
5499 asym->flags &= ~BSF_GLOBAL;
5500 break;
5504 static bool
5505 elf_x86_64_common_definition (Elf_Internal_Sym *sym)
5507 return (sym->st_shndx == SHN_COMMON
5508 || sym->st_shndx == SHN_X86_64_LCOMMON);
5511 static unsigned int
5512 elf_x86_64_common_section_index (asection *sec)
5514 if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
5515 return SHN_COMMON;
5516 else
5517 return SHN_X86_64_LCOMMON;
5520 static asection *
5521 elf_x86_64_common_section (asection *sec)
5523 if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
5524 return bfd_com_section_ptr;
5525 else
5526 return &_bfd_elf_large_com_section;
5529 static bool
5530 elf_x86_64_merge_symbol (struct elf_link_hash_entry *h,
5531 const Elf_Internal_Sym *sym,
5532 asection **psec,
5533 bool newdef,
5534 bool olddef,
5535 bfd *oldbfd,
5536 const asection *oldsec)
5538 /* A normal common symbol and a large common symbol result in a
5539 normal common symbol. We turn the large common symbol into a
5540 normal one. */
5541 if (!olddef
5542 && h->root.type == bfd_link_hash_common
5543 && !newdef
5544 && bfd_is_com_section (*psec)
5545 && oldsec != *psec)
5547 if (sym->st_shndx == SHN_COMMON
5548 && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) != 0)
5550 h->root.u.c.p->section
5551 = bfd_make_section_old_way (oldbfd, "COMMON");
5552 h->root.u.c.p->section->flags = SEC_ALLOC;
5554 else if (sym->st_shndx == SHN_X86_64_LCOMMON
5555 && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) == 0)
5556 *psec = bfd_com_section_ptr;
5559 return true;
5562 static bool
5563 elf_x86_64_section_flags (const Elf_Internal_Shdr *hdr)
5565 if ((hdr->sh_flags & SHF_X86_64_LARGE) != 0)
5566 hdr->bfd_section->flags |= SEC_ELF_LARGE;
5568 return true;
5571 static bool
5572 elf_x86_64_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
5573 Elf_Internal_Shdr *hdr, asection *sec)
5575 if (sec->flags & SEC_ELF_LARGE)
5576 hdr->sh_flags |= SHF_X86_64_LARGE;
5578 return true;
5581 static bool
5582 elf_x86_64_copy_private_section_data (bfd *ibfd, asection *isec,
5583 bfd *obfd, asection *osec)
5585 if (!_bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec))
5586 return false;
5588 /* objcopy --set-section-flags without "large" drops SHF_X86_64_LARGE. */
5589 if (ibfd != obfd)
5590 elf_section_flags (osec) &= ~SHF_X86_64_LARGE;
5592 return true;
5595 static int
5596 elf_x86_64_additional_program_headers (bfd *abfd,
5597 struct bfd_link_info *info ATTRIBUTE_UNUSED)
5599 asection *s;
5600 int count = 0;
5602 /* Check to see if we need a large readonly segment. */
5603 s = bfd_get_section_by_name (abfd, ".lrodata");
5604 if (s && (s->flags & SEC_LOAD))
5605 count++;
5607 /* Check to see if we need a large data segment. Since .lbss sections
5608 is placed right after the .bss section, there should be no need for
5609 a large data segment just because of .lbss. */
5610 s = bfd_get_section_by_name (abfd, ".ldata");
5611 if (s && (s->flags & SEC_LOAD))
5612 count++;
5614 return count;
5617 /* Return TRUE iff relocations for INPUT are compatible with OUTPUT. */
5619 static bool
5620 elf_x86_64_relocs_compatible (const bfd_target *input,
5621 const bfd_target *output)
5623 return ((xvec_get_elf_backend_data (input)->s->elfclass
5624 == xvec_get_elf_backend_data (output)->s->elfclass)
5625 && _bfd_elf_relocs_compatible (input, output));
5628 /* Set up x86-64 GNU properties. Return the first relocatable ELF input
5629 with GNU properties if found. Otherwise, return NULL. */
5631 static bfd *
5632 elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
5634 struct elf_x86_init_table init_table;
5635 const struct elf_backend_data *bed;
5636 struct elf_x86_link_hash_table *htab;
5638 if ((int) R_X86_64_standard >= (int) R_X86_64_converted_reloc_bit
5639 || (int) R_X86_64_max <= (int) R_X86_64_converted_reloc_bit
5640 || ((int) (R_X86_64_GNU_VTINHERIT | R_X86_64_converted_reloc_bit)
5641 != (int) R_X86_64_GNU_VTINHERIT)
5642 || ((int) (R_X86_64_GNU_VTENTRY | R_X86_64_converted_reloc_bit)
5643 != (int) R_X86_64_GNU_VTENTRY))
5644 abort ();
5646 /* This is unused for x86-64. */
5647 init_table.plt0_pad_byte = 0x90;
5649 bed = get_elf_backend_data (info->output_bfd);
5650 htab = elf_x86_hash_table (info, bed->target_id);
5651 if (!htab)
5652 abort ();
5654 init_table.lazy_plt = &elf_x86_64_lazy_plt;
5655 init_table.non_lazy_plt = &elf_x86_64_non_lazy_plt;
5657 init_table.lazy_ibt_plt = &elf_x32_lazy_ibt_plt;
5658 init_table.non_lazy_ibt_plt = &elf_x32_non_lazy_ibt_plt;
5660 if (ABI_64_P (info->output_bfd))
5662 init_table.sframe_lazy_plt = &elf_x86_64_sframe_plt;
5663 init_table.sframe_non_lazy_plt = &elf_x86_64_sframe_non_lazy_plt;
5664 init_table.sframe_lazy_ibt_plt = &elf_x86_64_sframe_plt;
5665 init_table.sframe_non_lazy_ibt_plt = &elf_x86_64_sframe_non_lazy_plt;
5667 else
5669 /* SFrame is not supported for non AMD64. */
5670 init_table.sframe_lazy_plt = NULL;
5671 init_table.sframe_non_lazy_plt = NULL;
5674 if (ABI_64_P (info->output_bfd))
5676 init_table.r_info = elf64_r_info;
5677 init_table.r_sym = elf64_r_sym;
5679 else
5681 init_table.r_info = elf32_r_info;
5682 init_table.r_sym = elf32_r_sym;
5685 return _bfd_x86_elf_link_setup_gnu_properties (info, &init_table);
5688 static void
5689 elf_x86_64_add_glibc_version_dependency
5690 (struct elf_find_verdep_info *rinfo)
5692 unsigned int i = 0;
5693 const char *version[3] = { NULL, NULL, NULL };
5694 struct elf_x86_link_hash_table *htab;
5696 if (rinfo->info->enable_dt_relr)
5698 version[i] = "GLIBC_ABI_DT_RELR";
5699 i++;
5702 htab = elf_x86_hash_table (rinfo->info, X86_64_ELF_DATA);
5703 if (htab != NULL && htab->params->mark_plt)
5705 version[i] = "GLIBC_2.36";
5706 i++;
5709 if (i != 0)
5710 _bfd_elf_link_add_glibc_version_dependency (rinfo, version);
5713 static const struct bfd_elf_special_section
5714 elf_x86_64_special_sections[]=
5716 { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
5717 { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
5718 { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE},
5719 { STRING_COMMA_LEN (".lbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
5720 { STRING_COMMA_LEN (".ldata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
5721 { STRING_COMMA_LEN (".lrodata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
5722 { NULL, 0, 0, 0, 0 }
5725 #define TARGET_LITTLE_SYM x86_64_elf64_vec
5726 #define TARGET_LITTLE_NAME "elf64-x86-64"
5727 #define ELF_ARCH bfd_arch_i386
5728 #define ELF_TARGET_ID X86_64_ELF_DATA
5729 #define ELF_MACHINE_CODE EM_X86_64
5730 #define ELF_MAXPAGESIZE 0x1000
5731 #define ELF_COMMONPAGESIZE 0x1000
5733 #define elf_backend_can_gc_sections 1
5734 #define elf_backend_can_refcount 1
5735 #define elf_backend_want_got_plt 1
5736 #define elf_backend_plt_readonly 1
5737 #define elf_backend_want_plt_sym 0
5738 #define elf_backend_got_header_size (GOT_ENTRY_SIZE*3)
5739 #define elf_backend_rela_normal 1
5740 #define elf_backend_plt_alignment 4
5741 #define elf_backend_caches_rawsize 1
5742 #define elf_backend_dtrel_excludes_plt 1
5743 #define elf_backend_want_dynrelro 1
5745 #define elf_info_to_howto elf_x86_64_info_to_howto
5747 #define bfd_elf64_bfd_copy_private_section_data \
5748 elf_x86_64_copy_private_section_data
5749 #define bfd_elf64_bfd_reloc_type_lookup elf_x86_64_reloc_type_lookup
5750 #define bfd_elf64_bfd_reloc_name_lookup \
5751 elf_x86_64_reloc_name_lookup
5753 #define elf_backend_relocs_compatible elf_x86_64_relocs_compatible
5754 #define elf_backend_early_size_sections elf_x86_64_early_size_sections
5755 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
5756 #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections
5757 #define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol
5758 #define elf_backend_output_arch_local_syms elf_x86_64_output_arch_local_syms
5759 #define elf_backend_grok_prstatus elf_x86_64_grok_prstatus
5760 #define elf_backend_grok_psinfo elf_x86_64_grok_psinfo
5761 #ifdef CORE_HEADER
5762 #define elf_backend_write_core_note elf_x86_64_write_core_note
5763 #endif
5764 #define elf_backend_reloc_type_class elf_x86_64_reloc_type_class
5765 #define elf_backend_relocate_section elf_x86_64_relocate_section
5766 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
5767 #define elf_backend_object_p elf64_x86_64_elf_object_p
5768 #define bfd_elf64_get_synthetic_symtab elf_x86_64_get_synthetic_symtab
5770 #define elf_backend_section_from_shdr \
5771 elf_x86_64_section_from_shdr
5773 #define elf_backend_section_from_bfd_section \
5774 elf_x86_64_elf_section_from_bfd_section
5775 #define elf_backend_add_symbol_hook \
5776 elf_x86_64_add_symbol_hook
5777 #define elf_backend_symbol_processing \
5778 elf_x86_64_symbol_processing
5779 #define elf_backend_common_section_index \
5780 elf_x86_64_common_section_index
5781 #define elf_backend_common_section \
5782 elf_x86_64_common_section
5783 #define elf_backend_common_definition \
5784 elf_x86_64_common_definition
5785 #define elf_backend_merge_symbol \
5786 elf_x86_64_merge_symbol
5787 #define elf_backend_special_sections \
5788 elf_x86_64_special_sections
5789 #define elf_backend_section_flags elf_x86_64_section_flags
5790 #define elf_backend_fake_sections elf_x86_64_fake_sections
5791 #define elf_backend_additional_program_headers \
5792 elf_x86_64_additional_program_headers
5793 #define elf_backend_setup_gnu_properties \
5794 elf_x86_64_link_setup_gnu_properties
5795 #define elf_backend_hide_symbol \
5796 _bfd_x86_elf_hide_symbol
5797 #define elf_backend_add_glibc_version_dependency \
5798 elf_x86_64_add_glibc_version_dependency
5800 #undef elf64_bed
5801 #define elf64_bed elf64_x86_64_bed
5803 #include "elf64-target.h"
5805 /* CloudABI support. */
5807 #undef TARGET_LITTLE_SYM
5808 #define TARGET_LITTLE_SYM x86_64_elf64_cloudabi_vec
5809 #undef TARGET_LITTLE_NAME
5810 #define TARGET_LITTLE_NAME "elf64-x86-64-cloudabi"
5812 #undef ELF_OSABI
5813 #define ELF_OSABI ELFOSABI_CLOUDABI
5815 #undef elf64_bed
5816 #define elf64_bed elf64_x86_64_cloudabi_bed
5818 #include "elf64-target.h"
5820 /* FreeBSD support. */
5822 #undef TARGET_LITTLE_SYM
5823 #define TARGET_LITTLE_SYM x86_64_elf64_fbsd_vec
5824 #undef TARGET_LITTLE_NAME
5825 #define TARGET_LITTLE_NAME "elf64-x86-64-freebsd"
5827 #undef ELF_OSABI
5828 #define ELF_OSABI ELFOSABI_FREEBSD
5830 #undef elf64_bed
5831 #define elf64_bed elf64_x86_64_fbsd_bed
5833 #include "elf64-target.h"
5835 /* Solaris 2 support. */
5837 #undef TARGET_LITTLE_SYM
5838 #define TARGET_LITTLE_SYM x86_64_elf64_sol2_vec
5839 #undef TARGET_LITTLE_NAME
5840 #define TARGET_LITTLE_NAME "elf64-x86-64-sol2"
5842 #undef ELF_TARGET_OS
5843 #define ELF_TARGET_OS is_solaris
5845 /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
5846 objects won't be recognized. */
5847 #undef ELF_OSABI
5849 #undef elf64_bed
5850 #define elf64_bed elf64_x86_64_sol2_bed
5852 /* The 64-bit static TLS arena size is rounded to the nearest 16-byte
5853 boundary. */
5854 #undef elf_backend_static_tls_alignment
5855 #define elf_backend_static_tls_alignment 16
5857 /* The Solaris 2 ABI requires a plt symbol on all platforms.
5859 Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
5860 File, p.63. */
5861 #undef elf_backend_want_plt_sym
5862 #define elf_backend_want_plt_sym 1
5864 #undef elf_backend_strtab_flags
5865 #define elf_backend_strtab_flags SHF_STRINGS
5867 static bool
5868 elf64_x86_64_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
5869 bfd *obfd ATTRIBUTE_UNUSED,
5870 const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
5871 Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED)
5873 /* PR 19938: FIXME: Need to add code for setting the sh_info
5874 and sh_link fields of Solaris specific section types. */
5875 return false;
5878 #undef elf_backend_copy_special_section_fields
5879 #define elf_backend_copy_special_section_fields elf64_x86_64_copy_solaris_special_section_fields
5881 #include "elf64-target.h"
5883 /* Restore defaults. */
5884 #undef ELF_OSABI
5885 #undef elf_backend_static_tls_alignment
5886 #undef elf_backend_want_plt_sym
5887 #define elf_backend_want_plt_sym 0
5888 #undef elf_backend_strtab_flags
5889 #undef elf_backend_copy_special_section_fields
5891 /* 32bit x86-64 support. */
5893 #undef TARGET_LITTLE_SYM
5894 #define TARGET_LITTLE_SYM x86_64_elf32_vec
5895 #undef TARGET_LITTLE_NAME
5896 #define TARGET_LITTLE_NAME "elf32-x86-64"
5897 #undef elf32_bed
5898 #define elf32_bed elf32_x86_64_bed
5900 #undef ELF_ARCH
5901 #define ELF_ARCH bfd_arch_i386
5903 #undef ELF_MACHINE_CODE
5904 #define ELF_MACHINE_CODE EM_X86_64
5906 #undef ELF_TARGET_OS
5907 #undef ELF_OSABI
5909 #define bfd_elf32_bfd_copy_private_section_data \
5910 elf_x86_64_copy_private_section_data
5911 #define bfd_elf32_bfd_reloc_type_lookup \
5912 elf_x86_64_reloc_type_lookup
5913 #define bfd_elf32_bfd_reloc_name_lookup \
5914 elf_x86_64_reloc_name_lookup
5915 #define bfd_elf32_get_synthetic_symtab \
5916 elf_x86_64_get_synthetic_symtab
5918 #undef elf_backend_object_p
5919 #define elf_backend_object_p \
5920 elf32_x86_64_elf_object_p
5922 #undef elf_backend_bfd_from_remote_memory
5923 #define elf_backend_bfd_from_remote_memory \
5924 _bfd_elf32_bfd_from_remote_memory
5926 #undef elf_backend_size_info
5927 #define elf_backend_size_info \
5928 _bfd_elf32_size_info
5930 #include "elf32-target.h"