Skip to content

Commit c578c17

Browse files
committed
Fixed DWARF unwinding of nativemem stacks on ARM64
1 parent 49aadce commit c578c17

2 files changed

Lines changed: 37 additions & 17 deletions

File tree

src/arch.h

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
#define _ARCH_H
88

99

10-
# ifndef likely
11-
# define likely(x) (__builtin_expect(!!(x), 1))
12-
# endif
10+
#ifndef likely
11+
# define likely(x) (__builtin_expect(!!(x), 1))
12+
#endif
13+
14+
#ifndef unlikely
15+
# define unlikely(x) (__builtin_expect(!!(x), 0))
16+
#endif
17+
18+
#define callerPC() __builtin_return_address(0)
1319

14-
# ifndef unlikely
15-
# define unlikely(x) (__builtin_expect(!!(x), 0))
16-
# endif
1720

1821
typedef unsigned char u8;
1922
typedef unsigned short u16;
@@ -58,6 +61,9 @@ const int PERF_REG_PC = 8; // PERF_REG_X86_IP
5861
#define rmb() asm volatile("lfence" : : : "memory")
5962
#define flushCache(addr) asm volatile("mfence; clflush (%0); mfence" : : "r" (addr) : "memory")
6063

64+
#define callerFP() __builtin_frame_address(1)
65+
#define callerSP() ((void**)__builtin_frame_address(0) + 2)
66+
6167
#elif defined(__arm__) || defined(__thumb__)
6268

6369
typedef unsigned int instruction_t;
@@ -76,6 +82,9 @@ const int PERF_REG_PC = 15; // PERF_REG_ARM_PC
7682
#define rmb() asm volatile("dmb ish" : : : "memory")
7783
#define flushCache(addr) __builtin___clear_cache((char*)(addr), (char*)(addr) + sizeof(instruction_t))
7884

85+
#define callerFP() __builtin_frame_address(1)
86+
#define callerSP() __builtin_frame_address(1)
87+
7988
#elif defined(__aarch64__)
8089

8190
typedef unsigned int instruction_t;
@@ -93,6 +102,9 @@ const int PERF_REG_PC = 32; // PERF_REG_ARM64_PC
93102
#define rmb() asm volatile("dmb ish" : : : "memory")
94103
#define flushCache(addr) __builtin___clear_cache((char*)(addr), (char*)(addr) + sizeof(instruction_t))
95104

105+
#define callerFP() __builtin_frame_address(1)
106+
#define callerSP() __builtin_frame_address(1)
107+
96108
#elif defined(__PPC64__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
97109

98110
typedef unsigned int instruction_t;
@@ -112,6 +124,9 @@ const int PERF_REG_PC = 32; // PERF_REG_POWERPC_NIP
112124
#define rmb() asm volatile ("sync" : : : "memory") // lwsync would do but better safe than sorry
113125
#define flushCache(addr) __builtin___clear_cache((char*)(addr), (char*)(addr) + sizeof(instruction_t))
114126

127+
#define callerFP() __builtin_frame_address(1)
128+
#define callerSP() __builtin_frame_address(0)
129+
115130
#elif defined(__riscv) && (__riscv_xlen == 64)
116131

117132
typedef unsigned int instruction_t;
@@ -133,6 +148,9 @@ const int PERF_REG_PC = 0; // PERF_REG_RISCV_PC
133148
#define rmb() asm volatile ("fence" : : : "memory")
134149
#define flushCache(addr) __builtin___clear_cache((char*)(addr), (char*)(addr) + sizeof(instruction_t))
135150

151+
#define callerFP() __builtin_frame_address(1)
152+
#define callerSP() __builtin_frame_address(0)
153+
136154
#elif defined(__loongarch_lp64)
137155

138156
typedef unsigned int instruction_t;
@@ -150,6 +168,9 @@ const int PERF_REG_PC = 0; // PERF_REG_LOONGARCH_PC
150168
#define rmb() asm volatile("dbar 0x0" : : : "memory")
151169
#define flushCache(addr) __builtin___clear_cache((char*)(addr), (char*)(addr) + sizeof(instruction_t))
152170

171+
#define callerFP() __builtin_frame_address(1)
172+
#define callerSP() __builtin_frame_address(0)
173+
153174
#else
154175

155176
#error "Compiling on unsupported arch"

src/stackWalker.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ int StackWalker::walkFP(void* ucontext, const void** callchain, int max_depth, S
6060

6161
StackFrame frame(ucontext);
6262
if (ucontext == NULL) {
63-
pc = __builtin_return_address(0);
64-
fp = (uintptr_t)__builtin_frame_address(1);
65-
sp = (uintptr_t)__builtin_frame_address(0) + LINKED_FRAME_SIZE;
63+
pc = callerPC();
64+
fp = (uintptr_t)callerFP();
65+
sp = (uintptr_t)callerSP();
6666
} else {
6767
pc = (const void*)frame.pc();
6868
fp = frame.fp();
@@ -110,9 +110,9 @@ int StackWalker::walkDwarf(void* ucontext, const void** callchain, int max_depth
110110

111111
StackFrame frame(ucontext);
112112
if (ucontext == NULL) {
113-
pc = __builtin_return_address(0);
114-
fp = (uintptr_t)__builtin_frame_address(1);
115-
sp = (uintptr_t)__builtin_frame_address(0) + LINKED_FRAME_SIZE;
113+
pc = callerPC();
114+
fp = (uintptr_t)callerFP();
115+
sp = (uintptr_t)callerSP();
116116
} else {
117117
pc = (const void*)frame.pc();
118118
fp = frame.fp();
@@ -195,13 +195,12 @@ int StackWalker::walkDwarf(void* ucontext, const void** callchain, int max_depth
195195

196196
int StackWalker::walkVM(void* ucontext, ASGCT_CallFrame* frames, int max_depth, StackDetail detail) {
197197
if (ucontext == NULL) {
198-
const void* pc = __builtin_return_address(0);
199-
uintptr_t sp = (uintptr_t)__builtin_frame_address(0) + LINKED_FRAME_SIZE;
200-
uintptr_t fp = (uintptr_t)__builtin_frame_address(1);
201-
return walkVM(ucontext, frames, max_depth, detail, pc, sp, fp);
198+
return walkVM(ucontext, frames, max_depth, detail,
199+
callerPC(), (uintptr_t)callerSP(), (uintptr_t)callerFP());
202200
} else {
203201
StackFrame frame(ucontext);
204-
return walkVM(ucontext, frames, max_depth, detail, (const void*)frame.pc(), frame.sp(), frame.fp());
202+
return walkVM(ucontext, frames, max_depth, detail,
203+
(const void*)frame.pc(), frame.sp(), frame.fp());
205204
}
206205
}
207206

0 commit comments

Comments
 (0)