|
21 | 21 | #ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_ |
22 | 22 | #define ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_ |
23 | 23 |
|
| 24 | +#include "absl/debugging/internal/addresses.h" |
24 | 25 | #if defined(__linux__) |
25 | 26 | #include <asm/ptrace.h> // for PT_NIP. |
26 | 27 | #include <ucontext.h> // for ucontext_t |
|
40 | 41 |
|
41 | 42 | // Given a stack pointer, return the saved link register value. |
42 | 43 | // Note that this is the link register for a callee. |
43 | | -static inline void *StacktracePowerPCGetLR(void **sp) { |
| 44 | +static inline void **StacktracePowerPCGetLRPtr(void **sp) { |
44 | 45 | // PowerPC has 3 main ABIs, which say where in the stack the |
45 | 46 | // Link Register is. For DARWIN and AIX (used by apple and |
46 | 47 | // linux ppc64), it's in sp[2]. For SYSV (used by linux ppc), |
47 | 48 | // it's in sp[1]. |
48 | 49 | #if defined(_CALL_AIX) || defined(_CALL_DARWIN) |
49 | | - return *(sp+2); |
| 50 | + return (sp + 2); |
50 | 51 | #elif defined(_CALL_SYSV) |
51 | | - return *(sp+1); |
| 52 | + return (sp + 1); |
52 | 53 | #elif defined(__APPLE__) || defined(__FreeBSD__) || \ |
53 | 54 | (defined(__linux__) && defined(__PPC64__)) |
54 | 55 | // This check is in case the compiler doesn't define _CALL_AIX/etc. |
55 | | - return *(sp+2); |
| 56 | + return (sp + 2); |
56 | 57 | #elif defined(__linux) |
57 | 58 | // This check is in case the compiler doesn't define _CALL_SYSV. |
58 | | - return *(sp+1); |
| 59 | + return (sp + 1); |
59 | 60 | #else |
60 | 61 | #error Need to specify the PPC ABI for your architecture. |
61 | 62 | #endif |
@@ -125,9 +126,8 @@ static void **NextStackFrame(void **old_sp, const void *uc) { |
125 | 126 | } |
126 | 127 | } |
127 | 128 |
|
128 | | - if (new_sp != nullptr && |
129 | | - kernel_symbol_status == kAddressValid && |
130 | | - StacktracePowerPCGetLR(new_sp) == kernel_sigtramp_rt64_address) { |
| 129 | + if (new_sp != nullptr && kernel_symbol_status == kAddressValid && |
| 130 | + *StacktracePowerPCGetLRPtr(new_sp) == kernel_sigtramp_rt64_address) { |
131 | 131 | const ucontext_t* signal_context = |
132 | 132 | reinterpret_cast<const ucontext_t*>(uc); |
133 | 133 | void **const sp_before_signal = |
@@ -164,8 +164,9 @@ ABSL_ATTRIBUTE_NOINLINE static void AbslStacktracePowerPCDummyFunction() { |
164 | 164 | template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> |
165 | 165 | ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. |
166 | 166 | ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. |
167 | | -static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, |
168 | | - const void *ucp, int *min_dropped_frames) { |
| 167 | +static int UnwindImpl(void **result, uintptr_t *frames, int *sizes, |
| 168 | + int max_depth, int skip_count, const void *ucp, |
| 169 | + int *min_dropped_frames) { |
169 | 170 | void **sp; |
170 | 171 | // Apple macOS uses an old version of gnu as -- both Darwin 7.9.0 (Panther) |
171 | 172 | // and Darwin 8.8.1 (Tiger) use as 1.38. This means we have to use a |
@@ -211,13 +212,21 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, |
211 | 212 | if (skip_count > 0) { |
212 | 213 | skip_count--; |
213 | 214 | } else { |
214 | | - result[n] = StacktracePowerPCGetLR(sp); |
| 215 | + void **lr = StacktracePowerPCGetLRPtr(sp); |
| 216 | + result[n] = *lr; |
215 | 217 | if (IS_STACK_FRAMES) { |
216 | | - if (next_sp > sp) { |
217 | | - sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp; |
218 | | - } else { |
219 | | - // A frame-size of 0 is used to indicate unknown frame size. |
220 | | - sizes[n] = 0; |
| 218 | + if (frames != nullptr) { |
| 219 | + frames[n] = absl::debugging_internal::StripPointerMetadata(lr) + |
| 220 | + 1 * sizeof(void *) /* go past the return address */; |
| 221 | + } |
| 222 | + if (sizes != nullptr) { |
| 223 | + if (next_sp > sp) { |
| 224 | + sizes[n] = absl::debugging_internal::StripPointerMetadata(next_sp) - |
| 225 | + absl::debugging_internal::StripPointerMetadata(sp); |
| 226 | + } else { |
| 227 | + // A frame-size of 0 is used to indicate unknown frame size. |
| 228 | + sizes[n] = 0; |
| 229 | + } |
221 | 230 | } |
222 | 231 | } |
223 | 232 | n++; |
|
0 commit comments