Skip to content

Commit e894df6

Browse files
authored
[compiler-rt] Implement DumpAllRegisters for arm-linux and aarch64-linux (#100398)
Reland with a couple of build fixes #100337 #100342 #99613
1 parent 115c89b commit e894df6

File tree

3 files changed

+191
-5
lines changed

3 files changed

+191
-5
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp

+149-5
Original file line numberDiff line numberDiff line change
@@ -2172,15 +2172,125 @@ static const char *RegNumToRegName(int reg) {
21722172
return "ebp";
21732173
case REG_ESP:
21742174
return "esp";
2175+
# elif defined(__arm__)
2176+
# ifdef MAKE_CASE
2177+
# undef MAKE_CASE
2178+
# endif
2179+
# define REG_STR(reg) #reg
2180+
# define MAKE_CASE(N) \
2181+
case REG_R##N: \
2182+
return REG_STR(r##N)
2183+
MAKE_CASE(0);
2184+
MAKE_CASE(1);
2185+
MAKE_CASE(2);
2186+
MAKE_CASE(3);
2187+
MAKE_CASE(4);
2188+
MAKE_CASE(5);
2189+
MAKE_CASE(6);
2190+
MAKE_CASE(7);
2191+
MAKE_CASE(8);
2192+
MAKE_CASE(9);
2193+
MAKE_CASE(10);
2194+
MAKE_CASE(11);
2195+
MAKE_CASE(12);
2196+
case REG_R13:
2197+
return "sp";
2198+
case REG_R14:
2199+
return "lr";
2200+
case REG_R15:
2201+
return "pc";
2202+
# elif defined(__aarch64__)
2203+
# define REG_STR(reg) #reg
2204+
# define MAKE_CASE(N) \
2205+
case N: \
2206+
return REG_STR(x##N)
2207+
MAKE_CASE(0);
2208+
MAKE_CASE(1);
2209+
MAKE_CASE(2);
2210+
MAKE_CASE(3);
2211+
MAKE_CASE(4);
2212+
MAKE_CASE(5);
2213+
MAKE_CASE(6);
2214+
MAKE_CASE(7);
2215+
MAKE_CASE(8);
2216+
MAKE_CASE(9);
2217+
MAKE_CASE(10);
2218+
MAKE_CASE(11);
2219+
MAKE_CASE(12);
2220+
MAKE_CASE(13);
2221+
MAKE_CASE(14);
2222+
MAKE_CASE(15);
2223+
MAKE_CASE(16);
2224+
MAKE_CASE(17);
2225+
MAKE_CASE(18);
2226+
MAKE_CASE(19);
2227+
MAKE_CASE(20);
2228+
MAKE_CASE(21);
2229+
MAKE_CASE(22);
2230+
MAKE_CASE(23);
2231+
MAKE_CASE(24);
2232+
MAKE_CASE(25);
2233+
MAKE_CASE(26);
2234+
MAKE_CASE(27);
2235+
MAKE_CASE(28);
2236+
case 29:
2237+
return "fp";
2238+
case 30:
2239+
return "lr";
2240+
case 31:
2241+
return "sp";
21752242
# endif
2176-
# endif
2243+
# endif // SANITIZER_LINUX
21772244
default:
21782245
return NULL;
21792246
}
21802247
return NULL;
21812248
}
21822249

2183-
# if SANITIZER_LINUX
2250+
# if SANITIZER_LINUX && (defined(__arm__) || defined(__aarch64__))
2251+
static uptr GetArmRegister(ucontext_t *ctx, int RegNum) {
2252+
switch (RegNum) {
2253+
# if defined(__arm__)
2254+
# ifdef MAKE_CASE
2255+
# undef MAKE_CASE
2256+
# endif
2257+
# define MAKE_CASE(N) \
2258+
case REG_R##N: \
2259+
return ctx->uc_mcontext.arm_r##N
2260+
MAKE_CASE(0);
2261+
MAKE_CASE(1);
2262+
MAKE_CASE(2);
2263+
MAKE_CASE(3);
2264+
MAKE_CASE(4);
2265+
MAKE_CASE(5);
2266+
MAKE_CASE(6);
2267+
MAKE_CASE(7);
2268+
MAKE_CASE(8);
2269+
MAKE_CASE(9);
2270+
MAKE_CASE(10);
2271+
case REG_R11:
2272+
return ctx->uc_mcontext.arm_fp;
2273+
case REG_R12:
2274+
return ctx->uc_mcontext.arm_ip;
2275+
case REG_R13:
2276+
return ctx->uc_mcontext.arm_sp;
2277+
case REG_R14:
2278+
return ctx->uc_mcontext.arm_lr;
2279+
case REG_R15:
2280+
return ctx->uc_mcontext.arm_pc;
2281+
# elif defined(__aarch64__)
2282+
case 0 ... 30:
2283+
return ctx->uc_mcontext.regs[RegNum];
2284+
case 31:
2285+
return ctx->uc_mcontext.sp;
2286+
# endif
2287+
default:
2288+
return 0;
2289+
}
2290+
return 0;
2291+
}
2292+
# endif // SANITIZER_LINUX && (defined(__arm__) || defined(__aarch64__))
2293+
21842294
UNUSED
21852295
static void DumpSingleReg(ucontext_t *ctx, int RegNum) {
21862296
const char *RegName = RegNumToRegName(RegNum);
@@ -2189,11 +2299,16 @@ static void DumpSingleReg(ucontext_t *ctx, int RegNum) {
21892299
RegName, ctx->uc_mcontext.gregs[RegNum]);
21902300
# elif defined(__i386__)
21912301
Printf("%s = 0x%08x ", RegName, ctx->uc_mcontext.gregs[RegNum]);
2192-
# else
2302+
# elif defined(__arm__)
2303+
Printf("%s%s = 0x%08zx ", internal_strlen(RegName) == 2 ? " " : "", RegName,
2304+
GetArmRegister(ctx, RegNum));
2305+
# elif defined(__aarch64__)
2306+
Printf("%s%s = 0x%016zx ", internal_strlen(RegName) == 2 ? " " : "", RegName,
2307+
GetArmRegister(ctx, RegNum));
2308+
# else
21932309
(void)RegName;
2194-
# endif
2195-
}
21962310
# endif
2311+
}
21972312

21982313
void SignalContext::DumpAllRegisters(void *context) {
21992314
ucontext_t *ucontext = (ucontext_t *)context;
@@ -2236,6 +2351,35 @@ void SignalContext::DumpAllRegisters(void *context) {
22362351
DumpSingleReg(ucontext, REG_EBP);
22372352
DumpSingleReg(ucontext, REG_ESP);
22382353
Printf("\n");
2354+
# elif defined(__arm__)
2355+
Report("Register values:\n");
2356+
DumpSingleReg(ucontext, REG_R0);
2357+
DumpSingleReg(ucontext, REG_R1);
2358+
DumpSingleReg(ucontext, REG_R2);
2359+
DumpSingleReg(ucontext, REG_R3);
2360+
Printf("\n");
2361+
DumpSingleReg(ucontext, REG_R4);
2362+
DumpSingleReg(ucontext, REG_R5);
2363+
DumpSingleReg(ucontext, REG_R6);
2364+
DumpSingleReg(ucontext, REG_R7);
2365+
Printf("\n");
2366+
DumpSingleReg(ucontext, REG_R8);
2367+
DumpSingleReg(ucontext, REG_R9);
2368+
DumpSingleReg(ucontext, REG_R10);
2369+
DumpSingleReg(ucontext, REG_R11);
2370+
Printf("\n");
2371+
DumpSingleReg(ucontext, REG_R12);
2372+
DumpSingleReg(ucontext, REG_R13);
2373+
DumpSingleReg(ucontext, REG_R14);
2374+
DumpSingleReg(ucontext, REG_R15);
2375+
Printf("\n");
2376+
# elif defined(__aarch64__)
2377+
Report("Register values:\n");
2378+
for (int i = 0; i <= 31; ++i) {
2379+
DumpSingleReg(ucontext, i);
2380+
if (i % 4 == 3)
2381+
Printf("\n");
2382+
}
22392383
# else
22402384
(void)ucontext;
22412385
# endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Check that sanitizer prints registers dump_registers on dump_registers=1
2+
// RUN: %clangxx %s -o %t
3+
// RUN: %env_tool_opts=dump_registers=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP
4+
// RUN: not %run %t 2>&1 | FileCheck %s --strict-whitespace --check-prefix=CHECK-DUMP
5+
//
6+
// REQUIRES: aarch64-target-arch
7+
8+
#include <signal.h>
9+
10+
int main() {
11+
raise(SIGSEGV);
12+
// CHECK-DUMP: Register values
13+
// CHECK-DUMP-NEXT: x0 = {{0x[0-9a-f]+}} x1 = {{0x[0-9a-f]+}} x2 = {{0x[0-9a-f]+}} x3 = {{0x[0-9a-f]+}}
14+
// CHECK-DUMP-NEXT: x4 = {{0x[0-9a-f]+}} x5 = {{0x[0-9a-f]+}} x6 = {{0x[0-9a-f]+}} x7 = {{0x[0-9a-f]+}}
15+
// CHECK-DUMP-NEXT: x8 = {{0x[0-9a-f]+}} x9 = {{0x[0-9a-f]+}} x10 = {{0x[0-9a-f]+}} x11 = {{0x[0-9a-f]+}}
16+
// CHECK-DUMP-NEXT:x12 = {{0x[0-9a-f]+}} x13 = {{0x[0-9a-f]+}} x14 = {{0x[0-9a-f]+}} x15 = {{0x[0-9a-f]+}}
17+
// CHECK-DUMP-NEXT:x16 = {{0x[0-9a-f]+}} x17 = {{0x[0-9a-f]+}} x18 = {{0x[0-9a-f]+}} x19 = {{0x[0-9a-f]+}}
18+
// CHECK-DUMP-NEXT:x20 = {{0x[0-9a-f]+}} x21 = {{0x[0-9a-f]+}} x22 = {{0x[0-9a-f]+}} x23 = {{0x[0-9a-f]+}}
19+
// CHECK-DUMP-NEXT:x24 = {{0x[0-9a-f]+}} x25 = {{0x[0-9a-f]+}} x26 = {{0x[0-9a-f]+}} x27 = {{0x[0-9a-f]+}}
20+
// CHECK-DUMP-NEXT:x28 = {{0x[0-9a-f]+}} fp = {{0x[0-9a-f]+}} lr = {{0x[0-9a-f]+}} sp = {{0x[0-9a-f]+}}
21+
// CHECK-NODUMP-NOT: Register values
22+
return 0;
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Check that sanitizer prints registers dump_registers on dump_registers=1
2+
// RUN: %clangxx %s -o %t
3+
// RUN: %env_tool_opts=dump_registers=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP
4+
// RUN: not %run %t 2>&1 | FileCheck %s --strict-whitespace --check-prefix=CHECK-DUMP
5+
//
6+
// REQUIRES: arm-target-arch
7+
8+
#include <signal.h>
9+
10+
int main() {
11+
raise(SIGSEGV);
12+
// CHECK-DUMP: Register values
13+
// CHECK-DUMP-NEXT: r0 = {{0x[0-9a-f]+}} r1 = {{0x[0-9a-f]+}} r2 = {{0x[0-9a-f]+}} r3 = {{0x[0-9a-f]+}}
14+
// CHECK-DUMP-NEXT: r4 = {{0x[0-9a-f]+}} r5 = {{0x[0-9a-f]+}} r6 = {{0x[0-9a-f]+}} r7 = {{0x[0-9a-f]+}}
15+
// CHECK-DUMP-NEXT: r8 = {{0x[0-9a-f]+}} r9 = {{0x[0-9a-f]+}} r10 = {{0x[0-9a-f]+}} r11 = {{0x[0-9a-f]+}}
16+
// CHECK-DUMP-NEXT:r12 = {{0x[0-9a-f]+}} sp = {{0x[0-9a-f]+}} lr = {{0x[0-9a-f]+}} pc = {{0x[0-9a-f]+}}
17+
// CHECK-NODUMP-NOT: Register values
18+
return 0;
19+
}

0 commit comments

Comments
 (0)