aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Desaulniers (paternity leave) <nickdesaulniers@users.noreply.github.com>2024-06-25 09:58:50 -0700
committerGitHub <noreply@github.com>2024-06-25 09:58:50 -0700
commit4c87212d63c3b45e9371434239553ef007216106 (patch)
tree006f9a23b1563cb5652be4375c7938965363dcbd
parent0b049ce64653a8cbdeedaa2bfe6cc79fc6af5d40 (diff)
downloadllvm-4c87212d63c3b45e9371434239553ef007216106.zip
llvm-4c87212d63c3b45e9371434239553ef007216106.tar.gz
llvm-4c87212d63c3b45e9371434239553ef007216106.tar.bz2
[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
-rw-r--r--libc/src/__support/OSUtil/linux/arm/syscall.h26
1 files changed, 19 insertions, 7 deletions
diff --git a/libc/src/__support/OSUtil/linux/arm/syscall.h b/libc/src/__support/OSUtil/linux/arm/syscall.h
index af10074..9674ee4 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) {