diff options
author | Harish Sadineni <Harish.Sadineni@windriver.com> | 2025-05-21 08:02:13 -0700 |
---|---|---|
committer | Steve Sakoman <steve@sakoman.com> | 2025-06-02 07:12:34 -0700 |
commit | 186e2b2b0540a091cdc3b0646eedafa8646c575a (patch) | |
tree | f59d3aba3e170d1818723714a13caa9b95010273 | |
parent | 53ab80ae8f0394f7a57ae144076ac0c1c97e9002 (diff) | |
download | poky-186e2b2b0540a091cdc3b0646eedafa8646c575a.tar.gz |
binutils: Fix CVE-2025-1179
CVE-2025-1179-pre.patch is dependency patch for CVE-2025-1179.patch
Upstream-Status: Submitted [https://sourceware.org/pipermail/binutils/2025-May/141322.html &&
https://sourceware.org/pipermail/binutils/2025-May/141321.html]
CVE: CVE-2025-1179
cherry picked from upstream commit:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=67e30b15212adc1502b898a1ca224fdf65dc110d
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1d68a49ac5d71b648304f69af978fce0f4413800
(From OE-Core rev: 8f54548f784ef60eaf7fb6b3f539d48b0f7192a3)
Signed-off-by: Harish Sadineni <Harish.Sadineni@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
3 files changed, 1357 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.42.inc b/meta/recipes-devtools/binutils/binutils-2.42.inc index bc826753cf..6d0390b5a9 100644 --- a/meta/recipes-devtools/binutils/binutils-2.42.inc +++ b/meta/recipes-devtools/binutils/binutils-2.42.inc | |||
@@ -48,5 +48,7 @@ SRC_URI = "\ | |||
48 | file://0019-CVE-2025-1153-1.patch \ | 48 | file://0019-CVE-2025-1153-1.patch \ |
49 | file://0020-CVE-2025-1153-2.patch \ | 49 | file://0020-CVE-2025-1153-2.patch \ |
50 | file://0021-CVE-2025-1153-3.patch \ | 50 | file://0021-CVE-2025-1153-3.patch \ |
51 | file://CVE-2025-1179-pre.patch \ | ||
52 | file://CVE-2025-1179.patch \ | ||
51 | " | 53 | " |
52 | S = "${WORKDIR}/git" | 54 | S = "${WORKDIR}/git" |
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2025-1179-pre.patch b/meta/recipes-devtools/binutils/binutils/CVE-2025-1179-pre.patch new file mode 100644 index 0000000000..b5bf27ec6d --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2025-1179-pre.patch | |||
@@ -0,0 +1,1086 @@ | |||
1 | From 1d68a49ac5d71b648304f69af978fce0f4413800 Mon Sep 17 00:00:00 2001 | ||
2 | From: "H.J. Lu" <hjl.tools@gmail.com> | ||
3 | Date: Tue, 23 Jul 2024 23:39:50 -0700 | ||
4 | Subject: [PATCH 1/2] x86: Improve TLS transition error check | ||
5 | |||
6 | Provide detailed TLS transition errors when unsupported instructions are | ||
7 | used. Treat R_X86_64_CODE_4_GOTTPOFF and R_X86_64_CODE_6_GOTTPOFF as | ||
8 | R_X86_64_GOTTPOFF when performing TLS transition. | ||
9 | |||
10 | bfd/ | ||
11 | |||
12 | PR ld/32017 | ||
13 | * elf32-i386.c (elf_i386_check_tls_transition): Return different | ||
14 | enums for different errors. | ||
15 | (elf_i386_tls_transition): Change argument from r_symndx to sym. | ||
16 | Call _bfd_x86_elf_link_report_tls_transition_error to report TLS | ||
17 | transition errors. | ||
18 | (elf_i386_scan_relocs): Pass isym instead of r_symndx to | ||
19 | elf_i386_tls_transition. | ||
20 | (elf_i386_relocate_section): Pass sym instead of r_symndx to | ||
21 | elf_i386_tls_transition. | ||
22 | * elf64-x86-64.c (elf_x86_64_check_tls_transition): Return | ||
23 | different enums for different errors. | ||
24 | (elf_x86_64_tls_transition): Change argument from r_symndx to sym. | ||
25 | Treat R_X86_64_CODE_4_GOTTPOFF and R_X86_64_CODE_6_GOTTPOFF as | ||
26 | R_X86_64_GOTTPOFF. Call | ||
27 | _bfd_x86_elf_link_report_tls_transition_error to report TLS | ||
28 | transition errors. | ||
29 | (elf_x86_64_scan_relocs): Pass isym instead of r_symndx to | ||
30 | elf_x86_64_tls_transition. | ||
31 | (elf_x86_64_relocate_section): Pass sym instead of r_symndx to | ||
32 | elf_x86_64_tls_transition. | ||
33 | * elfxx-x86.c (_bfd_x86_elf_link_report_tls_transition_error): New. | ||
34 | * elfxx-x86.h (elf_x86_tls_error_type): Likewise. | ||
35 | (_bfd_x86_elf_link_report_tls_transition_error): Likewise. | ||
36 | |||
37 | ld/ | ||
38 | |||
39 | PR ld/32017 | ||
40 | * testsuite/ld-i386/i386.exp: Run tlsgdesc1 and tlsgdesc2. | ||
41 | * testsuite/ld-i386/tlsie2.d: Updated. | ||
42 | * testsuite/ld-i386/tlsie3.d: Likewise. | ||
43 | * testsuite/ld-i386/tlsie4.d: Likewise. | ||
44 | * testsuite/ld-i386/tlsie5.d: Likewise. | ||
45 | * testsuite/ld-x86-64/tlsie2.d: Likewise. | ||
46 | * testsuite/ld-x86-64/tlsie3.d: Likewise. | ||
47 | * testsuite/ld-i386/tlsgdesc1.d: New file. | ||
48 | * testsuite/ld-i386/tlsgdesc1.s: Likewise. | ||
49 | * testsuite/ld-i386/tlsgdesc2.d: Likewise. | ||
50 | * testsuite/ld-i386/tlsgdesc2.s: Likewise. | ||
51 | * testsuite/ld-x86-64/tlsdesc3.d: Likewise. | ||
52 | * testsuite/ld-x86-64/tlsdesc3.s: Likewise. | ||
53 | * testsuite/ld-x86-64/tlsdesc4.d: Likewise. | ||
54 | * testsuite/ld-x86-64/tlsdesc4.s: Likewise. | ||
55 | * testsuite/ld-x86-64/tlsie5.d: Likewise. | ||
56 | * testsuite/ld-x86-64/tlsie5.s: Likewise. | ||
57 | * testsuite/ld-x86-64/x86-64.exp: Run tlsie5, tlsdesc3 and | ||
58 | tlsdesc4. | ||
59 | |||
60 | (cherry picked from commit:1d68a49ac5d71b648304f69af978fce0f4413800) | ||
61 | Upstream-Status: Submitted [https://sourceware.org/pipermail/binutils/2025-May/141322.html] | ||
62 | CVE: CVE-2025-1179 | ||
63 | |||
64 | Signed-off-by: Harish Sadineni <Harish.Sadineni@windriver.com> | ||
65 | --- | ||
66 | bfd/elf32-i386.c | 118 +++++++++++++------------- | ||
67 | bfd/elf64-x86-64.c | 133 ++++++++++++++++-------------- | ||
68 | bfd/elfxx-x86.c | 85 +++++++++++++++++++ | ||
69 | bfd/elfxx-x86.h | 18 ++++ | ||
70 | ld/testsuite/ld-i386/i386.exp | 2 + | ||
71 | ld/testsuite/ld-i386/tlsgdesc1.d | 4 + | ||
72 | ld/testsuite/ld-i386/tlsgdesc1.s | 11 +++ | ||
73 | ld/testsuite/ld-i386/tlsgdesc2.d | 4 + | ||
74 | ld/testsuite/ld-i386/tlsgdesc2.s | 11 +++ | ||
75 | ld/testsuite/ld-i386/tlsie2.d | 2 +- | ||
76 | ld/testsuite/ld-i386/tlsie3.d | 2 +- | ||
77 | ld/testsuite/ld-i386/tlsie4.d | 2 +- | ||
78 | ld/testsuite/ld-i386/tlsie5.d | 2 +- | ||
79 | ld/testsuite/ld-x86-64/tlsdesc3.d | 4 + | ||
80 | ld/testsuite/ld-x86-64/tlsdesc3.s | 13 +++ | ||
81 | ld/testsuite/ld-x86-64/tlsdesc4.d | 4 + | ||
82 | ld/testsuite/ld-x86-64/tlsdesc4.s | 13 +++ | ||
83 | ld/testsuite/ld-x86-64/tlsie2.d | 2 +- | ||
84 | ld/testsuite/ld-x86-64/tlsie3.d | 2 +- | ||
85 | ld/testsuite/ld-x86-64/tlsie5.d | 4 + | ||
86 | ld/testsuite/ld-x86-64/tlsie5.s | 12 +++ | ||
87 | ld/testsuite/ld-x86-64/x86-64.exp | 3 + | ||
88 | 22 files changed, 319 insertions(+), 132 deletions(-) | ||
89 | create mode 100644 ld/testsuite/ld-i386/tlsgdesc1.d | ||
90 | create mode 100644 ld/testsuite/ld-i386/tlsgdesc1.s | ||
91 | create mode 100644 ld/testsuite/ld-i386/tlsgdesc2.d | ||
92 | create mode 100644 ld/testsuite/ld-i386/tlsgdesc2.s | ||
93 | create mode 100644 ld/testsuite/ld-x86-64/tlsdesc3.d | ||
94 | create mode 100644 ld/testsuite/ld-x86-64/tlsdesc3.s | ||
95 | create mode 100644 ld/testsuite/ld-x86-64/tlsdesc4.d | ||
96 | create mode 100644 ld/testsuite/ld-x86-64/tlsdesc4.s | ||
97 | create mode 100644 ld/testsuite/ld-x86-64/tlsie5.d | ||
98 | create mode 100644 ld/testsuite/ld-x86-64/tlsie5.s | ||
99 | |||
100 | diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c | ||
101 | index e2f88a11487..18a28d2491c 100644 | ||
102 | --- a/bfd/elf32-i386.c | ||
103 | +++ b/bfd/elf32-i386.c | ||
104 | @@ -839,7 +839,7 @@ static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt = | ||
105 | /* Return TRUE if the TLS access code sequence support transition | ||
106 | from R_TYPE. */ | ||
107 | |||
108 | -static bool | ||
109 | +static enum elf_x86_tls_error_type | ||
110 | elf_i386_check_tls_transition (asection *sec, | ||
111 | bfd_byte *contents, | ||
112 | Elf_Internal_Shdr *symtab_hdr, | ||
113 | @@ -861,7 +861,7 @@ elf_i386_check_tls_transition (asection *sec, | ||
114 | case R_386_TLS_GD: | ||
115 | case R_386_TLS_LDM: | ||
116 | if (offset < 2 || (rel + 1) >= relend) | ||
117 | - return false; | ||
118 | + return elf_x86_tls_error_yes; | ||
119 | |||
120 | indirect_call = false; | ||
121 | call = contents + offset + 4; | ||
122 | @@ -884,19 +884,19 @@ elf_i386_check_tls_transition (asection *sec, | ||
123 | can transit to different access model. */ | ||
124 | if ((offset + 10) > sec->size | ||
125 | || (type != 0x8d && type != 0x04)) | ||
126 | - return false; | ||
127 | + return elf_x86_tls_error_yes; | ||
128 | |||
129 | if (type == 0x04) | ||
130 | { | ||
131 | /* leal foo@tlsgd(,%ebx,1), %eax | ||
132 | call ___tls_get_addr@PLT */ | ||
133 | if (offset < 3) | ||
134 | - return false; | ||
135 | + return elf_x86_tls_error_yes; | ||
136 | |||
137 | if (*(call - 7) != 0x8d | ||
138 | || val != 0x1d | ||
139 | || call[0] != 0xe8) | ||
140 | - return false; | ||
141 | + return elf_x86_tls_error_yes; | ||
142 | } | ||
143 | else | ||
144 | { | ||
145 | @@ -914,7 +914,7 @@ elf_i386_check_tls_transition (asection *sec, | ||
146 | is used to pass parameter to ___tls_get_addr. */ | ||
147 | reg = val & 7; | ||
148 | if ((val & 0xf8) != 0x80 || reg == 4 || reg == 0) | ||
149 | - return false; | ||
150 | + return elf_x86_tls_error_yes; | ||
151 | |||
152 | indirect_call = call[0] == 0xff; | ||
153 | if (!(reg == 3 && call[0] == 0xe8 && call[5] == 0x90) | ||
154 | @@ -922,7 +922,7 @@ elf_i386_check_tls_transition (asection *sec, | ||
155 | && !(indirect_call | ||
156 | && (call[1] & 0xf8) == 0x90 | ||
157 | && (call[1] & 0x7) == reg)) | ||
158 | - return false; | ||
159 | + return elf_x86_tls_error_yes; | ||
160 | } | ||
161 | } | ||
162 | else | ||
163 | @@ -937,13 +937,13 @@ elf_i386_check_tls_transition (asection *sec, | ||
164 | addr32 call ___tls_get_addr | ||
165 | can transit to different access model. */ | ||
166 | if (type != 0x8d || (offset + 9) > sec->size) | ||
167 | - return false; | ||
168 | + return elf_x86_tls_error_yes; | ||
169 | |||
170 | /* %eax can't be used as the GOT base register since it is | ||
171 | used to pass parameter to ___tls_get_addr. */ | ||
172 | reg = val & 7; | ||
173 | if ((val & 0xf8) != 0x80 || reg == 4 || reg == 0) | ||
174 | - return false; | ||
175 | + return elf_x86_tls_error_yes; | ||
176 | |||
177 | indirect_call = call[0] == 0xff; | ||
178 | if (!(reg == 3 && call[0] == 0xe8) | ||
179 | @@ -951,23 +951,27 @@ elf_i386_check_tls_transition (asection *sec, | ||
180 | && !(indirect_call | ||
181 | && (call[1] & 0xf8) == 0x90 | ||
182 | && (call[1] & 0x7) == reg)) | ||
183 | - return false; | ||
184 | + return elf_x86_tls_error_yes; | ||
185 | } | ||
186 | |||
187 | r_symndx = ELF32_R_SYM (rel[1].r_info); | ||
188 | if (r_symndx < symtab_hdr->sh_info) | ||
189 | - return false; | ||
190 | + return elf_x86_tls_error_yes; | ||
191 | |||
192 | h = sym_hashes[r_symndx - symtab_hdr->sh_info]; | ||
193 | if (h == NULL | ||
194 | || !((struct elf_x86_link_hash_entry *) h)->tls_get_addr) | ||
195 | - return false; | ||
196 | + return elf_x86_tls_error_yes; | ||
197 | else if (indirect_call) | ||
198 | - return (ELF32_R_TYPE (rel[1].r_info) == R_386_GOT32X | ||
199 | - || ELF32_R_TYPE (rel[1].r_info) == R_386_GOT32); | ||
200 | + return ((ELF32_R_TYPE (rel[1].r_info) == R_386_GOT32X | ||
201 | + || ELF32_R_TYPE (rel[1].r_info) == R_386_GOT32) | ||
202 | + ? elf_x86_tls_error_none | ||
203 | + : elf_x86_tls_error_yes); | ||
204 | else | ||
205 | - return (ELF32_R_TYPE (rel[1].r_info) == R_386_PC32 | ||
206 | - || ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32); | ||
207 | + return ((ELF32_R_TYPE (rel[1].r_info) == R_386_PC32 | ||
208 | + || ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32) | ||
209 | + ? elf_x86_tls_error_none | ||
210 | + : elf_x86_tls_error_yes); | ||
211 | |||
212 | case R_386_TLS_IE: | ||
213 | /* Check transition from IE access model: | ||
214 | @@ -977,20 +981,23 @@ elf_i386_check_tls_transition (asection *sec, | ||
215 | */ | ||
216 | |||
217 | if (offset < 1 || (offset + 4) > sec->size) | ||
218 | - return false; | ||
219 | + return elf_x86_tls_error_yes; | ||
220 | |||
221 | /* Check "movl foo@tpoff(%rip), %eax" first. */ | ||
222 | val = bfd_get_8 (abfd, contents + offset - 1); | ||
223 | if (val == 0xa1) | ||
224 | - return true; | ||
225 | + return elf_x86_tls_error_none; | ||
226 | |||
227 | if (offset < 2) | ||
228 | - return false; | ||
229 | + return elf_x86_tls_error_yes; | ||
230 | |||
231 | /* Check movl|addl foo@tpoff(%rip), %reg. */ | ||
232 | type = bfd_get_8 (abfd, contents + offset - 2); | ||
233 | - return ((type == 0x8b || type == 0x03) | ||
234 | - && (val & 0xc7) == 0x05); | ||
235 | + if (type != 0x8b && type != 0x03) | ||
236 | + return elf_x86_tls_error_add_mov; | ||
237 | + return ((val & 0xc7) == 0x05 | ||
238 | + ? elf_x86_tls_error_none | ||
239 | + : elf_x86_tls_error_yes); | ||
240 | |||
241 | case R_386_TLS_GOTIE: | ||
242 | case R_386_TLS_IE_32: | ||
243 | @@ -1001,14 +1008,16 @@ elf_i386_check_tls_transition (asection *sec, | ||
244 | */ | ||
245 | |||
246 | if (offset < 2 || (offset + 4) > sec->size) | ||
247 | - return false; | ||
248 | + return elf_x86_tls_error_yes; | ||
249 | |||
250 | val = bfd_get_8 (abfd, contents + offset - 1); | ||
251 | if ((val & 0xc0) != 0x80 || (val & 7) == 4) | ||
252 | - return false; | ||
253 | + return elf_x86_tls_error_yes; | ||
254 | |||
255 | type = bfd_get_8 (abfd, contents + offset - 2); | ||
256 | - return type == 0x8b || type == 0x2b || type == 0x03; | ||
257 | + return (type == 0x8b || type == 0x2b || type == 0x03 | ||
258 | + ? elf_x86_tls_error_none | ||
259 | + : elf_x86_tls_error_add_sub_mov); | ||
260 | |||
261 | case R_386_TLS_GOTDESC: | ||
262 | /* Check transition from GDesc access model: | ||
263 | @@ -1019,13 +1028,15 @@ elf_i386_check_tls_transition (asection *sec, | ||
264 | going to be eax. */ | ||
265 | |||
266 | if (offset < 2 || (offset + 4) > sec->size) | ||
267 | - return false; | ||
268 | + return elf_x86_tls_error_yes; | ||
269 | |||
270 | if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d) | ||
271 | - return false; | ||
272 | + return elf_x86_tls_error_lea; | ||
273 | |||
274 | val = bfd_get_8 (abfd, contents + offset - 1); | ||
275 | - return (val & 0xc7) == 0x83; | ||
276 | + return ((val & 0xc7) == 0x83 | ||
277 | + ? elf_x86_tls_error_none | ||
278 | + : elf_x86_tls_error_yes); | ||
279 | |||
280 | case R_386_TLS_DESC_CALL: | ||
281 | /* Check transition from GDesc access model: | ||
282 | @@ -1035,10 +1046,12 @@ elf_i386_check_tls_transition (asection *sec, | ||
283 | { | ||
284 | /* Make sure that it's a call *x@tlsdesc(%eax). */ | ||
285 | call = contents + offset; | ||
286 | - return call[0] == 0xff && call[1] == 0x10; | ||
287 | + return (call[0] == 0xff && call[1] == 0x10 | ||
288 | + ? elf_x86_tls_error_none | ||
289 | + : elf_x86_tls_error_indirect_call); | ||
290 | } | ||
291 | |||
292 | - return false; | ||
293 | + return elf_x86_tls_error_yes; | ||
294 | |||
295 | default: | ||
296 | abort (); | ||
297 | @@ -1057,7 +1070,7 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, | ||
298 | const Elf_Internal_Rela *rel, | ||
299 | const Elf_Internal_Rela *relend, | ||
300 | struct elf_link_hash_entry *h, | ||
301 | - unsigned long r_symndx, | ||
302 | + Elf_Internal_Sym *sym, | ||
303 | bool from_relocate_section) | ||
304 | { | ||
305 | unsigned int from_type = *r_type; | ||
306 | @@ -1142,43 +1155,24 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, | ||
307 | return true; | ||
308 | |||
309 | /* Check if the transition can be performed. */ | ||
310 | + enum elf_x86_tls_error_type tls_error; | ||
311 | if (check | ||
312 | - && ! elf_i386_check_tls_transition (sec, contents, | ||
313 | - symtab_hdr, sym_hashes, | ||
314 | - from_type, rel, relend)) | ||
315 | + && ((tls_error = elf_i386_check_tls_transition (sec, contents, | ||
316 | + symtab_hdr, | ||
317 | + sym_hashes, | ||
318 | + from_type, rel, | ||
319 | + relend)) | ||
320 | + != elf_x86_tls_error_none)) | ||
321 | { | ||
322 | reloc_howto_type *from, *to; | ||
323 | - const char *name; | ||
324 | |||
325 | from = elf_i386_rtype_to_howto (from_type); | ||
326 | to = elf_i386_rtype_to_howto (to_type); | ||
327 | |||
328 | - if (h) | ||
329 | - name = h->root.root.string; | ||
330 | - else | ||
331 | - { | ||
332 | - struct elf_x86_link_hash_table *htab; | ||
333 | - | ||
334 | - htab = elf_x86_hash_table (info, I386_ELF_DATA); | ||
335 | - if (htab == NULL) | ||
336 | - name = "*unknown*"; | ||
337 | - else | ||
338 | - { | ||
339 | - Elf_Internal_Sym *isym; | ||
340 | - | ||
341 | - isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, | ||
342 | - abfd, r_symndx); | ||
343 | - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); | ||
344 | - } | ||
345 | - } | ||
346 | + _bfd_x86_elf_link_report_tls_transition_error | ||
347 | + (info, abfd, sec, symtab_hdr, h, sym, rel, from->name, | ||
348 | + to->name, tls_error); | ||
349 | |||
350 | - _bfd_error_handler | ||
351 | - /* xgettext:c-format */ | ||
352 | - (_("%pB: TLS transition from %s to %s against `%s'" | ||
353 | - " at %#" PRIx64 " in section `%pA' failed"), | ||
354 | - abfd, from->name, to->name, name, | ||
355 | - (uint64_t) rel->r_offset, sec); | ||
356 | - bfd_set_error (bfd_error_bad_value); | ||
357 | return false; | ||
358 | } | ||
359 | |||
360 | @@ -1600,7 +1594,7 @@ elf_i386_scan_relocs (bfd *abfd, | ||
361 | if (! elf_i386_tls_transition (info, abfd, sec, contents, | ||
362 | symtab_hdr, sym_hashes, | ||
363 | &r_type, GOT_UNKNOWN, | ||
364 | - rel, rel_end, h, r_symndx, false)) | ||
365 | + rel, rel_end, h, isym, false)) | ||
366 | goto error_return; | ||
367 | |||
368 | /* Check if _GLOBAL_OFFSET_TABLE_ is referenced. */ | ||
369 | @@ -2875,7 +2869,7 @@ elf_i386_relocate_section (bfd *output_bfd, | ||
370 | input_section, contents, | ||
371 | symtab_hdr, sym_hashes, | ||
372 | &r_type_tls, tls_type, rel, | ||
373 | - relend, h, r_symndx, true)) | ||
374 | + relend, h, sym, true)) | ||
375 | return false; | ||
376 | |||
377 | expected_tls_le = htab->elf.target_os == is_solaris | ||
378 | @@ -3365,7 +3359,7 @@ elf_i386_relocate_section (bfd *output_bfd, | ||
379 | input_section, contents, | ||
380 | symtab_hdr, sym_hashes, | ||
381 | &r_type, GOT_UNKNOWN, rel, | ||
382 | - relend, h, r_symndx, true)) | ||
383 | + relend, h, sym, true)) | ||
384 | return false; | ||
385 | |||
386 | if (r_type != R_386_TLS_LDM) | ||
387 | diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c | ||
388 | index 2ed120af780..f116e423f61 100644 | ||
389 | --- a/bfd/elf64-x86-64.c | ||
390 | +++ b/bfd/elf64-x86-64.c | ||
391 | @@ -1120,7 +1120,7 @@ elf32_x86_64_elf_object_p (bfd *abfd) | ||
392 | /* Return TRUE if the TLS access code sequence support transition | ||
393 | from R_TYPE. */ | ||
394 | |||
395 | -static bool | ||
396 | +static enum elf_x86_tls_error_type | ||
397 | elf_x86_64_check_tls_transition (bfd *abfd, | ||
398 | struct bfd_link_info *info, | ||
399 | asection *sec, | ||
400 | @@ -1147,7 +1147,7 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
401 | case R_X86_64_TLSGD: | ||
402 | case R_X86_64_TLSLD: | ||
403 | if ((rel + 1) >= relend) | ||
404 | - return false; | ||
405 | + return elf_x86_tls_error_yes; | ||
406 | |||
407 | if (r_type == R_X86_64_TLSGD) | ||
408 | { | ||
409 | @@ -1184,7 +1184,7 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
410 | static const unsigned char leaq[] = { 0x66, 0x48, 0x8d, 0x3d }; | ||
411 | |||
412 | if ((offset + 12) > sec->size) | ||
413 | - return false; | ||
414 | + return elf_x86_tls_error_yes; | ||
415 | |||
416 | call = contents + offset + 4; | ||
417 | if (call[0] != 0x66 | ||
418 | @@ -1208,20 +1208,20 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
419 | || call[14] != 0xd0 | ||
420 | || !((call[10] == 0x48 && call[12] == 0xd8) | ||
421 | || (call[10] == 0x4c && call[12] == 0xf8))) | ||
422 | - return false; | ||
423 | + return elf_x86_tls_error_yes; | ||
424 | largepic = true; | ||
425 | } | ||
426 | else if (ABI_64_P (abfd)) | ||
427 | { | ||
428 | if (offset < 4 | ||
429 | || memcmp (contents + offset - 4, leaq, 4) != 0) | ||
430 | - return false; | ||
431 | + return elf_x86_tls_error_yes; | ||
432 | } | ||
433 | else | ||
434 | { | ||
435 | if (offset < 3 | ||
436 | || memcmp (contents + offset - 3, leaq + 1, 3) != 0) | ||
437 | - return false; | ||
438 | + return elf_x86_tls_error_yes; | ||
439 | } | ||
440 | indirect_call = call[2] == 0xff; | ||
441 | } | ||
442 | @@ -1250,10 +1250,10 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
443 | static const unsigned char lea[] = { 0x48, 0x8d, 0x3d }; | ||
444 | |||
445 | if (offset < 3 || (offset + 9) > sec->size) | ||
446 | - return false; | ||
447 | + return elf_x86_tls_error_yes; | ||
448 | |||
449 | if (memcmp (contents + offset - 3, lea, 3) != 0) | ||
450 | - return false; | ||
451 | + return elf_x86_tls_error_yes; | ||
452 | |||
453 | call = contents + offset + 4; | ||
454 | if (!(call[0] == 0xe8 | ||
455 | @@ -1268,7 +1268,7 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
456 | || call[14] != 0xd0 | ||
457 | || !((call[10] == 0x48 && call[12] == 0xd8) | ||
458 | || (call[10] == 0x4c && call[12] == 0xf8))) | ||
459 | - return false; | ||
460 | + return elf_x86_tls_error_yes; | ||
461 | largepic = true; | ||
462 | } | ||
463 | indirect_call = call[0] == 0xff; | ||
464 | @@ -1276,22 +1276,30 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
465 | |||
466 | r_symndx = htab->r_sym (rel[1].r_info); | ||
467 | if (r_symndx < symtab_hdr->sh_info) | ||
468 | - return false; | ||
469 | + return elf_x86_tls_error_yes; | ||
470 | |||
471 | h = sym_hashes[r_symndx - symtab_hdr->sh_info]; | ||
472 | if (h == NULL | ||
473 | || !((struct elf_x86_link_hash_entry *) h)->tls_get_addr) | ||
474 | - return false; | ||
475 | + return elf_x86_tls_error_yes; | ||
476 | else | ||
477 | { | ||
478 | r_type = (ELF32_R_TYPE (rel[1].r_info) | ||
479 | & ~R_X86_64_converted_reloc_bit); | ||
480 | if (largepic) | ||
481 | - return r_type == R_X86_64_PLTOFF64; | ||
482 | + return (r_type == R_X86_64_PLTOFF64 | ||
483 | + ? elf_x86_tls_error_none | ||
484 | + : elf_x86_tls_error_yes); | ||
485 | else if (indirect_call) | ||
486 | - return (r_type == R_X86_64_GOTPCRELX || r_type == R_X86_64_GOTPCREL); | ||
487 | + return ((r_type == R_X86_64_GOTPCRELX | ||
488 | + || r_type == R_X86_64_GOTPCREL) | ||
489 | + ? elf_x86_tls_error_none | ||
490 | + : elf_x86_tls_error_yes); | ||
491 | else | ||
492 | - return (r_type == R_X86_64_PC32 || r_type == R_X86_64_PLT32); | ||
493 | + return ((r_type == R_X86_64_PC32 | ||
494 | + || r_type == R_X86_64_PLT32) | ||
495 | + ? elf_x86_tls_error_none | ||
496 | + : elf_x86_tls_error_yes); | ||
497 | } | ||
498 | |||
499 | case R_X86_64_CODE_4_GOTTPOFF: | ||
500 | @@ -1303,7 +1311,7 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
501 | if (offset < 4 | ||
502 | || (offset + 4) > sec->size | ||
503 | || contents[offset - 4] != 0xd5) | ||
504 | - return false; | ||
505 | + return elf_x86_tls_error_yes; | ||
506 | |||
507 | goto check_gottpoff; | ||
508 | |||
509 | @@ -1315,14 +1323,16 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
510 | if (offset < 6 | ||
511 | || (offset + 4) > sec->size | ||
512 | || contents[offset - 6] != 0x62) | ||
513 | - return false; | ||
514 | + return elf_x86_tls_error_yes; | ||
515 | |||
516 | val = bfd_get_8 (abfd, contents + offset - 2); | ||
517 | if (val != 0x01 && val != 0x03) | ||
518 | - return false; | ||
519 | + return elf_x86_tls_error_add; | ||
520 | |||
521 | val = bfd_get_8 (abfd, contents + offset - 1); | ||
522 | - return (val & 0xc7) == 5; | ||
523 | + return ((val & 0xc7) == 5 | ||
524 | + ? elf_x86_tls_error_none | ||
525 | + : elf_x86_tls_error_yes); | ||
526 | |||
527 | case R_X86_64_GOTTPOFF: | ||
528 | /* Check transition from IE access model: | ||
529 | @@ -1338,25 +1348,27 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
530 | { | ||
531 | /* X32 may have 0x44 REX prefix or no REX prefix. */ | ||
532 | if (ABI_64_P (abfd)) | ||
533 | - return false; | ||
534 | + return elf_x86_tls_error_yes; | ||
535 | } | ||
536 | } | ||
537 | else | ||
538 | { | ||
539 | /* X32 may not have any REX prefix. */ | ||
540 | if (ABI_64_P (abfd)) | ||
541 | - return false; | ||
542 | + return elf_x86_tls_error_yes; | ||
543 | if (offset < 2 || (offset + 3) > sec->size) | ||
544 | - return false; | ||
545 | + return elf_x86_tls_error_yes; | ||
546 | } | ||
547 | |||
548 | check_gottpoff: | ||
549 | val = bfd_get_8 (abfd, contents + offset - 2); | ||
550 | if (val != 0x8b && val != 0x03) | ||
551 | - return false; | ||
552 | + return elf_x86_tls_error_add_mov; | ||
553 | |||
554 | val = bfd_get_8 (abfd, contents + offset - 1); | ||
555 | - return (val & 0xc7) == 5; | ||
556 | + return ((val & 0xc7) == 5 | ||
557 | + ? elf_x86_tls_error_none | ||
558 | + : elf_x86_tls_error_yes); | ||
559 | |||
560 | case R_X86_64_CODE_4_GOTPC32_TLSDESC: | ||
561 | /* Check transition from GDesc access model: | ||
562 | @@ -1366,7 +1378,7 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
563 | if (offset < 4 | ||
564 | || (offset + 4) > sec->size | ||
565 | || contents[offset - 4] != 0xd5) | ||
566 | - return false; | ||
567 | + return elf_x86_tls_error_yes; | ||
568 | |||
569 | goto check_tlsdesc; | ||
570 | |||
571 | @@ -1380,19 +1392,21 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
572 | going to be rax. */ | ||
573 | |||
574 | if (offset < 3 || (offset + 4) > sec->size) | ||
575 | - return false; | ||
576 | + return elf_x86_tls_error_yes; | ||
577 | |||
578 | val = bfd_get_8 (abfd, contents + offset - 3); | ||
579 | val &= 0xfb; | ||
580 | if (val != 0x48 && (ABI_64_P (abfd) || val != 0x40)) | ||
581 | - return false; | ||
582 | + return elf_x86_tls_error_yes; | ||
583 | |||
584 | check_tlsdesc: | ||
585 | if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d) | ||
586 | - return false; | ||
587 | + return elf_x86_tls_error_lea; | ||
588 | |||
589 | val = bfd_get_8 (abfd, contents + offset - 1); | ||
590 | - return (val & 0xc7) == 0x05; | ||
591 | + return ((val & 0xc7) == 0x05 | ||
592 | + ? elf_x86_tls_error_none | ||
593 | + : elf_x86_tls_error_yes); | ||
594 | |||
595 | case R_X86_64_TLSDESC_CALL: | ||
596 | /* Check transition from GDesc access model: | ||
597 | @@ -1411,14 +1425,16 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
598 | { | ||
599 | prefix = 1; | ||
600 | if (offset + 3 > sec->size) | ||
601 | - return false; | ||
602 | + return elf_x86_tls_error_yes; | ||
603 | } | ||
604 | } | ||
605 | /* Make sure that it's a call *x@tlsdesc(%rax). */ | ||
606 | - return call[prefix] == 0xff && call[1 + prefix] == 0x10; | ||
607 | + return (call[prefix] == 0xff && call[1 + prefix] == 0x10 | ||
608 | + ? elf_x86_tls_error_none | ||
609 | + : elf_x86_tls_error_indirect_call); | ||
610 | } | ||
611 | |||
612 | - return false; | ||
613 | + return elf_x86_tls_error_yes; | ||
614 | |||
615 | default: | ||
616 | abort (); | ||
617 | @@ -1437,7 +1453,7 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, | ||
618 | const Elf_Internal_Rela *rel, | ||
619 | const Elf_Internal_Rela *relend, | ||
620 | struct elf_link_hash_entry *h, | ||
621 | - unsigned long r_symndx, | ||
622 | + Elf_Internal_Sym *sym, | ||
623 | bool from_relocate_section) | ||
624 | { | ||
625 | unsigned int from_type = *r_type; | ||
626 | @@ -1488,7 +1504,12 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, | ||
627 | /* We checked the transition before when we were called from | ||
628 | elf_x86_64_scan_relocs. We only want to check the new | ||
629 | transition which hasn't been checked before. */ | ||
630 | - check = new_to_type != to_type && from_type == to_type; | ||
631 | + check = (new_to_type != to_type | ||
632 | + && (from_type == to_type | ||
633 | + || (from_type == R_X86_64_CODE_4_GOTTPOFF | ||
634 | + && to_type == R_X86_64_GOTTPOFF) | ||
635 | + || (from_type == R_X86_64_CODE_6_GOTTPOFF | ||
636 | + && to_type == R_X86_64_GOTTPOFF))); | ||
637 | to_type = new_to_type; | ||
638 | } | ||
639 | |||
640 | @@ -1512,13 +1533,18 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, | ||
641 | return true; | ||
642 | |||
643 | /* Check if the transition can be performed. */ | ||
644 | + enum elf_x86_tls_error_type tls_error; | ||
645 | if (check | ||
646 | - && ! elf_x86_64_check_tls_transition (abfd, info, sec, contents, | ||
647 | - symtab_hdr, sym_hashes, | ||
648 | - from_type, rel, relend)) | ||
649 | + && ((tls_error = elf_x86_64_check_tls_transition (abfd, info, sec, | ||
650 | + contents, | ||
651 | + symtab_hdr, | ||
652 | + sym_hashes, | ||
653 | + from_type, rel, | ||
654 | + relend)) | ||
655 | + != elf_x86_tls_error_none)) | ||
656 | + | ||
657 | { | ||
658 | reloc_howto_type *from, *to; | ||
659 | - const char *name; | ||
660 | |||
661 | from = elf_x86_64_rtype_to_howto (abfd, from_type); | ||
662 | to = elf_x86_64_rtype_to_howto (abfd, to_type); | ||
663 | @@ -1526,31 +1552,10 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, | ||
664 | if (from == NULL || to == NULL) | ||
665 | return false; | ||
666 | |||
667 | - if (h) | ||
668 | - name = h->root.root.string; | ||
669 | - else | ||
670 | - { | ||
671 | - struct elf_x86_link_hash_table *htab; | ||
672 | - | ||
673 | - htab = elf_x86_hash_table (info, X86_64_ELF_DATA); | ||
674 | - if (htab == NULL) | ||
675 | - name = "*unknown*"; | ||
676 | - else | ||
677 | - { | ||
678 | - Elf_Internal_Sym *isym; | ||
679 | + _bfd_x86_elf_link_report_tls_transition_error | ||
680 | + (info, abfd, sec, symtab_hdr, h, sym, rel, from->name, | ||
681 | + to->name, tls_error); | ||
682 | |||
683 | - isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, | ||
684 | - abfd, r_symndx); | ||
685 | - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); | ||
686 | - } | ||
687 | - } | ||
688 | - | ||
689 | - _bfd_error_handler | ||
690 | - /* xgettext:c-format */ | ||
691 | - (_("%pB: TLS transition from %s to %s against `%s' at %#" PRIx64 | ||
692 | - " in section `%pA' failed"), | ||
693 | - abfd, from->name, to->name, name, (uint64_t) rel->r_offset, sec); | ||
694 | - bfd_set_error (bfd_error_bad_value); | ||
695 | return false; | ||
696 | } | ||
697 | |||
698 | @@ -2198,7 +2203,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info, | ||
699 | if (! elf_x86_64_tls_transition (info, abfd, sec, contents, | ||
700 | symtab_hdr, sym_hashes, | ||
701 | &r_type, GOT_UNKNOWN, | ||
702 | - rel, rel_end, h, r_symndx, false)) | ||
703 | + rel, rel_end, h, isym, false)) | ||
704 | goto error_return; | ||
705 | |||
706 | /* Check if _GLOBAL_OFFSET_TABLE_ is referenced. */ | ||
707 | @@ -3648,7 +3653,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, | ||
708 | input_section, contents, | ||
709 | symtab_hdr, sym_hashes, | ||
710 | &r_type_tls, tls_type, rel, | ||
711 | - relend, h, r_symndx, true)) | ||
712 | + relend, h, sym, true)) | ||
713 | return false; | ||
714 | |||
715 | if (r_type_tls == R_X86_64_TPOFF32) | ||
716 | @@ -4308,7 +4313,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, | ||
717 | input_section, contents, | ||
718 | symtab_hdr, sym_hashes, | ||
719 | &r_type, GOT_UNKNOWN, rel, | ||
720 | - relend, h, r_symndx, true)) | ||
721 | + relend, h, sym, true)) | ||
722 | return false; | ||
723 | |||
724 | if (r_type != R_X86_64_TLSLD) | ||
725 | diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c | ||
726 | index 508fd771da3..b17dad759c8 100644 | ||
727 | --- a/bfd/elfxx-x86.c | ||
728 | +++ b/bfd/elfxx-x86.c | ||
729 | @@ -3202,6 +3202,91 @@ _bfd_x86_elf_link_report_relative_reloc | ||
730 | asect, abfd); | ||
731 | } | ||
732 | |||
733 | +/* Report TLS transition error. */ | ||
734 | + | ||
735 | +void | ||
736 | +_bfd_x86_elf_link_report_tls_transition_error | ||
737 | + (struct bfd_link_info *info, bfd *abfd, asection *asect, | ||
738 | + Elf_Internal_Shdr *symtab_hdr, struct elf_link_hash_entry *h, | ||
739 | + Elf_Internal_Sym *sym, const Elf_Internal_Rela *rel, | ||
740 | + const char *from_reloc_name, const char *to_reloc_name, | ||
741 | + enum elf_x86_tls_error_type tls_error) | ||
742 | +{ | ||
743 | + const char *name; | ||
744 | + | ||
745 | + if (h) | ||
746 | + name = h->root.root.string; | ||
747 | + else | ||
748 | + { | ||
749 | + const struct elf_backend_data *bed | ||
750 | + = get_elf_backend_data (abfd); | ||
751 | + struct elf_x86_link_hash_table *htab | ||
752 | + = elf_x86_hash_table (info, bed->target_id); | ||
753 | + if (htab == NULL) | ||
754 | + name = "*unknown*"; | ||
755 | + else | ||
756 | + name = bfd_elf_sym_name (abfd, symtab_hdr, sym, NULL); | ||
757 | + } | ||
758 | + | ||
759 | + switch (tls_error) | ||
760 | + { | ||
761 | + case elf_x86_tls_error_yes: | ||
762 | + info->callbacks->einfo | ||
763 | + /* xgettext:c-format */ | ||
764 | + (_("%pB: TLS transition from %s to %s against `%s' at 0x%v in " | ||
765 | + "section `%pA' failed"), | ||
766 | + abfd, from_reloc_name, to_reloc_name, name, rel->r_offset, | ||
767 | + asect); | ||
768 | + break; | ||
769 | + | ||
770 | + case elf_x86_tls_error_add: | ||
771 | + info->callbacks->einfo | ||
772 | + /* xgettext:c-format */ | ||
773 | + (_("%pB(%pA+0x%v): relocation %s against `%s' must be used " | ||
774 | + "in ADD only"), | ||
775 | + abfd, asect, rel->r_offset, from_reloc_name, name); | ||
776 | + break; | ||
777 | + | ||
778 | + case elf_x86_tls_error_add_mov: | ||
779 | + info->callbacks->einfo | ||
780 | + /* xgettext:c-format */ | ||
781 | + (_("%pB(%pA+0x%v): relocation %s against `%s' must be used " | ||
782 | + "in ADD or MOV only"), | ||
783 | + abfd, asect, rel->r_offset, from_reloc_name, name); | ||
784 | + break; | ||
785 | + | ||
786 | + case elf_x86_tls_error_add_sub_mov: | ||
787 | + info->callbacks->einfo | ||
788 | + /* xgettext:c-format */ | ||
789 | + (_("%pB(%pA+0x%v): relocation %s against `%s' must be used " | ||
790 | + "in ADD, SUB or MOV only"), | ||
791 | + abfd, asect, rel->r_offset, from_reloc_name, name); | ||
792 | + break; | ||
793 | + | ||
794 | + case elf_x86_tls_error_indirect_call: | ||
795 | + info->callbacks->einfo | ||
796 | + /* xgettext:c-format */ | ||
797 | + (_("%pB(%pA+0x%v): relocation %s against `%s' must be used " | ||
798 | + "in indirect CALL only"), | ||
799 | + abfd, asect, rel->r_offset, from_reloc_name, name); | ||
800 | + break; | ||
801 | + | ||
802 | + case elf_x86_tls_error_lea: | ||
803 | + info->callbacks->einfo | ||
804 | + /* xgettext:c-format */ | ||
805 | + (_("%pB(%pA+0x%v): relocation %s against `%s' must be used " | ||
806 | + "in LEA only"), | ||
807 | + abfd, asect, rel->r_offset, from_reloc_name, name); | ||
808 | + break; | ||
809 | + | ||
810 | + default: | ||
811 | + abort (); | ||
812 | + break; | ||
813 | + } | ||
814 | + | ||
815 | + bfd_set_error (bfd_error_bad_value); | ||
816 | +} | ||
817 | + | ||
818 | /* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ | ||
819 | |||
820 | bool | ||
821 | diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h | ||
822 | index 110bcb9ad71..02e2efa6c56 100644 | ||
823 | --- a/bfd/elfxx-x86.h | ||
824 | +++ b/bfd/elfxx-x86.h | ||
825 | @@ -767,6 +767,18 @@ struct elf_x86_plt | ||
826 | long count; | ||
827 | }; | ||
828 | |||
829 | +enum elf_x86_tls_error_type | ||
830 | +{ | ||
831 | + elf_x86_tls_error_none, | ||
832 | + elf_x86_tls_error_add, | ||
833 | + elf_x86_tls_error_add_mov, | ||
834 | + elf_x86_tls_error_add_sub_mov, | ||
835 | + elf_x86_tls_error_indirect_call, | ||
836 | + elf_x86_tls_error_lea, | ||
837 | + elf_x86_tls_error_yes | ||
838 | +}; | ||
839 | + | ||
840 | + | ||
841 | /* Set if a relocation is converted from a GOTPCREL relocation. */ | ||
842 | #define R_X86_64_converted_reloc_bit (1 << 7) | ||
843 | |||
844 | @@ -908,6 +920,12 @@ extern void _bfd_x86_elf_link_fixup_ifunc_symbol | ||
845 | extern void _bfd_x86_elf_link_report_relative_reloc | ||
846 | (struct bfd_link_info *, asection *, struct elf_link_hash_entry *, | ||
847 | Elf_Internal_Sym *, const char *, const void *); | ||
848 | +extern void _bfd_x86_elf_link_report_tls_transition_error | ||
849 | + (struct bfd_link_info *, bfd *, asection *, Elf_Internal_Shdr *, | ||
850 | + struct elf_link_hash_entry *, Elf_Internal_Sym *, | ||
851 | + const Elf_Internal_Rela *, const char *, const char *, | ||
852 | + enum elf_x86_tls_error_type); | ||
853 | + | ||
854 | |||
855 | #define bfd_elf64_mkobject \ | ||
856 | _bfd_x86_elf_mkobject | ||
857 | diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp | ||
858 | index 18d1c9198ca..a8db2c713f3 100644 | ||
859 | --- a/ld/testsuite/ld-i386/i386.exp | ||
860 | +++ b/ld/testsuite/ld-i386/i386.exp | ||
861 | @@ -541,6 +541,8 @@ run_dump_test "tlsdesc2" | ||
862 | run_dump_test "report-reloc-1" | ||
863 | run_dump_test "pr27998a" | ||
864 | run_dump_test "pr27998b" | ||
865 | +run_dump_test "tlsgdesc1" | ||
866 | +run_dump_test "tlsgdesc2" | ||
867 | |||
868 | proc undefined_weak {cflags ldflags} { | ||
869 | set testname "Undefined weak symbol" | ||
870 | diff --git a/ld/testsuite/ld-i386/tlsgdesc1.d b/ld/testsuite/ld-i386/tlsgdesc1.d | ||
871 | new file mode 100644 | ||
872 | index 00000000000..2a70e81c444 | ||
873 | --- /dev/null | ||
874 | +++ b/ld/testsuite/ld-i386/tlsgdesc1.d | ||
875 | @@ -0,0 +1,4 @@ | ||
876 | +#name: TLS GDesc->LE transition check (LEA) | ||
877 | +#as: --32 | ||
878 | +#ld: -melf_i386 | ||
879 | +#error: .*: relocation R_386_TLS_GOTDESC against `foo' must be used in LEA only | ||
880 | diff --git a/ld/testsuite/ld-i386/tlsgdesc1.s b/ld/testsuite/ld-i386/tlsgdesc1.s | ||
881 | new file mode 100644 | ||
882 | index 00000000000..c30f7523462 | ||
883 | --- /dev/null | ||
884 | +++ b/ld/testsuite/ld-i386/tlsgdesc1.s | ||
885 | @@ -0,0 +1,11 @@ | ||
886 | + .text | ||
887 | + .globl _start | ||
888 | +_start: | ||
889 | + movl foo@tlsdesc(%ebx), %eax | ||
890 | + call *foo@tlscall(%eax) | ||
891 | + .section .tdata,"awT",@progbits | ||
892 | + .align 4 | ||
893 | + .type foo, @object | ||
894 | + .size foo, 4 | ||
895 | +foo: | ||
896 | + .long 100 | ||
897 | diff --git a/ld/testsuite/ld-i386/tlsgdesc2.d b/ld/testsuite/ld-i386/tlsgdesc2.d | ||
898 | new file mode 100644 | ||
899 | index 00000000000..2e6a66d372c | ||
900 | --- /dev/null | ||
901 | +++ b/ld/testsuite/ld-i386/tlsgdesc2.d | ||
902 | @@ -0,0 +1,4 @@ | ||
903 | +#name: TLS GDesc->LE transition check (indirect CALL) | ||
904 | +#as: --32 | ||
905 | +#ld: -melf_i386 | ||
906 | +#error: .*: relocation R_386_TLS_DESC_CALL against `foo' must be used in indirect CALL only | ||
907 | diff --git a/ld/testsuite/ld-i386/tlsgdesc2.s b/ld/testsuite/ld-i386/tlsgdesc2.s | ||
908 | new file mode 100644 | ||
909 | index 00000000000..7d9d556e2ab | ||
910 | --- /dev/null | ||
911 | +++ b/ld/testsuite/ld-i386/tlsgdesc2.s | ||
912 | @@ -0,0 +1,11 @@ | ||
913 | + .text | ||
914 | + .globl _start | ||
915 | +_start: | ||
916 | + leal foo@tlsdesc(%ebx), %eax | ||
917 | + jmp *foo@tlscall(%eax) | ||
918 | + .section .tdata,"awT",@progbits | ||
919 | + .align 4 | ||
920 | + .type foo, @object | ||
921 | + .size foo, 4 | ||
922 | +foo: | ||
923 | + .long 100 | ||
924 | diff --git a/ld/testsuite/ld-i386/tlsie2.d b/ld/testsuite/ld-i386/tlsie2.d | ||
925 | index ebb85fde7e7..9f9e63029d6 100644 | ||
926 | --- a/ld/testsuite/ld-i386/tlsie2.d | ||
927 | +++ b/ld/testsuite/ld-i386/tlsie2.d | ||
928 | @@ -1,4 +1,4 @@ | ||
929 | #name: TLS IE->LE transition check (R_386_TLS_GOTIE with %eax) | ||
930 | #as: --32 | ||
931 | #ld: -melf_i386 | ||
932 | -#error: .*TLS transition from R_386_TLS_GOTIE to R_386_TLS_LE_32 against `foo'.*failed.* | ||
933 | +#error: .*: relocation R_386_TLS_GOTIE against `foo' must be used in ADD, SUB or MOV only | ||
934 | diff --git a/ld/testsuite/ld-i386/tlsie3.d b/ld/testsuite/ld-i386/tlsie3.d | ||
935 | index d993f303c25..506f1a02605 100644 | ||
936 | --- a/ld/testsuite/ld-i386/tlsie3.d | ||
937 | +++ b/ld/testsuite/ld-i386/tlsie3.d | ||
938 | @@ -1,4 +1,4 @@ | ||
939 | #name: TLS IE->LE transition check (R_386_TLS_GOTIE) | ||
940 | #as: --32 | ||
941 | #ld: -melf_i386 | ||
942 | -#error: .*TLS transition from R_386_TLS_GOTIE to R_386_TLS_LE_32 against `foo'.*failed.* | ||
943 | +#error: .*: relocation R_386_TLS_GOTIE against `foo' must be used in ADD, SUB or MOV only | ||
944 | diff --git a/ld/testsuite/ld-i386/tlsie4.d b/ld/testsuite/ld-i386/tlsie4.d | ||
945 | index 3ca8fddf5dd..a516d002660 100644 | ||
946 | --- a/ld/testsuite/ld-i386/tlsie4.d | ||
947 | +++ b/ld/testsuite/ld-i386/tlsie4.d | ||
948 | @@ -1,4 +1,4 @@ | ||
949 | #name: TLS IE->LE transition check (R_386_TLS_IE with %eax) | ||
950 | #as: --32 | ||
951 | #ld: -melf_i386 | ||
952 | -#error: .*TLS transition from R_386_TLS_IE to R_386_TLS_LE_32 against `foo'.*failed.* | ||
953 | +#error: .*: relocation R_386_TLS_IE against `foo' must be used in ADD or MOV only | ||
954 | diff --git a/ld/testsuite/ld-i386/tlsie5.d b/ld/testsuite/ld-i386/tlsie5.d | ||
955 | index 3febeb159a9..d3447182e19 100644 | ||
956 | --- a/ld/testsuite/ld-i386/tlsie5.d | ||
957 | +++ b/ld/testsuite/ld-i386/tlsie5.d | ||
958 | @@ -1,4 +1,4 @@ | ||
959 | #name: TLS IE->LE transition check (R_386_TLS_IE) | ||
960 | #as: --32 | ||
961 | #ld: -melf_i386 | ||
962 | -#error: .*TLS transition from R_386_TLS_IE to R_386_TLS_LE_32 against `foo'.*failed.* | ||
963 | +#error: .*: relocation R_386_TLS_IE against `foo' must be used in ADD or MOV only | ||
964 | diff --git a/ld/testsuite/ld-x86-64/tlsdesc3.d b/ld/testsuite/ld-x86-64/tlsdesc3.d | ||
965 | new file mode 100644 | ||
966 | index 00000000000..bbf22ebeafe | ||
967 | --- /dev/null | ||
968 | +++ b/ld/testsuite/ld-x86-64/tlsdesc3.d | ||
969 | @@ -0,0 +1,4 @@ | ||
970 | +#name: TLS GDesc->LE transition check (LEA) | ||
971 | +#as: --64 | ||
972 | +#ld: -melf_x86_64 | ||
973 | +#error: .*: relocation R_X86_64_GOTPC32_TLSDESC against `foo' must be used in LEA only | ||
974 | diff --git a/ld/testsuite/ld-x86-64/tlsdesc3.s b/ld/testsuite/ld-x86-64/tlsdesc3.s | ||
975 | new file mode 100644 | ||
976 | index 00000000000..45310654ffc | ||
977 | --- /dev/null | ||
978 | +++ b/ld/testsuite/ld-x86-64/tlsdesc3.s | ||
979 | @@ -0,0 +1,13 @@ | ||
980 | + .text | ||
981 | + .globl _start | ||
982 | + .type _start,@function | ||
983 | +_start: | ||
984 | + movq foo@tlsdesc(%rip), %rax | ||
985 | + call *foo@tlscall(%rax) | ||
986 | + .globl foo | ||
987 | + .section .tdata,"awT",@progbits | ||
988 | + .align 8 | ||
989 | + .type foo, @object | ||
990 | + .size foo, 8 | ||
991 | +foo: | ||
992 | + .quad 100 | ||
993 | diff --git a/ld/testsuite/ld-x86-64/tlsdesc4.d b/ld/testsuite/ld-x86-64/tlsdesc4.d | ||
994 | new file mode 100644 | ||
995 | index 00000000000..b50115c7178 | ||
996 | --- /dev/null | ||
997 | +++ b/ld/testsuite/ld-x86-64/tlsdesc4.d | ||
998 | @@ -0,0 +1,4 @@ | ||
999 | +#name: TLS GDesc->LE transition check (indirect CALL) | ||
1000 | +#as: --64 | ||
1001 | +#ld: -melf_x86_64 | ||
1002 | +#error: .*: relocation R_X86_64_TLSDESC_CALL against `foo' must be used in indirect CALL only | ||
1003 | diff --git a/ld/testsuite/ld-x86-64/tlsdesc4.s b/ld/testsuite/ld-x86-64/tlsdesc4.s | ||
1004 | new file mode 100644 | ||
1005 | index 00000000000..b3d6c12d4fc | ||
1006 | --- /dev/null | ||
1007 | +++ b/ld/testsuite/ld-x86-64/tlsdesc4.s | ||
1008 | @@ -0,0 +1,13 @@ | ||
1009 | + .text | ||
1010 | + .globl _start | ||
1011 | + .type _start,@function | ||
1012 | +_start: | ||
1013 | + leaq foo@tlsdesc(%rip), %rax | ||
1014 | + jmp *foo@tlscall(%rax) | ||
1015 | + .globl foo | ||
1016 | + .section .tdata,"awT",@progbits | ||
1017 | + .align 8 | ||
1018 | + .type foo, @object | ||
1019 | + .size foo, 8 | ||
1020 | +foo: | ||
1021 | + .quad 100 | ||
1022 | diff --git a/ld/testsuite/ld-x86-64/tlsie2.d b/ld/testsuite/ld-x86-64/tlsie2.d | ||
1023 | index 97dcc288a3d..bf8a8198b5b 100644 | ||
1024 | --- a/ld/testsuite/ld-x86-64/tlsie2.d | ||
1025 | +++ b/ld/testsuite/ld-x86-64/tlsie2.d | ||
1026 | @@ -1,4 +1,4 @@ | ||
1027 | #name: TLS IE->LE transition check | ||
1028 | #as: --64 | ||
1029 | #ld: -melf_x86_64 | ||
1030 | -#error: .*TLS transition from R_X86_64_GOTTPOFF to R_X86_64_TPOFF32 against `foo'.*failed.* | ||
1031 | +#error: .*: relocation R_X86_64_GOTTPOFF against `foo' must be used in ADD or MOV only | ||
1032 | diff --git a/ld/testsuite/ld-x86-64/tlsie3.d b/ld/testsuite/ld-x86-64/tlsie3.d | ||
1033 | index 8c982a69838..49d8464fbaf 100644 | ||
1034 | --- a/ld/testsuite/ld-x86-64/tlsie3.d | ||
1035 | +++ b/ld/testsuite/ld-x86-64/tlsie3.d | ||
1036 | @@ -1,4 +1,4 @@ | ||
1037 | #name: TLS IE->LE transition check (%r12) | ||
1038 | #as: --64 | ||
1039 | #ld: -melf_x86_64 | ||
1040 | -#error: .*TLS transition from R_X86_64_GOTTPOFF to R_X86_64_TPOFF32 against `foo'.*failed.* | ||
1041 | +#error: .*: relocation R_X86_64_GOTTPOFF against `foo' must be used in ADD or MOV only | ||
1042 | diff --git a/ld/testsuite/ld-x86-64/tlsie5.d b/ld/testsuite/ld-x86-64/tlsie5.d | ||
1043 | new file mode 100644 | ||
1044 | index 00000000000..29de1cebf8e | ||
1045 | --- /dev/null | ||
1046 | +++ b/ld/testsuite/ld-x86-64/tlsie5.d | ||
1047 | @@ -0,0 +1,4 @@ | ||
1048 | +#name: TLS IE->LE transition check (APX) | ||
1049 | +#as: --64 | ||
1050 | +#ld: -melf_x86_64 | ||
1051 | +#error: .*: relocation R_X86_64_CODE_6_GOTTPOFF against `foo' must be used in ADD only | ||
1052 | diff --git a/ld/testsuite/ld-x86-64/tlsie5.s b/ld/testsuite/ld-x86-64/tlsie5.s | ||
1053 | new file mode 100644 | ||
1054 | index 00000000000..c39e46fd97b | ||
1055 | --- /dev/null | ||
1056 | +++ b/ld/testsuite/ld-x86-64/tlsie5.s | ||
1057 | @@ -0,0 +1,12 @@ | ||
1058 | + .text | ||
1059 | + .globl _start | ||
1060 | +_start: | ||
1061 | + xorq %rax, foo@GOTTPOFF(%rip), %rax | ||
1062 | + movq (%rax), %rax | ||
1063 | + .globl foo | ||
1064 | + .section .tdata,"awT",@progbits | ||
1065 | + .align 4 | ||
1066 | + .type foo, @object | ||
1067 | + .size foo, 4 | ||
1068 | +foo: | ||
1069 | + .long 100 | ||
1070 | diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp | ||
1071 | index 2a40f0b095b..811813466f8 100644 | ||
1072 | --- a/ld/testsuite/ld-x86-64/x86-64.exp | ||
1073 | +++ b/ld/testsuite/ld-x86-64/x86-64.exp | ||
1074 | @@ -741,6 +741,9 @@ run_dump_test "pr27016b" | ||
1075 | run_dump_test "report-reloc-1" | ||
1076 | run_dump_test "report-reloc-1-x32" | ||
1077 | run_dump_test "pr29820" | ||
1078 | +run_dump_test "tlsie5" | ||
1079 | +run_dump_test "tlsdesc3" | ||
1080 | +run_dump_test "tlsdesc4" | ||
1081 | |||
1082 | proc undefined_weak {cflags ldflags} { | ||
1083 | set testname "Undefined weak symbol" | ||
1084 | -- | ||
1085 | 2.49.0 | ||
1086 | |||
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2025-1179.patch b/meta/recipes-devtools/binutils/binutils/CVE-2025-1179.patch new file mode 100644 index 0000000000..89312d8501 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2025-1179.patch | |||
@@ -0,0 +1,269 @@ | |||
1 | From 67e30b15212adc1502b898a1ca224fdf65dc110d Mon Sep 17 00:00:00 2001 | ||
2 | From: "H.J. Lu" <hjl.tools@gmail.com> | ||
3 | Date: Thu, 29 Aug 2024 08:47:00 -0700 | ||
4 | Subject: [PATCH] x86: Check invalid TLS descriptor call TLS descriptor | ||
5 | call, | ||
6 | |||
7 | call *x@tlsdesc(%rax) | ||
8 | |||
9 | or | ||
10 | |||
11 | call *x@tlsdesc(%eax) | ||
12 | |||
13 | calls _dl_tlsdesc_return which expects that RAX/EAX points to the TLS | ||
14 | descriptor. Update x86 linker to issue an error with or without TLS | ||
15 | transition. | ||
16 | |||
17 | bfd/ | ||
18 | |||
19 | PR ld/32123 | ||
20 | * elf32-i386.c (elf_i386_check_tls_transition): Move | ||
21 | R_386_TLS_DESC_CALL to ... | ||
22 | (elf_i386_tls_transition): Here. | ||
23 | * elf64-x86-64.c (elf_x86_64_check_tls_transition): Move. | ||
24 | R_X86_64_TLSDESC_CALL check to ... | ||
25 | (elf_x86_64_tls_transition): Here. | ||
26 | |||
27 | ld/ | ||
28 | |||
29 | PR ld/32123 | ||
30 | * testsuite/ld-i386/i386.exp: Run tlsgdesc3. | ||
31 | * testsuite/ld-i386/tlsgdesc3.d: New file. | ||
32 | * testsuite/ld-x86-64/tlsdesc5.d: Likewise. | ||
33 | * testsuite/ld-x86-64/x86-64.exp: Run tlsdesc5. | ||
34 | |||
35 | (cherry picked from commit:67e30b15212adc1502b898a1ca224fdf65dc110d) | ||
36 | Upstream-Status: Submitted [https://sourceware.org/pipermail/binutils/2025-May/141321.html] | ||
37 | CVE: CVE-2025-1179 | ||
38 | |||
39 | Signed-off-by: Harish Sadineni <Harish.Sadineni@windriver.com> | ||
40 | --- | ||
41 | bfd/elf32-i386.c | 44 +++++++++++++------ | ||
42 | bfd/elf64-x86-64.c | 71 +++++++++++++++++++------------ | ||
43 | ld/testsuite/ld-i386/i386.exp | 1 + | ||
44 | ld/testsuite/ld-i386/tlsgdesc3.d | 5 +++ | ||
45 | ld/testsuite/ld-x86-64/tlsdesc5.d | 5 +++ | ||
46 | ld/testsuite/ld-x86-64/x86-64.exp | 1 + | ||
47 | 6 files changed, 86 insertions(+), 41 deletions(-) | ||
48 | create mode 100644 ld/testsuite/ld-i386/tlsgdesc3.d | ||
49 | create mode 100644 ld/testsuite/ld-x86-64/tlsdesc5.d | ||
50 | |||
51 | diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c | ||
52 | index 18a28d2491c..9dea465f721 100644 | ||
53 | --- a/bfd/elf32-i386.c | ||
54 | +++ b/bfd/elf32-i386.c | ||
55 | @@ -1039,19 +1039,8 @@ elf_i386_check_tls_transition (asection *sec, | ||
56 | : elf_x86_tls_error_yes); | ||
57 | |||
58 | case R_386_TLS_DESC_CALL: | ||
59 | - /* Check transition from GDesc access model: | ||
60 | - call *x@tlsdesc(%eax) | ||
61 | - */ | ||
62 | - if (offset + 2 <= sec->size) | ||
63 | - { | ||
64 | - /* Make sure that it's a call *x@tlsdesc(%eax). */ | ||
65 | - call = contents + offset; | ||
66 | - return (call[0] == 0xff && call[1] == 0x10 | ||
67 | - ? elf_x86_tls_error_none | ||
68 | - : elf_x86_tls_error_indirect_call); | ||
69 | - } | ||
70 | - | ||
71 | - return elf_x86_tls_error_yes; | ||
72 | + /* It has been checked in elf_i386_tls_transition. */ | ||
73 | + return elf_x86_tls_error_none; | ||
74 | |||
75 | default: | ||
76 | abort (); | ||
77 | @@ -1077,6 +1066,8 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, | ||
78 | unsigned int to_type = from_type; | ||
79 | bool check = true; | ||
80 | unsigned int to_le_type, to_ie_type; | ||
81 | + bfd_vma offset; | ||
82 | + bfd_byte *call; | ||
83 | |||
84 | /* Skip TLS transition for functions. */ | ||
85 | if (h != NULL | ||
86 | @@ -1098,9 +1089,34 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, | ||
87 | |||
88 | switch (from_type) | ||
89 | { | ||
90 | + case R_386_TLS_DESC_CALL: | ||
91 | + /* Check valid GDesc call: | ||
92 | + call *x@tlsdesc(%eax) | ||
93 | + */ | ||
94 | + offset = rel->r_offset; | ||
95 | + call = NULL; | ||
96 | + if (offset + 2 <= sec->size) | ||
97 | + { | ||
98 | + /* Make sure that it's a call *x@tlsdesc(%eax). */ | ||
99 | + call = contents + offset; | ||
100 | + if (call[0] != 0xff || call[1] != 0x10) | ||
101 | + call = NULL; | ||
102 | + } | ||
103 | + | ||
104 | + if (call == NULL) | ||
105 | + { | ||
106 | + _bfd_x86_elf_link_report_tls_transition_error | ||
107 | + (info, abfd, sec, symtab_hdr, h, sym, rel, | ||
108 | + "R_386_TLS_DESC_CALL", NULL, | ||
109 | + elf_x86_tls_error_indirect_call); | ||
110 | + | ||
111 | + return false; | ||
112 | + } | ||
113 | + | ||
114 | + /* Fall through. */ | ||
115 | + | ||
116 | case R_386_TLS_GD: | ||
117 | case R_386_TLS_GOTDESC: | ||
118 | - case R_386_TLS_DESC_CALL: | ||
119 | case R_386_TLS_IE_32: | ||
120 | case R_386_TLS_IE: | ||
121 | case R_386_TLS_GOTIE: | ||
122 | diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c | ||
123 | index f116e423f61..7af2e607b02 100644 | ||
124 | --- a/bfd/elf64-x86-64.c | ||
125 | +++ b/bfd/elf64-x86-64.c | ||
126 | @@ -1409,32 +1409,8 @@ elf_x86_64_check_tls_transition (bfd *abfd, | ||
127 | : elf_x86_tls_error_yes); | ||
128 | |||
129 | case R_X86_64_TLSDESC_CALL: | ||
130 | - /* Check transition from GDesc access model: | ||
131 | - call *x@tlsdesc(%rax) <--- LP64 mode. | ||
132 | - call *x@tlsdesc(%eax) <--- X32 mode. | ||
133 | - */ | ||
134 | - if (offset + 2 <= sec->size) | ||
135 | - { | ||
136 | - unsigned int prefix; | ||
137 | - call = contents + offset; | ||
138 | - prefix = 0; | ||
139 | - if (!ABI_64_P (abfd)) | ||
140 | - { | ||
141 | - /* Check for call *x@tlsdesc(%eax). */ | ||
142 | - if (call[0] == 0x67) | ||
143 | - { | ||
144 | - prefix = 1; | ||
145 | - if (offset + 3 > sec->size) | ||
146 | - return elf_x86_tls_error_yes; | ||
147 | - } | ||
148 | - } | ||
149 | - /* Make sure that it's a call *x@tlsdesc(%rax). */ | ||
150 | - return (call[prefix] == 0xff && call[1 + prefix] == 0x10 | ||
151 | - ? elf_x86_tls_error_none | ||
152 | - : elf_x86_tls_error_indirect_call); | ||
153 | - } | ||
154 | - | ||
155 | - return elf_x86_tls_error_yes; | ||
156 | + /* It has been checked in elf_x86_64_tls_transition. */ | ||
157 | + return elf_x86_tls_error_none; | ||
158 | |||
159 | default: | ||
160 | abort (); | ||
161 | @@ -1459,6 +1435,8 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, | ||
162 | unsigned int from_type = *r_type; | ||
163 | unsigned int to_type = from_type; | ||
164 | bool check = true; | ||
165 | + bfd_vma offset; | ||
166 | + bfd_byte *call; | ||
167 | |||
168 | /* Skip TLS transition for functions. */ | ||
169 | if (h != NULL | ||
170 | @@ -1468,10 +1446,49 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, | ||
171 | |||
172 | switch (from_type) | ||
173 | { | ||
174 | + case R_X86_64_TLSDESC_CALL: | ||
175 | + /* Check valid GDesc call: | ||
176 | + call *x@tlsdesc(%rax) <--- LP64 mode. | ||
177 | + call *x@tlsdesc(%eax) <--- X32 mode. | ||
178 | + */ | ||
179 | + offset = rel->r_offset; | ||
180 | + call = NULL; | ||
181 | + if (offset + 2 <= sec->size) | ||
182 | + { | ||
183 | + unsigned int prefix; | ||
184 | + call = contents + offset; | ||
185 | + prefix = 0; | ||
186 | + if (!ABI_64_P (abfd)) | ||
187 | + { | ||
188 | + /* Check for call *x@tlsdesc(%eax). */ | ||
189 | + if (call[0] == 0x67) | ||
190 | + { | ||
191 | + prefix = 1; | ||
192 | + if (offset + 3 > sec->size) | ||
193 | + call = NULL; | ||
194 | + } | ||
195 | + } | ||
196 | + | ||
197 | + /* Make sure that it's a call *x@tlsdesc(%rax). */ | ||
198 | + if (call != NULL | ||
199 | + && (call[prefix] != 0xff || call[1 + prefix] != 0x10)) | ||
200 | + call = NULL; | ||
201 | + } | ||
202 | + | ||
203 | + if (call == NULL) | ||
204 | + { | ||
205 | + _bfd_x86_elf_link_report_tls_transition_error | ||
206 | + (info, abfd, sec, symtab_hdr, h, sym, rel, | ||
207 | + "R_X86_64_TLSDESC_CALL", NULL, | ||
208 | + elf_x86_tls_error_indirect_call); | ||
209 | + return false; | ||
210 | + } | ||
211 | + | ||
212 | + /* Fall through. */ | ||
213 | + | ||
214 | case R_X86_64_TLSGD: | ||
215 | case R_X86_64_GOTPC32_TLSDESC: | ||
216 | case R_X86_64_CODE_4_GOTPC32_TLSDESC: | ||
217 | - case R_X86_64_TLSDESC_CALL: | ||
218 | case R_X86_64_GOTTPOFF: | ||
219 | case R_X86_64_CODE_4_GOTTPOFF: | ||
220 | case R_X86_64_CODE_6_GOTTPOFF: | ||
221 | diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp | ||
222 | index a8db2c713f3..41e8725d059 100644 | ||
223 | --- a/ld/testsuite/ld-i386/i386.exp | ||
224 | +++ b/ld/testsuite/ld-i386/i386.exp | ||
225 | @@ -543,6 +543,7 @@ run_dump_test "pr27998a" | ||
226 | run_dump_test "pr27998b" | ||
227 | run_dump_test "tlsgdesc1" | ||
228 | run_dump_test "tlsgdesc2" | ||
229 | +run_dump_test "tlsgdesc3" | ||
230 | |||
231 | proc undefined_weak {cflags ldflags} { | ||
232 | set testname "Undefined weak symbol" | ||
233 | diff --git a/ld/testsuite/ld-i386/tlsgdesc3.d b/ld/testsuite/ld-i386/tlsgdesc3.d | ||
234 | new file mode 100644 | ||
235 | index 00000000000..f2c29d880f2 | ||
236 | --- /dev/null | ||
237 | +++ b/ld/testsuite/ld-i386/tlsgdesc3.d | ||
238 | @@ -0,0 +1,5 @@ | ||
239 | +#source: tlsgdesc2.s | ||
240 | +#name: TLS GDesc call (indirect CALL) | ||
241 | +#as: --32 | ||
242 | +#ld: -shared -melf_i386 | ||
243 | +#error: .*: relocation R_386_TLS_DESC_CALL against `foo' must be used in indirect CALL with EAX register only | ||
244 | diff --git a/ld/testsuite/ld-x86-64/tlsdesc5.d b/ld/testsuite/ld-x86-64/tlsdesc5.d | ||
245 | new file mode 100644 | ||
246 | index 00000000000..6a0158b44b7 | ||
247 | --- /dev/null | ||
248 | +++ b/ld/testsuite/ld-x86-64/tlsdesc5.d | ||
249 | @@ -0,0 +1,5 @@ | ||
250 | +#source: tlsdesc4.s | ||
251 | +#name: TLS GDesc call (indirect CALL) | ||
252 | +#as: --64 | ||
253 | +#ld: -shared -melf_x86_64 | ||
254 | +#error: .*: relocation R_X86_64_TLSDESC_CALL against `foo' must be used in indirect CALL with RAX register only | ||
255 | diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp | ||
256 | index 811813466f8..82b0520c52a 100644 | ||
257 | --- a/ld/testsuite/ld-x86-64/x86-64.exp | ||
258 | +++ b/ld/testsuite/ld-x86-64/x86-64.exp | ||
259 | @@ -744,6 +744,7 @@ run_dump_test "pr29820" | ||
260 | run_dump_test "tlsie5" | ||
261 | run_dump_test "tlsdesc3" | ||
262 | run_dump_test "tlsdesc4" | ||
263 | +run_dump_test "tlsdesc5" | ||
264 | |||
265 | proc undefined_weak {cflags ldflags} { | ||
266 | set testname "Undefined weak symbol" | ||
267 | -- | ||
268 | 2.49.0 | ||
269 | |||