[PATCH] linux/arm/raw_syscall.h: avoid r7 specified register variables with Thumb

Andre McCurdy armccurdy at gmail.com
Tue May 15 22:34:39 UTC 2018


If Thumb code is being generated and frame pointers are enabled, the
Thumb frame pointer in r7 clashes with any local variable which may
need to be assigned to r7 (e.g. the syscall NR when making a raw
syscall).

With gcc, the double use of r7 results in a build error, e.g.

  strace-4.22/tests/inject-nf.c:86:1: error: r7 cannot be used in asm here

With clang, the double use of r7 can result in the compiler silently
generating broken code which crashes at run time due to frame pointer
corruption:

  https://bugs.llvm.org/show_bug.cgi?id=34165

In most cases the problem isn't visible as frame pointers will be
disabled automatically due to optimisation level. However to handle
cases where frame pointers are enabled (e.g. when CFLAGS etc are set
to support a debug build, etc) provide a version of raw_syscall_0
which manually saves and restores the frame pointer value in r7 to a
temporary register before setting up the syscall NR in r7 and
invoking the syscall.

Signed-off-by: Andre McCurdy <armccurdy at gmail.com>
---
 linux/arm/raw_syscall.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/linux/arm/raw_syscall.h b/linux/arm/raw_syscall.h
index 69c7e23..ec534ec 100644
--- a/linux/arm/raw_syscall.h
+++ b/linux/arm/raw_syscall.h
@@ -36,12 +36,27 @@ static inline kernel_ulong_t
 raw_syscall_0(const kernel_ulong_t nr, kernel_ulong_t *err)
 {
 	*err = 0;
+
+#ifdef __thumb__ /* && FRAME_POINTERS_ENABLED */
+
+	register kernel_ulong_t rt;
+	register kernel_ulong_t r0 __asm__("r0");
+	__asm__ __volatile__("mov %1,r7; mov r7,%2; swi 0x0; mov r7,%1"
+			     : "=r"(r0), "=&r"(rt)
+			     : "r"(nr)
+			     : "memory");
+
+#else
+
 	register kernel_ulong_t r7 __asm__("r7") = nr;
 	register kernel_ulong_t r0 __asm__("r0");
 	__asm__ __volatile__("swi 0x0"
 			     : "=r"(r0)
 			     : "r"(r7)
 			     : "memory");
+
+#endif
+
 	return r0;
 }
 # define raw_syscall_0 raw_syscall_0
-- 
1.9.1



More information about the Strace-devel mailing list