[libc-commits] [libc] 952dc12 - Force to inline syscall_impl on all platforms (#186849)

via libc-commits libc-commits at lists.llvm.org
Wed Mar 25 01:55:43 PDT 2026


Author: Jakob Koschel
Date: 2026-03-25T09:55:37+01:00
New Revision: 952dc121244765e6d2b5614b51d7293ab7a2f232

URL: https://github.com/llvm/llvm-project/commit/952dc121244765e6d2b5614b51d7293ab7a2f232
DIFF: https://github.com/llvm/llvm-project/commit/952dc121244765e6d2b5614b51d7293ab7a2f232.diff

LOG: Force to inline syscall_impl on all platforms (#186849)

With currently only LIBC_INLINE, we just hint the compiler to inline the
function which however in practice is not always the case.

Since we added `[[gnu::always_inline]]` on linux/x86_64 it makes sense
to do it on all platforms consistently and add a comment explaining why
we need it.

Added: 
    

Modified: 
    libc/src/__support/OSUtil/darwin/aarch64/syscall.h
    libc/src/__support/OSUtil/linux/aarch64/syscall.h
    libc/src/__support/OSUtil/linux/arm/syscall.h
    libc/src/__support/OSUtil/linux/i386/syscall.h
    libc/src/__support/OSUtil/linux/riscv/syscall.h
    libc/src/__support/OSUtil/linux/x86_64/syscall.h

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/OSUtil/darwin/aarch64/syscall.h b/libc/src/__support/OSUtil/darwin/aarch64/syscall.h
index dc98c07a8ba33..8e273f487fd75 100644
--- a/libc/src/__support/OSUtil/darwin/aarch64/syscall.h
+++ b/libc/src/__support/OSUtil/darwin/aarch64/syscall.h
@@ -47,46 +47,51 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LIBC_INLINE long syscall_impl(long number) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number) {
   REGISTER_DECL_0;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_0);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1) {
   REGISTER_DECL_1;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_1);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2) {
   REGISTER_DECL_2;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_2);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3) {
   REGISTER_DECL_3;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_3);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4) {
+[[gnu::always_inline]] LIBC_INLINE long
+syscall_impl(long number, long arg1, long arg2, long arg3, long arg4) {
   REGISTER_DECL_4;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_4);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4, long arg5) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3,
+                                                     long arg4, long arg5) {
   REGISTER_DECL_5;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_5);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4, long arg5, long arg6) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3,
+                                                     long arg4, long arg5,
+                                                     long arg6) {
   REGISTER_DECL_6;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_6);
   return x0;

diff  --git a/libc/src/__support/OSUtil/linux/aarch64/syscall.h b/libc/src/__support/OSUtil/linux/aarch64/syscall.h
index f28392de5dced..c211c0e4cf11a 100644
--- a/libc/src/__support/OSUtil/linux/aarch64/syscall.h
+++ b/libc/src/__support/OSUtil/linux/aarch64/syscall.h
@@ -45,46 +45,51 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LIBC_INLINE long syscall_impl(long number) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number) {
   REGISTER_DECL_0;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_0);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1) {
   REGISTER_DECL_1;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_1);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2) {
   REGISTER_DECL_2;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_2);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3) {
   REGISTER_DECL_3;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_3);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4) {
+[[gnu::always_inline]] LIBC_INLINE long
+syscall_impl(long number, long arg1, long arg2, long arg3, long arg4) {
   REGISTER_DECL_4;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_4);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4, long arg5) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3,
+                                                     long arg4, long arg5) {
   REGISTER_DECL_5;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_5);
   return x0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4, long arg5, long arg6) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3,
+                                                     long arg4, long arg5,
+                                                     long arg6) {
   REGISTER_DECL_6;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_6);
   return x0;

diff  --git a/libc/src/__support/OSUtil/linux/arm/syscall.h b/libc/src/__support/OSUtil/linux/arm/syscall.h
index d1058c84281fe..252c8c80249b3 100644
--- a/libc/src/__support/OSUtil/linux/arm/syscall.h
+++ b/libc/src/__support/OSUtil/linux/arm/syscall.h
@@ -63,46 +63,51 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LIBC_INLINE long syscall_impl(long number) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number) {
   REGISTER_DECL_0;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_0);
   return r0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1) {
   REGISTER_DECL_1;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_1);
   return r0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2) {
   REGISTER_DECL_2;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_2);
   return r0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3) {
   REGISTER_DECL_3;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_3);
   return r0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4) {
+[[gnu::always_inline]] LIBC_INLINE long
+syscall_impl(long number, long arg1, long arg2, long arg3, long arg4) {
   REGISTER_DECL_4;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_4);
   return r0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4, long arg5) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3,
+                                                     long arg4, long arg5) {
   REGISTER_DECL_5;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_5);
   return r0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4, long arg5, long arg6) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3,
+                                                     long arg4, long arg5,
+                                                     long arg6) {
   REGISTER_DECL_6;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_6);
   return r0;

