]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/x86_64/sysdep.h
x86: Add seperate non-temporal tunable for memset
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / x86_64 / sysdep.h
CommitLineData
dff8da6b 1/* Copyright (C) 2001-2024 Free Software Foundation, Inc.
c9cf6dde
AJ
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
59ba27a6 15 License along with the GNU C Library; if not, see
5a82c748 16 <https://www.gnu.org/licenses/>. */
c9cf6dde
AJ
17
18#ifndef _LINUX_X86_64_SYSDEP_H
19#define _LINUX_X86_64_SYSDEP_H 1
20
21/* There is some commonality. */
fb1cf108 22#include <sysdeps/unix/sysv/linux/sysdep.h>
c9cf6dde 23#include <sysdeps/unix/x86_64/sysdep.h>
89b91a92 24#include <tls.h>
c9cf6dde 25
dd28d4ba
ST
26/* Defines RTLD_PRIVATE_ERRNO. */
27#include <dl-sysdep.h>
ce460d04 28
c9cf6dde
AJ
29/* For Linux we can use the system call table in the header file
30 /usr/include/asm/unistd.h
31 of the kernel. But these symbols do not follow the SYS_* syntax
32 so we have to redefine the `SYS_ify' macro here. */
33#undef SYS_ify
34#define SYS_ify(syscall_name) __NR_##syscall_name
35
c9cf6dde
AJ
36#ifdef __ASSEMBLER__
37
38/* Linux uses a negative return value to indicate syscall errors,
39 unlike most Unices, which use the condition codes' carry flag.
40
41 Since version 2.1 the return value of a system call might be
42 negative even if the call succeeded. E.g., the `lseek' system call
43 might return a large offset. Therefore we must not anymore test
44 for < 0, but test for a real error by making sure the value in %eax
45 is a real error number. Linus said he will make sure the no syscall
d13733c1 46 returns a value in -1 .. -4095 as a valid result so we can safely
c9cf6dde
AJ
47 test with -4095. */
48
49/* We don't want the label for the error handle to be global when we define
50 it here. */
fcb78a55 51# undef SYSCALL_ERROR_LABEL
75fb247e 52# ifdef PIC
bc2eb932 53# undef SYSCALL_ERROR_LABEL
75fb247e
UD
54# define SYSCALL_ERROR_LABEL 0f
55# else
bc2eb932 56# undef SYSCALL_ERROR_LABEL
75fb247e
UD
57# define SYSCALL_ERROR_LABEL syscall_error
58# endif
c9cf6dde 59
2ad5d084
L
60/* PSEUDO and T_PSEUDO macros have 2 extra arguments for unsigned long
61 int arguments. */
62# define PSEUDOS_HAVE_ULONG_INDICES 1
63
64# ifndef SYSCALL_ULONG_ARG_1
65# define SYSCALL_ULONG_ARG_1 0
66# define SYSCALL_ULONG_ARG_2 0
67# endif
68
75fb247e 69# undef PSEUDO
2ad5d084
L
70# if SYSCALL_ULONG_ARG_1
71# define PSEUDO(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \
72 .text; \
73 ENTRY (name) \
74 DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2); \
75 cmpq $-4095, %rax; \
842a39cd 76 jae SYSCALL_ERROR_LABEL
2ad5d084
L
77# else
78# define PSEUDO(name, syscall_name, args) \
79 .text; \
80 ENTRY (name) \
81 DO_CALL (syscall_name, args, 0, 0); \
82 cmpq $-4095, %rax; \
83 jae SYSCALL_ERROR_LABEL
84# endif
c9cf6dde 85
75fb247e
UD
86# undef PSEUDO_END
87# define PSEUDO_END(name) \
c9cf6dde
AJ
88 SYSCALL_ERROR_HANDLER \
89 END (name)
90
75fb247e 91# undef PSEUDO_NOERRNO
2ad5d084
L
92# if SYSCALL_ULONG_ARG_1
93# define PSEUDO_NOERRNO(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \
94 .text; \
95 ENTRY (name) \
96 DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2)
97# else
98# define PSEUDO_NOERRNO(name, syscall_name, args) \
99 .text; \
100 ENTRY (name) \
101 DO_CALL (syscall_name, args, 0, 0)
102# endif
9eb88290 103
75fb247e
UD
104# undef PSEUDO_END_NOERRNO
105# define PSEUDO_END_NOERRNO(name) \
9eb88290
UD
106 END (name)
107
75fb247e 108# define ret_NOERRNO ret
f38afd78 109
75fb247e 110# undef PSEUDO_ERRVAL
2ad5d084
L
111# if SYSCALL_ULONG_ARG_1
112# define PSEUDO_ERRVAL(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \
113 .text; \
114 ENTRY (name) \
115 DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2); \
116 negq %rax
117# else
118# define PSEUDO_ERRVAL(name, syscall_name, args) \
119 .text; \
120 ENTRY (name) \
121 DO_CALL (syscall_name, args, 0, 0); \
f38afd78 122 negq %rax
2ad5d084 123# endif
bfef9264 124
75fb247e
UD
125# undef PSEUDO_END_ERRVAL
126# define PSEUDO_END_ERRVAL(name) \
bfef9264
UD
127 END (name)
128
75fb247e 129# define ret_ERRVAL ret
9eb88290 130
dd28d4ba 131# if defined PIC && RTLD_PRIVATE_ERRNO
bbb3154b
L
132# define SYSCALL_SET_ERRNO \
133 lea rtld_errno(%rip), %RCX_LP; \
0e44a77e
L
134 neg %eax; \
135 movl %eax, (%rcx)
d063d164 136# else
4f41c682 137# if IS_IN (libc)
75fb247e
UD
138# define SYSCALL_ERROR_ERRNO __libc_errno
139# else
140# define SYSCALL_ERROR_ERRNO errno
141# endif
bbb3154b 142# define SYSCALL_SET_ERRNO \
0a951d0e 143 movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\
0e44a77e
L
144 neg %eax; \
145 movl %eax, %fs:(%rcx);
bbb3154b
L
146# endif
147
148# ifndef PIC
149# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
150# else
151# define SYSCALL_ERROR_HANDLER \
1520: \
153 SYSCALL_SET_ERRNO; \
154 or $-1, %RAX_LP; \
5e292e4f 155 ret;
75fb247e 156# endif /* PIC */
c9cf6dde 157
092fd00d
AJ
158/* The Linux/x86-64 kernel expects the system call parameters in
159 registers according to the following table:
c9cf6dde 160
092fd00d 161 syscall number rax
c9cf6dde
AJ
162 arg 1 rdi
163 arg 2 rsi
164 arg 3 rdx
092fd00d 165 arg 4 r10
c9cf6dde
AJ
166 arg 5 r8
167 arg 6 r9
168
092fd00d 169 The Linux kernel uses and destroys internally these registers:
c9cf6dde
AJ
170 return address from
171 syscall rcx
c9cf6dde
AJ
172 eflags from syscall r11
173
092fd00d
AJ
174 Normal function call, including calls to the system call stub
175 functions in the libc, get the first six parameters passed in
176 registers and the seventh parameter and later on the stack. The
177 register use is as follows:
178
179 system call number in the DO_CALL macro
180 arg 1 rdi
181 arg 2 rsi
182 arg 3 rdx
183 arg 4 rcx
184 arg 5 r8
185 arg 6 r9
186
187 We have to take care that the stack is aligned to 16 bytes. When
188 called the stack is not aligned since the return address has just
189 been pushed.
190
9eb88290 191
092fd00d 192 Syscalls of more than 6 arguments are not supported. */
c9cf6dde 193
75fb247e 194# undef DO_CALL
2ad5d084 195# define DO_CALL(syscall_name, args, ulong_arg_1, ulong_arg_2) \
c9cf6dde 196 DOARGS_##args \
2ad5d084
L
197 ZERO_EXTEND_##ulong_arg_1 \
198 ZERO_EXTEND_##ulong_arg_2 \
ee618985 199 movl $SYS_ify (syscall_name), %eax; \
c9cf6dde
AJ
200 syscall;
201
75fb247e
UD
202# define DOARGS_0 /* nothing */
203# define DOARGS_1 /* nothing */
204# define DOARGS_2 /* nothing */
205# define DOARGS_3 /* nothing */
206# define DOARGS_4 movq %rcx, %r10;
207# define DOARGS_5 DOARGS_4
208# define DOARGS_6 DOARGS_5
c9cf6dde 209
2ad5d084
L
210# define ZERO_EXTEND_0 /* nothing */
211# define ZERO_EXTEND_1 /* nothing */
212# define ZERO_EXTEND_2 /* nothing */
213# define ZERO_EXTEND_3 /* nothing */
214# define ZERO_EXTEND_4 /* nothing */
215# define ZERO_EXTEND_5 /* nothing */
216# define ZERO_EXTEND_6 /* nothing */
217
c9cf6dde 218#else /* !__ASSEMBLER__ */
6aca81bb 219
d29d57ee
L
220/* Registers clobbered by syscall. */
221# define REGISTERS_CLOBBERED_BY_SYSCALL "cc", "r11", "cx"
222
df76ff3a
L
223/* NB: This also works when X is an array. For an array X, type of
224 (X) - (X) is ptrdiff_t, which is signed, since size of ptrdiff_t
225 == size of pointer, cast is a NOP. */
226#define TYPEFY1(X) __typeof__ ((X) - (X))
227/* Explicit cast the argument. */
228#define ARGIFY(X) ((TYPEFY1 (X)) (X))
229/* Create a variable 'name' based on type of variable 'X' to avoid
230 explicit types. */
231#define TYPEFY(X, name) __typeof__ (ARGIFY (X)) name
78ca091c
AZ
232
233#undef INTERNAL_SYSCALL
bc2eb932
AZ
234#define INTERNAL_SYSCALL(name, nr, args...) \
235 internal_syscall##nr (SYS_ify (name), args)
78ca091c
AZ
236
237#undef INTERNAL_SYSCALL_NCS
bc2eb932
AZ
238#define INTERNAL_SYSCALL_NCS(number, nr, args...) \
239 internal_syscall##nr (number, args)
78ca091c
AZ
240
241#undef internal_syscall0
bc2eb932 242#define internal_syscall0(number, dummy...) \
78ca091c
AZ
243({ \
244 unsigned long int resultvar; \
245 asm volatile ( \
246 "syscall\n\t" \
247 : "=a" (resultvar) \
248 : "0" (number) \
249 : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \
250 (long int) resultvar; \
251})
252
253#undef internal_syscall1
bc2eb932 254#define internal_syscall1(number, arg1) \
78ca091c
AZ
255({ \
256 unsigned long int resultvar; \
257 TYPEFY (arg1, __arg1) = ARGIFY (arg1); \
258 register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \
259 asm volatile ( \
260 "syscall\n\t" \
261 : "=a" (resultvar) \
262 : "0" (number), "r" (_a1) \
263 : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \
264 (long int) resultvar; \
265})
266
267#undef internal_syscall2
bc2eb932 268#define internal_syscall2(number, arg1, arg2) \
78ca091c
AZ
269({ \
270 unsigned long int resultvar; \
271 TYPEFY (arg2, __arg2) = ARGIFY (arg2); \
272 TYPEFY (arg1, __arg1) = ARGIFY (arg1); \
273 register TYPEFY (arg2, _a2) asm ("rsi") = __arg2; \
274 register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \
275 asm volatile ( \
276 "syscall\n\t" \
277 : "=a" (resultvar) \
278 : "0" (number), "r" (_a1), "r" (_a2) \
279 : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \
280 (long int) resultvar; \
281})
282
283#undef internal_syscall3
bc2eb932 284#define internal_syscall3(number, arg1, arg2, arg3) \
78ca091c
AZ
285({ \
286 unsigned long int resultvar; \
287 TYPEFY (arg3, __arg3) = ARGIFY (arg3); \
288 TYPEFY (arg2, __arg2) = ARGIFY (arg2); \
289 TYPEFY (arg1, __arg1) = ARGIFY (arg1); \
290 register TYPEFY (arg3, _a3) asm ("rdx") = __arg3; \
291 register TYPEFY (arg2, _a2) asm ("rsi") = __arg2; \
292 register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \
293 asm volatile ( \
294 "syscall\n\t" \
295 : "=a" (resultvar) \
296 : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3) \
297 : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \
298 (long int) resultvar; \
299})
300
301#undef internal_syscall4
bc2eb932 302#define internal_syscall4(number, arg1, arg2, arg3, arg4) \
78ca091c
AZ
303({ \
304 unsigned long int resultvar; \
305 TYPEFY (arg4, __arg4) = ARGIFY (arg4); \
306 TYPEFY (arg3, __arg3) = ARGIFY (arg3); \
307 TYPEFY (arg2, __arg2) = ARGIFY (arg2); \
308 TYPEFY (arg1, __arg1) = ARGIFY (arg1); \
309 register TYPEFY (arg4, _a4) asm ("r10") = __arg4; \
310 register TYPEFY (arg3, _a3) asm ("rdx") = __arg3; \
311 register TYPEFY (arg2, _a2) asm ("rsi") = __arg2; \
312 register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \
313 asm volatile ( \
314 "syscall\n\t" \
315 : "=a" (resultvar) \
316 : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4) \
317 : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \
318 (long int) resultvar; \
319})
320
321#undef internal_syscall5
bc2eb932 322#define internal_syscall5(number, arg1, arg2, arg3, arg4, arg5) \
78ca091c
AZ
323({ \
324 unsigned long int resultvar; \
325 TYPEFY (arg5, __arg5) = ARGIFY (arg5); \
326 TYPEFY (arg4, __arg4) = ARGIFY (arg4); \
327 TYPEFY (arg3, __arg3) = ARGIFY (arg3); \
328 TYPEFY (arg2, __arg2) = ARGIFY (arg2); \
329 TYPEFY (arg1, __arg1) = ARGIFY (arg1); \
330 register TYPEFY (arg5, _a5) asm ("r8") = __arg5; \
331 register TYPEFY (arg4, _a4) asm ("r10") = __arg4; \
332 register TYPEFY (arg3, _a3) asm ("rdx") = __arg3; \
333 register TYPEFY (arg2, _a2) asm ("rsi") = __arg2; \
334 register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \
335 asm volatile ( \
336 "syscall\n\t" \
337 : "=a" (resultvar) \
338 : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4), \
339 "r" (_a5) \
340 : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \
341 (long int) resultvar; \
342})
343
344#undef internal_syscall6
bc2eb932 345#define internal_syscall6(number, arg1, arg2, arg3, arg4, arg5, arg6) \
78ca091c
AZ
346({ \
347 unsigned long int resultvar; \
348 TYPEFY (arg6, __arg6) = ARGIFY (arg6); \
349 TYPEFY (arg5, __arg5) = ARGIFY (arg5); \
350 TYPEFY (arg4, __arg4) = ARGIFY (arg4); \
351 TYPEFY (arg3, __arg3) = ARGIFY (arg3); \
352 TYPEFY (arg2, __arg2) = ARGIFY (arg2); \
353 TYPEFY (arg1, __arg1) = ARGIFY (arg1); \
354 register TYPEFY (arg6, _a6) asm ("r9") = __arg6; \
355 register TYPEFY (arg5, _a5) asm ("r8") = __arg5; \
356 register TYPEFY (arg4, _a4) asm ("r10") = __arg4; \
357 register TYPEFY (arg3, _a3) asm ("rdx") = __arg3; \
358 register TYPEFY (arg2, _a2) asm ("rsi") = __arg2; \
359 register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \
360 asm volatile ( \
361 "syscall\n\t" \
362 : "=a" (resultvar) \
363 : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4), \
364 "r" (_a5), "r" (_a6) \
365 : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \
366 (long int) resultvar; \
367})
31a39bd8 368
75fb247e 369
b8386c28
AZ
370# define VDSO_NAME "LINUX_2.6"
371# define VDSO_HASH 61765110
372
1395ef21 373/* List of system calls which are supported as vsyscalls. */
ff500a62 374# define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime"
b8a7c7da 375# define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday"
eca6aec6 376# define HAVE_TIME_VSYSCALL "__vdso_time"
b8a7c7da 377# define HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
0dc1a378 378# define HAVE_CLOCK_GETRES64_VSYSCALL "__vdso_clock_getres"
1395ef21 379
c25c3216 380# define HAVE_CLONE3_WRAPPER 1
24c78e2c 381
c9cf6dde
AJ
382#endif /* __ASSEMBLER__ */
383
cf1ad5b3
L
384/* How to pass the off{64}_t argument on p{readv,writev}{64}. */
385#undef LO_HI_LONG
d8a7d103 386#define LO_HI_LONG(val) (val), 0
cf1ad5b3 387
25123a1c
L
388/* Each shadow stack slot takes 8 bytes. Assuming that each stack
389 frame takes 256 bytes, this is used to compute shadow stack size
390 from stack size. */
391#define STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT 5
392
c9cf6dde 393#endif /* linux/x86_64/sysdep.h */