[TSan] Improve handling of stack pointer mangling in {set,long}jmp, pt.7

Factor out `ExtractLongJmpSp` helper function and move platform-specific
code to tsan_platform_{linux,mac}.cc.

Reviewed By: dvyukov

Differential Revision: https://reviews.llvm.org/D64050

llvm-svn: 364947
This commit is contained in:
Julian Lettner 2019-07-02 17:32:04 +00:00
parent f9b91a5279
commit 36face4c1d
4 changed files with 36 additions and 29 deletions

View File

@ -505,29 +505,7 @@ static void SetJmp(ThreadState *thr, uptr sp) {
}
static void LongJmp(ThreadState *thr, uptr *env) {
#ifdef __powerpc__
uptr mangled_sp = env[0];
#elif SANITIZER_FREEBSD
uptr mangled_sp = env[2];
#elif SANITIZER_NETBSD
uptr mangled_sp = env[6];
#elif SANITIZER_MAC
# ifdef __aarch64__
uptr mangled_sp =
(GetMacosVersion() >= MACOS_VERSION_MOJAVE) ? env[12] : env[13];
# else
uptr mangled_sp = env[2];
# endif
#elif SANITIZER_LINUX
# ifdef __aarch64__
uptr mangled_sp = env[13];
# elif defined(__mips64)
uptr mangled_sp = env[1];
# else
uptr mangled_sp = env[6];
# endif
#endif
uptr sp = UnmangleLongJmpSp(mangled_sp);
uptr sp = ExtractLongJmpSp(env);
// Find the saved buf with matching sp.
for (uptr i = 0; i < thr->jmp_bufs.Size(); i++) {
JmpBuf *buf = &thr->jmp_bufs[i];

View File

@ -1011,7 +1011,7 @@ void FlushShadowMemory();
void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive);
int ExtractResolvFDs(void *state, int *fds, int nfd);
int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
uptr UnmangleLongJmpSp(uptr mangled_sp);
uptr ExtractLongJmpSp(uptr *env);
void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size);
int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,

View File

@ -336,11 +336,11 @@ int ExtractRecvmsgFDs(void *msgp, int *fds, int nfd) {
}
// Reverse operation of libc stack pointer mangling
uptr UnmangleLongJmpSp(uptr mangled_sp) {
static uptr UnmangleLongJmpSp(uptr mangled_sp) {
#if defined(__x86_64__)
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
# if SANITIZER_FREEBSD || SANITIZER_NETBSD
return mangled_sp;
#else // Linux
# else // Linux
// Reverse of:
// xor %fs:0x30, %rsi
// rol $0x11, %rsi
@ -350,7 +350,7 @@ uptr UnmangleLongJmpSp(uptr mangled_sp) {
: "=r" (sp)
: "0" (mangled_sp));
return sp;
#endif
# endif
#elif defined(__aarch64__)
# if SANITIZER_LINUX
return mangled_sp ^ _tsan_pointer_chk_guard;
@ -371,6 +371,27 @@ uptr UnmangleLongJmpSp(uptr mangled_sp) {
#endif
}
#ifdef __powerpc__
# define LONG_JMP_SP_ENV_SLOT 0
#elif SANITIZER_FREEBSD
# define LONG_JMP_SP_ENV_SLOT 2
#elif SANITIZER_NETBSD
# define LONG_JMP_SP_ENV_SLOT 6
#elif SANITIZER_LINUX
# ifdef __aarch64__
# define LONG_JMP_SP_ENV_SLOT 13
# elif defined(__mips64)
# define LONG_JMP_SP_ENV_SLOT 1
# else
# define LONG_JMP_SP_ENV_SLOT 6
# endif
#endif
uptr ExtractLongJmpSp(uptr *env) {
uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT];
return UnmangleLongJmpSp(mangled_sp);
}
void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
// Check that the thr object is in tls;
const uptr thr_beg = (uptr)thr;

View File

@ -259,7 +259,15 @@ void InitializePlatform() {
}
}
uptr UnmangleLongJmpSp(uptr mangled_sp) {
#ifdef __aarch64__
# define LONG_JMP_SP_ENV_SLOT \
((GetMacosVersion() >= MACOS_VERSION_MOJAVE) ? 12 : 13)
#else
# define LONG_JMP_SP_ENV_SLOT 2
#endif
uptr ExtractLongJmpSp(uptr *env) {
uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT];
return mangled_sp ^ __tsan_darwin_setjmp_xor_key;
}