summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h')
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h19
1 files changed, 18 insertions, 1 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
index e755c052cb7..79be2879248 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
@@ -57,12 +57,29 @@ struct StackTrace {
}
static uptr GetCurrentPc();
- static uptr GetPreviousInstructionPc(uptr pc);
+ static inline uptr GetPreviousInstructionPc(uptr pc);
static uptr GetNextInstructionPc(uptr pc);
typedef bool (*SymbolizeCallback)(const void *pc, char *out_buffer,
int out_size);
};
+// Performance-critical, must be in the header.
+ALWAYS_INLINE
+uptr StackTrace::GetPreviousInstructionPc(uptr pc) {
+#if defined(__arm__)
+ // Cancel Thumb bit.
+ pc = pc & (~1);
+#endif
+#if defined(__powerpc__) || defined(__powerpc64__)
+ // PCs are always 4 byte aligned.
+ return pc - 4;
+#elif defined(__sparc__) || defined(__mips__)
+ return pc - 8;
+#else
+ return pc - 1;
+#endif
+}
+
// StackTrace that owns the buffer used to store the addresses.
struct BufferedStackTrace : public StackTrace {
uptr trace_buffer[kStackTraceMax];
OpenPOWER on IntegriCloud