diff  --git a/libc/src/__support/OSUtil/linux/i386/syscall.h b/libc/src/__support/OSUtil/linux/i386/syscall.h
index 88d7f2fb2c49f..76fb83cbb35a8 100644
--- a/libc/src/__support/OSUtil/linux/i386/syscall.h
+++ b/libc/src/__support/OSUtil/linux/i386/syscall.h
@@ -14,19 +14,20 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LIBC_INLINE long syscall_impl(long num) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long num) {
   long ret;
   LIBC_INLINE_ASM("int $128" : "=a"(ret) : "a"(num) : "memory");
   return ret;
 }
 
-LIBC_INLINE long syscall_impl(long num, long arg1) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long num, long arg1) {
   long ret;
   LIBC_INLINE_ASM("int $128" : "=a"(ret) : "a"(num), "b"(arg1) : "memory");
   return ret;
 }
 
-LIBC_INLINE long syscall_impl(long num, long arg1, long arg2) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long num, long arg1,
+                                                     long arg2) {
   long ret;
   LIBC_INLINE_ASM("int $128"
                   : "=a"(ret)
@@ -35,7 +36,8 @@ LIBC_INLINE long syscall_impl(long num, long arg1, long arg2) {
   return ret;
 }
 
-LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long num, long arg1,
+                                                     long arg2, long arg3) {
   long ret;
   LIBC_INLINE_ASM("int $128"
                   : "=a"(ret)
@@ -44,8 +46,8 @@ LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3) {
   return ret;
 }
 
-LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3,
-                              long arg4) {
+[[gnu::always_inline]] LIBC_INLINE long
+syscall_impl(long num, long arg1, long arg2, long arg3, long arg4) {
   long ret;
   LIBC_INLINE_ASM("int $128"
                   : "=a"(ret)
@@ -54,8 +56,8 @@ LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3,
   return ret;
 }
 
-LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3,
-                              long arg4, long arg5) {
+[[gnu::always_inline]] LIBC_INLINE long
+syscall_impl(long num, long arg1, long arg2, long arg3, long arg4, long arg5) {
   long ret;
   LIBC_INLINE_ASM("int $128"
                   : "=a"(ret)
@@ -65,8 +67,10 @@ LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3,
   return ret;
 }
 
-LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3,
-                              long arg4, long arg5, long arg6) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long num, long arg1,
+                                                     long arg2, long arg3,
+                                                     long arg4, long arg5,
+                                                     long arg6) {
   long ret;
   LIBC_INLINE_ASM(R"(
     push %[arg6]

diff  --git a/libc/src/__support/OSUtil/linux/riscv/syscall.h b/libc/src/__support/OSUtil/linux/riscv/syscall.h
index e460e9bb56e67..1fabc400b1c70 100644
--- a/libc/src/__support/OSUtil/linux/riscv/syscall.h
+++ b/libc/src/__support/OSUtil/linux/riscv/syscall.h
@@ -45,46 +45,51 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LIBC_INLINE long syscall_impl(long number) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number) {
   REGISTER_DECL_0;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_0);
   return a0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1) {
   REGISTER_DECL_1;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_1);
   return a0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2) {
   REGISTER_DECL_2;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_2);
   return a0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3) {
   REGISTER_DECL_3;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_3);
   return a0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4) {
+[[gnu::always_inline]] LIBC_INLINE long
+syscall_impl(long number, long arg1, long arg2, long arg3, long arg4) {
   REGISTER_DECL_4;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_4);
   return a0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4, long arg5) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3,
+                                                     long arg4, long arg5) {
   REGISTER_DECL_5;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_5);
   return a0;
 }
 
-LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3,
-                              long arg4, long arg5, long arg6) {
+[[gnu::always_inline]] LIBC_INLINE long syscall_impl(long number, long arg1,
+                                                     long arg2, long arg3,
+                                                     long arg4, long arg5,
+                                                     long arg6) {
   REGISTER_DECL_6;
   SYSCALL_INSTR(REGISTER_CONSTRAINT_6);
   return a0;

diff  --git a/libc/src/__support/OSUtil/linux/x86_64/syscall.h b/libc/src/__support/OSUtil/linux/x86_64/syscall.h
index f069d46185d0f..25ff5faf081b1 100644
--- a/libc/src/__support/OSUtil/linux/x86_64/syscall.h
+++ b/libc/src/__support/OSUtil/linux/x86_64/syscall.h
@@ -16,6 +16,11 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+// In order for SHSTK (CET ShadowStack) to work, we are required to force
+// inlining the syscall_impl, since we cannot return from an untracked call
+// after enabling support throught the system call.
+// For consistency, we do this consistently on all platforms, but can split it
+// into force-inlined and regular inlined functions in the future if necessary.
 [[gnu::always_inline]] LIBC_INLINE long syscall_impl(long __number) {
   long retcode;
   LIBC_INLINE_ASM("syscall"


        


More information about the libc-commits mailing list