1 | /* Check if TLSDESC relocation preserves %rdi, %rsi and %rbx. |
2 | Copyright (C) 2024 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ |
18 | |
19 | #include <sysdep.h> |
20 | |
21 | /* On AVX512 machines, OFFSET == 40 caused _dl_tlsdesc_dynamic_xsavec |
22 | to clobber %rdi, %rsi and %rbx. On Intel AVX CPUs, the state size |
23 | is 960 bytes and this test didn't fail. It may be due to the unused |
24 | last 128 bytes. On AMD AVX CPUs, the state size is 832 bytes and |
25 | this test might fail without the fix. */ |
26 | #ifndef OFFSET |
27 | # define OFFSET 40 |
28 | #endif |
29 | |
30 | .text |
31 | .p2align 4 |
32 | .globl apply_tls |
33 | .type apply_tls, @function |
34 | apply_tls: |
35 | cfi_startproc |
36 | _CET_ENDBR |
37 | pushq %rbp |
38 | cfi_def_cfa_offset (16) |
39 | cfi_offset (6, -16) |
40 | movdqu (%RDI_LP), %xmm0 |
41 | lea tls_var1@TLSDESC(%rip), %RAX_LP |
42 | mov %RSP_LP, %RBP_LP |
43 | cfi_def_cfa_register (6) |
44 | /* Align stack to 64 bytes. */ |
45 | and $-64, %RSP_LP |
46 | sub $OFFSET, %RSP_LP |
47 | pushq %rbx |
48 | /* Set %ebx to 0xbadbeef. */ |
49 | movl $0xbadbeef, %ebx |
50 | movl $0xbadbeef, %esi |
51 | movq %rdi, saved_rdi(%rip) |
52 | movq %rsi, saved_rsi(%rip) |
53 | call *tls_var1@TLSCALL(%RAX_LP) |
54 | /* Check if _dl_tlsdesc_dynamic preserves %rdi, %rsi and %rbx. */ |
55 | cmpq saved_rdi(%rip), %rdi |
56 | jne L(hlt) |
57 | cmpq saved_rsi(%rip), %rsi |
58 | jne L(hlt) |
59 | cmpl $0xbadbeef, %ebx |
60 | jne L(hlt) |
61 | add %fs:0, %RAX_LP |
62 | movups %xmm0, 32(%RAX_LP) |
63 | movdqu 16(%RDI_LP), %xmm1 |
64 | mov %RAX_LP, %RBX_LP |
65 | movups %xmm1, 48(%RAX_LP) |
66 | lea 32(%RBX_LP), %RAX_LP |
67 | pop %rbx |
68 | leave |
69 | cfi_def_cfa (7, 8) |
70 | ret |
71 | L(hlt): |
72 | hlt |
73 | cfi_endproc |
74 | .size apply_tls, .-apply_tls |
75 | .hidden tls_var1 |
76 | .globl tls_var1 |
77 | .section .tbss,"awT" ,@nobits |
78 | .align 16 |
79 | .type tls_var1, @object |
80 | .size tls_var1, 3200 |
81 | tls_var1: |
82 | .zero 3200 |
83 | .local saved_rdi |
84 | .comm saved_rdi,8,8 |
85 | .local saved_rsi |
86 | .comm saved_rsi,8,8 |
87 | .section .note.GNU-stack,"" ,@progbits |
88 | |