Support x86 Intel MSR_IMM
[binutils-gdb.git] / bfd / elf64-x86-64.c
blob4e1d822e637085458b9d5c4c4f5a79cbfd49ae68
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_bnd_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
634 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
635 0x68, 0, 0, 0, 0, /* pushq immediate */
636 0xf2, 0xe9, 0, 0, 0, 0, /* bnd jmpq relative */
637 0x90 /* nop */
640 /* The first entry in the IBT-enabled lazy procedure linkage table
641 is the same as the normal lazy PLT. Subsequent entries for an
642 IBT-enabled lazy procedure linkage table look like this. */
644 static const bfd_byte elf_x86_64_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
646 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
647 0x68, 0, 0, 0, 0, /* pushq immediate */
648 0xe9, 0, 0, 0, 0, /* jmpq relative */
649 0x66, 0x90 /* xchg %ax,%ax */
652 /* Entries in the non-lazey procedure linkage table look like this. */
654 static const bfd_byte elf_x86_64_non_lazy_plt_entry[NON_LAZY_PLT_ENTRY_SIZE] =
656 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
657 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
658 0x66, 0x90 /* xchg %ax,%ax */
661 /* Entries for branches with BND prefix in the non-lazey procedure
662 linkage table look like this. */
664 static const bfd_byte elf_x86_64_non_lazy_bnd_plt_entry[NON_LAZY_PLT_ENTRY_SIZE] =
666 0xf2, 0xff, 0x25, /* bnd jmpq *name@GOTPC(%rip) */
667 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
668 0x90 /* nop */
671 /* Entries for IBT-enabled branches with BND prefix in the non-lazey
672 procedure linkage table look like this. They have the same size as
673 the lazy PLT entry. */
675 static const bfd_byte elf_x86_64_non_lazy_bnd_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
677 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
678 0xf2, 0xff, 0x25, /* bnd jmpq *name@GOTPC(%rip) */
679 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
680 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopl 0x0(%rax,%rax,1) */
683 /* Entries for branches with IBT-enabled in the non-lazey procedure
684 linkage table look like this. They have the same size as the lazy
685 PLT entry. */
687 static const bfd_byte elf_x86_64_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
689 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
690 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
691 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
692 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
695 /* The TLSDESC entry in a lazy procedure linkage table. */
696 static const bfd_byte elf_x86_64_tlsdesc_plt_entry[LAZY_PLT_ENTRY_SIZE] =
698 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
699 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
700 0xff, 0x25, 16, 0, 0, 0 /* jmpq *GOT+TDG(%rip) */
703 /* .eh_frame covering the lazy .plt section. */
705 static const bfd_byte elf_x86_64_eh_frame_lazy_plt[] =
707 PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
708 0, 0, 0, 0, /* CIE ID */
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 and BND
774 prefix. */
776 static const bfd_byte elf_x86_64_eh_frame_lazy_bnd_ibt_plt[] =
778 PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
779 0, 0, 0, 0, /* CIE ID */
780 1, /* CIE version */
781 'z', 'R', 0, /* Augmentation string */
782 1, /* Code alignment factor */
783 0x78, /* Data alignment factor */
784 16, /* Return address column */
785 1, /* Augmentation size */
786 DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
787 DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
788 DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
789 DW_CFA_nop, DW_CFA_nop,
791 PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
792 PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
793 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
794 0, 0, 0, 0, /* .plt size goes here */
795 0, /* Augmentation size */
796 DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */
797 DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
798 DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */
799 DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
800 DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
801 11, /* Block length */
802 DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */
803 DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */
804 DW_OP_lit15, DW_OP_and, DW_OP_lit10, DW_OP_ge,
805 DW_OP_lit3, DW_OP_shl, DW_OP_plus,
806 DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
809 /* .eh_frame covering the lazy .plt section with IBT-enabled. */
811 static const bfd_byte elf_x86_64_eh_frame_lazy_ibt_plt[] =
813 PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
814 0, 0, 0, 0, /* CIE ID */
815 1, /* CIE version */
816 'z', 'R', 0, /* Augmentation string */
817 1, /* Code alignment factor */
818 0x78, /* Data alignment factor */
819 16, /* Return address column */
820 1, /* Augmentation size */
821 DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
822 DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
823 DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
824 DW_CFA_nop, DW_CFA_nop,
826 PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
827 PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
828 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
829 0, 0, 0, 0, /* .plt size goes here */
830 0, /* Augmentation size */
831 DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */
832 DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
833 DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */
834 DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
835 DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
836 11, /* Block length */
837 DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */
838 DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */
839 DW_OP_lit15, DW_OP_and, DW_OP_lit9, DW_OP_ge,
840 DW_OP_lit3, DW_OP_shl, DW_OP_plus,
841 DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
844 /* .eh_frame covering the non-lazy .plt section. */
846 static const bfd_byte elf_x86_64_eh_frame_non_lazy_plt[] =
848 #define PLT_GOT_FDE_LENGTH 20
849 PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
850 0, 0, 0, 0, /* CIE ID */
851 1, /* CIE version */
852 'z', 'R', 0, /* Augmentation string */
853 1, /* Code alignment factor */
854 0x78, /* Data alignment factor */
855 16, /* Return address column */
856 1, /* Augmentation size */
857 DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
858 DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
859 DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
860 DW_CFA_nop, DW_CFA_nop,
862 PLT_GOT_FDE_LENGTH, 0, 0, 0, /* FDE length */
863 PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
864 0, 0, 0, 0, /* the start of non-lazy .plt goes here */
865 0, 0, 0, 0, /* non-lazy .plt size goes here */
866 0, /* Augmentation size */
867 DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop,
868 DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
871 static const sframe_frame_row_entry elf_x86_64_sframe_null_fre =
874 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
875 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
878 /* .sframe FRE covering the .plt section entry. */
879 static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre1 =
881 0, /* SFrame FRE start address. */
882 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
883 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
886 /* .sframe FRE covering the .plt section entry. */
887 static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre2 =
889 6, /* SFrame FRE start address. */
890 {24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
891 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
894 /* .sframe FRE covering the .plt section entry. */
895 static const sframe_frame_row_entry elf_x86_64_sframe_pltn_fre1 =
897 0, /* SFrame FRE start address. */
898 {8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
899 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
902 /* .sframe FRE covering the .plt section entry. */
903 static const sframe_frame_row_entry elf_x86_64_sframe_pltn_fre2 =
905 11, /* SFrame FRE start address. */
906 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
907 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
910 /* .sframe FRE covering the .plt section entry for IBT. */
911 static const sframe_frame_row_entry elf_x86_64_sframe_ibt_pltn_fre2 =
913 9, /* SFrame FRE start address. */
914 {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
915 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
918 /* .sframe FRE covering the second .plt section entry. */
919 static const sframe_frame_row_entry elf_x86_64_sframe_sec_pltn_fre1 =
921 0, /* SFrame FRE start address. */
922 {8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */
923 SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */
926 /* SFrame helper object for non-lazy PLT. */
927 static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_plt =
929 LAZY_PLT_ENTRY_SIZE,
930 2, /* Number of FREs for PLT0. */
931 /* Array of SFrame FREs for plt0. */
932 { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 },
933 LAZY_PLT_ENTRY_SIZE,
934 1, /* Number of FREs for PLTn. */
935 /* Array of SFrame FREs for plt. */
936 { &elf_x86_64_sframe_sec_pltn_fre1, &elf_x86_64_sframe_null_fre },
938 0, /* There is no second PLT necessary. */
939 { &elf_x86_64_sframe_null_fre },
940 NON_LAZY_PLT_ENTRY_SIZE,
941 1, /* Number of FREs for PLT GOT. */
942 /* Array of SFrame FREs for PLT GOT. */
943 { &elf_x86_64_sframe_null_fre },
946 /* SFrame helper object for non-lazy IBT enabled PLT. */
947 static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_ibt_plt =
949 LAZY_PLT_ENTRY_SIZE,
950 2, /* Number of FREs for PLT0. */
951 /* Array of SFrame FREs for plt0. */
952 { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 },
953 LAZY_PLT_ENTRY_SIZE,
954 1, /* Number of FREs for PLTn. */
955 /* Array of SFrame FREs for plt. */
956 { &elf_x86_64_sframe_sec_pltn_fre1, &elf_x86_64_sframe_null_fre },
958 0, /* There is no second PLT necessary. */
959 { &elf_x86_64_sframe_null_fre },
960 LAZY_PLT_ENTRY_SIZE,
961 1, /* Number of FREs for PLT GOT. */
962 /* Array of SFrame FREs for PLT GOT. */
963 { &elf_x86_64_sframe_null_fre },
966 /* SFrame helper object for lazy PLT. */
967 static const struct elf_x86_sframe_plt elf_x86_64_sframe_plt =
969 LAZY_PLT_ENTRY_SIZE,
970 2, /* Number of FREs for PLT0. */
971 /* Array of SFrame FREs for plt0. */
972 { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 },
973 LAZY_PLT_ENTRY_SIZE,
974 2, /* Number of FREs for PLTn. */
975 /* Array of SFrame FREs for plt. */
976 { &elf_x86_64_sframe_pltn_fre1, &elf_x86_64_sframe_pltn_fre2 },
977 NON_LAZY_PLT_ENTRY_SIZE,
978 1, /* Number of FREs for second PLT. */
979 /* Array of SFrame FREs for second PLT. */
980 { &elf_x86_64_sframe_sec_pltn_fre1 },
981 NON_LAZY_PLT_ENTRY_SIZE,
982 1, /* Number of FREs for PLT GOT. */
983 /* Array of SFrame FREs for PLT GOT. */
984 { &elf_x86_64_sframe_null_fre },
987 /* SFrame helper object for lazy PLT with IBT. */
988 static const struct elf_x86_sframe_plt elf_x86_64_sframe_ibt_plt =
990 LAZY_PLT_ENTRY_SIZE,
991 2, /* Number of FREs for PLT0. */
992 /* Array of SFrame FREs for plt0. */
993 { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 },
994 LAZY_PLT_ENTRY_SIZE,
995 2, /* Number of FREs for PLTn. */
996 /* Array of SFrame FREs for plt. */
997 { &elf_x86_64_sframe_pltn_fre1, &elf_x86_64_sframe_ibt_pltn_fre2 },
998 LAZY_PLT_ENTRY_SIZE,
999 1, /* Number of FREs for second PLT. */
1000 /* Array of SFrame FREs for second plt. */
1001 { &elf_x86_64_sframe_sec_pltn_fre1 },
1002 LAZY_PLT_ENTRY_SIZE,
1003 1, /* Number of FREs for PLT GOT. */
1004 /* Array of SFrame FREs for PLT GOT. */
1005 { &elf_x86_64_sframe_null_fre },
1008 /* These are the standard parameters. */
1009 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_plt =
1011 elf_x86_64_lazy_plt0_entry, /* plt0_entry */
1012 LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */
1013 elf_x86_64_lazy_plt_entry, /* plt_entry */
1014 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1015 elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */
1016 LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */
1017 6, /* plt_tlsdesc_got1_offset */
1018 12, /* plt_tlsdesc_got2_offset */
1019 10, /* plt_tlsdesc_got1_insn_end */
1020 16, /* plt_tlsdesc_got2_insn_end */
1021 2, /* plt0_got1_offset */
1022 8, /* plt0_got2_offset */
1023 12, /* plt0_got2_insn_end */
1024 2, /* plt_got_offset */
1025 7, /* plt_reloc_offset */
1026 12, /* plt_plt_offset */
1027 6, /* plt_got_insn_size */
1028 LAZY_PLT_ENTRY_SIZE, /* plt_plt_insn_end */
1029 6, /* plt_lazy_offset */
1030 elf_x86_64_lazy_plt0_entry, /* pic_plt0_entry */
1031 elf_x86_64_lazy_plt_entry, /* pic_plt_entry */
1032 elf_x86_64_eh_frame_lazy_plt, /* eh_frame_plt */
1033 sizeof (elf_x86_64_eh_frame_lazy_plt) /* eh_frame_plt_size */
1036 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_plt =
1038 elf_x86_64_non_lazy_plt_entry, /* plt_entry */
1039 elf_x86_64_non_lazy_plt_entry, /* pic_plt_entry */
1040 NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1041 2, /* plt_got_offset */
1042 6, /* plt_got_insn_size */
1043 elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */
1044 sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
1047 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_plt =
1049 elf_x86_64_lazy_bnd_plt0_entry, /* plt0_entry */
1050 LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */
1051 elf_x86_64_lazy_bnd_plt_entry, /* plt_entry */
1052 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1053 elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */
1054 LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */
1055 6, /* plt_tlsdesc_got1_offset */
1056 12, /* plt_tlsdesc_got2_offset */
1057 10, /* plt_tlsdesc_got1_insn_end */
1058 16, /* plt_tlsdesc_got2_insn_end */
1059 2, /* plt0_got1_offset */
1060 1+8, /* plt0_got2_offset */
1061 1+12, /* plt0_got2_insn_end */
1062 1+2, /* plt_got_offset */
1063 1, /* plt_reloc_offset */
1064 7, /* plt_plt_offset */
1065 1+6, /* plt_got_insn_size */
1066 11, /* plt_plt_insn_end */
1067 0, /* plt_lazy_offset */
1068 elf_x86_64_lazy_bnd_plt0_entry, /* pic_plt0_entry */
1069 elf_x86_64_lazy_bnd_plt_entry, /* pic_plt_entry */
1070 elf_x86_64_eh_frame_lazy_bnd_plt, /* eh_frame_plt */
1071 sizeof (elf_x86_64_eh_frame_lazy_bnd_plt) /* eh_frame_plt_size */
1074 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt =
1076 elf_x86_64_non_lazy_bnd_plt_entry, /* plt_entry */
1077 elf_x86_64_non_lazy_bnd_plt_entry, /* pic_plt_entry */
1078 NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1079 1+2, /* plt_got_offset */
1080 1+6, /* plt_got_insn_size */
1081 elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */
1082 sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
1085 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_ibt_plt =
1087 elf_x86_64_lazy_bnd_plt0_entry, /* plt0_entry */
1088 LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */
1089 elf_x86_64_lazy_bnd_ibt_plt_entry, /* plt_entry */
1090 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1091 elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */
1092 LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */
1093 6, /* plt_tlsdesc_got1_offset */
1094 12, /* plt_tlsdesc_got2_offset */
1095 10, /* plt_tlsdesc_got1_insn_end */
1096 16, /* plt_tlsdesc_got2_insn_end */
1097 2, /* plt0_got1_offset */
1098 1+8, /* plt0_got2_offset */
1099 1+12, /* plt0_got2_insn_end */
1100 4+1+2, /* plt_got_offset */
1101 4+1, /* plt_reloc_offset */
1102 4+1+6, /* plt_plt_offset */
1103 4+1+6, /* plt_got_insn_size */
1104 4+1+5+5, /* plt_plt_insn_end */
1105 0, /* plt_lazy_offset */
1106 elf_x86_64_lazy_bnd_plt0_entry, /* pic_plt0_entry */
1107 elf_x86_64_lazy_bnd_ibt_plt_entry, /* pic_plt_entry */
1108 elf_x86_64_eh_frame_lazy_bnd_ibt_plt, /* eh_frame_plt */
1109 sizeof (elf_x86_64_eh_frame_lazy_bnd_ibt_plt) /* eh_frame_plt_size */
1112 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_ibt_plt =
1114 elf_x86_64_lazy_plt0_entry, /* plt0_entry */
1115 LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */
1116 elf_x86_64_lazy_ibt_plt_entry, /* plt_entry */
1117 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1118 elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */
1119 LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */
1120 6, /* plt_tlsdesc_got1_offset */
1121 12, /* plt_tlsdesc_got2_offset */
1122 10, /* plt_tlsdesc_got1_insn_end */
1123 16, /* plt_tlsdesc_got2_insn_end */
1124 2, /* plt0_got1_offset */
1125 8, /* plt0_got2_offset */
1126 12, /* plt0_got2_insn_end */
1127 4+2, /* plt_got_offset */
1128 4+1, /* plt_reloc_offset */
1129 4+6, /* plt_plt_offset */
1130 4+6, /* plt_got_insn_size */
1131 4+5+5, /* plt_plt_insn_end */
1132 0, /* plt_lazy_offset */
1133 elf_x86_64_lazy_plt0_entry, /* pic_plt0_entry */
1134 elf_x86_64_lazy_ibt_plt_entry, /* pic_plt_entry */
1135 elf_x86_64_eh_frame_lazy_ibt_plt, /* eh_frame_plt */
1136 sizeof (elf_x86_64_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
1139 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_ibt_plt =
1141 elf_x86_64_non_lazy_bnd_ibt_plt_entry, /* plt_entry */
1142 elf_x86_64_non_lazy_bnd_ibt_plt_entry, /* pic_plt_entry */
1143 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1144 4+1+2, /* plt_got_offset */
1145 4+1+6, /* plt_got_insn_size */
1146 elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */
1147 sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
1150 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt =
1152 elf_x86_64_non_lazy_ibt_plt_entry, /* plt_entry */
1153 elf_x86_64_non_lazy_ibt_plt_entry, /* pic_plt_entry */
1154 LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
1155 4+2, /* plt_got_offset */
1156 4+6, /* plt_got_insn_size */
1157 elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */
1158 sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
1161 static bool
1162 elf64_x86_64_elf_object_p (bfd *abfd)
1164 /* Set the right machine number for an x86-64 elf64 file. */
1165 bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
1166 return true;
1169 static bool
1170 elf32_x86_64_elf_object_p (bfd *abfd)
1172 /* Set the right machine number for an x86-64 elf32 file. */
1173 bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x64_32);
1174 return true;
1177 /* Return TRUE if the TLS access code sequence support transition
1178 from R_TYPE. */
1180 static enum elf_x86_tls_error_type
1181 elf_x86_64_check_tls_transition (bfd *abfd,
1182 struct bfd_link_info *info,
1183 asection *sec,
1184 bfd_byte *contents,
1185 Elf_Internal_Shdr *symtab_hdr,
1186 struct elf_link_hash_entry **sym_hashes,
1187 unsigned int r_type,
1188 const Elf_Internal_Rela *rel,
1189 const Elf_Internal_Rela *relend)
1191 unsigned int val;
1192 unsigned long r_symndx;
1193 bool largepic = false;
1194 struct elf_link_hash_entry *h;
1195 bfd_vma offset;
1196 struct elf_x86_link_hash_table *htab;
1197 bfd_byte *call;
1198 bool indirect_call;
1200 htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
1201 offset = rel->r_offset;
1202 switch (r_type)
1204 case R_X86_64_TLSGD:
1205 case R_X86_64_TLSLD:
1206 if ((rel + 1) >= relend)
1207 return elf_x86_tls_error_yes;
1209 if (r_type == R_X86_64_TLSGD)
1211 /* Check transition from GD access model. For 64bit, only
1212 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
1213 .word 0x6666; rex64; call __tls_get_addr@PLT
1215 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
1216 .byte 0x66; rex64
1217 call *__tls_get_addr@GOTPCREL(%rip)
1218 which may be converted to
1219 addr32 call __tls_get_addr
1220 can transit to different access model. For 32bit, only
1221 leaq foo@tlsgd(%rip), %rdi
1222 .word 0x6666; rex64; call __tls_get_addr@PLT
1224 leaq foo@tlsgd(%rip), %rdi
1225 .byte 0x66; rex64
1226 call *__tls_get_addr@GOTPCREL(%rip)
1227 which may be converted to
1228 addr32 call __tls_get_addr
1229 can transit to different access model. For largepic,
1230 we also support:
1231 leaq foo@tlsgd(%rip), %rdi
1232 movabsq $__tls_get_addr@pltoff, %rax
1233 addq $r15, %rax
1234 call *%rax
1236 leaq foo@tlsgd(%rip), %rdi
1237 movabsq $__tls_get_addr@pltoff, %rax
1238 addq $rbx, %rax
1239 call *%rax */
1241 static const unsigned char leaq[] = { 0x66, 0x48, 0x8d, 0x3d };
1243 if ((offset + 12) > sec->size)
1244 return elf_x86_tls_error_yes;
1246 call = contents + offset + 4;
1247 if (call[0] != 0x66
1248 || !((call[1] == 0x48
1249 && call[2] == 0xff
1250 && call[3] == 0x15)
1251 || (call[1] == 0x48
1252 && call[2] == 0x67
1253 && call[3] == 0xe8)
1254 || (call[1] == 0x66
1255 && call[2] == 0x48
1256 && call[3] == 0xe8)))
1258 if (!ABI_64_P (abfd)
1259 || (offset + 19) > sec->size
1260 || offset < 3
1261 || memcmp (call - 7, leaq + 1, 3) != 0
1262 || memcmp (call, "\x48\xb8", 2) != 0
1263 || call[11] != 0x01
1264 || call[13] != 0xff
1265 || call[14] != 0xd0
1266 || !((call[10] == 0x48 && call[12] == 0xd8)
1267 || (call[10] == 0x4c && call[12] == 0xf8)))
1268 return elf_x86_tls_error_yes;
1269 largepic = true;
1271 else if (ABI_64_P (abfd))
1273 if (offset < 4
1274 || memcmp (contents + offset - 4, leaq, 4) != 0)
1275 return elf_x86_tls_error_yes;
1277 else
1279 if (offset < 3
1280 || memcmp (contents + offset - 3, leaq + 1, 3) != 0)
1281 return elf_x86_tls_error_yes;
1283 indirect_call = call[2] == 0xff;
1285 else
1287 /* Check transition from LD access model. Only
1288 leaq foo@tlsld(%rip), %rdi;
1289 call __tls_get_addr@PLT
1291 leaq foo@tlsld(%rip), %rdi;
1292 call *__tls_get_addr@GOTPCREL(%rip)
1293 which may be converted to
1294 addr32 call __tls_get_addr
1295 can transit to different access model. For largepic
1296 we also support:
1297 leaq foo@tlsld(%rip), %rdi
1298 movabsq $__tls_get_addr@pltoff, %rax
1299 addq $r15, %rax
1300 call *%rax
1302 leaq foo@tlsld(%rip), %rdi
1303 movabsq $__tls_get_addr@pltoff, %rax
1304 addq $rbx, %rax
1305 call *%rax */
1307 static const unsigned char lea[] = { 0x48, 0x8d, 0x3d };
1309 if (offset < 3 || (offset + 9) > sec->size)
1310 return elf_x86_tls_error_yes;
1312 if (memcmp (contents + offset - 3, lea, 3) != 0)
1313 return elf_x86_tls_error_yes;
1315 call = contents + offset + 4;
1316 if (!(call[0] == 0xe8
1317 || (call[0] == 0xff && call[1] == 0x15)
1318 || (call[0] == 0x67 && call[1] == 0xe8)))
1320 if (!ABI_64_P (abfd)
1321 || (offset + 19) > sec->size
1322 || memcmp (call, "\x48\xb8", 2) != 0
1323 || call[11] != 0x01
1324 || call[13] != 0xff
1325 || call[14] != 0xd0
1326 || !((call[10] == 0x48 && call[12] == 0xd8)
1327 || (call[10] == 0x4c && call[12] == 0xf8)))
1328 return elf_x86_tls_error_yes;
1329 largepic = true;
1331 indirect_call = call[0] == 0xff;
1334 r_symndx = htab->r_sym (rel[1].r_info);
1335 if (r_symndx < symtab_hdr->sh_info)
1336 return elf_x86_tls_error_yes;
1338 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1339 if (h == NULL
1340 || !((struct elf_x86_link_hash_entry *) h)->tls_get_addr)
1341 return elf_x86_tls_error_yes;
1342 else
1344 r_type = (ELF32_R_TYPE (rel[1].r_info)
1345 & ~R_X86_64_converted_reloc_bit);
1346 if (largepic)
1347 return (r_type == R_X86_64_PLTOFF64
1348 ? elf_x86_tls_error_none
1349 : elf_x86_tls_error_yes);
1350 else if (indirect_call)
1351 return ((r_type == R_X86_64_GOTPCRELX
1352 || r_type == R_X86_64_GOTPCREL)
1353 ? elf_x86_tls_error_none
1354 : elf_x86_tls_error_yes);
1355 else
1356 return ((r_type == R_X86_64_PC32
1357 || r_type == R_X86_64_PLT32)
1358 ? elf_x86_tls_error_none
1359 : elf_x86_tls_error_yes);
1362 case R_X86_64_CODE_4_GOTTPOFF:
1363 /* Check transition from IE access model:
1364 mov foo@gottpoff(%rip), %reg
1365 add foo@gottpoff(%rip), %reg
1366 where reg is one of r16 to r31. */
1368 if (offset < 4
1369 || (offset + 4) > sec->size
1370 || contents[offset - 4] != 0xd5)
1371 return elf_x86_tls_error_yes;
1373 goto check_gottpoff;
1375 case R_X86_64_CODE_6_GOTTPOFF:
1376 /* Check transition from IE access model:
1377 add %reg1, foo@gottpoff(%rip), %reg2
1378 where reg1/reg2 are one of r16 to r31. */
1380 if (offset < 6
1381 || (offset + 4) > sec->size
1382 || contents[offset - 6] != 0x62)
1383 return elf_x86_tls_error_yes;
1385 val = bfd_get_8 (abfd, contents + offset - 2);
1386 if (val != 0x01 && val != 0x03)
1387 return elf_x86_tls_error_add;
1389 val = bfd_get_8 (abfd, contents + offset - 1);
1390 return ((val & 0xc7) == 5
1391 ? elf_x86_tls_error_none
1392 : elf_x86_tls_error_yes);
1394 case R_X86_64_GOTTPOFF:
1395 /* Check transition from IE access model:
1396 mov foo@gottpoff(%rip), %reg
1397 add foo@gottpoff(%rip), %reg
1400 /* Check REX prefix first. */
1401 if (offset >= 3 && (offset + 4) <= sec->size)
1403 val = bfd_get_8 (abfd, contents + offset - 3);
1404 if (val != 0x48 && val != 0x4c)
1406 /* X32 may have 0x44 REX prefix or no REX prefix. */
1407 if (ABI_64_P (abfd))
1408 return elf_x86_tls_error_yes;
1411 else
1413 /* X32 may not have any REX prefix. */
1414 if (ABI_64_P (abfd))
1415 return elf_x86_tls_error_yes;
1416 if (offset < 2 || (offset + 3) > sec->size)
1417 return elf_x86_tls_error_yes;
1420 check_gottpoff:
1421 val = bfd_get_8 (abfd, contents + offset - 2);
1422 if (val != 0x8b && val != 0x03)
1423 return elf_x86_tls_error_add_mov;
1425 val = bfd_get_8 (abfd, contents + offset - 1);
1426 return ((val & 0xc7) == 5
1427 ? elf_x86_tls_error_none
1428 : elf_x86_tls_error_yes);
1430 case R_X86_64_CODE_4_GOTPC32_TLSDESC:
1431 /* Check transition from GDesc access model:
1432 lea x@tlsdesc(%rip), %reg
1433 where reg is one of r16 to r31. */
1435 if (offset < 4
1436 || (offset + 4) > sec->size
1437 || contents[offset - 4] != 0xd5)
1438 return elf_x86_tls_error_yes;
1440 goto check_tlsdesc;
1442 case R_X86_64_GOTPC32_TLSDESC:
1443 /* Check transition from GDesc access model:
1444 leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
1445 rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
1447 Make sure it's a leaq adding rip to a 32-bit offset
1448 into any register, although it's probably almost always
1449 going to be rax. */
1451 if (offset < 3 || (offset + 4) > sec->size)
1452 return elf_x86_tls_error_yes;
1454 val = bfd_get_8 (abfd, contents + offset - 3);
1455 val &= 0xfb;
1456 if (val != 0x48 && (ABI_64_P (abfd) || val != 0x40))
1457 return elf_x86_tls_error_yes;
1459 check_tlsdesc:
1460 if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
1461 return elf_x86_tls_error_lea;
1463 val = bfd_get_8 (abfd, contents + offset - 1);
1464 return ((val & 0xc7) == 0x05
1465 ? elf_x86_tls_error_none
1466 : elf_x86_tls_error_yes);
1468 case R_X86_64_TLSDESC_CALL:
1469 /* It has been checked in elf_x86_64_tls_transition. */
1470 return elf_x86_tls_error_none;
1472 default:
1473 abort ();
1477 /* Return TRUE if the TLS access transition is OK or no transition
1478 will be performed. Update R_TYPE if there is a transition. */
1480 static bool
1481 elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
1482 asection *sec, bfd_byte *contents,
1483 Elf_Internal_Shdr *symtab_hdr,
1484 struct elf_link_hash_entry **sym_hashes,
1485 unsigned int *r_type, int tls_type,
1486 const Elf_Internal_Rela *rel,
1487 const Elf_Internal_Rela *relend,
1488 struct elf_link_hash_entry *h,
1489 Elf_Internal_Sym *sym,
1490 bool from_relocate_section)
1492 unsigned int from_type = *r_type;
1493 unsigned int to_type = from_type;
1494 bool check = true;
1495 bfd_vma offset;
1496 bfd_byte *call;
1498 /* Skip TLS transition for functions. */
1499 if (h != NULL
1500 && (h->type == STT_FUNC
1501 || h->type == STT_GNU_IFUNC))
1502 return true;
1504 switch (from_type)
1506 case R_X86_64_TLSDESC_CALL:
1507 /* Check valid GDesc call:
1508 call *x@tlscall(%rax) <--- LP64 mode.
1509 call *x@tlscall(%eax) <--- X32 mode.
1511 offset = rel->r_offset;
1512 call = NULL;
1513 if (offset + 2 <= sec->size)
1515 unsigned int prefix;
1516 call = contents + offset;
1517 prefix = 0;
1518 if (!ABI_64_P (abfd))
1520 /* Check for call *x@tlscall(%eax). */
1521 if (call[0] == 0x67)
1523 prefix = 1;
1524 if (offset + 3 > sec->size)
1525 call = NULL;
1529 /* Make sure that it's a call *x@tlscall(%rax). */
1530 if (call != NULL
1531 && (call[prefix] != 0xff || call[1 + prefix] != 0x10))
1532 call = NULL;
1535 if (call == NULL)
1537 _bfd_x86_elf_link_report_tls_transition_error
1538 (info, abfd, sec, symtab_hdr, h, sym, rel,
1539 "R_X86_64_TLSDESC_CALL", NULL,
1540 elf_x86_tls_error_indirect_call);
1541 return false;
1544 /* Fall through. */
1546 case R_X86_64_TLSGD:
1547 case R_X86_64_GOTPC32_TLSDESC:
1548 case R_X86_64_CODE_4_GOTPC32_TLSDESC:
1549 case R_X86_64_GOTTPOFF:
1550 case R_X86_64_CODE_4_GOTTPOFF:
1551 case R_X86_64_CODE_6_GOTTPOFF:
1552 if (bfd_link_executable (info))
1554 if (h == NULL)
1555 to_type = R_X86_64_TPOFF32;
1556 else
1557 to_type = R_X86_64_GOTTPOFF;
1560 /* When we are called from elf_x86_64_relocate_section, there may
1561 be additional transitions based on TLS_TYPE. */
1562 if (from_relocate_section)
1564 unsigned int new_to_type = to_type;
1566 if (TLS_TRANSITION_IE_TO_LE_P (info, h, tls_type))
1567 new_to_type = R_X86_64_TPOFF32;
1569 if (to_type == R_X86_64_TLSGD
1570 || to_type == R_X86_64_GOTPC32_TLSDESC
1571 || to_type == R_X86_64_CODE_4_GOTPC32_TLSDESC
1572 || to_type == R_X86_64_TLSDESC_CALL)
1574 if (tls_type == GOT_TLS_IE)
1575 new_to_type = R_X86_64_GOTTPOFF;
1578 /* We checked the transition before when we were called from
1579 elf_x86_64_scan_relocs. We only want to check the new
1580 transition which hasn't been checked before. */
1581 check = (new_to_type != to_type
1582 && (from_type == to_type
1583 || (from_type == R_X86_64_CODE_4_GOTTPOFF
1584 && to_type == R_X86_64_GOTTPOFF)
1585 || (from_type == R_X86_64_CODE_6_GOTTPOFF
1586 && to_type == R_X86_64_GOTTPOFF)));
1587 to_type = new_to_type;
1590 break;
1592 case R_X86_64_TLSLD:
1593 if (bfd_link_executable (info))
1594 to_type = R_X86_64_TPOFF32;
1595 break;
1597 default:
1598 return true;
1601 /* Return TRUE if there is no transition. */
1602 if (from_type == to_type
1603 || (from_type == R_X86_64_CODE_4_GOTTPOFF
1604 && to_type == R_X86_64_GOTTPOFF)
1605 || (from_type == R_X86_64_CODE_6_GOTTPOFF
1606 && to_type == R_X86_64_GOTTPOFF))
1607 return true;
1609 /* Check if the transition can be performed. */
1610 enum elf_x86_tls_error_type tls_error;
1611 if (check
1612 && ((tls_error = elf_x86_64_check_tls_transition (abfd, info, sec,
1613 contents,
1614 symtab_hdr,
1615 sym_hashes,
1616 from_type, rel,
1617 relend))
1618 != elf_x86_tls_error_none))
1621 reloc_howto_type *from, *to;
1623 from = elf_x86_64_rtype_to_howto (abfd, from_type);
1624 to = elf_x86_64_rtype_to_howto (abfd, to_type);
1626 if (from == NULL || to == NULL)
1627 return false;
1629 _bfd_x86_elf_link_report_tls_transition_error
1630 (info, abfd, sec, symtab_hdr, h, sym, rel, from->name,
1631 to->name, tls_error);
1633 return false;
1636 *r_type = to_type;
1637 return true;
1640 static bool
1641 elf_x86_64_need_pic (struct bfd_link_info *info,
1642 bfd *input_bfd, asection *sec,
1643 struct elf_link_hash_entry *h,
1644 Elf_Internal_Shdr *symtab_hdr,
1645 Elf_Internal_Sym *isym,
1646 reloc_howto_type *howto)
1648 const char *v = "";
1649 const char *und = "";
1650 const char *pic = "";
1651 const char *object;
1653 const char *name;
1654 if (h)
1656 name = h->root.root.string;
1657 switch (ELF_ST_VISIBILITY (h->other))
1659 case STV_HIDDEN:
1660 v = _("hidden symbol ");
1661 break;
1662 case STV_INTERNAL:
1663 v = _("internal symbol ");
1664 break;
1665 case STV_PROTECTED:
1666 v = _("protected symbol ");
1667 break;
1668 default:
1669 if (((struct elf_x86_link_hash_entry *) h)->def_protected)
1670 v = _("protected symbol ");
1671 else
1672 v = _("symbol ");
1673 pic = NULL;
1674 break;
1677 if (!SYMBOL_DEFINED_NON_SHARED_P (h) && !h->def_dynamic)
1678 und = _("undefined ");
1680 else
1682 name = bfd_elf_sym_name (input_bfd, symtab_hdr, isym, NULL);
1683 pic = NULL;
1686 if (bfd_link_dll (info))
1688 object = _("a shared object");
1689 if (!pic)
1690 pic = _("; recompile with -fPIC");
1692 else
1694 if (bfd_link_pie (info))
1695 object = _("a PIE object");
1696 else
1697 object = _("a PDE object");
1698 if (!pic)
1699 pic = _("; recompile with -fPIE");
1702 /* xgettext:c-format */
1703 _bfd_error_handler (_("%pB: relocation %s against %s%s`%s' can "
1704 "not be used when making %s%s"),
1705 input_bfd, howto->name, und, v, name,
1706 object, pic);
1707 bfd_set_error (bfd_error_bad_value);
1708 sec->check_relocs_failed = 1;
1709 return false;
1712 /* With the local symbol, foo, we convert
1713 mov foo@GOTPCREL(%rip), %reg
1715 lea foo(%rip), %reg
1716 and convert
1717 call/jmp *foo@GOTPCREL(%rip)
1719 nop call foo/jmp foo nop
1720 When PIC is false, convert
1721 test %reg, foo@GOTPCREL(%rip)
1723 test $foo, %reg
1724 and convert
1725 binop foo@GOTPCREL(%rip), %reg
1727 binop $foo, %reg
1728 where binop is one of adc, add, and, cmp, or, sbb, sub, xor
1729 instructions. */
1731 static bool
1732 elf_x86_64_convert_load_reloc (bfd *abfd,
1733 bfd_byte *contents,
1734 unsigned int *r_type_p,
1735 Elf_Internal_Rela *irel,
1736 struct elf_link_hash_entry *h,
1737 bool *converted,
1738 struct bfd_link_info *link_info)
1740 struct elf_x86_link_hash_table *htab;
1741 bool is_pic;
1742 bool no_overflow;
1743 bool relocx;
1744 bool to_reloc_pc32;
1745 bool abs_symbol;
1746 bool local_ref;
1747 asection *tsec;
1748 bfd_signed_vma raddend;
1749 unsigned int opcode;
1750 unsigned int modrm;
1751 unsigned int r_type = *r_type_p;
1752 unsigned int r_symndx;
1753 bfd_vma roff = irel->r_offset;
1754 bfd_vma abs_relocation;
1756 if (roff < (r_type == R_X86_64_CODE_4_GOTPCRELX
1757 ? 4 : (r_type == R_X86_64_REX_GOTPCRELX ? 3 : 2)))
1758 return true;
1760 raddend = irel->r_addend;
1761 /* Addend for 32-bit PC-relative relocation must be -4. */
1762 if (raddend != -4)
1763 return true;
1765 htab = elf_x86_hash_table (link_info, X86_64_ELF_DATA);
1766 is_pic = bfd_link_pic (link_info);
1768 if (r_type == R_X86_64_CODE_4_GOTPCRELX)
1770 /* Skip if this isn't a REX2 instruction. */
1771 opcode = bfd_get_8 (abfd, contents + roff - 4);
1772 if (opcode != 0xd5)
1773 return true;
1775 relocx = true;
1777 else
1778 relocx = (r_type == R_X86_64_GOTPCRELX
1779 || r_type == R_X86_64_REX_GOTPCRELX);
1781 /* TRUE if --no-relax is used. */
1782 no_overflow = link_info->disable_target_specific_optimizations > 1;
1784 r_symndx = htab->r_sym (irel->r_info);
1786 opcode = bfd_get_8 (abfd, contents + roff - 2);
1788 /* Convert mov to lea since it has been done for a while. */
1789 if (opcode != 0x8b)
1791 /* Only convert R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX
1792 and R_X86_64_CODE_4_GOTPCRELX for call, jmp or one of adc,
1793 add, and, cmp, or, sbb, sub, test, xor instructions. */
1794 if (!relocx)
1795 return true;
1798 /* We convert only to R_X86_64_PC32:
1799 1. Branch.
1800 2. R_X86_64_GOTPCREL since we can't modify REX byte.
1801 3. no_overflow is true.
1802 4. PIC.
1804 to_reloc_pc32 = (opcode == 0xff
1805 || !relocx
1806 || no_overflow
1807 || is_pic);
1809 abs_symbol = false;
1810 abs_relocation = 0;
1812 /* Get the symbol referred to by the reloc. */
1813 if (h == NULL)
1815 Elf_Internal_Sym *isym
1816 = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
1818 /* Skip relocation against undefined symbols. */
1819 if (isym->st_shndx == SHN_UNDEF)
1820 return true;
1822 local_ref = true;
1823 if (isym->st_shndx == SHN_ABS)
1825 tsec = bfd_abs_section_ptr;
1826 abs_symbol = true;
1827 abs_relocation = isym->st_value;
1829 else if (isym->st_shndx == SHN_COMMON)
1830 tsec = bfd_com_section_ptr;
1831 else if (isym->st_shndx == SHN_X86_64_LCOMMON)
1832 tsec = &_bfd_elf_large_com_section;
1833 else
1834 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1836 else
1838 /* Undefined weak symbol is only bound locally in executable
1839 and its reference is resolved as 0 without relocation
1840 overflow. We can only perform this optimization for
1841 GOTPCRELX relocations since we need to modify REX byte.
1842 It is OK convert mov with R_X86_64_GOTPCREL to
1843 R_X86_64_PC32. */
1844 struct elf_x86_link_hash_entry *eh = elf_x86_hash_entry (h);
1846 abs_symbol = ABS_SYMBOL_P (h);
1847 abs_relocation = h->root.u.def.value;
1849 /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P. */
1850 local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h);
1851 if ((relocx || opcode == 0x8b)
1852 && (h->root.type == bfd_link_hash_undefweak
1853 && !eh->linker_def
1854 && local_ref))
1856 if (opcode == 0xff)
1858 /* Skip for branch instructions since R_X86_64_PC32
1859 may overflow. */
1860 if (no_overflow)
1861 return true;
1863 else if (relocx)
1865 /* For non-branch instructions, we can convert to
1866 R_X86_64_32/R_X86_64_32S since we know if there
1867 is a REX byte. */
1868 to_reloc_pc32 = false;
1871 /* Since we don't know the current PC when PIC is true,
1872 we can't convert to R_X86_64_PC32. */
1873 if (to_reloc_pc32 && is_pic)
1874 return true;
1876 goto convert;
1878 /* Avoid optimizing GOTPCREL relocations againt _DYNAMIC since
1879 ld.so may use its link-time address. */
1880 else if (h->start_stop
1881 || eh->linker_def
1882 || ((h->def_regular
1883 || h->root.type == bfd_link_hash_defined
1884 || h->root.type == bfd_link_hash_defweak)
1885 && h != htab->elf.hdynamic
1886 && local_ref))
1888 /* bfd_link_hash_new or bfd_link_hash_undefined is
1889 set by an assignment in a linker script in
1890 bfd_elf_record_link_assignment. start_stop is set
1891 on __start_SECNAME/__stop_SECNAME which mark section
1892 SECNAME. */
1893 if (h->start_stop
1894 || eh->linker_def
1895 || (h->def_regular
1896 && (h->root.type == bfd_link_hash_new
1897 || h->root.type == bfd_link_hash_undefined
1898 || ((h->root.type == bfd_link_hash_defined
1899 || h->root.type == bfd_link_hash_defweak)
1900 && h->root.u.def.section == bfd_und_section_ptr))))
1902 /* Skip since R_X86_64_32/R_X86_64_32S may overflow. */
1903 if (no_overflow)
1904 return true;
1905 goto convert;
1907 tsec = h->root.u.def.section;
1909 else
1910 return true;
1913 /* Don't convert GOTPCREL relocation against large section. */
1914 if (elf_section_data (tsec) != NULL
1915 && (elf_section_flags (tsec) & SHF_X86_64_LARGE) != 0)
1916 return true;
1918 /* Skip since R_X86_64_PC32/R_X86_64_32/R_X86_64_32S may overflow. */
1919 if (no_overflow)
1920 return true;
1922 convert:
1923 if (opcode == 0xff)
1925 /* We have "call/jmp *foo@GOTPCREL(%rip)". */
1926 unsigned int nop;
1927 unsigned int disp;
1928 bfd_vma nop_offset;
1930 /* Convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX to
1931 R_X86_64_PC32. */
1932 modrm = bfd_get_8 (abfd, contents + roff - 1);
1933 if (modrm == 0x25)
1935 /* Convert to "jmp foo nop". */
1936 modrm = 0xe9;
1937 nop = NOP_OPCODE;
1938 nop_offset = irel->r_offset + 3;
1939 disp = bfd_get_32 (abfd, contents + irel->r_offset);
1940 irel->r_offset -= 1;
1941 bfd_put_32 (abfd, disp, contents + irel->r_offset);
1943 else
1945 struct elf_x86_link_hash_entry *eh
1946 = (struct elf_x86_link_hash_entry *) h;
1948 /* Convert to "nop call foo". ADDR_PREFIX_OPCODE
1949 is a nop prefix. */
1950 modrm = 0xe8;
1951 /* To support TLS optimization, always use addr32 prefix for
1952 "call *__tls_get_addr@GOTPCREL(%rip)". */
1953 if (eh && eh->tls_get_addr)
1955 nop = 0x67;
1956 nop_offset = irel->r_offset - 2;
1958 else
1960 nop = htab->params->call_nop_byte;
1961 if (htab->params->call_nop_as_suffix)
1963 nop_offset = irel->r_offset + 3;
1964 disp = bfd_get_32 (abfd, contents + irel->r_offset);
1965 irel->r_offset -= 1;
1966 bfd_put_32 (abfd, disp, contents + irel->r_offset);
1968 else
1969 nop_offset = irel->r_offset - 2;
1972 bfd_put_8 (abfd, nop, contents + nop_offset);
1973 bfd_put_8 (abfd, modrm, contents + irel->r_offset - 1);
1974 r_type = R_X86_64_PC32;
1976 else
1978 unsigned int rex = 0;
1979 unsigned int rex_mask = REX_R;
1980 unsigned int rex2 = 0;
1981 unsigned int rex2_mask = REX_R | REX_R << 4;
1982 bool rex_w = false;
1984 if (r_type == R_X86_64_CODE_4_GOTPCRELX)
1986 rex2 = bfd_get_8 (abfd, contents + roff - 3);
1987 rex_w = (rex2 & REX_W) != 0;
1989 else if (r_type == R_X86_64_REX_GOTPCRELX)
1991 rex = bfd_get_8 (abfd, contents + roff - 3);
1992 rex_w = (rex & REX_W) != 0;
1995 if (opcode == 0x8b)
1997 if (abs_symbol && local_ref && relocx)
1998 to_reloc_pc32 = false;
2000 if (to_reloc_pc32)
2002 /* Convert "mov foo@GOTPCREL(%rip), %reg" to
2003 "lea foo(%rip), %reg". */
2004 opcode = 0x8d;
2005 r_type = R_X86_64_PC32;
2007 else
2009 /* Convert "mov foo@GOTPCREL(%rip), %reg" to
2010 "mov $foo, %reg". */
2011 opcode = 0xc7;
2012 modrm = bfd_get_8 (abfd, contents + roff - 1);
2013 modrm = 0xc0 | (modrm & 0x38) >> 3;
2014 if (rex_w && ABI_64_P (link_info->output_bfd))
2016 /* Keep the REX_W bit in REX byte for LP64. */
2017 r_type = R_X86_64_32S;
2018 goto rewrite_modrm_rex;
2020 else
2022 /* If the REX_W bit in REX byte isn't needed,
2023 use R_X86_64_32 and clear the W bit to avoid
2024 sign-extend imm32 to imm64. */
2025 r_type = R_X86_64_32;
2026 /* Clear the W bit in REX byte and REX2 payload. */
2027 rex_mask |= REX_W;
2028 rex2_mask |= REX_W;
2029 goto rewrite_modrm_rex;
2033 else
2035 /* R_X86_64_PC32 isn't supported. */
2036 if (to_reloc_pc32)
2037 return true;
2039 modrm = bfd_get_8 (abfd, contents + roff - 1);
2040 if (opcode == 0x85)
2042 /* Convert "test %reg, foo@GOTPCREL(%rip)" to
2043 "test $foo, %reg". */
2044 modrm = 0xc0 | (modrm & 0x38) >> 3;
2045 opcode = 0xf7;
2047 else
2049 /* Convert "binop foo@GOTPCREL(%rip), %reg" to
2050 "binop $foo, %reg". */
2051 modrm = 0xc0 | (modrm & 0x38) >> 3 | (opcode & 0x3c);
2052 opcode = 0x81;
2055 /* Use R_X86_64_32 with 32-bit operand to avoid relocation
2056 overflow when sign-extending imm32 to imm64. */
2057 r_type = rex_w ? R_X86_64_32S : R_X86_64_32;
2059 rewrite_modrm_rex:
2060 if (abs_relocation)
2062 /* Check if R_X86_64_32S/R_X86_64_32 fits. */
2063 if (r_type == R_X86_64_32S)
2065 if ((abs_relocation + 0x80000000) > 0xffffffff)
2066 return true;
2068 else
2070 if (abs_relocation > 0xffffffff)
2071 return true;
2075 bfd_put_8 (abfd, modrm, contents + roff - 1);
2077 if (rex)
2079 /* Move the R bit to the B bit in REX byte. */
2080 rex = (rex & ~rex_mask) | (rex & REX_R) >> 2;
2081 bfd_put_8 (abfd, rex, contents + roff - 3);
2083 else if (rex2)
2085 /* Move the R bits to the B bits in REX2 payload byte. */
2086 rex2 = ((rex2 & ~rex2_mask)
2087 | (rex2 & (REX_R | REX_R << 4)) >> 2);
2088 bfd_put_8 (abfd, rex2, contents + roff - 3);
2091 /* No addend for R_X86_64_32/R_X86_64_32S relocations. */
2092 irel->r_addend = 0;
2095 bfd_put_8 (abfd, opcode, contents + roff - 2);
2098 *r_type_p = r_type;
2099 irel->r_info = htab->r_info (r_symndx,
2100 r_type | R_X86_64_converted_reloc_bit);
2102 *converted = true;
2104 return true;
2107 /* Look through the relocs for a section during the first phase, and
2108 calculate needed space in the global offset table, and procedure
2109 linkage table. */
2111 static bool
2112 elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
2113 asection *sec,
2114 const Elf_Internal_Rela *relocs)
2116 struct elf_x86_link_hash_table *htab;
2117 Elf_Internal_Shdr *symtab_hdr;
2118 struct elf_link_hash_entry **sym_hashes;
2119 const Elf_Internal_Rela *rel;
2120 const Elf_Internal_Rela *rel_end;
2121 bfd_byte *contents;
2122 bool converted;
2124 if (bfd_link_relocatable (info))
2125 return true;
2127 htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
2128 if (htab == NULL)
2130 sec->check_relocs_failed = 1;
2131 return false;
2134 BFD_ASSERT (is_x86_elf (abfd, htab));
2136 /* Get the section contents. */
2137 if (elf_section_data (sec)->this_hdr.contents != NULL)
2138 contents = elf_section_data (sec)->this_hdr.contents;
2139 else if (!_bfd_elf_mmap_section_contents (abfd, sec, &contents))
2141 sec->check_relocs_failed = 1;
2142 return false;
2145 symtab_hdr = &elf_symtab_hdr (abfd);
2146 sym_hashes = elf_sym_hashes (abfd);
2148 converted = false;
2150 rel_end = relocs + sec->reloc_count;
2151 for (rel = relocs; rel < rel_end; rel++)
2153 unsigned int r_type;
2154 unsigned int r_symndx;
2155 struct elf_link_hash_entry *h;
2156 struct elf_x86_link_hash_entry *eh;
2157 Elf_Internal_Sym *isym;
2158 const char *name;
2159 bool size_reloc;
2160 bool converted_reloc;
2161 bool no_dynreloc;
2163 r_symndx = htab->r_sym (rel->r_info);
2164 r_type = ELF32_R_TYPE (rel->r_info);
2166 /* Don't check R_X86_64_NONE. */
2167 if (r_type == R_X86_64_NONE)
2168 continue;
2170 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
2172 /* xgettext:c-format */
2173 _bfd_error_handler (_("%pB: bad symbol index: %d"),
2174 abfd, r_symndx);
2175 goto error_return;
2178 if (r_symndx < symtab_hdr->sh_info)
2180 /* A local symbol. */
2181 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
2182 abfd, r_symndx);
2183 if (isym == NULL)
2184 goto error_return;
2186 /* Check relocation against local STT_GNU_IFUNC symbol. */
2187 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
2189 h = _bfd_elf_x86_get_local_sym_hash (htab, abfd, rel,
2190 true);
2191 if (h == NULL)
2192 goto error_return;
2194 /* Fake a STT_GNU_IFUNC symbol. */
2195 h->root.root.string = bfd_elf_sym_name (abfd, symtab_hdr,
2196 isym, NULL);
2197 h->type = STT_GNU_IFUNC;
2198 h->def_regular = 1;
2199 h->ref_regular = 1;
2200 h->forced_local = 1;
2201 h->root.type = bfd_link_hash_defined;
2203 else
2204 h = NULL;
2206 else
2208 isym = NULL;
2209 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2210 while (h->root.type == bfd_link_hash_indirect
2211 || h->root.type == bfd_link_hash_warning)
2212 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2215 /* Check invalid x32 relocations. */
2216 if (!ABI_64_P (abfd))
2217 switch (r_type)
2219 default:
2220 break;
2222 case R_X86_64_DTPOFF64:
2223 case R_X86_64_TPOFF64:
2224 case R_X86_64_PC64:
2225 case R_X86_64_GOTOFF64:
2226 case R_X86_64_GOT64:
2227 case R_X86_64_GOTPCREL64:
2228 case R_X86_64_GOTPC64:
2229 case R_X86_64_GOTPLT64:
2230 case R_X86_64_PLTOFF64:
2232 if (h)
2233 name = h->root.root.string;
2234 else
2235 name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
2236 NULL);
2237 _bfd_error_handler
2238 /* xgettext:c-format */
2239 (_("%pB: relocation %s against symbol `%s' isn't "
2240 "supported in x32 mode"), abfd,
2241 x86_64_elf_howto_table[r_type].name, name);
2242 bfd_set_error (bfd_error_bad_value);
2243 goto error_return;
2245 break;
2248 eh = (struct elf_x86_link_hash_entry *) h;
2250 if (h != NULL)
2252 /* It is referenced by a non-shared object. */
2253 h->ref_regular = 1;
2256 converted_reloc = false;
2257 if ((r_type == R_X86_64_GOTPCREL
2258 || r_type == R_X86_64_GOTPCRELX
2259 || r_type == R_X86_64_REX_GOTPCRELX
2260 || r_type == R_X86_64_CODE_4_GOTPCRELX)
2261 && (h == NULL || h->type != STT_GNU_IFUNC))
2263 Elf_Internal_Rela *irel = (Elf_Internal_Rela *) rel;
2264 if (!elf_x86_64_convert_load_reloc (abfd, contents, &r_type,
2265 irel, h, &converted_reloc,
2266 info))
2267 goto error_return;
2269 if (converted_reloc)
2270 converted = true;
2273 if (!_bfd_elf_x86_valid_reloc_p (sec, info, htab, rel, h, isym,
2274 symtab_hdr, &no_dynreloc))
2275 return false;
2277 if (! elf_x86_64_tls_transition (info, abfd, sec, contents,
2278 symtab_hdr, sym_hashes,
2279 &r_type, GOT_UNKNOWN,
2280 rel, rel_end, h, isym, false))
2281 goto error_return;
2283 /* Check if _GLOBAL_OFFSET_TABLE_ is referenced. */
2284 if (h == htab->elf.hgot)
2285 htab->got_referenced = true;
2287 switch (r_type)
2289 case R_X86_64_TLSLD:
2290 htab->tls_ld_or_ldm_got.refcount = 1;
2291 goto create_got;
2293 case R_X86_64_TPOFF32:
2294 if (!bfd_link_executable (info) && ABI_64_P (abfd))
2295 return elf_x86_64_need_pic (info, abfd, sec, h, symtab_hdr, isym,
2296 &x86_64_elf_howto_table[r_type]);
2297 if (eh != NULL)
2298 eh->zero_undefweak &= 0x2;
2299 break;
2301 case R_X86_64_GOTTPOFF:
2302 case R_X86_64_CODE_4_GOTTPOFF:
2303 case R_X86_64_CODE_6_GOTTPOFF:
2304 if (!bfd_link_executable (info))
2305 info->flags |= DF_STATIC_TLS;
2306 /* Fall through */
2308 case R_X86_64_GOT32:
2309 case R_X86_64_GOTPCREL:
2310 case R_X86_64_GOTPCRELX:
2311 case R_X86_64_REX_GOTPCRELX:
2312 case R_X86_64_CODE_4_GOTPCRELX:
2313 case R_X86_64_TLSGD:
2314 case R_X86_64_GOT64:
2315 case R_X86_64_GOTPCREL64:
2316 case R_X86_64_GOTPLT64:
2317 case R_X86_64_GOTPC32_TLSDESC:
2318 case R_X86_64_CODE_4_GOTPC32_TLSDESC:
2319 case R_X86_64_TLSDESC_CALL:
2320 /* This symbol requires a global offset table entry. */
2322 int tls_type, old_tls_type;
2324 switch (r_type)
2326 default:
2327 tls_type = GOT_NORMAL;
2328 if (h)
2330 if (ABS_SYMBOL_P (h))
2331 tls_type = GOT_ABS;
2333 else if (isym->st_shndx == SHN_ABS)
2334 tls_type = GOT_ABS;
2335 break;
2336 case R_X86_64_TLSGD:
2337 tls_type = GOT_TLS_GD;
2338 break;
2339 case R_X86_64_GOTTPOFF:
2340 case R_X86_64_CODE_4_GOTTPOFF:
2341 case R_X86_64_CODE_6_GOTTPOFF:
2342 tls_type = GOT_TLS_IE;
2343 break;
2344 case R_X86_64_GOTPC32_TLSDESC:
2345 case R_X86_64_CODE_4_GOTPC32_TLSDESC:
2346 case R_X86_64_TLSDESC_CALL:
2347 tls_type = GOT_TLS_GDESC;
2348 break;
2351 if (h != NULL)
2353 h->got.refcount = 1;
2354 old_tls_type = eh->tls_type;
2356 else
2358 bfd_signed_vma *local_got_refcounts;
2360 if (!elf_x86_allocate_local_got_info (abfd,
2361 symtab_hdr->sh_info))
2362 goto error_return;
2364 /* This is a global offset table entry for a local symbol. */
2365 local_got_refcounts = elf_local_got_refcounts (abfd);
2366 local_got_refcounts[r_symndx] = 1;
2367 old_tls_type
2368 = elf_x86_local_got_tls_type (abfd) [r_symndx];
2371 /* If a TLS symbol is accessed using IE at least once,
2372 there is no point to use dynamic model for it. */
2373 if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
2374 && (! GOT_TLS_GD_ANY_P (old_tls_type)
2375 || tls_type != GOT_TLS_IE))
2377 if (old_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (tls_type))
2378 tls_type = old_tls_type;
2379 else if (GOT_TLS_GD_ANY_P (old_tls_type)
2380 && GOT_TLS_GD_ANY_P (tls_type))
2381 tls_type |= old_tls_type;
2382 else
2384 if (h)
2385 name = h->root.root.string;
2386 else
2387 name = bfd_elf_sym_name (abfd, symtab_hdr,
2388 isym, NULL);
2389 _bfd_error_handler
2390 /* xgettext:c-format */
2391 (_("%pB: '%s' accessed both as normal and"
2392 " thread local symbol"),
2393 abfd, name);
2394 bfd_set_error (bfd_error_bad_value);
2395 goto error_return;
2399 if (old_tls_type != tls_type)
2401 if (eh != NULL)
2402 eh->tls_type = tls_type;
2403 else
2404 elf_x86_local_got_tls_type (abfd) [r_symndx] = tls_type;
2407 /* Fall through */
2409 case R_X86_64_GOTOFF64:
2410 case R_X86_64_GOTPC32:
2411 case R_X86_64_GOTPC64:
2412 create_got:
2413 if (eh != NULL)
2414 eh->zero_undefweak &= 0x2;
2415 break;
2417 case R_X86_64_PLT32:
2418 /* This symbol requires a procedure linkage table entry. We
2419 actually build the entry in adjust_dynamic_symbol,
2420 because this might be a case of linking PIC code which is
2421 never referenced by a dynamic object, in which case we
2422 don't need to generate a procedure linkage table entry
2423 after all. */
2425 /* If this is a local symbol, we resolve it directly without
2426 creating a procedure linkage table entry. */
2427 if (h == NULL)
2428 continue;
2430 eh->zero_undefweak &= 0x2;
2431 h->needs_plt = 1;
2432 h->plt.refcount = 1;
2433 break;
2435 case R_X86_64_PLTOFF64:
2436 /* This tries to form the 'address' of a function relative
2437 to GOT. For global symbols we need a PLT entry. */
2438 if (h != NULL)
2440 h->needs_plt = 1;
2441 h->plt.refcount = 1;
2443 goto create_got;
2445 case R_X86_64_SIZE32:
2446 case R_X86_64_SIZE64:
2447 size_reloc = true;
2448 goto do_size;
2450 case R_X86_64_32:
2451 if (!ABI_64_P (abfd))
2452 goto pointer;
2453 /* Fall through. */
2454 case R_X86_64_8:
2455 case R_X86_64_16:
2456 case R_X86_64_32S:
2457 /* Check relocation overflow as these relocs may lead to
2458 run-time relocation overflow. Don't error out for
2459 sections we don't care about, such as debug sections or
2460 when relocation overflow check is disabled. */
2461 if (!htab->params->no_reloc_overflow_check
2462 && !converted_reloc
2463 && (bfd_link_pic (info)
2464 || (bfd_link_executable (info)
2465 && h != NULL
2466 && !h->def_regular
2467 && h->def_dynamic
2468 && (sec->flags & SEC_READONLY) == 0)))
2469 return elf_x86_64_need_pic (info, abfd, sec, h, symtab_hdr, isym,
2470 &x86_64_elf_howto_table[r_type]);
2471 /* Fall through. */
2473 case R_X86_64_PC8:
2474 case R_X86_64_PC16:
2475 case R_X86_64_PC32:
2476 case R_X86_64_PC64:
2477 case R_X86_64_64:
2478 pointer:
2479 if (eh != NULL && (sec->flags & SEC_CODE) != 0)
2480 eh->zero_undefweak |= 0x2;
2481 /* We are called after all symbols have been resolved. Only
2482 relocation against STT_GNU_IFUNC symbol must go through
2483 PLT. */
2484 if (h != NULL
2485 && (bfd_link_executable (info)
2486 || h->type == STT_GNU_IFUNC))
2488 bool func_pointer_ref = false;
2490 if (r_type == R_X86_64_PC32)
2492 /* Since something like ".long foo - ." may be used
2493 as pointer, make sure that PLT is used if foo is
2494 a function defined in a shared library. */
2495 if ((sec->flags & SEC_CODE) == 0)
2497 h->pointer_equality_needed = 1;
2498 if (bfd_link_pie (info)
2499 && h->type == STT_FUNC
2500 && !h->def_regular
2501 && h->def_dynamic)
2503 h->needs_plt = 1;
2504 h->plt.refcount = 1;
2508 else if (r_type != R_X86_64_PC64)
2510 /* At run-time, R_X86_64_64 can be resolved for both
2511 x86-64 and x32. But R_X86_64_32 and R_X86_64_32S
2512 can only be resolved for x32. Function pointer
2513 reference doesn't need PLT for pointer equality. */
2514 if ((sec->flags & SEC_READONLY) == 0
2515 && (r_type == R_X86_64_64
2516 || (!ABI_64_P (abfd)
2517 && (r_type == R_X86_64_32
2518 || r_type == R_X86_64_32S))))
2519 func_pointer_ref = true;
2521 /* IFUNC symbol needs pointer equality in PDE so that
2522 function pointer reference will be resolved to its
2523 PLT entry directly. */
2524 if (!func_pointer_ref
2525 || (bfd_link_pde (info)
2526 && h->type == STT_GNU_IFUNC))
2527 h->pointer_equality_needed = 1;
2530 if (!func_pointer_ref)
2532 /* If this reloc is in a read-only section, we might
2533 need a copy reloc. We can't check reliably at this
2534 stage whether the section is read-only, as input
2535 sections have not yet been mapped to output sections.
2536 Tentatively set the flag for now, and correct in
2537 adjust_dynamic_symbol. */
2538 h->non_got_ref = 1;
2540 if (!elf_has_indirect_extern_access (sec->owner))
2541 eh->non_got_ref_without_indirect_extern_access = 1;
2543 /* We may need a .plt entry if the symbol is a function
2544 defined in a shared lib or is a function referenced
2545 from the code or read-only section. */
2546 if (!h->def_regular
2547 || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
2548 h->plt.refcount = 1;
2550 if (htab->elf.target_os != is_solaris
2551 && h->pointer_equality_needed
2552 && h->type == STT_FUNC
2553 && eh->def_protected
2554 && !SYMBOL_DEFINED_NON_SHARED_P (h)
2555 && h->def_dynamic)
2557 /* Disallow non-canonical reference to canonical
2558 protected function. */
2559 _bfd_error_handler
2560 /* xgettext:c-format */
2561 (_("%pB: non-canonical reference to canonical "
2562 "protected function `%s' in %pB"),
2563 abfd, h->root.root.string,
2564 h->root.u.def.section->owner);
2565 bfd_set_error (bfd_error_bad_value);
2566 goto error_return;
2571 size_reloc = false;
2572 do_size:
2573 if (!no_dynreloc
2574 && NEED_DYNAMIC_RELOCATION_P (true, info, true, h, sec,
2575 r_type,
2576 htab->pointer_r_type))
2578 struct elf_dyn_relocs *p;
2579 struct elf_dyn_relocs **head;
2581 /* If this is a global symbol, we count the number of
2582 relocations we need for this symbol. */
2583 if (h != NULL)
2584 head = &h->dyn_relocs;
2585 else
2587 /* Track dynamic relocs needed for local syms too.
2588 We really need local syms available to do this
2589 easily. Oh well. */
2590 asection *s;
2591 void **vpp;
2593 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
2594 abfd, r_symndx);
2595 if (isym == NULL)
2596 goto error_return;
2598 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2599 if (s == NULL)
2600 s = sec;
2602 /* Beware of type punned pointers vs strict aliasing
2603 rules. */
2604 vpp = &(elf_section_data (s)->local_dynrel);
2605 head = (struct elf_dyn_relocs **)vpp;
2608 p = *head;
2609 if (p == NULL || p->sec != sec)
2611 size_t amt = sizeof *p;
2613 p = ((struct elf_dyn_relocs *)
2614 bfd_alloc (htab->elf.dynobj, amt));
2615 if (p == NULL)
2616 goto error_return;
2617 p->next = *head;
2618 *head = p;
2619 p->sec = sec;
2620 p->count = 0;
2621 p->pc_count = 0;
2624 p->count += 1;
2625 /* Count size relocation as PC-relative relocation. */
2626 if (X86_PCREL_TYPE_P (true, r_type) || size_reloc)
2627 p->pc_count += 1;
2629 break;
2631 case R_X86_64_CODE_5_GOTPCRELX:
2632 case R_X86_64_CODE_5_GOTTPOFF:
2633 case R_X86_64_CODE_5_GOTPC32_TLSDESC:
2634 case R_X86_64_CODE_6_GOTPCRELX:
2635 case R_X86_64_CODE_6_GOTPC32_TLSDESC:
2637 /* These relocations are added only for completeness and
2638 aren't be used. */
2639 if (h)
2640 name = h->root.root.string;
2641 else
2642 name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
2643 NULL);
2644 _bfd_error_handler
2645 /* xgettext:c-format */
2646 (_("%pB: unsupported relocation %s against symbol `%s'"),
2647 abfd, x86_64_elf_howto_table[r_type].name, name);
2649 break;
2651 /* This relocation describes the C++ object vtable hierarchy.
2652 Reconstruct it for later use during GC. */
2653 case R_X86_64_GNU_VTINHERIT:
2654 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2655 goto error_return;
2656 break;
2658 /* This relocation describes which C++ vtable entries are actually
2659 used. Record for later use during GC. */
2660 case R_X86_64_GNU_VTENTRY:
2661 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2662 goto error_return;
2663 break;
2665 default:
2666 break;
2670 if (elf_section_data (sec)->this_hdr.contents != contents)
2672 if (!converted)
2673 _bfd_elf_munmap_section_contents (sec, contents);
2674 else
2676 /* Cache the section contents for elf_link_input_bfd if any
2677 load is converted or --no-keep-memory isn't used. */
2678 elf_section_data (sec)->this_hdr.contents = contents;
2679 info->cache_size += sec->size;
2683 /* Cache relocations if any load is converted. */
2684 if (elf_section_data (sec)->relocs != relocs && converted)
2685 elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
2687 return true;
2689 error_return:
2690 if (elf_section_data (sec)->this_hdr.contents != contents)
2691 _bfd_elf_munmap_section_contents (sec, contents);
2692 sec->check_relocs_failed = 1;
2693 return false;
2696 static bool
2697 elf_x86_64_early_size_sections (bfd *output_bfd, struct bfd_link_info *info)
2699 bfd *abfd;
2701 /* Scan relocations after rel_from_abs has been set on __ehdr_start. */
2702 for (abfd = info->input_bfds;
2703 abfd != (bfd *) NULL;
2704 abfd = abfd->link.next)
2705 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
2706 && !_bfd_elf_link_iterate_on_relocs (abfd, info,
2707 elf_x86_64_scan_relocs))
2708 return false;
2710 return _bfd_x86_elf_early_size_sections (output_bfd, info);
2713 /* Return the relocation value for @tpoff relocation
2714 if STT_TLS virtual address is ADDRESS. */
2716 static bfd_vma
2717 elf_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
2719 struct elf_link_hash_table *htab = elf_hash_table (info);
2720 const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
2721 bfd_vma static_tls_size;
2723 /* If tls_segment is NULL, we should have signalled an error already. */
2724 if (htab->tls_sec == NULL)
2725 return 0;
2727 /* Consider special static TLS alignment requirements. */
2728 static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment);
2729 return address - static_tls_size - htab->tls_sec->vma;
2732 /* Relocate an x86_64 ELF section. */
2734 static int
2735 elf_x86_64_relocate_section (bfd *output_bfd,
2736 struct bfd_link_info *info,
2737 bfd *input_bfd,
2738 asection *input_section,
2739 bfd_byte *contents,
2740 Elf_Internal_Rela *relocs,
2741 Elf_Internal_Sym *local_syms,
2742 asection **local_sections)
2744 struct elf_x86_link_hash_table *htab;
2745 Elf_Internal_Shdr *symtab_hdr;
2746 struct elf_link_hash_entry **sym_hashes;
2747 bfd_vma *local_got_offsets;
2748 bfd_vma *local_tlsdesc_gotents;
2749 Elf_Internal_Rela *rel;
2750 Elf_Internal_Rela *wrel;
2751 Elf_Internal_Rela *relend;
2752 unsigned int plt_entry_size;
2753 bool status;
2755 /* Skip if check_relocs or scan_relocs failed. */
2756 if (input_section->check_relocs_failed)
2757 return false;
2759 htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
2760 if (htab == NULL)
2761 return false;
2763 if (!is_x86_elf (input_bfd, htab))
2765 bfd_set_error (bfd_error_wrong_format);
2766 return false;
2769 plt_entry_size = htab->plt.plt_entry_size;
2770 symtab_hdr = &elf_symtab_hdr (input_bfd);
2771 sym_hashes = elf_sym_hashes (input_bfd);
2772 local_got_offsets = elf_local_got_offsets (input_bfd);
2773 local_tlsdesc_gotents = elf_x86_local_tlsdesc_gotent (input_bfd);
2775 _bfd_x86_elf_set_tls_module_base (info);
2777 status = true;
2778 rel = wrel = relocs;
2779 relend = relocs + input_section->reloc_count;
2780 for (; rel < relend; wrel++, rel++)
2782 unsigned int r_type, r_type_tls;
2783 reloc_howto_type *howto;
2784 unsigned long r_symndx;
2785 struct elf_link_hash_entry *h;
2786 struct elf_x86_link_hash_entry *eh;
2787 Elf_Internal_Sym *sym;
2788 asection *sec;
2789 bfd_vma off, offplt, plt_offset;
2790 bfd_vma relocation;
2791 bool unresolved_reloc;
2792 bfd_reloc_status_type r;
2793 int tls_type;
2794 asection *base_got, *resolved_plt;
2795 bfd_vma st_size;
2796 bool resolved_to_zero;
2797 bool relative_reloc;
2798 bool converted_reloc;
2799 bool need_copy_reloc_in_pie;
2800 bool no_copyreloc_p;
2802 r_type = ELF32_R_TYPE (rel->r_info);
2803 if (r_type == (int) R_X86_64_GNU_VTINHERIT
2804 || r_type == (int) R_X86_64_GNU_VTENTRY)
2806 if (wrel != rel)
2807 *wrel = *rel;
2808 continue;
2811 r_symndx = htab->r_sym (rel->r_info);
2812 converted_reloc = (r_type & R_X86_64_converted_reloc_bit) != 0;
2813 if (converted_reloc)
2815 r_type &= ~R_X86_64_converted_reloc_bit;
2816 rel->r_info = htab->r_info (r_symndx, r_type);
2819 howto = elf_x86_64_rtype_to_howto (input_bfd, r_type);
2820 if (howto == NULL)
2821 return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
2823 h = NULL;
2824 sym = NULL;
2825 sec = NULL;
2826 unresolved_reloc = false;
2827 if (r_symndx < symtab_hdr->sh_info)
2829 sym = local_syms + r_symndx;
2830 sec = local_sections[r_symndx];
2832 relocation = _bfd_elf_rela_local_sym (output_bfd, sym,
2833 &sec, rel);
2834 st_size = sym->st_size;
2836 /* Relocate against local STT_GNU_IFUNC symbol. */
2837 if (!bfd_link_relocatable (info)
2838 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2840 h = _bfd_elf_x86_get_local_sym_hash (htab, input_bfd,
2841 rel, false);
2842 if (h == NULL)
2843 abort ();
2845 /* Set STT_GNU_IFUNC symbol value. */
2846 h->root.u.def.value = sym->st_value;
2847 h->root.u.def.section = sec;
2850 else
2852 bool warned ATTRIBUTE_UNUSED;
2853 bool ignored ATTRIBUTE_UNUSED;
2855 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2856 r_symndx, symtab_hdr, sym_hashes,
2857 h, sec, relocation,
2858 unresolved_reloc, warned, ignored);
2859 st_size = h->size;
2862 if (sec != NULL && discarded_section (sec))
2864 _bfd_clear_contents (howto, input_bfd, input_section,
2865 contents, rel->r_offset);
2866 wrel->r_offset = rel->r_offset;
2867 wrel->r_info = 0;
2868 wrel->r_addend = 0;
2870 /* For ld -r, remove relocations in debug sections against
2871 sections defined in discarded sections. Not done for
2872 eh_frame editing code expects to be present. */
2873 if (bfd_link_relocatable (info)
2874 && (input_section->flags & SEC_DEBUGGING))
2875 wrel--;
2877 continue;
2880 if (bfd_link_relocatable (info))
2882 if (wrel != rel)
2883 *wrel = *rel;
2884 continue;
2887 if (rel->r_addend == 0 && !ABI_64_P (output_bfd))
2889 if (r_type == R_X86_64_64)
2891 /* For x32, treat R_X86_64_64 like R_X86_64_32 and
2892 zero-extend it to 64bit if addend is zero. */
2893 r_type = R_X86_64_32;
2894 memset (contents + rel->r_offset + 4, 0, 4);
2896 else if (r_type == R_X86_64_SIZE64)
2898 /* For x32, treat R_X86_64_SIZE64 like R_X86_64_SIZE32 and
2899 zero-extend it to 64bit if addend is zero. */
2900 r_type = R_X86_64_SIZE32;
2901 memset (contents + rel->r_offset + 4, 0, 4);
2905 eh = (struct elf_x86_link_hash_entry *) h;
2907 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
2908 it here if it is defined in a non-shared object. */
2909 if (h != NULL
2910 && h->type == STT_GNU_IFUNC
2911 && h->def_regular)
2913 bfd_vma plt_index;
2914 const char *name;
2916 if ((input_section->flags & SEC_ALLOC) == 0)
2918 /* If this is a SHT_NOTE section without SHF_ALLOC, treat
2919 STT_GNU_IFUNC symbol as STT_FUNC. */
2920 if (elf_section_type (input_section) == SHT_NOTE)
2921 goto skip_ifunc;
2922 /* Dynamic relocs are not propagated for SEC_DEBUGGING
2923 sections because such sections are not SEC_ALLOC and
2924 thus ld.so will not process them. */
2925 if ((input_section->flags & SEC_DEBUGGING) != 0)
2926 continue;
2927 abort ();
2930 switch (r_type)
2932 default:
2933 break;
2935 case R_X86_64_GOTPCREL:
2936 case R_X86_64_GOTPCRELX:
2937 case R_X86_64_REX_GOTPCRELX:
2938 case R_X86_64_CODE_4_GOTPCRELX:
2939 case R_X86_64_GOTPCREL64:
2940 base_got = htab->elf.sgot;
2941 off = h->got.offset;
2943 if (base_got == NULL)
2944 abort ();
2946 if (off == (bfd_vma) -1)
2948 /* We can't use h->got.offset here to save state, or
2949 even just remember the offset, as finish_dynamic_symbol
2950 would use that as offset into .got. */
2952 if (h->plt.offset == (bfd_vma) -1)
2953 abort ();
2955 if (htab->elf.splt != NULL)
2957 plt_index = (h->plt.offset / plt_entry_size
2958 - htab->plt.has_plt0);
2959 off = (plt_index + 3) * GOT_ENTRY_SIZE;
2960 base_got = htab->elf.sgotplt;
2962 else
2964 plt_index = h->plt.offset / plt_entry_size;
2965 off = plt_index * GOT_ENTRY_SIZE;
2966 base_got = htab->elf.igotplt;
2969 if (h->dynindx == -1
2970 || h->forced_local
2971 || info->symbolic)
2973 /* This references the local defitionion. We must
2974 initialize this entry in the global offset table.
2975 Since the offset must always be a multiple of 8,
2976 we use the least significant bit to record
2977 whether we have initialized it already.
2979 When doing a dynamic link, we create a .rela.got
2980 relocation entry to initialize the value. This
2981 is done in the finish_dynamic_symbol routine. */
2982 if ((off & 1) != 0)
2983 off &= ~1;
2984 else
2986 bfd_put_64 (output_bfd, relocation,
2987 base_got->contents + off);
2988 /* Note that this is harmless for the GOTPLT64
2989 case, as -1 | 1 still is -1. */
2990 h->got.offset |= 1;
2995 relocation = (base_got->output_section->vma
2996 + base_got->output_offset + off);
2998 goto do_relocation;
3001 if (h->plt.offset == (bfd_vma) -1)
3003 /* Handle static pointers of STT_GNU_IFUNC symbols. */
3004 if (r_type == htab->pointer_r_type
3005 && (input_section->flags & SEC_CODE) == 0)
3006 goto do_ifunc_pointer;
3007 goto bad_ifunc_reloc;
3010 /* STT_GNU_IFUNC symbol must go through PLT. */
3011 if (htab->elf.splt != NULL)
3013 if (htab->plt_second != NULL)
3015 resolved_plt = htab->plt_second;
3016 plt_offset = eh->plt_second.offset;
3018 else
3020 resolved_plt = htab->elf.splt;
3021 plt_offset = h->plt.offset;
3024 else
3026 resolved_plt = htab->elf.iplt;
3027 plt_offset = h->plt.offset;
3030 relocation = (resolved_plt->output_section->vma
3031 + resolved_plt->output_offset + plt_offset);
3033 switch (r_type)
3035 default:
3036 bad_ifunc_reloc:
3037 if (h->root.root.string)
3038 name = h->root.root.string;
3039 else
3040 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
3041 NULL);
3042 _bfd_error_handler
3043 /* xgettext:c-format */
3044 (_("%pB: relocation %s against STT_GNU_IFUNC "
3045 "symbol `%s' isn't supported"), input_bfd,
3046 howto->name, name);
3047 bfd_set_error (bfd_error_bad_value);
3048 return false;
3050 case R_X86_64_32S:
3051 if (bfd_link_pic (info))
3052 abort ();
3053 goto do_relocation;
3055 case R_X86_64_32:
3056 if (ABI_64_P (output_bfd))
3057 goto do_relocation;
3058 /* FALLTHROUGH */
3059 case R_X86_64_64:
3060 do_ifunc_pointer:
3061 if (rel->r_addend != 0)
3063 if (h->root.root.string)
3064 name = h->root.root.string;
3065 else
3066 name = bfd_elf_sym_name (input_bfd, symtab_hdr,
3067 sym, NULL);
3068 _bfd_error_handler
3069 /* xgettext:c-format */
3070 (_("%pB: relocation %s against STT_GNU_IFUNC "
3071 "symbol `%s' has non-zero addend: %" PRId64),
3072 input_bfd, howto->name, name, (int64_t) rel->r_addend);
3073 bfd_set_error (bfd_error_bad_value);
3074 return false;
3077 /* Generate dynamic relcoation only when there is a
3078 non-GOT reference in a shared object or there is no
3079 PLT. */
3080 if ((bfd_link_pic (info) && h->non_got_ref)
3081 || h->plt.offset == (bfd_vma) -1)
3083 Elf_Internal_Rela outrel;
3084 asection *sreloc;
3086 /* Need a dynamic relocation to get the real function
3087 address. */
3088 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
3089 info,
3090 input_section,
3091 rel->r_offset);
3092 if (outrel.r_offset == (bfd_vma) -1
3093 || outrel.r_offset == (bfd_vma) -2)
3094 abort ();
3096 outrel.r_offset += (input_section->output_section->vma
3097 + input_section->output_offset);
3099 if (POINTER_LOCAL_IFUNC_P (info, h))
3101 info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
3102 h->root.root.string,
3103 h->root.u.def.section->owner);
3105 /* This symbol is resolved locally. */
3106 outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
3107 outrel.r_addend = (h->root.u.def.value
3108 + h->root.u.def.section->output_section->vma
3109 + h->root.u.def.section->output_offset);
3111 if (htab->params->report_relative_reloc)
3112 _bfd_x86_elf_link_report_relative_reloc
3113 (info, input_section, h, sym,
3114 "R_X86_64_IRELATIVE", &outrel);
3116 else
3118 outrel.r_info = htab->r_info (h->dynindx, r_type);
3119 outrel.r_addend = 0;
3122 /* Dynamic relocations are stored in
3123 1. .rela.ifunc section in PIC object.
3124 2. .rela.got section in dynamic executable.
3125 3. .rela.iplt section in static executable. */
3126 if (bfd_link_pic (info))
3127 sreloc = htab->elf.irelifunc;
3128 else if (htab->elf.splt != NULL)
3129 sreloc = htab->elf.srelgot;
3130 else
3131 sreloc = htab->elf.irelplt;
3132 elf_append_rela (output_bfd, sreloc, &outrel);
3134 /* If this reloc is against an external symbol, we
3135 do not want to fiddle with the addend. Otherwise,
3136 we need to include the symbol value so that it
3137 becomes an addend for the dynamic reloc. For an
3138 internal symbol, we have updated addend. */
3139 continue;
3141 /* FALLTHROUGH */
3142 case R_X86_64_PC32:
3143 case R_X86_64_PC64:
3144 case R_X86_64_PLT32:
3145 goto do_relocation;
3149 skip_ifunc:
3150 resolved_to_zero = (eh != NULL
3151 && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
3153 /* When generating a shared object, the relocations handled here are
3154 copied into the output file to be resolved at run time. */
3155 switch (r_type)
3157 case R_X86_64_GOT32:
3158 case R_X86_64_GOT64:
3159 /* Relocation is to the entry for this symbol in the global
3160 offset table. */
3161 case R_X86_64_GOTPCREL:
3162 case R_X86_64_GOTPCRELX:
3163 case R_X86_64_REX_GOTPCRELX:
3164 case R_X86_64_CODE_4_GOTPCRELX:
3165 case R_X86_64_GOTPCREL64:
3166 /* Use global offset table entry as symbol value. */
3167 case R_X86_64_GOTPLT64:
3168 /* This is obsolete and treated the same as GOT64. */
3169 base_got = htab->elf.sgot;
3171 if (htab->elf.sgot == NULL)
3172 abort ();
3174 relative_reloc = false;
3175 if (h != NULL)
3177 off = h->got.offset;
3178 if (h->needs_plt
3179 && h->plt.offset != (bfd_vma)-1
3180 && off == (bfd_vma)-1)
3182 /* We can't use h->got.offset here to save
3183 state, or even just remember the offset, as
3184 finish_dynamic_symbol would use that as offset into
3185 .got. */
3186 bfd_vma plt_index = (h->plt.offset / plt_entry_size
3187 - htab->plt.has_plt0);
3188 off = (plt_index + 3) * GOT_ENTRY_SIZE;
3189 base_got = htab->elf.sgotplt;
3192 if (RESOLVED_LOCALLY_P (info, h, htab))
3194 /* We must initialize this entry in the global offset
3195 table. Since the offset must always be a multiple
3196 of 8, we use the least significant bit to record
3197 whether we have initialized it already.
3199 When doing a dynamic link, we create a .rela.got
3200 relocation entry to initialize the value. This is
3201 done in the finish_dynamic_symbol routine. */
3202 if ((off & 1) != 0)
3203 off &= ~1;
3204 else
3206 bfd_put_64 (output_bfd, relocation,
3207 base_got->contents + off);
3208 /* Note that this is harmless for the GOTPLT64 case,
3209 as -1 | 1 still is -1. */
3210 h->got.offset |= 1;
3212 /* NB: Don't generate relative relocation here if
3213 it has been generated by DT_RELR. */
3214 if (!info->enable_dt_relr
3215 && GENERATE_RELATIVE_RELOC_P (info, h))
3217 /* If this symbol isn't dynamic in PIC,
3218 generate R_X86_64_RELATIVE here. */
3219 eh->no_finish_dynamic_symbol = 1;
3220 relative_reloc = true;
3224 else
3225 unresolved_reloc = false;
3227 else
3229 if (local_got_offsets == NULL)
3230 abort ();
3232 off = local_got_offsets[r_symndx];
3234 /* The offset must always be a multiple of 8. We use
3235 the least significant bit to record whether we have
3236 already generated the necessary reloc. */
3237 if ((off & 1) != 0)
3238 off &= ~1;
3239 else
3241 bfd_put_64 (output_bfd, relocation,
3242 base_got->contents + off);
3243 local_got_offsets[r_symndx] |= 1;
3245 /* NB: GOTPCREL relocations against local absolute
3246 symbol store relocation value in the GOT slot
3247 without relative relocation. Don't generate
3248 relative relocation here if it has been generated
3249 by DT_RELR. */
3250 if (!info->enable_dt_relr
3251 && bfd_link_pic (info)
3252 && !(sym->st_shndx == SHN_ABS
3253 && (r_type == R_X86_64_GOTPCREL
3254 || r_type == R_X86_64_GOTPCRELX
3255 || r_type == R_X86_64_REX_GOTPCRELX
3256 || r_type == R_X86_64_CODE_4_GOTPCRELX)))
3257 relative_reloc = true;
3261 if (relative_reloc)
3263 asection *s;
3264 Elf_Internal_Rela outrel;
3266 /* We need to generate a R_X86_64_RELATIVE reloc
3267 for the dynamic linker. */
3268 s = htab->elf.srelgot;
3269 if (s == NULL)
3270 abort ();
3272 outrel.r_offset = (base_got->output_section->vma
3273 + base_got->output_offset
3274 + off);
3275 outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
3276 outrel.r_addend = relocation;
3278 if (htab->params->report_relative_reloc)
3279 _bfd_x86_elf_link_report_relative_reloc
3280 (info, input_section, h, sym, "R_X86_64_RELATIVE",
3281 &outrel);
3283 elf_append_rela (output_bfd, s, &outrel);
3286 if (off >= (bfd_vma) -2)
3287 abort ();
3289 relocation = base_got->output_section->vma
3290 + base_got->output_offset + off;
3291 if (r_type != R_X86_64_GOTPCREL
3292 && r_type != R_X86_64_GOTPCRELX
3293 && r_type != R_X86_64_REX_GOTPCRELX
3294 && r_type != R_X86_64_CODE_4_GOTPCRELX
3295 && r_type != R_X86_64_GOTPCREL64)
3296 relocation -= htab->elf.sgotplt->output_section->vma
3297 - htab->elf.sgotplt->output_offset;
3299 break;
3301 case R_X86_64_GOTOFF64:
3302 /* Relocation is relative to the start of the global offset
3303 table. */
3305 /* Check to make sure it isn't a protected function or data
3306 symbol for shared library since it may not be local when
3307 used as function address or with copy relocation. We also
3308 need to make sure that a symbol is referenced locally. */
3309 if (bfd_link_pic (info) && h)
3311 if (!h->def_regular)
3313 const char *v;
3315 switch (ELF_ST_VISIBILITY (h->other))
3317 case STV_HIDDEN:
3318 v = _("hidden symbol");
3319 break;
3320 case STV_INTERNAL:
3321 v = _("internal symbol");
3322 break;
3323 case STV_PROTECTED:
3324 v = _("protected symbol");
3325 break;
3326 default:
3327 v = _("symbol");
3328 break;
3331 _bfd_error_handler
3332 /* xgettext:c-format */
3333 (_("%pB: relocation R_X86_64_GOTOFF64 against undefined %s"
3334 " `%s' can not be used when making a shared object"),
3335 input_bfd, v, h->root.root.string);
3336 bfd_set_error (bfd_error_bad_value);
3337 return false;
3339 else if (!bfd_link_executable (info)
3340 && !SYMBOL_REFERENCES_LOCAL_P (info, h)
3341 && (h->type == STT_FUNC
3342 || h->type == STT_OBJECT)
3343 && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
3345 _bfd_error_handler
3346 /* xgettext:c-format */
3347 (_("%pB: relocation R_X86_64_GOTOFF64 against protected %s"
3348 " `%s' can not be used when making a shared object"),
3349 input_bfd,
3350 h->type == STT_FUNC ? "function" : "data",
3351 h->root.root.string);
3352 bfd_set_error (bfd_error_bad_value);
3353 return false;
3357 /* Note that sgot is not involved in this
3358 calculation. We always want the start of .got.plt. If we
3359 defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
3360 permitted by the ABI, we might have to change this
3361 calculation. */
3362 relocation -= htab->elf.sgotplt->output_section->vma
3363 + htab->elf.sgotplt->output_offset;
3364 break;
3366 case R_X86_64_GOTPC32:
3367 case R_X86_64_GOTPC64:
3368 /* Use global offset table as symbol value. */
3369 relocation = htab->elf.sgotplt->output_section->vma
3370 + htab->elf.sgotplt->output_offset;
3371 unresolved_reloc = false;
3372 break;
3374 case R_X86_64_PLTOFF64:
3375 /* Relocation is PLT entry relative to GOT. For local
3376 symbols it's the symbol itself relative to GOT. */
3377 if (h != NULL
3378 /* See PLT32 handling. */
3379 && (h->plt.offset != (bfd_vma) -1
3380 || eh->plt_got.offset != (bfd_vma) -1)
3381 && htab->elf.splt != NULL)
3383 if (eh->plt_got.offset != (bfd_vma) -1)
3385 /* Use the GOT PLT. */
3386 resolved_plt = htab->plt_got;
3387 plt_offset = eh->plt_got.offset;
3389 else if (htab->plt_second != NULL)
3391 resolved_plt = htab->plt_second;
3392 plt_offset = eh->plt_second.offset;
3394 else
3396 resolved_plt = htab->elf.splt;
3397 plt_offset = h->plt.offset;
3400 relocation = (resolved_plt->output_section->vma
3401 + resolved_plt->output_offset
3402 + plt_offset);
3403 unresolved_reloc = false;
3406 relocation -= htab->elf.sgotplt->output_section->vma
3407 + htab->elf.sgotplt->output_offset;
3408 break;
3410 case R_X86_64_PLT32:
3411 /* Relocation is to the entry for this symbol in the
3412 procedure linkage table. */
3414 /* Resolve a PLT32 reloc against a local symbol directly,
3415 without using the procedure linkage table. */
3416 if (h == NULL)
3417 break;
3419 if ((h->plt.offset == (bfd_vma) -1
3420 && eh->plt_got.offset == (bfd_vma) -1)
3421 || htab->elf.splt == NULL)
3423 /* We didn't make a PLT entry for this symbol. This
3424 happens when statically linking PIC code, or when
3425 using -Bsymbolic. */
3426 break;
3429 use_plt:
3430 if (h->plt.offset != (bfd_vma) -1)
3432 if (htab->plt_second != NULL)
3434 resolved_plt = htab->plt_second;
3435 plt_offset = eh->plt_second.offset;
3437 else
3439 resolved_plt = htab->elf.splt;
3440 plt_offset = h->plt.offset;
3443 else
3445 /* Use the GOT PLT. */
3446 resolved_plt = htab->plt_got;
3447 plt_offset = eh->plt_got.offset;
3450 relocation = (resolved_plt->output_section->vma
3451 + resolved_plt->output_offset
3452 + plt_offset);
3453 unresolved_reloc = false;
3454 break;
3456 case R_X86_64_SIZE32:
3457 case R_X86_64_SIZE64:
3458 /* Set to symbol size. */
3459 relocation = st_size;
3460 goto direct;
3462 case R_X86_64_PC8:
3463 case R_X86_64_PC16:
3464 case R_X86_64_PC32:
3465 /* Don't complain about -fPIC if the symbol is undefined when
3466 building executable unless it is unresolved weak symbol,
3467 references a dynamic definition in PIE or -z nocopyreloc
3468 is used. */
3469 no_copyreloc_p
3470 = (info->nocopyreloc
3471 || (h != NULL
3472 && !h->root.linker_def
3473 && !h->root.ldscript_def
3474 && eh->def_protected));
3476 if ((input_section->flags & SEC_ALLOC) != 0
3477 && (input_section->flags & SEC_READONLY) != 0
3478 && h != NULL
3479 && ((bfd_link_executable (info)
3480 && ((h->root.type == bfd_link_hash_undefweak
3481 && (eh == NULL
3482 || !UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
3483 eh)))
3484 || (bfd_link_pie (info)
3485 && !SYMBOL_DEFINED_NON_SHARED_P (h)
3486 && h->def_dynamic)
3487 || (no_copyreloc_p
3488 && h->def_dynamic
3489 && !(h->root.u.def.section->flags & SEC_CODE))))
3490 || (bfd_link_pie (info)
3491 && h->root.type == bfd_link_hash_undefweak)
3492 || bfd_link_dll (info)))
3494 bool fail = false;
3495 if (SYMBOL_REFERENCES_LOCAL_P (info, h))
3497 /* Symbol is referenced locally. Make sure it is
3498 defined locally. */
3499 fail = !SYMBOL_DEFINED_NON_SHARED_P (h);
3501 else if (bfd_link_pie (info))
3503 /* We can only use PC-relative relocations in PIE
3504 from non-code sections. */
3505 if (h->root.type == bfd_link_hash_undefweak
3506 || (h->type == STT_FUNC
3507 && (sec->flags & SEC_CODE) != 0))
3508 fail = true;
3510 else if (no_copyreloc_p || bfd_link_dll (info))
3512 /* Symbol doesn't need copy reloc and isn't
3513 referenced locally. Don't allow PC-relative
3514 relocations against default and protected
3515 symbols since address of protected function
3516 and location of protected data may not be in
3517 the shared object. */
3518 fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3519 || ELF_ST_VISIBILITY (h->other) == STV_PROTECTED);
3522 if (fail)
3523 return elf_x86_64_need_pic (info, input_bfd, input_section,
3524 h, NULL, NULL, howto);
3526 /* Since x86-64 has PC-relative PLT, we can use PLT in PIE
3527 as function address. */
3528 else if (h != NULL
3529 && (input_section->flags & SEC_CODE) == 0
3530 && bfd_link_pie (info)
3531 && h->type == STT_FUNC
3532 && !h->def_regular
3533 && h->def_dynamic)
3534 goto use_plt;
3535 /* Fall through. */
3537 case R_X86_64_8:
3538 case R_X86_64_16:
3539 case R_X86_64_32:
3540 case R_X86_64_PC64:
3541 case R_X86_64_64:
3542 /* FIXME: The ABI says the linker should make sure the value is
3543 the same when it's zeroextended to 64 bit. */
3545 direct:
3546 if ((input_section->flags & SEC_ALLOC) == 0)
3547 break;
3549 need_copy_reloc_in_pie = (bfd_link_pie (info)
3550 && h != NULL
3551 && (h->needs_copy
3552 || eh->needs_copy
3553 || (h->root.type
3554 == bfd_link_hash_undefined))
3555 && (X86_PCREL_TYPE_P (true, r_type)
3556 || X86_SIZE_TYPE_P (true,
3557 r_type)));
3559 if (GENERATE_DYNAMIC_RELOCATION_P (true, info, eh, r_type, sec,
3560 need_copy_reloc_in_pie,
3561 resolved_to_zero, false))
3563 Elf_Internal_Rela outrel;
3564 bool skip, relocate;
3565 bool generate_dynamic_reloc = true;
3566 asection *sreloc;
3567 const char *relative_reloc_name = NULL;
3569 /* When generating a shared object, these relocations
3570 are copied into the output file to be resolved at run
3571 time. */
3572 skip = false;
3573 relocate = false;
3575 outrel.r_offset =
3576 _bfd_elf_section_offset (output_bfd, info, input_section,
3577 rel->r_offset);
3578 if (outrel.r_offset == (bfd_vma) -1)
3579 skip = true;
3580 else if (outrel.r_offset == (bfd_vma) -2)
3581 skip = true, relocate = true;
3583 outrel.r_offset += (input_section->output_section->vma
3584 + input_section->output_offset);
3586 if (skip)
3587 memset (&outrel, 0, sizeof outrel);
3589 else if (COPY_INPUT_RELOC_P (true, info, h, r_type))
3591 outrel.r_info = htab->r_info (h->dynindx, r_type);
3592 outrel.r_addend = rel->r_addend;
3594 else
3596 /* This symbol is local, or marked to become local.
3597 When relocation overflow check is disabled, we
3598 convert R_X86_64_32 to dynamic R_X86_64_RELATIVE. */
3599 if (r_type == htab->pointer_r_type
3600 || (r_type == R_X86_64_32
3601 && htab->params->no_reloc_overflow_check))
3603 relocate = true;
3604 /* NB: Don't generate relative relocation here if
3605 it has been generated by DT_RELR. */
3606 if (info->enable_dt_relr)
3607 generate_dynamic_reloc = false;
3608 else
3610 outrel.r_info =
3611 htab->r_info (0, R_X86_64_RELATIVE);
3612 outrel.r_addend = relocation + rel->r_addend;
3613 relative_reloc_name = "R_X86_64_RELATIVE";
3616 else if (r_type == R_X86_64_64
3617 && !ABI_64_P (output_bfd))
3619 relocate = true;
3620 outrel.r_info = htab->r_info (0,
3621 R_X86_64_RELATIVE64);
3622 outrel.r_addend = relocation + rel->r_addend;
3623 relative_reloc_name = "R_X86_64_RELATIVE64";
3624 /* Check addend overflow. */
3625 if ((outrel.r_addend & 0x80000000)
3626 != (rel->r_addend & 0x80000000))
3628 const char *name;
3629 int addend = rel->r_addend;
3630 if (h && h->root.root.string)
3631 name = h->root.root.string;
3632 else
3633 name = bfd_elf_sym_name (input_bfd, symtab_hdr,
3634 sym, NULL);
3635 _bfd_error_handler
3636 /* xgettext:c-format */
3637 (_("%pB: addend %s%#x in relocation %s against "
3638 "symbol `%s' at %#" PRIx64
3639 " in section `%pA' is out of range"),
3640 input_bfd, addend < 0 ? "-" : "", addend,
3641 howto->name, name, (uint64_t) rel->r_offset,
3642 input_section);
3643 bfd_set_error (bfd_error_bad_value);
3644 return false;
3647 else
3649 long sindx;
3651 if (bfd_is_abs_section (sec))
3652 sindx = 0;
3653 else if (sec == NULL || sec->owner == NULL)
3655 bfd_set_error (bfd_error_bad_value);
3656 return false;
3658 else
3660 asection *osec;
3662 /* We are turning this relocation into one
3663 against a section symbol. It would be
3664 proper to subtract the symbol's value,
3665 osec->vma, from the emitted reloc addend,
3666 but ld.so expects buggy relocs. */
3667 osec = sec->output_section;
3668 sindx = elf_section_data (osec)->dynindx;
3669 if (sindx == 0)
3671 asection *oi = htab->elf.text_index_section;
3672 sindx = elf_section_data (oi)->dynindx;
3674 BFD_ASSERT (sindx != 0);
3677 outrel.r_info = htab->r_info (sindx, r_type);
3678 outrel.r_addend = relocation + rel->r_addend;
3682 if (generate_dynamic_reloc)
3684 sreloc = elf_section_data (input_section)->sreloc;
3686 if (sreloc == NULL || sreloc->contents == NULL)
3688 r = bfd_reloc_notsupported;
3689 goto check_relocation_error;
3692 if (relative_reloc_name
3693 && htab->params->report_relative_reloc)
3694 _bfd_x86_elf_link_report_relative_reloc
3695 (info, input_section, h, sym,
3696 relative_reloc_name, &outrel);
3698 elf_append_rela (output_bfd, sreloc, &outrel);
3701 /* If this reloc is against an external symbol, we do
3702 not want to fiddle with the addend. Otherwise, we
3703 need to include the symbol value so that it becomes
3704 an addend for the dynamic reloc. */
3705 if (! relocate)
3706 continue;
3709 break;
3711 case R_X86_64_TLSGD:
3712 case R_X86_64_GOTPC32_TLSDESC:
3713 case R_X86_64_CODE_4_GOTPC32_TLSDESC:
3714 case R_X86_64_TLSDESC_CALL:
3715 case R_X86_64_GOTTPOFF:
3716 case R_X86_64_CODE_4_GOTTPOFF:
3717 case R_X86_64_CODE_6_GOTTPOFF:
3718 tls_type = GOT_UNKNOWN;
3719 if (h == NULL && local_got_offsets)
3720 tls_type = elf_x86_local_got_tls_type (input_bfd) [r_symndx];
3721 else if (h != NULL)
3722 tls_type = elf_x86_hash_entry (h)->tls_type;
3724 r_type_tls = r_type;
3725 if (! elf_x86_64_tls_transition (info, input_bfd,
3726 input_section, contents,
3727 symtab_hdr, sym_hashes,
3728 &r_type_tls, tls_type, rel,
3729 relend, h, sym, true))
3730 return false;
3732 if (r_type_tls == R_X86_64_TPOFF32)
3734 bfd_vma roff = rel->r_offset;
3736 if (roff >= input_section->size)
3737 goto corrupt_input;
3739 BFD_ASSERT (! unresolved_reloc);
3741 if (r_type == R_X86_64_TLSGD)
3743 /* GD->LE transition. For 64bit, change
3744 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3745 .word 0x6666; rex64; call __tls_get_addr@PLT
3747 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3748 .byte 0x66; rex64
3749 call *__tls_get_addr@GOTPCREL(%rip)
3750 which may be converted to
3751 addr32 call __tls_get_addr
3752 into:
3753 movq %fs:0, %rax
3754 leaq foo@tpoff(%rax), %rax
3755 For 32bit, change
3756 leaq foo@tlsgd(%rip), %rdi
3757 .word 0x6666; rex64; call __tls_get_addr@PLT
3759 leaq foo@tlsgd(%rip), %rdi
3760 .byte 0x66; rex64
3761 call *__tls_get_addr@GOTPCREL(%rip)
3762 which may be converted to
3763 addr32 call __tls_get_addr
3764 into:
3765 movl %fs:0, %eax
3766 leaq foo@tpoff(%rax), %rax
3767 For largepic, change:
3768 leaq foo@tlsgd(%rip), %rdi
3769 movabsq $__tls_get_addr@pltoff, %rax
3770 addq %r15, %rax
3771 call *%rax
3772 into:
3773 movq %fs:0, %rax
3774 leaq foo@tpoff(%rax), %rax
3775 nopw 0x0(%rax,%rax,1) */
3776 int largepic = 0;
3777 if (ABI_64_P (output_bfd))
3779 if (roff + 5 >= input_section->size)
3780 goto corrupt_input;
3781 if (contents[roff + 5] == 0xb8)
3783 if (roff < 3
3784 || (roff - 3 + 22) > input_section->size)
3786 corrupt_input:
3787 info->callbacks->einfo
3788 (_("%F%P: corrupt input: %pB\n"),
3789 input_bfd);
3790 return false;
3792 memcpy (contents + roff - 3,
3793 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80"
3794 "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
3795 largepic = 1;
3797 else
3799 if (roff < 4
3800 || (roff - 4 + 16) > input_section->size)
3801 goto corrupt_input;
3802 memcpy (contents + roff - 4,
3803 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
3804 16);
3807 else
3809 if (roff < 3
3810 || (roff - 3 + 15) > input_section->size)
3811 goto corrupt_input;
3812 memcpy (contents + roff - 3,
3813 "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
3814 15);
3817 if (roff + 8 + largepic >= input_section->size)
3818 goto corrupt_input;
3820 bfd_put_32 (output_bfd,
3821 elf_x86_64_tpoff (info, relocation),
3822 contents + roff + 8 + largepic);
3823 /* Skip R_X86_64_PC32, R_X86_64_PLT32,
3824 R_X86_64_GOTPCRELX and R_X86_64_PLTOFF64. */
3825 rel++;
3826 wrel++;
3827 continue;
3829 else if (r_type == R_X86_64_GOTPC32_TLSDESC)
3831 /* GDesc -> LE transition.
3832 It's originally something like:
3833 leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
3834 rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
3836 Change it to:
3837 movq $x@tpoff, %rax <--- LP64 mode.
3838 rex movl $x@tpoff, %eax <--- X32 mode.
3841 unsigned int val, type;
3843 if (roff < 3)
3844 goto corrupt_input;
3845 type = bfd_get_8 (input_bfd, contents + roff - 3);
3846 val = bfd_get_8 (input_bfd, contents + roff - 1);
3847 bfd_put_8 (output_bfd,
3848 (type & 0x48) | ((type >> 2) & 1),
3849 contents + roff - 3);
3850 bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
3851 bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
3852 contents + roff - 1);
3853 bfd_put_32 (output_bfd,
3854 elf_x86_64_tpoff (info, relocation),
3855 contents + roff);
3856 continue;
3858 else if (r_type == R_X86_64_CODE_4_GOTPC32_TLSDESC)
3860 /* GDesc -> LE transition.
3861 It's originally something like:
3862 lea x@tlsdesc(%rip), %reg
3864 Change it to:
3865 mov $x@tpoff, %reg
3866 where reg is one of r16 to r31. */
3868 unsigned int val, rex2;
3869 unsigned int rex2_mask = REX_R | REX_R << 4;
3871 if (roff < 4)
3872 goto corrupt_input;
3873 rex2 = bfd_get_8 (input_bfd, contents + roff - 3);
3874 val = bfd_get_8 (input_bfd, contents + roff - 1);
3875 /* Move the R bits to the B bits in REX2 payload
3876 byte. */
3877 bfd_put_8 (output_bfd,
3878 ((rex2 & ~rex2_mask)
3879 | (rex2 & rex2_mask) >> 2),
3880 contents + roff - 3);
3881 bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
3882 bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
3883 contents + roff - 1);
3884 bfd_put_32 (output_bfd,
3885 elf_x86_64_tpoff (info, relocation),
3886 contents + roff);
3887 continue;
3889 else if (r_type == R_X86_64_TLSDESC_CALL)
3891 /* GDesc -> LE transition.
3892 It's originally:
3893 call *(%rax) <--- LP64 mode.
3894 call *(%eax) <--- X32 mode.
3895 Turn it into:
3896 xchg %ax,%ax <-- LP64 mode.
3897 nopl (%rax) <-- X32 mode.
3899 unsigned int prefix = 0;
3900 if (!ABI_64_P (input_bfd))
3902 /* Check for call *x@tlscall(%eax). */
3903 if (contents[roff] == 0x67)
3904 prefix = 1;
3906 if (prefix)
3908 if (roff + 2 >= input_section->size)
3909 goto corrupt_input;
3911 bfd_put_8 (output_bfd, 0x0f, contents + roff);
3912 bfd_put_8 (output_bfd, 0x1f, contents + roff + 1);
3913 bfd_put_8 (output_bfd, 0x00, contents + roff + 2);
3915 else
3917 if (roff + 1 >= input_section->size)
3918 goto corrupt_input;
3920 bfd_put_8 (output_bfd, 0x66, contents + roff);
3921 bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
3923 continue;
3925 else if (r_type == R_X86_64_GOTTPOFF)
3927 /* IE->LE transition:
3928 For 64bit, originally it can be one of:
3929 movq foo@gottpoff(%rip), %reg
3930 addq foo@gottpoff(%rip), %reg
3931 We change it into:
3932 movq $foo, %reg
3933 leaq foo(%reg), %reg
3934 addq $foo, %reg.
3935 For 32bit, originally it can be one of:
3936 movq foo@gottpoff(%rip), %reg
3937 addl foo@gottpoff(%rip), %reg
3938 We change it into:
3939 movq $foo, %reg
3940 leal foo(%reg), %reg
3941 addl $foo, %reg. */
3943 unsigned int val, type, reg;
3945 if (roff >= 3)
3946 val = bfd_get_8 (input_bfd, contents + roff - 3);
3947 else
3949 if (roff < 2)
3950 goto corrupt_input;
3951 val = 0;
3953 type = bfd_get_8 (input_bfd, contents + roff - 2);
3954 reg = bfd_get_8 (input_bfd, contents + roff - 1);
3955 reg >>= 3;
3956 if (type == 0x8b)
3958 /* movq */
3959 if (val == 0x4c)
3961 if (roff < 3)
3962 goto corrupt_input;
3963 bfd_put_8 (output_bfd, 0x49,
3964 contents + roff - 3);
3966 else if (!ABI_64_P (output_bfd) && val == 0x44)
3968 if (roff < 3)
3969 goto corrupt_input;
3970 bfd_put_8 (output_bfd, 0x41,
3971 contents + roff - 3);
3973 bfd_put_8 (output_bfd, 0xc7,
3974 contents + roff - 2);
3975 bfd_put_8 (output_bfd, 0xc0 | reg,
3976 contents + roff - 1);
3978 else if (reg == 4)
3980 /* addq/addl -> addq/addl - addressing with %rsp/%r12
3981 is special */
3982 if (val == 0x4c)
3984 if (roff < 3)
3985 goto corrupt_input;
3986 bfd_put_8 (output_bfd, 0x49,
3987 contents + roff - 3);
3989 else if (!ABI_64_P (output_bfd) && val == 0x44)
3991 if (roff < 3)
3992 goto corrupt_input;
3993 bfd_put_8 (output_bfd, 0x41,
3994 contents + roff - 3);
3996 bfd_put_8 (output_bfd, 0x81,
3997 contents + roff - 2);
3998 bfd_put_8 (output_bfd, 0xc0 | reg,
3999 contents + roff - 1);
4001 else
4003 /* addq/addl -> leaq/leal */
4004 if (val == 0x4c)
4006 if (roff < 3)
4007 goto corrupt_input;
4008 bfd_put_8 (output_bfd, 0x4d,
4009 contents + roff - 3);
4011 else if (!ABI_64_P (output_bfd) && val == 0x44)
4013 if (roff < 3)
4014 goto corrupt_input;
4015 bfd_put_8 (output_bfd, 0x45,
4016 contents + roff - 3);
4018 bfd_put_8 (output_bfd, 0x8d,
4019 contents + roff - 2);
4020 bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
4021 contents + roff - 1);
4023 bfd_put_32 (output_bfd,
4024 elf_x86_64_tpoff (info, relocation),
4025 contents + roff);
4026 continue;
4028 else if (r_type == R_X86_64_CODE_4_GOTTPOFF)
4030 /* IE->LE transition:
4031 Originally it can be one of:
4032 mov foo@gottpoff(%rip), %reg
4033 add foo@gottpoff(%rip), %reg
4034 We change it into:
4035 mov $foo@tpoff, %reg
4036 add $foo@tpoff, %reg
4037 where reg is one of r16 to r31. */
4039 unsigned int rex2, type, reg;
4040 unsigned int rex2_mask = REX_R | REX_R << 4;
4042 if (roff < 4)
4043 goto corrupt_input;
4045 rex2 = bfd_get_8 (input_bfd, contents + roff - 3);
4046 type = bfd_get_8 (input_bfd, contents + roff - 2);
4047 reg = bfd_get_8 (input_bfd, contents + roff - 1);
4048 reg >>= 3;
4049 /* Move the R bits to the B bits in REX2 payload
4050 byte. */
4051 if (type == 0x8b)
4052 type = 0xc7;
4053 else
4054 type = 0x81;
4055 bfd_put_8 (output_bfd,
4056 ((rex2 & ~rex2_mask)
4057 | (rex2 & rex2_mask) >> 2),
4058 contents + roff - 3);
4059 bfd_put_8 (output_bfd, type,
4060 contents + roff - 2);
4061 bfd_put_8 (output_bfd, 0xc0 | reg,
4062 contents + roff - 1);
4063 bfd_put_32 (output_bfd,
4064 elf_x86_64_tpoff (info, relocation),
4065 contents + roff);
4066 continue;
4068 else if (r_type == R_X86_64_CODE_6_GOTTPOFF)
4070 /* IE->LE transition:
4071 Originally it is
4072 add %reg1, foo@gottpoff(%rip), %reg2
4074 add foo@gottpoff(%rip), %reg1, %reg2
4075 We change it into:
4076 add $foo@tpoff, %reg1, %reg2
4078 unsigned int reg, byte1;
4079 unsigned int updated_byte1;
4081 if (roff < 6)
4082 goto corrupt_input;
4084 /* Move the R bits to the B bits in EVEX payload
4085 byte 1. */
4086 byte1 = bfd_get_8 (input_bfd, contents + roff - 5);
4087 updated_byte1 = byte1;
4089 /* Set the R bits since they is inverted. */
4090 updated_byte1 |= 1 << 7 | 1 << 4;
4092 /* Update the B bits from the R bits. */
4093 if ((byte1 & (1 << 7)) == 0)
4094 updated_byte1 &= ~(1 << 5);
4095 if ((byte1 & (1 << 4)) == 0)
4096 updated_byte1 |= 1 << 3;
4098 reg = bfd_get_8 (input_bfd, contents + roff - 1);
4099 reg >>= 3;
4101 bfd_put_8 (output_bfd, updated_byte1,
4102 contents + roff - 5);
4103 bfd_put_8 (output_bfd, 0x81,
4104 contents + roff - 2);
4105 bfd_put_8 (output_bfd, 0xc0 | reg,
4106 contents + roff - 1);
4107 bfd_put_32 (output_bfd,
4108 elf_x86_64_tpoff (info, relocation),
4109 contents + roff);
4110 continue;
4112 else
4113 BFD_ASSERT (false);
4116 if (htab->elf.sgot == NULL)
4117 abort ();
4119 if (h != NULL)
4121 off = h->got.offset;
4122 offplt = elf_x86_hash_entry (h)->tlsdesc_got;
4124 else
4126 if (local_got_offsets == NULL)
4127 abort ();
4129 off = local_got_offsets[r_symndx];
4130 offplt = local_tlsdesc_gotents[r_symndx];
4133 if ((off & 1) != 0)
4134 off &= ~1;
4135 else
4137 Elf_Internal_Rela outrel;
4138 int dr_type, indx;
4139 asection *sreloc;
4141 if (htab->elf.srelgot == NULL)
4142 abort ();
4144 indx = h && h->dynindx != -1 ? h->dynindx : 0;
4146 if (GOT_TLS_GDESC_P (tls_type))
4148 outrel.r_info = htab->r_info (indx, R_X86_64_TLSDESC);
4149 BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
4150 + 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size);
4151 outrel.r_offset = (htab->elf.sgotplt->output_section->vma
4152 + htab->elf.sgotplt->output_offset
4153 + offplt
4154 + htab->sgotplt_jump_table_size);
4155 sreloc = htab->elf.srelplt;
4156 if (indx == 0)
4157 outrel.r_addend = relocation - _bfd_x86_elf_dtpoff_base (info);
4158 else
4159 outrel.r_addend = 0;
4160 elf_append_rela (output_bfd, sreloc, &outrel);
4163 sreloc = htab->elf.srelgot;
4165 outrel.r_offset = (htab->elf.sgot->output_section->vma
4166 + htab->elf.sgot->output_offset + off);
4168 if (GOT_TLS_GD_P (tls_type))
4169 dr_type = R_X86_64_DTPMOD64;
4170 else if (GOT_TLS_GDESC_P (tls_type))
4171 goto dr_done;
4172 else
4173 dr_type = R_X86_64_TPOFF64;
4175 bfd_put_64 (output_bfd, 0, htab->elf.sgot->contents + off);
4176 outrel.r_addend = 0;
4177 if ((dr_type == R_X86_64_TPOFF64
4178 || dr_type == R_X86_64_TLSDESC) && indx == 0)
4179 outrel.r_addend = relocation - _bfd_x86_elf_dtpoff_base (info);
4180 outrel.r_info = htab->r_info (indx, dr_type);
4182 elf_append_rela (output_bfd, sreloc, &outrel);
4184 if (GOT_TLS_GD_P (tls_type))
4186 if (indx == 0)
4188 BFD_ASSERT (! unresolved_reloc);
4189 bfd_put_64 (output_bfd,
4190 relocation - _bfd_x86_elf_dtpoff_base (info),
4191 htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
4193 else
4195 bfd_put_64 (output_bfd, 0,
4196 htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
4197 outrel.r_info = htab->r_info (indx,
4198 R_X86_64_DTPOFF64);
4199 outrel.r_offset += GOT_ENTRY_SIZE;
4200 elf_append_rela (output_bfd, sreloc,
4201 &outrel);
4205 dr_done:
4206 if (h != NULL)
4207 h->got.offset |= 1;
4208 else
4209 local_got_offsets[r_symndx] |= 1;
4212 if (off >= (bfd_vma) -2
4213 && ! GOT_TLS_GDESC_P (tls_type))
4214 abort ();
4215 if (r_type_tls == r_type)
4217 if (r_type == R_X86_64_GOTPC32_TLSDESC
4218 || r_type == R_X86_64_CODE_4_GOTPC32_TLSDESC
4219 || r_type == R_X86_64_TLSDESC_CALL)
4220 relocation = htab->elf.sgotplt->output_section->vma
4221 + htab->elf.sgotplt->output_offset
4222 + offplt + htab->sgotplt_jump_table_size;
4223 else
4224 relocation = htab->elf.sgot->output_section->vma
4225 + htab->elf.sgot->output_offset + off;
4226 unresolved_reloc = false;
4228 else
4230 bfd_vma roff = rel->r_offset;
4232 if (r_type == R_X86_64_TLSGD)
4234 /* GD->IE transition. For 64bit, change
4235 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
4236 .word 0x6666; rex64; call __tls_get_addr@PLT
4238 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
4239 .byte 0x66; rex64
4240 call *__tls_get_addr@GOTPCREL(%rip
4241 which may be converted to
4242 addr32 call __tls_get_addr
4243 into:
4244 movq %fs:0, %rax
4245 addq foo@gottpoff(%rip), %rax
4246 For 32bit, change
4247 leaq foo@tlsgd(%rip), %rdi
4248 .word 0x6666; rex64; call __tls_get_addr@PLT
4250 leaq foo@tlsgd(%rip), %rdi
4251 .byte 0x66; rex64;
4252 call *__tls_get_addr@GOTPCREL(%rip)
4253 which may be converted to
4254 addr32 call __tls_get_addr
4255 into:
4256 movl %fs:0, %eax
4257 addq foo@gottpoff(%rip), %rax
4258 For largepic, change:
4259 leaq foo@tlsgd(%rip), %rdi
4260 movabsq $__tls_get_addr@pltoff, %rax
4261 addq %r15, %rax
4262 call *%rax
4263 into:
4264 movq %fs:0, %rax
4265 addq foo@gottpoff(%rax), %rax
4266 nopw 0x0(%rax,%rax,1) */
4267 int largepic = 0;
4268 if (ABI_64_P (output_bfd))
4270 if (contents[roff + 5] == 0xb8)
4272 if (roff < 3
4273 || (roff - 3 + 22) > input_section->size)
4274 goto corrupt_input;
4275 memcpy (contents + roff - 3,
4276 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05"
4277 "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
4278 largepic = 1;
4280 else
4282 if (roff < 4
4283 || (roff - 4 + 16) > input_section->size)
4284 goto corrupt_input;
4285 memcpy (contents + roff - 4,
4286 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
4287 16);
4290 else
4292 if (roff < 3
4293 || (roff - 3 + 15) > input_section->size)
4294 goto corrupt_input;
4295 memcpy (contents + roff - 3,
4296 "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
4297 15);
4300 relocation = (htab->elf.sgot->output_section->vma
4301 + htab->elf.sgot->output_offset + off
4302 - roff
4303 - largepic
4304 - input_section->output_section->vma
4305 - input_section->output_offset
4306 - 12);
4307 bfd_put_32 (output_bfd, relocation,
4308 contents + roff + 8 + largepic);
4309 /* Skip R_X86_64_PLT32/R_X86_64_PLTOFF64. */
4310 rel++;
4311 wrel++;
4312 continue;
4314 else if (r_type == R_X86_64_GOTPC32_TLSDESC
4315 || r_type == R_X86_64_CODE_4_GOTPC32_TLSDESC)
4317 /* GDesc -> IE transition.
4318 It's originally something like:
4319 leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
4320 rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
4322 Change it to:
4323 # before xchg %ax,%ax in LP64 mode.
4324 movq x@gottpoff(%rip), %rax
4325 # before nopl (%rax) in X32 mode.
4326 rex movl x@gottpoff(%rip), %eax
4329 /* Now modify the instruction as appropriate. To
4330 turn a lea into a mov in the form we use it, it
4331 suffices to change the second byte from 0x8d to
4332 0x8b. */
4333 if (roff < 2)
4334 goto corrupt_input;
4335 bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
4337 bfd_put_32 (output_bfd,
4338 htab->elf.sgot->output_section->vma
4339 + htab->elf.sgot->output_offset + off
4340 - rel->r_offset
4341 - input_section->output_section->vma
4342 - input_section->output_offset
4343 - 4,
4344 contents + roff);
4345 continue;
4347 else if (r_type == R_X86_64_TLSDESC_CALL)
4349 /* GDesc -> IE transition.
4350 It's originally:
4351 call *(%rax) <--- LP64 mode.
4352 call *(%eax) <--- X32 mode.
4354 Change it to:
4355 xchg %ax, %ax <-- LP64 mode.
4356 nopl (%rax) <-- X32 mode.
4359 unsigned int prefix = 0;
4360 if (!ABI_64_P (input_bfd))
4362 /* Check for call *x@tlscall(%eax). */
4363 if (contents[roff] == 0x67)
4364 prefix = 1;
4366 if (prefix)
4368 bfd_put_8 (output_bfd, 0x0f, contents + roff);
4369 bfd_put_8 (output_bfd, 0x1f, contents + roff + 1);
4370 bfd_put_8 (output_bfd, 0x00, contents + roff + 2);
4372 else
4374 bfd_put_8 (output_bfd, 0x66, contents + roff);
4375 bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
4377 continue;
4379 else
4380 BFD_ASSERT (false);
4382 break;
4384 case R_X86_64_TLSLD:
4385 if (! elf_x86_64_tls_transition (info, input_bfd,
4386 input_section, contents,
4387 symtab_hdr, sym_hashes,
4388 &r_type, GOT_UNKNOWN, rel,
4389 relend, h, sym, true))
4390 return false;
4392 if (r_type != R_X86_64_TLSLD)
4394 /* LD->LE transition:
4395 leaq foo@tlsld(%rip), %rdi
4396 call __tls_get_addr@PLT
4397 For 64bit, we change it into:
4398 .word 0x6666; .byte 0x66; movq %fs:0, %rax
4399 For 32bit, we change it into:
4400 nopl 0x0(%rax); movl %fs:0, %eax
4402 leaq foo@tlsld(%rip), %rdi;
4403 call *__tls_get_addr@GOTPCREL(%rip)
4404 which may be converted to
4405 addr32 call __tls_get_addr
4406 For 64bit, we change it into:
4407 .word 0x6666; .word 0x6666; movq %fs:0, %rax
4408 For 32bit, we change it into:
4409 nopw 0x0(%rax); movl %fs:0, %eax
4410 For largepic, change:
4411 leaq foo@tlsgd(%rip), %rdi
4412 movabsq $__tls_get_addr@pltoff, %rax
4413 addq %rbx, %rax
4414 call *%rax
4415 into
4416 data16 data16 data16 nopw %cs:0x0(%rax,%rax,1)
4417 movq %fs:0, %eax */
4419 BFD_ASSERT (r_type == R_X86_64_TPOFF32);
4420 if (ABI_64_P (output_bfd))
4422 if ((rel->r_offset + 5) >= input_section->size)
4423 goto corrupt_input;
4424 if (contents[rel->r_offset + 5] == 0xb8)
4426 if (rel->r_offset < 3
4427 || (rel->r_offset - 3 + 22) > input_section->size)
4428 goto corrupt_input;
4429 memcpy (contents + rel->r_offset - 3,
4430 "\x66\x66\x66\x66\x2e\x0f\x1f\x84\0\0\0\0\0"
4431 "\x64\x48\x8b\x04\x25\0\0\0", 22);
4433 else if (contents[rel->r_offset + 4] == 0xff
4434 || contents[rel->r_offset + 4] == 0x67)
4436 if (rel->r_offset < 3
4437 || (rel->r_offset - 3 + 13) > input_section->size)
4438 goto corrupt_input;
4439 memcpy (contents + rel->r_offset - 3,
4440 "\x66\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0",
4441 13);
4444 else
4446 if (rel->r_offset < 3
4447 || (rel->r_offset - 3 + 12) > input_section->size)
4448 goto corrupt_input;
4449 memcpy (contents + rel->r_offset - 3,
4450 "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
4453 else
4455 if ((rel->r_offset + 4) >= input_section->size)
4456 goto corrupt_input;
4457 if (contents[rel->r_offset + 4] == 0xff)
4459 if (rel->r_offset < 3
4460 || (rel->r_offset - 3 + 13) > input_section->size)
4461 goto corrupt_input;
4462 memcpy (contents + rel->r_offset - 3,
4463 "\x66\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0",
4464 13);
4466 else
4468 if (rel->r_offset < 3
4469 || (rel->r_offset - 3 + 12) > input_section->size)
4470 goto corrupt_input;
4471 memcpy (contents + rel->r_offset - 3,
4472 "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
4475 /* Skip R_X86_64_PC32, R_X86_64_PLT32, R_X86_64_GOTPCRELX
4476 and R_X86_64_PLTOFF64. */
4477 rel++;
4478 wrel++;
4479 continue;
4482 if (htab->elf.sgot == NULL)
4483 abort ();
4485 off = htab->tls_ld_or_ldm_got.offset;
4486 if (off & 1)
4487 off &= ~1;
4488 else
4490 Elf_Internal_Rela outrel;
4492 if (htab->elf.srelgot == NULL)
4493 abort ();
4495 outrel.r_offset = (htab->elf.sgot->output_section->vma
4496 + htab->elf.sgot->output_offset + off);
4498 bfd_put_64 (output_bfd, 0,
4499 htab->elf.sgot->contents + off);
4500 bfd_put_64 (output_bfd, 0,
4501 htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
4502 outrel.r_info = htab->r_info (0, R_X86_64_DTPMOD64);
4503 outrel.r_addend = 0;
4504 elf_append_rela (output_bfd, htab->elf.srelgot,
4505 &outrel);
4506 htab->tls_ld_or_ldm_got.offset |= 1;
4508 relocation = htab->elf.sgot->output_section->vma
4509 + htab->elf.sgot->output_offset + off;
4510 unresolved_reloc = false;
4511 break;
4513 case R_X86_64_DTPOFF32:
4514 if (!bfd_link_executable (info)
4515 || (input_section->flags & SEC_CODE) == 0)
4516 relocation -= _bfd_x86_elf_dtpoff_base (info);
4517 else
4518 relocation = elf_x86_64_tpoff (info, relocation);
4519 break;
4521 case R_X86_64_TPOFF32:
4522 case R_X86_64_TPOFF64:
4523 BFD_ASSERT (bfd_link_executable (info));
4524 relocation = elf_x86_64_tpoff (info, relocation);
4525 break;
4527 case R_X86_64_DTPOFF64:
4528 BFD_ASSERT ((input_section->flags & SEC_CODE) == 0);
4529 relocation -= _bfd_x86_elf_dtpoff_base (info);
4530 break;
4532 default:
4533 break;
4536 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
4537 because such sections are not SEC_ALLOC and thus ld.so will
4538 not process them. */
4539 if (unresolved_reloc
4540 && !((input_section->flags & SEC_DEBUGGING) != 0
4541 && h->def_dynamic)
4542 && _bfd_elf_section_offset (output_bfd, info, input_section,
4543 rel->r_offset) != (bfd_vma) -1)
4545 switch (r_type)
4547 case R_X86_64_32S:
4548 sec = h->root.u.def.section;
4549 if ((info->nocopyreloc || eh->def_protected)
4550 && !(h->root.u.def.section->flags & SEC_CODE))
4551 return elf_x86_64_need_pic (info, input_bfd, input_section,
4552 h, NULL, NULL, howto);
4553 /* Fall through. */
4555 default:
4556 _bfd_error_handler
4557 /* xgettext:c-format */
4558 (_("%pB(%pA+%#" PRIx64 "): "
4559 "unresolvable %s relocation against symbol `%s'"),
4560 input_bfd,
4561 input_section,
4562 (uint64_t) rel->r_offset,
4563 howto->name,
4564 h->root.root.string);
4565 return false;
4569 do_relocation:
4570 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
4571 contents, rel->r_offset,
4572 relocation, rel->r_addend);
4574 check_relocation_error:
4575 if (r != bfd_reloc_ok)
4577 const char *name;
4579 if (h != NULL)
4580 name = h->root.root.string;
4581 else
4583 name = bfd_elf_string_from_elf_section (input_bfd,
4584 symtab_hdr->sh_link,
4585 sym->st_name);
4586 if (name == NULL)
4587 return false;
4588 if (*name == '\0')
4589 name = bfd_section_name (sec);
4592 if (r == bfd_reloc_overflow)
4594 if (converted_reloc)
4596 info->callbacks->einfo
4597 ("%X%H:", input_bfd, input_section, rel->r_offset);
4598 info->callbacks->einfo
4599 (_(" failed to convert GOTPCREL relocation against "
4600 "'%s'; relink with --no-relax\n"),
4601 name);
4602 status = false;
4603 continue;
4605 (*info->callbacks->reloc_overflow)
4606 (info, (h ? &h->root : NULL), name, howto->name,
4607 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
4609 else
4611 _bfd_error_handler
4612 /* xgettext:c-format */
4613 (_("%pB(%pA+%#" PRIx64 "): reloc against `%s': error %d"),
4614 input_bfd, input_section,
4615 (uint64_t) rel->r_offset, name, (int) r);
4616 return false;
4620 if (wrel != rel)
4621 *wrel = *rel;
4624 if (wrel != rel)
4626 Elf_Internal_Shdr *rel_hdr;
4627 size_t deleted = rel - wrel;
4629 rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section);
4630 rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
4631 if (rel_hdr->sh_size == 0)
4633 /* It is too late to remove an empty reloc section. Leave
4634 one NONE reloc.
4635 ??? What is wrong with an empty section??? */
4636 rel_hdr->sh_size = rel_hdr->sh_entsize;
4637 deleted -= 1;
4639 rel_hdr = _bfd_elf_single_rel_hdr (input_section);
4640 rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
4641 input_section->reloc_count -= deleted;
4644 return status;
4647 /* Finish up dynamic symbol handling. We set the contents of various
4648 dynamic sections here. */
4650 static bool
4651 elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
4652 struct bfd_link_info *info,
4653 struct elf_link_hash_entry *h,
4654 Elf_Internal_Sym *sym)
4656 struct elf_x86_link_hash_table *htab;
4657 bool use_plt_second;
4658 struct elf_x86_link_hash_entry *eh;
4659 bool local_undefweak;
4661 htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
4663 /* Use the second PLT section only if there is .plt section. */
4664 use_plt_second = htab->elf.splt != NULL && htab->plt_second != NULL;
4666 eh = (struct elf_x86_link_hash_entry *) h;
4667 if (eh->no_finish_dynamic_symbol)
4668 abort ();
4670 /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for
4671 resolved undefined weak symbols in executable so that their
4672 references have value 0 at run-time. */
4673 local_undefweak = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
4675 if (h->plt.offset != (bfd_vma) -1)
4677 bfd_vma plt_index;
4678 bfd_vma got_offset, plt_offset;
4679 Elf_Internal_Rela rela;
4680 bfd_byte *loc;
4681 asection *plt, *gotplt, *relplt, *resolved_plt;
4682 const struct elf_backend_data *bed;
4683 bfd_vma plt_got_pcrel_offset;
4685 /* When building a static executable, use .iplt, .igot.plt and
4686 .rela.iplt sections for STT_GNU_IFUNC symbols. */
4687 if (htab->elf.splt != NULL)
4689 plt = htab->elf.splt;
4690 gotplt = htab->elf.sgotplt;
4691 relplt = htab->elf.srelplt;
4693 else
4695 plt = htab->elf.iplt;
4696 gotplt = htab->elf.igotplt;
4697 relplt = htab->elf.irelplt;
4700 VERIFY_PLT_ENTRY (info, h, plt, gotplt, relplt, local_undefweak)
4702 /* Get the index in the procedure linkage table which
4703 corresponds to this symbol. This is the index of this symbol
4704 in all the symbols for which we are making plt entries. The
4705 first entry in the procedure linkage table is reserved.
4707 Get the offset into the .got table of the entry that
4708 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
4709 bytes. The first three are reserved for the dynamic linker.
4711 For static executables, we don't reserve anything. */
4713 if (plt == htab->elf.splt)
4715 got_offset = (h->plt.offset / htab->plt.plt_entry_size
4716 - htab->plt.has_plt0);
4717 got_offset = (got_offset + 3) * GOT_ENTRY_SIZE;
4719 else
4721 got_offset = h->plt.offset / htab->plt.plt_entry_size;
4722 got_offset = got_offset * GOT_ENTRY_SIZE;
4725 /* Fill in the entry in the procedure linkage table. */
4726 memcpy (plt->contents + h->plt.offset, htab->plt.plt_entry,
4727 htab->plt.plt_entry_size);
4728 if (use_plt_second)
4730 memcpy (htab->plt_second->contents + eh->plt_second.offset,
4731 htab->non_lazy_plt->plt_entry,
4732 htab->non_lazy_plt->plt_entry_size);
4734 resolved_plt = htab->plt_second;
4735 plt_offset = eh->plt_second.offset;
4737 else
4739 resolved_plt = plt;
4740 plt_offset = h->plt.offset;
4743 /* Insert the relocation positions of the plt section. */
4745 /* Put offset the PC-relative instruction referring to the GOT entry,
4746 subtracting the size of that instruction. */
4747 plt_got_pcrel_offset = (gotplt->output_section->vma
4748 + gotplt->output_offset
4749 + got_offset
4750 - resolved_plt->output_section->vma
4751 - resolved_plt->output_offset
4752 - plt_offset
4753 - htab->plt.plt_got_insn_size);
4755 /* Check PC-relative offset overflow in PLT entry. */
4756 if ((plt_got_pcrel_offset + 0x80000000) > 0xffffffff)
4757 /* xgettext:c-format */
4758 info->callbacks->einfo (_("%F%pB: PC-relative offset overflow in PLT entry for `%s'\n"),
4759 output_bfd, h->root.root.string);
4761 bfd_put_32 (output_bfd, plt_got_pcrel_offset,
4762 (resolved_plt->contents + plt_offset
4763 + htab->plt.plt_got_offset));
4765 /* Fill in the entry in the global offset table, initially this
4766 points to the second part of the PLT entry. Leave the entry
4767 as zero for undefined weak symbol in PIE. No PLT relocation
4768 against undefined weak symbol in PIE. */
4769 if (!local_undefweak)
4771 if (htab->plt.has_plt0)
4772 bfd_put_64 (output_bfd, (plt->output_section->vma
4773 + plt->output_offset
4774 + h->plt.offset
4775 + htab->lazy_plt->plt_lazy_offset),
4776 gotplt->contents + got_offset);
4778 /* Fill in the entry in the .rela.plt section. */
4779 rela.r_offset = (gotplt->output_section->vma
4780 + gotplt->output_offset
4781 + got_offset);
4782 if (PLT_LOCAL_IFUNC_P (info, h))
4784 info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
4785 h->root.root.string,
4786 h->root.u.def.section->owner);
4788 /* If an STT_GNU_IFUNC symbol is locally defined, generate
4789 R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT. */
4790 rela.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
4791 rela.r_addend = (h->root.u.def.value
4792 + h->root.u.def.section->output_section->vma
4793 + h->root.u.def.section->output_offset);
4795 if (htab->params->report_relative_reloc)
4796 _bfd_x86_elf_link_report_relative_reloc
4797 (info, relplt, h, sym, "R_X86_64_IRELATIVE", &rela);
4799 /* R_X86_64_IRELATIVE comes last. */
4800 plt_index = htab->next_irelative_index--;
4802 else
4804 rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT);
4805 if (htab->params->mark_plt)
4806 rela.r_addend = (resolved_plt->output_section->vma
4807 + plt_offset
4808 + htab->plt.plt_indirect_branch_offset);
4809 else
4810 rela.r_addend = 0;
4811 plt_index = htab->next_jump_slot_index++;
4814 /* Don't fill the second and third slots in PLT entry for
4815 static executables nor without PLT0. */
4816 if (plt == htab->elf.splt && htab->plt.has_plt0)
4818 bfd_vma plt0_offset
4819 = h->plt.offset + htab->lazy_plt->plt_plt_insn_end;
4821 /* Put relocation index. */
4822 bfd_put_32 (output_bfd, plt_index,
4823 (plt->contents + h->plt.offset
4824 + htab->lazy_plt->plt_reloc_offset));
4826 /* Put offset for jmp .PLT0 and check for overflow. We don't
4827 check relocation index for overflow since branch displacement
4828 will overflow first. */
4829 if (plt0_offset > 0x80000000)
4830 /* xgettext:c-format */
4831 info->callbacks->einfo (_("%F%pB: branch displacement overflow in PLT entry for `%s'\n"),
4832 output_bfd, h->root.root.string);
4833 bfd_put_32 (output_bfd, - plt0_offset,
4834 (plt->contents + h->plt.offset
4835 + htab->lazy_plt->plt_plt_offset));
4838 bed = get_elf_backend_data (output_bfd);
4839 loc = relplt->contents + plt_index * bed->s->sizeof_rela;
4840 bed->s->swap_reloca_out (output_bfd, &rela, loc);
4843 else if (eh->plt_got.offset != (bfd_vma) -1)
4845 bfd_vma got_offset, plt_offset;
4846 asection *plt, *got;
4847 bool got_after_plt;
4848 int32_t got_pcrel_offset;
4850 /* Set the entry in the GOT procedure linkage table. */
4851 plt = htab->plt_got;
4852 got = htab->elf.sgot;
4853 got_offset = h->got.offset;
4855 if (got_offset == (bfd_vma) -1
4856 || (h->type == STT_GNU_IFUNC && h->def_regular)
4857 || plt == NULL
4858 || got == NULL)
4859 abort ();
4861 /* Use the non-lazy PLT entry template for the GOT PLT since they
4862 are the identical. */
4863 /* Fill in the entry in the GOT procedure linkage table. */
4864 plt_offset = eh->plt_got.offset;
4865 memcpy (plt->contents + plt_offset,
4866 htab->non_lazy_plt->plt_entry,
4867 htab->non_lazy_plt->plt_entry_size);
4869 /* Put offset the PC-relative instruction referring to the GOT
4870 entry, subtracting the size of that instruction. */
4871 got_pcrel_offset = (got->output_section->vma
4872 + got->output_offset
4873 + got_offset
4874 - plt->output_section->vma
4875 - plt->output_offset
4876 - plt_offset
4877 - htab->non_lazy_plt->plt_got_insn_size);
4879 /* Check PC-relative offset overflow in GOT PLT entry. */
4880 got_after_plt = got->output_section->vma > plt->output_section->vma;
4881 if ((got_after_plt && got_pcrel_offset < 0)
4882 || (!got_after_plt && got_pcrel_offset > 0))
4883 /* xgettext:c-format */
4884 info->callbacks->einfo (_("%F%pB: PC-relative offset overflow in GOT PLT entry for `%s'\n"),
4885 output_bfd, h->root.root.string);
4887 bfd_put_32 (output_bfd, got_pcrel_offset,
4888 (plt->contents + plt_offset
4889 + htab->non_lazy_plt->plt_got_offset));
4892 if (!local_undefweak
4893 && !h->def_regular
4894 && (h->plt.offset != (bfd_vma) -1
4895 || eh->plt_got.offset != (bfd_vma) -1))
4897 /* Mark the symbol as undefined, rather than as defined in
4898 the .plt section. Leave the value if there were any
4899 relocations where pointer equality matters (this is a clue
4900 for the dynamic linker, to make function pointer
4901 comparisons work between an application and shared
4902 library), otherwise set it to zero. If a function is only
4903 called from a binary, there is no need to slow down
4904 shared libraries because of that. */
4905 sym->st_shndx = SHN_UNDEF;
4906 if (!h->pointer_equality_needed)
4907 sym->st_value = 0;
4910 _bfd_x86_elf_link_fixup_ifunc_symbol (info, htab, h, sym);
4912 /* Don't generate dynamic GOT relocation against undefined weak
4913 symbol in executable. */
4914 if (h->got.offset != (bfd_vma) -1
4915 && ! GOT_TLS_GD_ANY_P (elf_x86_hash_entry (h)->tls_type)
4916 && elf_x86_hash_entry (h)->tls_type != GOT_TLS_IE
4917 && !local_undefweak)
4919 Elf_Internal_Rela rela;
4920 asection *relgot = htab->elf.srelgot;
4921 const char *relative_reloc_name = NULL;
4922 bool generate_dynamic_reloc = true;
4924 /* This symbol has an entry in the global offset table. Set it
4925 up. */
4926 if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
4927 abort ();
4929 rela.r_offset = (htab->elf.sgot->output_section->vma
4930 + htab->elf.sgot->output_offset
4931 + (h->got.offset &~ (bfd_vma) 1));
4933 /* If this is a static link, or it is a -Bsymbolic link and the
4934 symbol is defined locally or was forced to be local because
4935 of a version file, we just want to emit a RELATIVE reloc.
4936 The entry in the global offset table will already have been
4937 initialized in the relocate_section function. */
4938 if (h->def_regular
4939 && h->type == STT_GNU_IFUNC)
4941 if (h->plt.offset == (bfd_vma) -1)
4943 /* STT_GNU_IFUNC is referenced without PLT. */
4944 if (htab->elf.splt == NULL)
4946 /* use .rel[a].iplt section to store .got relocations
4947 in static executable. */
4948 relgot = htab->elf.irelplt;
4950 if (SYMBOL_REFERENCES_LOCAL_P (info, h))
4952 info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
4953 h->root.root.string,
4954 h->root.u.def.section->owner);
4956 rela.r_info = htab->r_info (0,
4957 R_X86_64_IRELATIVE);
4958 rela.r_addend = (h->root.u.def.value
4959 + h->root.u.def.section->output_section->vma
4960 + h->root.u.def.section->output_offset);
4961 relative_reloc_name = "R_X86_64_IRELATIVE";
4963 else
4964 goto do_glob_dat;
4966 else if (bfd_link_pic (info))
4968 /* Generate R_X86_64_GLOB_DAT. */
4969 goto do_glob_dat;
4971 else
4973 asection *plt;
4974 bfd_vma plt_offset;
4976 if (!h->pointer_equality_needed)
4977 abort ();
4979 /* For non-shared object, we can't use .got.plt, which
4980 contains the real function addres if we need pointer
4981 equality. We load the GOT entry with the PLT entry. */
4982 if (htab->plt_second != NULL)
4984 plt = htab->plt_second;
4985 plt_offset = eh->plt_second.offset;
4987 else
4989 plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
4990 plt_offset = h->plt.offset;
4992 bfd_put_64 (output_bfd, (plt->output_section->vma
4993 + plt->output_offset
4994 + plt_offset),
4995 htab->elf.sgot->contents + h->got.offset);
4996 return true;
4999 else if (bfd_link_pic (info)
5000 && SYMBOL_REFERENCES_LOCAL_P (info, h))
5002 if (!SYMBOL_DEFINED_NON_SHARED_P (h))
5003 return false;
5004 BFD_ASSERT((h->got.offset & 1) != 0);
5005 if (info->enable_dt_relr)
5006 generate_dynamic_reloc = false;
5007 else
5009 rela.r_info = htab->r_info (0, R_X86_64_RELATIVE);
5010 rela.r_addend = (h->root.u.def.value
5011 + h->root.u.def.section->output_section->vma
5012 + h->root.u.def.section->output_offset);
5013 relative_reloc_name = "R_X86_64_RELATIVE";
5016 else
5018 BFD_ASSERT((h->got.offset & 1) == 0);
5019 do_glob_dat:
5020 bfd_put_64 (output_bfd, (bfd_vma) 0,
5021 htab->elf.sgot->contents + h->got.offset);
5022 rela.r_info = htab->r_info (h->dynindx, R_X86_64_GLOB_DAT);
5023 rela.r_addend = 0;
5026 if (generate_dynamic_reloc)
5028 if (relative_reloc_name != NULL
5029 && htab->params->report_relative_reloc)
5030 _bfd_x86_elf_link_report_relative_reloc
5031 (info, relgot, h, sym, relative_reloc_name, &rela);
5033 elf_append_rela (output_bfd, relgot, &rela);
5037 if (h->needs_copy)
5039 Elf_Internal_Rela rela;
5040 asection *s;
5042 /* This symbol needs a copy reloc. Set it up. */
5043 VERIFY_COPY_RELOC (h, htab)
5045 rela.r_offset = (h->root.u.def.value
5046 + h->root.u.def.section->output_section->vma
5047 + h->root.u.def.section->output_offset);
5048 rela.r_info = htab->r_info (h->dynindx, R_X86_64_COPY);
5049 rela.r_addend = 0;
5050 if (h->root.u.def.section == htab->elf.sdynrelro)
5051 s = htab->elf.sreldynrelro;
5052 else
5053 s = htab->elf.srelbss;
5054 elf_append_rela (output_bfd, s, &rela);
5057 return true;
5060 /* Finish up local dynamic symbol handling. We set the contents of
5061 various dynamic sections here. */
5063 static int
5064 elf_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
5066 struct elf_link_hash_entry *h
5067 = (struct elf_link_hash_entry *) *slot;
5068 struct bfd_link_info *info
5069 = (struct bfd_link_info *) inf;
5071 return elf_x86_64_finish_dynamic_symbol (info->output_bfd,
5072 info, h, NULL);
5075 /* Finish up undefined weak symbol handling in PIE. Fill its PLT entry
5076 here since undefined weak symbol may not be dynamic and may not be
5077 called for elf_x86_64_finish_dynamic_symbol. */
5079 static bool
5080 elf_x86_64_pie_finish_undefweak_symbol (struct bfd_hash_entry *bh,
5081 void *inf)
5083 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh;
5084 struct bfd_link_info *info = (struct bfd_link_info *) inf;
5086 if (h->root.type != bfd_link_hash_undefweak
5087 || h->dynindx != -1)
5088 return true;
5090 return elf_x86_64_finish_dynamic_symbol (info->output_bfd,
5091 info, h, NULL);
5094 /* Used to decide how to sort relocs in an optimal manner for the
5095 dynamic linker, before writing them out. */
5097 static enum elf_reloc_type_class
5098 elf_x86_64_reloc_type_class (const struct bfd_link_info *info,
5099 const asection *rel_sec ATTRIBUTE_UNUSED,
5100 const Elf_Internal_Rela *rela)
5102 bfd *abfd = info->output_bfd;
5103 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
5104 struct elf_x86_link_hash_table *htab
5105 = elf_x86_hash_table (info, X86_64_ELF_DATA);
5107 if (htab->elf.dynsym != NULL
5108 && htab->elf.dynsym->contents != NULL)
5110 /* Check relocation against STT_GNU_IFUNC symbol if there are
5111 dynamic symbols. */
5112 unsigned long r_symndx = htab->r_sym (rela->r_info);
5113 if (r_symndx != STN_UNDEF)
5115 Elf_Internal_Sym sym;
5116 if (!bed->s->swap_symbol_in (abfd,
5117 (htab->elf.dynsym->contents
5118 + r_symndx * bed->s->sizeof_sym),
5119 0, &sym))
5120 abort ();
5122 if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
5123 return reloc_class_ifunc;
5127 switch ((int) ELF32_R_TYPE (rela->r_info))
5129 case R_X86_64_IRELATIVE:
5130 return reloc_class_ifunc;
5131 case R_X86_64_RELATIVE:
5132 case R_X86_64_RELATIVE64:
5133 return reloc_class_relative;
5134 case R_X86_64_JUMP_SLOT:
5135 return reloc_class_plt;
5136 case R_X86_64_COPY:
5137 return reloc_class_copy;
5138 default:
5139 return reloc_class_normal;
5143 /* Finish up the dynamic sections. */
5145 static bool
5146 elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
5147 struct bfd_link_info *info)
5149 struct elf_x86_link_hash_table *htab;
5151 htab = _bfd_x86_elf_finish_dynamic_sections (output_bfd, info);
5152 if (htab == NULL)
5153 return false;
5155 if (! htab->elf.dynamic_sections_created)
5156 return true;
5158 if (htab->elf.splt && htab->elf.splt->size > 0)
5160 if (bfd_is_abs_section (htab->elf.splt->output_section))
5162 info->callbacks->einfo
5163 (_("%F%P: discarded output section: `%pA'\n"),
5164 htab->elf.splt);
5165 return false;
5168 elf_section_data (htab->elf.splt->output_section)
5169 ->this_hdr.sh_entsize = htab->plt.plt_entry_size;
5171 if (htab->plt.has_plt0)
5173 /* Fill in the special first entry in the procedure linkage
5174 table. */
5175 memcpy (htab->elf.splt->contents,
5176 htab->lazy_plt->plt0_entry,
5177 htab->lazy_plt->plt0_entry_size);
5178 /* Add offset for pushq GOT+8(%rip), since the instruction
5179 uses 6 bytes subtract this value. */
5180 bfd_put_32 (output_bfd,
5181 (htab->elf.sgotplt->output_section->vma
5182 + htab->elf.sgotplt->output_offset
5184 - htab->elf.splt->output_section->vma
5185 - htab->elf.splt->output_offset
5186 - 6),
5187 (htab->elf.splt->contents
5188 + htab->lazy_plt->plt0_got1_offset));
5189 /* Add offset for the PC-relative instruction accessing
5190 GOT+16, subtracting the offset to the end of that
5191 instruction. */
5192 bfd_put_32 (output_bfd,
5193 (htab->elf.sgotplt->output_section->vma
5194 + htab->elf.sgotplt->output_offset
5195 + 16
5196 - htab->elf.splt->output_section->vma
5197 - htab->elf.splt->output_offset
5198 - htab->lazy_plt->plt0_got2_insn_end),
5199 (htab->elf.splt->contents
5200 + htab->lazy_plt->plt0_got2_offset));
5203 if (htab->elf.tlsdesc_plt)
5205 bfd_put_64 (output_bfd, (bfd_vma) 0,
5206 htab->elf.sgot->contents + htab->elf.tlsdesc_got);
5208 memcpy (htab->elf.splt->contents + htab->elf.tlsdesc_plt,
5209 htab->lazy_plt->plt_tlsdesc_entry,
5210 htab->lazy_plt->plt_tlsdesc_entry_size);
5212 /* Add offset for pushq GOT+8(%rip), since ENDBR64 uses 4
5213 bytes and the instruction uses 6 bytes, subtract these
5214 values. */
5215 bfd_put_32 (output_bfd,
5216 (htab->elf.sgotplt->output_section->vma
5217 + htab->elf.sgotplt->output_offset
5219 - htab->elf.splt->output_section->vma
5220 - htab->elf.splt->output_offset
5221 - htab->elf.tlsdesc_plt
5222 - htab->lazy_plt->plt_tlsdesc_got1_insn_end),
5223 (htab->elf.splt->contents
5224 + htab->elf.tlsdesc_plt
5225 + htab->lazy_plt->plt_tlsdesc_got1_offset));
5226 /* Add offset for indirect branch via GOT+TDG, where TDG
5227 stands for htab->tlsdesc_got, subtracting the offset
5228 to the end of that instruction. */
5229 bfd_put_32 (output_bfd,
5230 (htab->elf.sgot->output_section->vma
5231 + htab->elf.sgot->output_offset
5232 + htab->elf.tlsdesc_got
5233 - htab->elf.splt->output_section->vma
5234 - htab->elf.splt->output_offset
5235 - htab->elf.tlsdesc_plt
5236 - htab->lazy_plt->plt_tlsdesc_got2_insn_end),
5237 (htab->elf.splt->contents
5238 + htab->elf.tlsdesc_plt
5239 + htab->lazy_plt->plt_tlsdesc_got2_offset));
5243 /* Fill PLT entries for undefined weak symbols in PIE. */
5244 if (bfd_link_pie (info))
5245 bfd_hash_traverse (&info->hash->table,
5246 elf_x86_64_pie_finish_undefweak_symbol,
5247 info);
5249 return true;
5252 /* Fill PLT/GOT entries and allocate dynamic relocations for local
5253 STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table.
5254 It has to be done before elf_link_sort_relocs is called so that
5255 dynamic relocations are properly sorted. */
5257 static bool
5258 elf_x86_64_output_arch_local_syms
5259 (bfd *output_bfd ATTRIBUTE_UNUSED,
5260 struct bfd_link_info *info,
5261 void *flaginfo ATTRIBUTE_UNUSED,
5262 int (*func) (void *, const char *,
5263 Elf_Internal_Sym *,
5264 asection *,
5265 struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
5267 struct elf_x86_link_hash_table *htab
5268 = elf_x86_hash_table (info, X86_64_ELF_DATA);
5269 if (htab == NULL)
5270 return false;
5272 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
5273 htab_traverse (htab->loc_hash_table,
5274 elf_x86_64_finish_local_dynamic_symbol,
5275 info);
5277 return true;
5280 /* Similar to _bfd_elf_get_synthetic_symtab. Support PLTs with all
5281 dynamic relocations. */
5283 static long
5284 elf_x86_64_get_synthetic_symtab (bfd *abfd,
5285 long symcount ATTRIBUTE_UNUSED,
5286 asymbol **syms ATTRIBUTE_UNUSED,
5287 long dynsymcount,
5288 asymbol **dynsyms,
5289 asymbol **ret)
5291 long count, i, n;
5292 int j;
5293 bfd_byte *plt_contents;
5294 long relsize;
5295 const struct elf_x86_lazy_plt_layout *lazy_plt;
5296 const struct elf_x86_non_lazy_plt_layout *non_lazy_plt;
5297 const struct elf_x86_lazy_plt_layout *lazy_bnd_plt;
5298 const struct elf_x86_non_lazy_plt_layout *non_lazy_bnd_plt;
5299 const struct elf_x86_lazy_plt_layout *lazy_bnd_ibt_plt;
5300 const struct elf_x86_non_lazy_plt_layout *non_lazy_bnd_ibt_plt;
5301 const struct elf_x86_lazy_plt_layout *lazy_ibt_plt;
5302 const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt;
5303 asection *plt;
5304 enum elf_x86_plt_type plt_type;
5305 struct elf_x86_plt plts[] =
5307 { ".plt", NULL, NULL, plt_unknown, 0, 0, 0, 0 },
5308 { ".plt.got", NULL, NULL, plt_non_lazy, 0, 0, 0, 0 },
5309 { ".plt.sec", NULL, NULL, plt_second, 0, 0, 0, 0 },
5310 { ".plt.bnd", NULL, NULL, plt_second, 0, 0, 0, 0 },
5311 { NULL, NULL, NULL, plt_non_lazy, 0, 0, 0, 0 }
5314 *ret = NULL;
5316 if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
5317 return 0;
5319 if (dynsymcount <= 0)
5320 return 0;
5322 relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
5323 if (relsize <= 0)
5324 return -1;
5326 lazy_plt = &elf_x86_64_lazy_plt;
5327 non_lazy_plt = &elf_x86_64_non_lazy_plt;
5328 lazy_ibt_plt = &elf_x86_64_lazy_ibt_plt;
5329 non_lazy_ibt_plt = &elf_x86_64_non_lazy_ibt_plt;
5330 if (ABI_64_P (abfd))
5332 lazy_bnd_ibt_plt = &elf_x86_64_lazy_bnd_ibt_plt;
5333 non_lazy_bnd_ibt_plt = &elf_x86_64_non_lazy_bnd_ibt_plt;
5334 lazy_bnd_plt = &elf_x86_64_lazy_bnd_plt;
5335 non_lazy_bnd_plt = &elf_x86_64_non_lazy_bnd_plt;
5337 else
5339 lazy_bnd_ibt_plt = NULL;
5340 non_lazy_bnd_ibt_plt = NULL;
5341 lazy_bnd_plt = NULL;
5342 non_lazy_bnd_plt = NULL;
5345 count = 0;
5346 for (j = 0; plts[j].name != NULL; j++)
5348 plt = bfd_get_section_by_name (abfd, plts[j].name);
5349 if (plt == NULL
5350 || plt->size == 0
5351 || (plt->flags & SEC_HAS_CONTENTS) == 0)
5352 continue;
5354 /* Get the PLT section contents. */
5355 if (!_bfd_elf_mmap_section_contents (abfd, plt, &plt_contents))
5356 break;
5358 /* Check what kind of PLT it is. */
5359 plt_type = plt_unknown;
5360 if (plts[j].type == plt_unknown
5361 && (plt->size >= (lazy_plt->plt_entry_size
5362 + lazy_plt->plt_entry_size)))
5364 /* Match lazy PLT first. Need to check the first two
5365 instructions. */
5366 if ((memcmp (plt_contents, lazy_plt->plt0_entry,
5367 lazy_plt->plt0_got1_offset) == 0)
5368 && (memcmp (plt_contents + 6, lazy_plt->plt0_entry + 6,
5369 2) == 0))
5371 if (memcmp (plt_contents + lazy_ibt_plt->plt_entry_size,
5372 lazy_ibt_plt->plt_entry,
5373 lazy_ibt_plt->plt_got_offset) == 0)
5375 /* The fist entry in the lazy IBT PLT is the same as
5376 the lazy PLT. */
5377 plt_type = plt_lazy | plt_second;
5378 lazy_plt = lazy_ibt_plt;
5380 else
5381 plt_type = plt_lazy;
5383 else if (lazy_bnd_plt != NULL
5384 && (memcmp (plt_contents, lazy_bnd_plt->plt0_entry,
5385 lazy_bnd_plt->plt0_got1_offset) == 0)
5386 && (memcmp (plt_contents + 6,
5387 lazy_bnd_plt->plt0_entry + 6, 3) == 0))
5389 plt_type = plt_lazy | plt_second;
5390 /* The fist entry in the lazy BND IBT PLT is the same as
5391 the lazy BND PLT. */
5392 if (memcmp (plt_contents
5393 + lazy_bnd_ibt_plt->plt_entry_size,
5394 lazy_bnd_ibt_plt->plt_entry,
5395 lazy_bnd_ibt_plt->plt_got_offset) == 0)
5396 lazy_plt = lazy_bnd_ibt_plt;
5397 else
5398 lazy_plt = lazy_bnd_plt;
5402 if (non_lazy_plt != NULL
5403 && (plt_type == plt_unknown || plt_type == plt_non_lazy)
5404 && plt->size >= non_lazy_plt->plt_entry_size)
5406 /* Match non-lazy PLT. */
5407 if (memcmp (plt_contents, non_lazy_plt->plt_entry,
5408 non_lazy_plt->plt_got_offset) == 0)
5409 plt_type = plt_non_lazy;
5412 if (plt_type == plt_unknown || plt_type == plt_second)
5414 if (plt->size >= non_lazy_ibt_plt->plt_entry_size
5415 && (memcmp (plt_contents,
5416 non_lazy_ibt_plt->plt_entry,
5417 non_lazy_ibt_plt->plt_got_offset) == 0))
5419 /* Match IBT PLT. */
5420 plt_type = plt_second;
5421 non_lazy_plt = non_lazy_ibt_plt;
5423 else if (non_lazy_bnd_plt != NULL)
5425 if (plt->size >= non_lazy_bnd_plt->plt_entry_size
5426 && (memcmp (plt_contents, non_lazy_bnd_plt->plt_entry,
5427 non_lazy_bnd_plt->plt_got_offset) == 0))
5429 /* Match BND PLT. */
5430 plt_type = plt_second;
5431 non_lazy_plt = non_lazy_bnd_plt;
5433 else if (plt->size >= non_lazy_bnd_ibt_plt->plt_entry_size
5434 && (memcmp (plt_contents,
5435 non_lazy_bnd_ibt_plt->plt_entry,
5436 non_lazy_bnd_ibt_plt->plt_got_offset)
5437 == 0))
5439 /* Match BND IBT PLT. */
5440 plt_type = plt_second;
5441 non_lazy_plt = non_lazy_bnd_ibt_plt;
5446 if (plt_type == plt_unknown)
5448 _bfd_elf_munmap_section_contents (plt, plt_contents);
5449 continue;
5452 plts[j].sec = plt;
5453 plts[j].type = plt_type;
5455 if ((plt_type & plt_lazy))
5457 plts[j].plt_got_offset = lazy_plt->plt_got_offset;
5458 plts[j].plt_got_insn_size = lazy_plt->plt_got_insn_size;
5459 plts[j].plt_entry_size = lazy_plt->plt_entry_size;
5460 /* Skip PLT0 in lazy PLT. */
5461 i = 1;
5463 else
5465 plts[j].plt_got_offset = non_lazy_plt->plt_got_offset;
5466 plts[j].plt_got_insn_size = non_lazy_plt->plt_got_insn_size;
5467 plts[j].plt_entry_size = non_lazy_plt->plt_entry_size;
5468 i = 0;
5471 /* Skip lazy PLT when the second PLT is used. */
5472 if (plt_type == (plt_lazy | plt_second))
5473 plts[j].count = 0;
5474 else
5476 n = plt->size / plts[j].plt_entry_size;
5477 plts[j].count = n;
5478 count += n - i;
5481 plts[j].contents = plt_contents;
5484 return _bfd_x86_elf_get_synthetic_symtab (abfd, count, relsize,
5485 (bfd_vma) 0, plts, dynsyms,
5486 ret);
5489 /* Handle an x86-64 specific section when reading an object file. This
5490 is called when elfcode.h finds a section with an unknown type. */
5492 static bool
5493 elf_x86_64_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
5494 const char *name, int shindex)
5496 if (hdr->sh_type != SHT_X86_64_UNWIND)
5497 return false;
5499 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
5500 return false;
5502 return true;
5505 /* Hook called by the linker routine which adds symbols from an object
5506 file. We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
5507 of .bss. */
5509 static bool
5510 elf_x86_64_add_symbol_hook (bfd *abfd,
5511 struct bfd_link_info *info ATTRIBUTE_UNUSED,
5512 Elf_Internal_Sym *sym,
5513 const char **namep ATTRIBUTE_UNUSED,
5514 flagword *flagsp ATTRIBUTE_UNUSED,
5515 asection **secp,
5516 bfd_vma *valp)
5518 asection *lcomm;
5520 switch (sym->st_shndx)
5522 case SHN_X86_64_LCOMMON:
5523 lcomm = bfd_get_section_by_name (abfd, "LARGE_COMMON");
5524 if (lcomm == NULL)
5526 lcomm = bfd_make_section_with_flags (abfd,
5527 "LARGE_COMMON",
5528 (SEC_ALLOC
5529 | SEC_IS_COMMON
5530 | SEC_LINKER_CREATED));
5531 if (lcomm == NULL)
5532 return false;
5533 elf_section_flags (lcomm) |= SHF_X86_64_LARGE;
5535 *secp = lcomm;
5536 *valp = sym->st_size;
5537 return true;
5540 return true;
5544 /* Given a BFD section, try to locate the corresponding ELF section
5545 index. */
5547 static bool
5548 elf_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
5549 asection *sec, int *index_return)
5551 if (sec == &_bfd_elf_large_com_section)
5553 *index_return = SHN_X86_64_LCOMMON;
5554 return true;
5556 return false;
5559 /* Process a symbol. */
5561 static void
5562 elf_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5563 asymbol *asym)
5565 elf_symbol_type *elfsym = (elf_symbol_type *) asym;
5567 switch (elfsym->internal_elf_sym.st_shndx)
5569 case SHN_X86_64_LCOMMON:
5570 asym->section = &_bfd_elf_large_com_section;
5571 asym->value = elfsym->internal_elf_sym.st_size;
5572 /* Common symbol doesn't set BSF_GLOBAL. */
5573 asym->flags &= ~BSF_GLOBAL;
5574 break;
5578 static bool
5579 elf_x86_64_common_definition (Elf_Internal_Sym *sym)
5581 return (sym->st_shndx == SHN_COMMON
5582 || sym->st_shndx == SHN_X86_64_LCOMMON);
5585 static unsigned int
5586 elf_x86_64_common_section_index (asection *sec)
5588 if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
5589 return SHN_COMMON;
5590 else
5591 return SHN_X86_64_LCOMMON;
5594 static asection *
5595 elf_x86_64_common_section (asection *sec)
5597 if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
5598 return bfd_com_section_ptr;
5599 else
5600 return &_bfd_elf_large_com_section;
5603 static bool
5604 elf_x86_64_merge_symbol (struct elf_link_hash_entry *h,
5605 const Elf_Internal_Sym *sym,
5606 asection **psec,
5607 bool newdef,
5608 bool olddef,
5609 bfd *oldbfd,
5610 const asection *oldsec)
5612 /* A normal common symbol and a large common symbol result in a
5613 normal common symbol. We turn the large common symbol into a
5614 normal one. */
5615 if (!olddef
5616 && h->root.type == bfd_link_hash_common
5617 && !newdef
5618 && bfd_is_com_section (*psec)
5619 && oldsec != *psec)
5621 if (sym->st_shndx == SHN_COMMON
5622 && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) != 0)
5624 h->root.u.c.p->section
5625 = bfd_make_section_old_way (oldbfd, "COMMON");
5626 h->root.u.c.p->section->flags = SEC_ALLOC;
5628 else if (sym->st_shndx == SHN_X86_64_LCOMMON
5629 && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) == 0)
5630 *psec = bfd_com_section_ptr;
5633 return true;
5636 static bool
5637 elf_x86_64_section_flags (const Elf_Internal_Shdr *hdr)
5639 if ((hdr->sh_flags & SHF_X86_64_LARGE) != 0)
5640 hdr->bfd_section->flags |= SEC_ELF_LARGE;
5642 return true;
5645 static bool
5646 elf_x86_64_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
5647 Elf_Internal_Shdr *hdr, asection *sec)
5649 if (sec->flags & SEC_ELF_LARGE)
5650 hdr->sh_flags |= SHF_X86_64_LARGE;
5652 return true;
5655 static bool
5656 elf_x86_64_copy_private_section_data (bfd *ibfd, asection *isec,
5657 bfd *obfd, asection *osec)
5659 if (!_bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec))
5660 return false;
5662 /* objcopy --set-section-flags without "large" drops SHF_X86_64_LARGE. */
5663 if (ibfd != obfd)
5664 elf_section_flags (osec) &= ~SHF_X86_64_LARGE;
5666 return true;
5669 static int
5670 elf_x86_64_additional_program_headers (bfd *abfd,
5671 struct bfd_link_info *info ATTRIBUTE_UNUSED)
5673 asection *s;
5674 int count = 0;
5676 /* Check to see if we need a large readonly segment. */
5677 s = bfd_get_section_by_name (abfd, ".lrodata");
5678 if (s && (s->flags & SEC_LOAD))
5679 count++;
5681 /* Check to see if we need a large data segment. Since .lbss sections
5682 is placed right after the .bss section, there should be no need for
5683 a large data segment just because of .lbss. */
5684 s = bfd_get_section_by_name (abfd, ".ldata");
5685 if (s && (s->flags & SEC_LOAD))
5686 count++;
5688 return count;
5691 /* Return TRUE iff relocations for INPUT are compatible with OUTPUT. */
5693 static bool
5694 elf_x86_64_relocs_compatible (const bfd_target *input,
5695 const bfd_target *output)
5697 return ((xvec_get_elf_backend_data (input)->s->elfclass
5698 == xvec_get_elf_backend_data (output)->s->elfclass)
5699 && _bfd_elf_relocs_compatible (input, output));
5702 /* Set up x86-64 GNU properties. Return the first relocatable ELF input
5703 with GNU properties if found. Otherwise, return NULL. */
5705 static bfd *
5706 elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
5708 struct elf_x86_init_table init_table;
5709 const struct elf_backend_data *bed;
5710 struct elf_x86_link_hash_table *htab;
5712 if ((int) R_X86_64_standard >= (int) R_X86_64_converted_reloc_bit
5713 || (int) R_X86_64_max <= (int) R_X86_64_converted_reloc_bit
5714 || ((int) (R_X86_64_GNU_VTINHERIT | R_X86_64_converted_reloc_bit)
5715 != (int) R_X86_64_GNU_VTINHERIT)
5716 || ((int) (R_X86_64_GNU_VTENTRY | R_X86_64_converted_reloc_bit)
5717 != (int) R_X86_64_GNU_VTENTRY))
5718 abort ();
5720 /* This is unused for x86-64. */
5721 init_table.plt0_pad_byte = 0x90;
5723 bed = get_elf_backend_data (info->output_bfd);
5724 htab = elf_x86_hash_table (info, bed->target_id);
5725 if (!htab)
5726 abort ();
5728 init_table.lazy_plt = &elf_x86_64_lazy_plt;
5729 init_table.non_lazy_plt = &elf_x86_64_non_lazy_plt;
5731 init_table.lazy_ibt_plt = &elf_x86_64_lazy_ibt_plt;
5732 init_table.non_lazy_ibt_plt = &elf_x86_64_non_lazy_ibt_plt;
5734 if (ABI_64_P (info->output_bfd))
5736 init_table.sframe_lazy_plt = &elf_x86_64_sframe_plt;
5737 init_table.sframe_non_lazy_plt = &elf_x86_64_sframe_non_lazy_plt;
5738 init_table.sframe_lazy_ibt_plt = &elf_x86_64_sframe_ibt_plt;
5739 init_table.sframe_non_lazy_ibt_plt = &elf_x86_64_sframe_non_lazy_ibt_plt;
5741 else
5743 /* SFrame is not supported for non AMD64. */
5744 init_table.sframe_lazy_plt = NULL;
5745 init_table.sframe_non_lazy_plt = NULL;
5748 if (ABI_64_P (info->output_bfd))
5750 init_table.r_info = elf64_r_info;
5751 init_table.r_sym = elf64_r_sym;
5753 else
5755 init_table.r_info = elf32_r_info;
5756 init_table.r_sym = elf32_r_sym;
5759 return _bfd_x86_elf_link_setup_gnu_properties (info, &init_table);
5762 static void
5763 elf_x86_64_add_glibc_version_dependency
5764 (struct elf_find_verdep_info *rinfo)
5766 unsigned int i = 0;
5767 const char *version[3] = { NULL, NULL, NULL };
5768 struct elf_x86_link_hash_table *htab;
5770 if (rinfo->info->enable_dt_relr)
5772 version[i] = "GLIBC_ABI_DT_RELR";
5773 i++;
5776 htab = elf_x86_hash_table (rinfo->info, X86_64_ELF_DATA);
5777 if (htab != NULL && htab->params->mark_plt)
5779 version[i] = "GLIBC_2.36";
5780 i++;
5783 if (i != 0)
5784 _bfd_elf_link_add_glibc_version_dependency (rinfo, version);
5787 static const struct bfd_elf_special_section
5788 elf_x86_64_special_sections[]=
5790 { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
5791 { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
5792 { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE},
5793 { STRING_COMMA_LEN (".lbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
5794 { STRING_COMMA_LEN (".ldata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
5795 { STRING_COMMA_LEN (".lrodata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
5796 { NULL, 0, 0, 0, 0 }
5799 #define TARGET_LITTLE_SYM x86_64_elf64_vec
5800 #define TARGET_LITTLE_NAME "elf64-x86-64"
5801 #define ELF_ARCH bfd_arch_i386
5802 #define ELF_TARGET_ID X86_64_ELF_DATA
5803 #define ELF_MACHINE_CODE EM_X86_64
5804 #define ELF_MAXPAGESIZE 0x1000
5805 #define ELF_COMMONPAGESIZE 0x1000
5807 #define elf_backend_can_gc_sections 1
5808 #define elf_backend_can_refcount 1
5809 #define elf_backend_want_got_plt 1
5810 #define elf_backend_plt_readonly 1
5811 #define elf_backend_want_plt_sym 0
5812 #define elf_backend_got_header_size (GOT_ENTRY_SIZE*3)
5813 #define elf_backend_rela_normal 1
5814 #define elf_backend_plt_alignment 4
5815 #define elf_backend_caches_rawsize 1
5816 #define elf_backend_dtrel_excludes_plt 1
5817 #define elf_backend_want_dynrelro 1
5819 #define elf_info_to_howto elf_x86_64_info_to_howto
5821 #define bfd_elf64_bfd_copy_private_section_data \
5822 elf_x86_64_copy_private_section_data
5823 #define bfd_elf64_bfd_reloc_type_lookup elf_x86_64_reloc_type_lookup
5824 #define bfd_elf64_bfd_reloc_name_lookup \
5825 elf_x86_64_reloc_name_lookup
5827 #define elf_backend_relocs_compatible elf_x86_64_relocs_compatible
5828 #define elf_backend_early_size_sections elf_x86_64_early_size_sections
5829 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
5830 #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections
5831 #define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol
5832 #define elf_backend_output_arch_local_syms elf_x86_64_output_arch_local_syms
5833 #define elf_backend_grok_prstatus elf_x86_64_grok_prstatus
5834 #define elf_backend_grok_psinfo elf_x86_64_grok_psinfo
5835 #ifdef CORE_HEADER
5836 #define elf_backend_write_core_note elf_x86_64_write_core_note
5837 #endif
5838 #define elf_backend_reloc_type_class elf_x86_64_reloc_type_class
5839 #define elf_backend_relocate_section elf_x86_64_relocate_section
5840 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
5841 #define elf_backend_object_p elf64_x86_64_elf_object_p
5842 #define bfd_elf64_get_synthetic_symtab elf_x86_64_get_synthetic_symtab
5844 #define elf_backend_section_from_shdr \
5845 elf_x86_64_section_from_shdr
5847 #define elf_backend_section_from_bfd_section \
5848 elf_x86_64_elf_section_from_bfd_section
5849 #define elf_backend_add_symbol_hook \
5850 elf_x86_64_add_symbol_hook
5851 #define elf_backend_symbol_processing \
5852 elf_x86_64_symbol_processing
5853 #define elf_backend_common_section_index \
5854 elf_x86_64_common_section_index
5855 #define elf_backend_common_section \
5856 elf_x86_64_common_section
5857 #define elf_backend_common_definition \
5858 elf_x86_64_common_definition
5859 #define elf_backend_merge_symbol \
5860 elf_x86_64_merge_symbol
5861 #define elf_backend_special_sections \
5862 elf_x86_64_special_sections
5863 #define elf_backend_section_flags elf_x86_64_section_flags
5864 #define elf_backend_fake_sections elf_x86_64_fake_sections
5865 #define elf_backend_additional_program_headers \
5866 elf_x86_64_additional_program_headers
5867 #define elf_backend_setup_gnu_properties \
5868 elf_x86_64_link_setup_gnu_properties
5869 #define elf_backend_hide_symbol \
5870 _bfd_x86_elf_hide_symbol
5871 #define elf_backend_add_glibc_version_dependency \
5872 elf_x86_64_add_glibc_version_dependency
5874 #undef elf64_bed
5875 #define elf64_bed elf64_x86_64_bed
5877 #include "elf64-target.h"
5879 /* CloudABI support. */
5881 #undef TARGET_LITTLE_SYM
5882 #define TARGET_LITTLE_SYM x86_64_elf64_cloudabi_vec
5883 #undef TARGET_LITTLE_NAME
5884 #define TARGET_LITTLE_NAME "elf64-x86-64-cloudabi"
5886 #undef ELF_OSABI
5887 #define ELF_OSABI ELFOSABI_CLOUDABI
5889 #undef elf64_bed
5890 #define elf64_bed elf64_x86_64_cloudabi_bed
5892 #include "elf64-target.h"
5894 /* FreeBSD support. */
5896 #undef TARGET_LITTLE_SYM
5897 #define TARGET_LITTLE_SYM x86_64_elf64_fbsd_vec
5898 #undef TARGET_LITTLE_NAME
5899 #define TARGET_LITTLE_NAME "elf64-x86-64-freebsd"
5901 #undef ELF_OSABI
5902 #define ELF_OSABI ELFOSABI_FREEBSD
5904 #undef elf64_bed
5905 #define elf64_bed elf64_x86_64_fbsd_bed
5907 #include "elf64-target.h"
5909 /* Solaris 2 support. */
5911 #undef TARGET_LITTLE_SYM
5912 #define TARGET_LITTLE_SYM x86_64_elf64_sol2_vec
5913 #undef TARGET_LITTLE_NAME
5914 #define TARGET_LITTLE_NAME "elf64-x86-64-sol2"
5916 #undef ELF_TARGET_OS
5917 #define ELF_TARGET_OS is_solaris
5919 /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
5920 objects won't be recognized. */
5921 #undef ELF_OSABI
5923 #undef elf64_bed
5924 #define elf64_bed elf64_x86_64_sol2_bed
5926 /* The 64-bit static TLS arena size is rounded to the nearest 16-byte
5927 boundary. */
5928 #undef elf_backend_static_tls_alignment
5929 #define elf_backend_static_tls_alignment 16
5931 /* The Solaris 2 ABI requires a plt symbol on all platforms.
5933 Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
5934 File, p.63. */
5935 #undef elf_backend_want_plt_sym
5936 #define elf_backend_want_plt_sym 1
5938 #undef elf_backend_strtab_flags
5939 #define elf_backend_strtab_flags SHF_STRINGS
5941 static bool
5942 elf64_x86_64_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
5943 bfd *obfd ATTRIBUTE_UNUSED,
5944 const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
5945 Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED)
5947 /* PR 19938: FIXME: Need to add code for setting the sh_info
5948 and sh_link fields of Solaris specific section types. */
5949 return false;
5952 #undef elf_backend_copy_special_section_fields
5953 #define elf_backend_copy_special_section_fields elf64_x86_64_copy_solaris_special_section_fields
5955 #include "elf64-target.h"
5957 /* Restore defaults. */
5958 #undef ELF_OSABI
5959 #undef elf_backend_static_tls_alignment
5960 #undef elf_backend_want_plt_sym
5961 #define elf_backend_want_plt_sym 0
5962 #undef elf_backend_strtab_flags
5963 #undef elf_backend_copy_special_section_fields
5965 /* 32bit x86-64 support. */
5967 #undef TARGET_LITTLE_SYM
5968 #define TARGET_LITTLE_SYM x86_64_elf32_vec
5969 #undef TARGET_LITTLE_NAME
5970 #define TARGET_LITTLE_NAME "elf32-x86-64"
5971 #undef elf32_bed
5972 #define elf32_bed elf32_x86_64_bed
5974 #undef ELF_ARCH
5975 #define ELF_ARCH bfd_arch_i386
5977 #undef ELF_MACHINE_CODE
5978 #define ELF_MACHINE_CODE EM_X86_64
5980 #undef ELF_TARGET_OS
5981 #undef ELF_OSABI
5983 #define bfd_elf32_bfd_copy_private_section_data \
5984 elf_x86_64_copy_private_section_data
5985 #define bfd_elf32_bfd_reloc_type_lookup \
5986 elf_x86_64_reloc_type_lookup
5987 #define bfd_elf32_bfd_reloc_name_lookup \
5988 elf_x86_64_reloc_name_lookup
5989 #define bfd_elf32_get_synthetic_symtab \
5990 elf_x86_64_get_synthetic_symtab
5992 #undef elf_backend_object_p
5993 #define elf_backend_object_p \
5994 elf32_x86_64_elf_object_p
5996 #undef elf_backend_bfd_from_remote_memory
5997 #define elf_backend_bfd_from_remote_memory \
5998 _bfd_elf32_bfd_from_remote_memory
6000 #undef elf_backend_size_info
6001 #define elf_backend_size_info \
6002 _bfd_elf32_size_info
6004 #include "elf32-target.h"