[libc-commits] [libc] 4c87212 - [libc][thumb] support syscalls from thumb mode (#96558)

via libc-commits libc-commits at lists.llvm.org
Tue Jun 25 09:58:54 PDT 2024


Author: Nick Desaulniers (paternity leave)
Date: 2024-06-25T09:58:50-07:00
New Revision: 4c87212d63c3b45e9371434239553ef007216106

URL: https://github.com/llvm/llvm-project/commit/4c87212d63c3b45e9371434239553ef007216106
DIFF: https://github.com/llvm/llvm-project/commit/4c87212d63c3b45e9371434239553ef007216106.diff

LOG: [libc][thumb] support syscalls from thumb mode (#96558)

r7 is reserved in thumb2 (typically for the frame pointer, as opposed to r11 in
ARM mode), so assigning to a variable with explicit register storage in r7 will
produce an error.

But r7 is where the Linux kernel expects the syscall number to be placed. We
can use a temporary to get the register allocator to pick a temporary, which we
save+restore the previous value of r7 in.

Fixes: #93738

Added: 
    

Modified: 
    libc/src/__support/OSUtil/linux/arm/syscall.h

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/OSUtil/linux/arm/syscall.h b/libc/src/__support/OSUtil/linux/arm/syscall.h
index af10074783275..9674ee45a49e9 100644
--- a/libc/src/__support/OSUtil/linux/arm/syscall.h
+++ b/libc/src/__support/OSUtil/linux/arm/syscall.h
@@ -12,14 +12,29 @@
 #include "src/__support/common.h"
 
 #ifdef __thumb__
-#error "The arm syscall implementation does not yet support thumb flavor."
-#endif // __thumb__
+#define R7 long r7 = number
+#define SYSCALL_INSTR(input_constraint)                                        \
+  int temp;                                                                    \
+  LIBC_INLINE_ASM(R"(
+    mov %[temp], r7
+    mov r7, %2
+    svc #0
+    mov r7, %[temp]
+  )"                                                          \
+                  : "=r"(r0), [temp] "=&r"(temp)                               \
+                  : input_constraint                                           \
+                  : "memory", "cc")
+#else
+#define R7 register long r7 asm("r7") = number
+#define SYSCALL_INSTR(input_constraint)                                        \
+  LIBC_INLINE_ASM("svc 0" : "=r"(r0) : input_constraint : "memory", "cc")
+#endif
 
 #define REGISTER_DECL_0                                                        \
-  register long r7 __asm__("r7") = number;                                     \
+  R7;                                                                          \
   register long r0 __asm__("r0");
 #define REGISTER_DECL_1                                                        \
-  register long r7 __asm__("r7") = number;                                     \
+  R7;                                                                          \
   register long r0 __asm__("r0") = arg1;
 #define REGISTER_DECL_2                                                        \
   REGISTER_DECL_1                                                              \
@@ -45,9 +60,6 @@
 #define REGISTER_CONSTRAINT_5 REGISTER_CONSTRAINT_4, "r"(r4)
 #define REGISTER_CONSTRAINT_6 REGISTER_CONSTRAINT_5, "r"(r5)
 
-#define SYSCALL_INSTR(input_constraint)                                        \
-  LIBC_INLINE_ASM("svc 0" : "=r"(r0) : input_constraint : "memory", "cc")
-
 namespace LIBC_NAMESPACE {
 
 LIBC_INLINE long syscall_impl(long number) {


        


More information about the libc-commits mailing list