namespace __sanitizer {
-uptr StackTrace::GetNextInstructionPc(uptr pc) {
-#if defined(__sparc__) || defined(__mips__)
- return pc + 8;
-#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__)
- return pc + 4;
-#elif SANITIZER_RISCV64
- // Current check order is 4 -> 2 -> 6 -> 8
- u8 InsnByte = *(u8 *)(pc);
- if (((InsnByte & 0x3) == 0x3) && ((InsnByte & 0x1c) != 0x1c)) {
- // xxxxxxxxxxxbbb11 | 32 bit | bbb != 111
- return pc + 4;
- }
- if ((InsnByte & 0x3) != 0x3) {
- // xxxxxxxxxxxxxxaa | 16 bit | aa != 11
- return pc + 2;
- }
- // RISC-V encoding allows instructions to be up to 8 bytes long
- if ((InsnByte & 0x3f) == 0x1f) {
- // xxxxxxxxxx011111 | 48 bit |
- return pc + 6;
- }
- if ((InsnByte & 0x7f) == 0x3f) {
- // xxxxxxxxx0111111 | 64 bit |
- return pc + 8;
- }
- // bail-out if could not figure out the instruction size
- return 0;
-#else
- return pc + 1;
-#endif
-}
-
uptr StackTrace::GetCurrentPc() {
return GET_CALLER_PC();
}
#endif
}
+ALWAYS_INLINE
+uptr StackTrace::GetNextInstructionPc(uptr pc) {
+#if defined(__sparc__) || defined(__mips__)
+ return pc + 8;
+#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__)
+ return pc + 4;
+#elif SANITIZER_RISCV64
+ // Current check order is 4 -> 2 -> 6 -> 8
+ u8 InsnByte = *(u8 *)(pc);
+ if (((InsnByte & 0x3) == 0x3) && ((InsnByte & 0x1c) != 0x1c)) {
+ // xxxxxxxxxxxbbb11 | 32 bit | bbb != 111
+ return pc + 4;
+ }
+ if ((InsnByte & 0x3) != 0x3) {
+ // xxxxxxxxxxxxxxaa | 16 bit | aa != 11
+ return pc + 2;
+ }
+ // RISC-V encoding allows instructions to be up to 8 bytes long
+ if ((InsnByte & 0x3f) == 0x1f) {
+ // xxxxxxxxxx011111 | 48 bit |
+ return pc + 6;
+ }
+ if ((InsnByte & 0x7f) == 0x3f) {
+ // xxxxxxxxx0111111 | 64 bit |
+ return pc + 8;
+ }
+ // bail-out if could not figure out the instruction size
+ return 0;
+#else
+ return pc + 1;
+#endif
+}
+
// StackTrace that owns the buffer used to store the addresses.
struct BufferedStackTrace : public StackTrace {
uptr trace_buffer[kStackTraceMax];
uptr local_stack; \
uptr sp = (uptr)&local_stack
+#define GET_CURRENT_PC() \
+ ({ \
+ this_pc: \
+ StackTrace::GetNextInstructionPc((uptr) && this_pc); \
+ })
#endif // SANITIZER_STACKTRACE_H
} // namespace __tsan
-#define SCOPED_INTERCEPTOR_RAW(func, ...) \
- cur_thread_init(); \
- ThreadState *thr = cur_thread(); \
- const uptr caller_pc = GET_CALLER_PC(); \
- ScopedInterceptor si(thr, #func, caller_pc); \
- const uptr pc = StackTrace::GetCurrentPc(); \
- (void)pc; \
-/**/
+#define SCOPED_INTERCEPTOR_RAW(func, ...) \
+ cur_thread_init(); \
+ ThreadState *thr = cur_thread(); \
+ const uptr caller_pc = GET_CALLER_PC(); \
+ ScopedInterceptor si(thr, #func, caller_pc); \
+ const uptr pc = GET_CURRENT_PC(); \
+ (void)pc; \
+ /**/
#define SCOPED_TSAN_INTERCEPTOR(func, ...) \
SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
if (in_symbolizer())
return;
ThreadState *thr = cur_thread();
- const uptr pc = StackTrace::GetCurrentPc();
+ const uptr pc = GET_CURRENT_PC();
ForkBefore(thr, pc);
}
if (in_symbolizer())
return;
ThreadState *thr = cur_thread();
- const uptr pc = StackTrace::GetCurrentPc();
+ const uptr pc = GET_CURRENT_PC();
ForkParentAfter(thr, pc);
}
if (in_symbolizer())
return;
ThreadState *thr = cur_thread();
- const uptr pc = StackTrace::GetCurrentPc();
+ const uptr pc = GET_CURRENT_PC();
ForkChildAfter(thr, pc);
FdOnFork(thr, pc);
}