Skip to content

Commit 23e4e84

Browse files
nickdesaulniersAlexisPerry
authored andcommitted
[libc][thumb] support syscalls from thumb mode (llvm#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: llvm#93738
1 parent 5ca93cb commit 23e4e84

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

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

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,29 @@
1212
#include "src/__support/common.h"
1313

1414
#ifdef __thumb__
15-
#error "The arm syscall implementation does not yet support thumb flavor."
16-
#endif // __thumb__
15+
#define R7 long r7 = number
16+
#define SYSCALL_INSTR(input_constraint) \
17+
int temp; \
18+
LIBC_INLINE_ASM(R"(
19+
mov %[temp], r7
20+
mov r7, %2
21+
svc #0
22+
mov r7, %[temp]
23+
)" \
24+
: "=r"(r0), [temp] "=&r"(temp) \
25+
: input_constraint \
26+
: "memory", "cc")
27+
#else
28+
#define R7 register long r7 asm("r7") = number
29+
#define SYSCALL_INSTR(input_constraint) \
30+
LIBC_INLINE_ASM("svc 0" : "=r"(r0) : input_constraint : "memory", "cc")
31+
#endif
1732

1833
#define REGISTER_DECL_0 \
19-
register long r7 __asm__("r7") = number; \
34+
R7; \
2035
register long r0 __asm__("r0");
2136
#define REGISTER_DECL_1 \
22-
register long r7 __asm__("r7") = number; \
37+
R7; \
2338
register long r0 __asm__("r0") = arg1;
2439
#define REGISTER_DECL_2 \
2540
REGISTER_DECL_1 \
@@ -45,9 +60,6 @@
4560
#define REGISTER_CONSTRAINT_5 REGISTER_CONSTRAINT_4, "r"(r4)
4661
#define REGISTER_CONSTRAINT_6 REGISTER_CONSTRAINT_5, "r"(r5)
4762

48-
#define SYSCALL_INSTR(input_constraint) \
49-
LIBC_INLINE_ASM("svc 0" : "=r"(r0) : input_constraint : "memory", "cc")
50-
5163
namespace LIBC_NAMESPACE {
5264

5365
LIBC_INLINE long syscall_impl(long number) {

0 commit comments

Comments
 (0)