diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-07-20 10:46:51 -0700 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-11-04 13:26:17 +0100 |
commit | 65ade6a34cb62f82494c0a8ca4ff3600f3a94af9 (patch) | |
tree | 39c87aa79f20855dec0ec03f01d5310cb4ac92d6 /libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp | |
parent | 0cedf1fb76c10bbb9d23f4953b8fecd8eba908d3 (diff) | |
download | gcc-65ade6a34cb62f82494c0a8ca4ff3600f3a94af9.tar.gz |
libsanitizer: Apply local patches
Diffstat (limited to 'libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp')
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp index 37e9e6dd08d..5a12422fc6f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp @@ -86,8 +86,8 @@ static inline uhwptr *GetCanonicFrame(uptr bp, // Nope, this does not look right either. This means the frame after next does // not have a valid frame pointer, but we can still extract the caller PC. // Unfortunately, there is no way to decide between GCC and LLVM frame - // layouts. Assume LLVM. - return bp_prev; + // layouts. Assume GCC. + return bp_prev - 1; #else return (uhwptr*)bp; #endif @@ -110,14 +110,21 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top, IsAligned((uptr)frame, sizeof(*frame)) && size < max_depth) { #ifdef __powerpc__ - // PowerPC ABIs specify that the return address is saved at offset - // 16 of the *caller's* stack frame. Thus we must dereference the - // back chain to find the caller frame before extracting it. + // PowerPC ABIs specify that the return address is saved on the + // *caller's* stack frame. Thus we must dereference the back chain + // to find the caller frame before extracting it. uhwptr *caller_frame = (uhwptr*)frame[0]; if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) || !IsAligned((uptr)caller_frame, sizeof(uhwptr))) break; + // For most ABIs the offset where the return address is saved is two + // register sizes. The exception is the SVR4 ABI, which uses an + // offset of only one register size. +#ifdef _CALL_SYSV + uhwptr pc1 = caller_frame[1]; +#else uhwptr pc1 = caller_frame[2]; +#endif #elif defined(__s390__) uhwptr pc1 = frame[14]; #elif defined(__riscv) |