[compiler-rt] [compiler-rt] Implement `DumpAllRegisters` for arm-linux and aarch64-linux (PR #99613)
Dmitriy Chestnykh via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 20 22:27:46 PDT 2024
https://github.com/chestnykh updated https://github.com/llvm/llvm-project/pull/99613
>From 8d488702ab55bcaab73dc5a5ddeb103f44241f25 Mon Sep 17 00:00:00 2001
From: Dmitry Chestnykh <dm.chestnykh at gmail.com>
Date: Fri, 19 Jul 2024 11:01:11 +0300
Subject: [PATCH 1/2] [compiler-rt] Add `DumpAllRegister` impl for arm and
aarch64
---
.../lib/sanitizer_common/sanitizer_linux.cpp | 140 ++++++++++++++++++
1 file changed, 140 insertions(+)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 47f9f0c4590fb..441945b6f9c5b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -2171,6 +2171,70 @@ static const char *RegNumToRegName(int reg) {
return "ebp";
case REG_ESP:
return "esp";
+# elif defined(__arm__)
+# define REG_STR(reg) #reg
+# define MAKE_CASE(N) \
+ case REG_R##N: \
+ return REG_STR(r##N)
+ MAKE_CASE(0);
+ MAKE_CASE(1);
+ MAKE_CASE(2);
+ MAKE_CASE(3);
+ MAKE_CASE(4);
+ MAKE_CASE(5);
+ MAKE_CASE(6);
+ MAKE_CASE(7);
+ MAKE_CASE(8);
+ MAKE_CASE(9);
+ MAKE_CASE(10);
+ MAKE_CASE(11);
+ MAKE_CASE(12);
+ case REG_R13:
+ return "sp";
+ case REG_R14:
+ return "lr";
+ case REG_R15:
+ return "pc";
+# elif defined(__aarch64__)
+# define REG_STR(reg) #reg
+# define MAKE_CASE(N) \
+ case N: \
+ return REG_STR(x##N)
+ MAKE_CASE(0);
+ MAKE_CASE(1);
+ MAKE_CASE(2);
+ MAKE_CASE(3);
+ MAKE_CASE(4);
+ MAKE_CASE(5);
+ MAKE_CASE(6);
+ MAKE_CASE(7);
+ MAKE_CASE(8);
+ MAKE_CASE(9);
+ MAKE_CASE(10);
+ MAKE_CASE(11);
+ MAKE_CASE(12);
+ MAKE_CASE(13);
+ MAKE_CASE(14);
+ MAKE_CASE(15);
+ MAKE_CASE(16);
+ MAKE_CASE(17);
+ MAKE_CASE(18);
+ MAKE_CASE(19);
+ MAKE_CASE(20);
+ MAKE_CASE(21);
+ MAKE_CASE(22);
+ MAKE_CASE(23);
+ MAKE_CASE(24);
+ MAKE_CASE(25);
+ MAKE_CASE(26);
+ MAKE_CASE(27);
+ MAKE_CASE(28);
+ case 29:
+ return "fp";
+ case 30:
+ return "lr";
+ case 31:
+ return "sp";
# endif
default:
return NULL;
@@ -2178,6 +2242,47 @@ static const char *RegNumToRegName(int reg) {
return NULL;
}
+# if SANITIZER_LINUX && (defined(__arm__) || defined(__aarch64__))
+static unsigned long GetArmRegister(ucontext_t *ctx, int RegNum) {
+ switch (RegNum) {
+# if defined(__arm__)
+# define MAKE_CASE(N) \
+ case REG_R##N: \
+ return ctx->uc_mcontext.arm_r##N
+ MAKE_CASE(0);
+ MAKE_CASE(1);
+ MAKE_CASE(2);
+ MAKE_CASE(3);
+ MAKE_CASE(4);
+ MAKE_CASE(5);
+ MAKE_CASE(6);
+ MAKE_CASE(7);
+ MAKE_CASE(8);
+ MAKE_CASE(9);
+ MAKE_CASE(10);
+ case REG_R11:
+ return ctx->uc_mcontext.arm_fp;
+ case REG_R12:
+ return ctx->uc_mcontext.arm_ip;
+ case REG_R13:
+ return ctx->uc_mcontext.arm_sp;
+ case REG_R14:
+ return ctx->uc_mcontext.arm_lr;
+ case REG_R15:
+ return ctx->uc_mcontext.arm_pc;
+# elif defined(__aarch64__)
+ case 0 ... 30:
+ return ctx->uc_mcontext.regs[RegNum];
+ case 31:
+ return ctx->uc_mcontext.sp;
+# endif
+ default:
+ return 0UL;
+ }
+ return 0UL;
+}
+# endif // SANITIZER_LINUX && (defined(__arm__) || defined(__aarch64__))
+
UNUSED
static void DumpSingleReg(ucontext_t *ctx, int RegNum) {
const char *RegName = RegNumToRegName(RegNum);
@@ -2186,6 +2291,12 @@ static void DumpSingleReg(ucontext_t *ctx, int RegNum) {
RegName, ctx->uc_mcontext.gregs[RegNum]);
# elif defined(__i386__)
Printf("%s = 0x%08x ", RegName, ctx->uc_mcontext.gregs[RegNum]);
+# elif defined(__arm__)
+ Printf("%s%s = 0x%08lx ", internal_strlen(RegName) == 2 ? " " : "", RegName,
+ GetArmRegister(ctx, RegNum));
+# elif defined(__aarch64__)
+ Printf("%s%s = 0x%016llx ", internal_strlen(RegName) == 2 ? " " : "",
+ RegName, GetArmRegister(ctx, RegNum));
# else
(void)RegName;
# endif
@@ -2232,6 +2343,35 @@ void SignalContext::DumpAllRegisters(void *context) {
DumpSingleReg(ucontext, REG_EBP);
DumpSingleReg(ucontext, REG_ESP);
Printf("\n");
+# elif defined(__arm__)
+ Report("Register values:\n");
+ DumpSingleReg(ucontext, REG_R0);
+ DumpSingleReg(ucontext, REG_R1);
+ DumpSingleReg(ucontext, REG_R2);
+ DumpSingleReg(ucontext, REG_R3);
+ Printf("\n");
+ DumpSingleReg(ucontext, REG_R4);
+ DumpSingleReg(ucontext, REG_R5);
+ DumpSingleReg(ucontext, REG_R6);
+ DumpSingleReg(ucontext, REG_R7);
+ Printf("\n");
+ DumpSingleReg(ucontext, REG_R8);
+ DumpSingleReg(ucontext, REG_R9);
+ DumpSingleReg(ucontext, REG_R10);
+ DumpSingleReg(ucontext, REG_R11);
+ Printf("\n");
+ DumpSingleReg(ucontext, REG_R12);
+ DumpSingleReg(ucontext, REG_R13);
+ DumpSingleReg(ucontext, REG_R14);
+ DumpSingleReg(ucontext, REG_R15);
+ Printf("\n");
+# elif defined(__aarch64__)
+ Report("Register values:\n");
+ for (int i = 0; i <= 31; ++i) {
+ DumpSingleReg(ucontext, i);
+ if (i % 4 == 3)
+ Printf("\n");
+ }
# endif
(void)ucontext;
# endif
>From 50fb153c9ca7eefea20a4d74e32f4f95f2f68386 Mon Sep 17 00:00:00 2001
From: Dmitry Chestnykh <dm.chestnykh at gmail.com>
Date: Fri, 19 Jul 2024 11:06:04 +0300
Subject: [PATCH 2/2] [compiler-rt][test] Add tests to `DumpAllRegisters`
- Add tests to check `DumpAllRegisters` output
on ARM and AArch64
---
.../lib/sanitizer_common/sanitizer_linux.cpp | 44 ++++++++++++++++++-
.../Linux/dump_registers_aarch64.cpp | 23 ++++++++++
.../TestCases/Linux/dump_registers_arm.cpp | 19 ++++++++
3 files changed, 85 insertions(+), 1 deletion(-)
create mode 100644 compiler-rt/test/sanitizer_common/TestCases/Linux/dump_registers_aarch64.cpp
create mode 100644 compiler-rt/test/sanitizer_common/TestCases/Linux/dump_registers_arm.cpp
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 441945b6f9c5b..861133253c4d2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -2283,6 +2283,8 @@ static unsigned long GetArmRegister(ucontext_t *ctx, int RegNum) {
}
# endif // SANITIZER_LINUX && (defined(__arm__) || defined(__aarch64__))
+
+# if SANITIZER_LINUX
UNUSED
static void DumpSingleReg(ucontext_t *ctx, int RegNum) {
const char *RegName = RegNumToRegName(RegNum);
@@ -2301,10 +2303,11 @@ static void DumpSingleReg(ucontext_t *ctx, int RegNum) {
(void)RegName;
# endif
}
+# endif
void SignalContext::DumpAllRegisters(void *context) {
-# if SANITIZER_LINUX
ucontext_t *ucontext = (ucontext_t *)context;
+# if SANITIZER_LINUX
# if defined(__x86_64__)
Report("Register values:\n");
DumpSingleReg(ucontext, REG_RAX);
@@ -2372,8 +2375,47 @@ void SignalContext::DumpAllRegisters(void *context) {
if (i % 4 == 3)
Printf("\n");
}
+# else
+ (void)ucontext;
# endif
+# elif SANITIZER_FREEBSD
+# if defined(__x86_64__)
+ Report("Register values:\n");
+ Printf("rax = 0x%016llx ", ucontext->uc_mcontext.mc_rax);
+ Printf("rbx = 0x%016llx ", ucontext->uc_mcontext.mc_rbx);
+ Printf("rcx = 0x%016llx ", ucontext->uc_mcontext.mc_rcx);
+ Printf("rdx = 0x%016llx ", ucontext->uc_mcontext.mc_rdx);
+ Printf("\n");
+ Printf("rdi = 0x%016llx ", ucontext->uc_mcontext.mc_rdi);
+ Printf("rsi = 0x%016llx ", ucontext->uc_mcontext.mc_rsi);
+ Printf("rbp = 0x%016llx ", ucontext->uc_mcontext.mc_rbp);
+ Printf("rsp = 0x%016llx ", ucontext->uc_mcontext.mc_rsp);
+ Printf("\n");
+ Printf(" r8 = 0x%016llx ", ucontext->uc_mcontext.mc_r8);
+ Printf(" r9 = 0x%016llx ", ucontext->uc_mcontext.mc_r9);
+ Printf("r10 = 0x%016llx ", ucontext->uc_mcontext.mc_r10);
+ Printf("r11 = 0x%016llx ", ucontext->uc_mcontext.mc_r11);
+ Printf("\n");
+ Printf("r12 = 0x%016llx ", ucontext->uc_mcontext.mc_r12);
+ Printf("r13 = 0x%016llx ", ucontext->uc_mcontext.mc_r13);
+ Printf("r14 = 0x%016llx ", ucontext->uc_mcontext.mc_r14);
+ Printf("r15 = 0x%016llx ", ucontext->uc_mcontext.mc_r15);
+ Printf("\n");
+# elif defined(__i386__)
+ Report("Register values:\n");
+ Printf("eax = 0x%08x ", ucontext->uc_mcontext.mc_eax);
+ Printf("ebx = 0x%08x ", ucontext->uc_mcontext.mc_ebx);
+ Printf("ecx = 0x%08x ", ucontext->uc_mcontext.mc_ecx);
+ Printf("edx = 0x%08x ", ucontext->uc_mcontext.mc_edx);
+ Printf("\n");
+ Printf("edi = 0x%08x ", ucontext->uc_mcontext.mc_edi);
+ Printf("esi = 0x%08x ", ucontext->uc_mcontext.mc_esi);
+ Printf("ebp = 0x%08x ", ucontext->uc_mcontext.mc_ebp);
+ Printf("esp = 0x%08x ", ucontext->uc_mcontext.mc_esp);
+ Printf("\n");
+# else
(void)ucontext;
+# endif
# endif
// FIXME: Implement this for other OSes and architectures.
}
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/dump_registers_aarch64.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/dump_registers_aarch64.cpp
new file mode 100644
index 0000000000000..e73de49b5c84e
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/dump_registers_aarch64.cpp
@@ -0,0 +1,23 @@
+// Check that sanitizer prints registers dump_registers on dump_registers=1
+// RUN: %clangxx %s -o %t
+// RUN: %env_tool_opts=dump_registers=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUMP
+//
+// REQUIRES: aarch64-target-arch
+
+#include <signal.h>
+
+int main() {
+ raise(SIGSEGV);
+ // CHECK-DUMP: Register values
+ // CHECK-DUMP-NEXT: x0 = {{0x[0-9a-f]+}} x1 = {{0x[0-9a-f]+}} x2 = {{0x[0-9a-f]+}} x3 = {{0x[0-9a-f]+}}
+ // CHECK-DUMP-NEXT: x4 = {{0x[0-9a-f]+}} x5 = {{0x[0-9a-f]+}} x6 = {{0x[0-9a-f]+}} x7 = {{0x[0-9a-f]+}}
+ // CHECK-DUMP-NEXT: x8 = {{0x[0-9a-f]+}} x9 = {{0x[0-9a-f]+}} x10 = {{0x[0-9a-f]+}} x11 = {{0x[0-9a-f]+}}
+ // CHECK-DUMP-NEXT:x12 = {{0x[0-9a-f]+}} x13 = {{0x[0-9a-f]+}} x14 = {{0x[0-9a-f]+}} x15 = {{0x[0-9a-f]+}}
+ // CHECK-DUMP-NEXT:x16 = {{0x[0-9a-f]+}} x17 = {{0x[0-9a-f]+}} x18 = {{0x[0-9a-f]+}} x19 = {{0x[0-9a-f]+}}
+ // CHECK-DUMP-NEXT:x20 = {{0x[0-9a-f]+}} x21 = {{0x[0-9a-f]+}} x22 = {{0x[0-9a-f]+}} x23 = {{0x[0-9a-f]+}}
+ // CHECK-DUMP-NEXT:x24 = {{0x[0-9a-f]+}} x25 = {{0x[0-9a-f]+}} x26 = {{0x[0-9a-f]+}} x27 = {{0x[0-9a-f]+}}
+ // CHECK-DUMP-NEXT:x28 = {{0x[0-9a-f]+}} fp = {{0x[0-9a-f]+}} lr = {{0x[0-9a-f]+}} sp = {{0x[0-9a-f]+}}
+ // CHECK-NODUMP-NOT: Register values
+ return 0;
+}
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/dump_registers_arm.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/dump_registers_arm.cpp
new file mode 100644
index 0000000000000..4b322ce2564eb
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/dump_registers_arm.cpp
@@ -0,0 +1,19 @@
+// Check that sanitizer prints registers dump_registers on dump_registers=1
+// RUN: %clangxx %s -o %t
+// RUN: %env_tool_opts=dump_registers=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUMP
+//
+// REQUIRES: arm-target-arch
+
+#include <signal.h>
+
+int main() {
+ raise(SIGSEGV);
+ // CHECK-DUMP: Register values
+ // CHECK-DUMP-NEXT: r0 = {{0x[0-9a-f]+}} r1 = {{0x[0-9a-f]+}} r2 = {{0x[0-9a-f]+}} r3 = {{0x[0-9a-f]+}}
+ // CHECK-DUMP-NEXT: r4 = {{0x[0-9a-f]+}} r5 = {{0x[0-9a-f]+}} r6 = {{0x[0-9a-f]+}} r7 = {{0x[0-9a-f]+}}
+ // CHECK-DUMP-NEXT: r8 = {{0x[0-9a-f]+}} r9 = {{0x[0-9a-f]+}} r10 = {{0x[0-9a-f]+}} r11 = {{0x[0-9a-f]+}}
+ // CHECK-DUMP-NEXT:r12 = {{0x[0-9a-f]+}} sp = {{0x[0-9a-f]+}} lr = {{0x[0-9a-f]+}} pc = {{0x[0-9a-f]+}}
+ // CHECK-NODUMP-NOT: Register values
+ return 0;
+}
More information about the llvm-commits
mailing list