forked from OSchip/llvm-project
[compiler-rt][TSan] Add TSan runtime support for Go on linux-aarch64.
Summary: This patch adds TSan runtime support for Go on linux-aarch64 platforms. This enables people working on golang to implement their platform/language part of the TSan support. Basic testing is done with lib/tsan/go/buildgo.sh. Additional testing will be done as part of the work done in the Go project. It is intended to support other VMA sizes, except 39 which does not have enough bits to support the Go heap requirements. Patch by Fangming Fang <Fangming.Fang@arm.com>. Reviewers: kubamracek, dvyukov, javed.absar Subscribers: mcrosier, dberris, mgorny, kristof.beyls, delcypher, #sanitizers, llvm-commits Differential Revision: https://reviews.llvm.org/D52167 llvm-svn: 342541
This commit is contained in:
parent
1a05697e7a
commit
86a5e43656
|
@ -158,6 +158,15 @@ else()
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
elseif(arch STREQUAL "aarch64")
|
elseif(arch STREQUAL "aarch64")
|
||||||
add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_aarch64.S)
|
add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_aarch64.S)
|
||||||
|
# Sanity check for Go runtime.
|
||||||
|
set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh)
|
||||||
|
add_custom_target(GotsanRuntimeCheck
|
||||||
|
COMMAND env "CC=${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"
|
||||||
|
IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT}
|
||||||
|
DEPENDS clang_rt.tsan-${arch} ${BUILDGO_SCRIPT}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go
|
||||||
|
COMMENT "Checking TSan Go runtime..."
|
||||||
|
VERBATIM)
|
||||||
elseif(arch MATCHES "powerpc64|powerpc64le")
|
elseif(arch MATCHES "powerpc64|powerpc64le")
|
||||||
add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_ppc64.S)
|
add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_ppc64.S)
|
||||||
# Sanity check for Go runtime.
|
# Sanity check for Go runtime.
|
||||||
|
|
|
@ -55,13 +55,19 @@ if [ "`uname -a | grep Linux`" != "" ]; then
|
||||||
"
|
"
|
||||||
if [ "`uname -a | grep ppc64le`" != "" ]; then
|
if [ "`uname -a | grep ppc64le`" != "" ]; then
|
||||||
SUFFIX="linux_ppc64le"
|
SUFFIX="linux_ppc64le"
|
||||||
|
ARCHCFLAGS="-m64"
|
||||||
elif [ "`uname -a | grep x86_64`" != "" ]; then
|
elif [ "`uname -a | grep x86_64`" != "" ]; then
|
||||||
SUFFIX="linux_amd64"
|
SUFFIX="linux_amd64"
|
||||||
|
ARCHCFLAGS="-m64"
|
||||||
OSCFLAGS="$OSCFLAGS -ffreestanding -Wno-unused-const-variable -Werror -Wno-unknown-warning-option"
|
OSCFLAGS="$OSCFLAGS -ffreestanding -Wno-unused-const-variable -Werror -Wno-unknown-warning-option"
|
||||||
|
elif [ "`uname -a | grep aarch64`" != "" ]; then
|
||||||
|
SUFFIX="linux_arm64"
|
||||||
|
ARCHCFLAGS=""
|
||||||
fi
|
fi
|
||||||
elif [ "`uname -a | grep FreeBSD`" != "" ]; then
|
elif [ "`uname -a | grep FreeBSD`" != "" ]; then
|
||||||
SUFFIX="freebsd_amd64"
|
SUFFIX="freebsd_amd64"
|
||||||
OSCFLAGS="-fno-strict-aliasing -fPIC -Werror"
|
OSCFLAGS="-fno-strict-aliasing -fPIC -Werror"
|
||||||
|
ARCHCFLAGS="-m64"
|
||||||
OSLDFLAGS="-lpthread -fPIC -fpie"
|
OSLDFLAGS="-lpthread -fPIC -fpie"
|
||||||
SRCS="
|
SRCS="
|
||||||
$SRCS
|
$SRCS
|
||||||
|
@ -77,6 +83,7 @@ elif [ "`uname -a | grep FreeBSD`" != "" ]; then
|
||||||
elif [ "`uname -a | grep NetBSD`" != "" ]; then
|
elif [ "`uname -a | grep NetBSD`" != "" ]; then
|
||||||
SUFFIX="netbsd_amd64"
|
SUFFIX="netbsd_amd64"
|
||||||
OSCFLAGS="-fno-strict-aliasing -fPIC -Werror"
|
OSCFLAGS="-fno-strict-aliasing -fPIC -Werror"
|
||||||
|
ARCHCFLAGS="-m64"
|
||||||
OSLDFLAGS="-lpthread -fPIC -fpie"
|
OSLDFLAGS="-lpthread -fPIC -fpie"
|
||||||
SRCS="
|
SRCS="
|
||||||
$SRCS
|
$SRCS
|
||||||
|
@ -92,6 +99,7 @@ elif [ "`uname -a | grep NetBSD`" != "" ]; then
|
||||||
elif [ "`uname -a | grep Darwin`" != "" ]; then
|
elif [ "`uname -a | grep Darwin`" != "" ]; then
|
||||||
SUFFIX="darwin_amd64"
|
SUFFIX="darwin_amd64"
|
||||||
OSCFLAGS="-fPIC -Wno-unused-const-variable -Wno-unknown-warning-option -mmacosx-version-min=10.7"
|
OSCFLAGS="-fPIC -Wno-unused-const-variable -Wno-unknown-warning-option -mmacosx-version-min=10.7"
|
||||||
|
ARCHCFLAGS="-m64"
|
||||||
OSLDFLAGS="-lpthread -fPIC -fpie -mmacosx-version-min=10.7"
|
OSLDFLAGS="-lpthread -fPIC -fpie -mmacosx-version-min=10.7"
|
||||||
SRCS="
|
SRCS="
|
||||||
$SRCS
|
$SRCS
|
||||||
|
@ -104,6 +112,7 @@ elif [ "`uname -a | grep Darwin`" != "" ]; then
|
||||||
elif [ "`uname -a | grep MINGW`" != "" ]; then
|
elif [ "`uname -a | grep MINGW`" != "" ]; then
|
||||||
SUFFIX="windows_amd64"
|
SUFFIX="windows_amd64"
|
||||||
OSCFLAGS="-Wno-error=attributes -Wno-attributes -Wno-unused-const-variable -Wno-unknown-warning-option"
|
OSCFLAGS="-Wno-error=attributes -Wno-attributes -Wno-unused-const-variable -Wno-unknown-warning-option"
|
||||||
|
ARCHCFLAGS="-m64"
|
||||||
OSLDFLAGS=""
|
OSLDFLAGS=""
|
||||||
SRCS="
|
SRCS="
|
||||||
$SRCS
|
$SRCS
|
||||||
|
@ -136,7 +145,7 @@ for F in $SRCS; do
|
||||||
cat $F >> $DIR/gotsan.cc
|
cat $F >> $DIR/gotsan.cc
|
||||||
done
|
done
|
||||||
|
|
||||||
FLAGS=" -I../rtl -I../.. -I../../sanitizer_common -I../../../include -std=c++11 -m64 -Wall -fno-exceptions -fno-rtti -DSANITIZER_GO=1 -DSANITIZER_DEADLOCK_DETECTOR_VERSION=2 $OSCFLAGS"
|
FLAGS=" -I../rtl -I../.. -I../../sanitizer_common -I../../../include -std=c++11 -Wall -fno-exceptions -fno-rtti -DSANITIZER_GO=1 -DSANITIZER_DEADLOCK_DETECTOR_VERSION=2 $OSCFLAGS $ARCHCFLAGS"
|
||||||
if [ "$DEBUG" = "" ]; then
|
if [ "$DEBUG" = "" ]; then
|
||||||
FLAGS="$FLAGS -DSANITIZER_DEBUG=0 -O3 -fomit-frame-pointer"
|
FLAGS="$FLAGS -DSANITIZER_DEBUG=0 -O3 -fomit-frame-pointer"
|
||||||
if [ "$SUFFIX" = "linux_ppc64le" ]; then
|
if [ "$SUFFIX" = "linux_ppc64le" ]; then
|
||||||
|
@ -153,7 +162,7 @@ if [ "$SILENT" != "1" ]; then
|
||||||
fi
|
fi
|
||||||
$CC $DIR/gotsan.cc -c -o $DIR/race_$SUFFIX.syso $FLAGS $CFLAGS
|
$CC $DIR/gotsan.cc -c -o $DIR/race_$SUFFIX.syso $FLAGS $CFLAGS
|
||||||
|
|
||||||
$CC $OSCFLAGS test.c $DIR/race_$SUFFIX.syso -m64 -g -o $DIR/test $OSLDFLAGS $LDFLAGS
|
$CC $OSCFLAGS $ARCHCFLAGS test.c $DIR/race_$SUFFIX.syso -g -o $DIR/test $OSLDFLAGS $LDFLAGS
|
||||||
|
|
||||||
export GORACE="exitcode=0 atexit_sleep_ms=0"
|
export GORACE="exitcode=0 atexit_sleep_ms=0"
|
||||||
if [ "$SILENT" != "1" ]; then
|
if [ "$SILENT" != "1" ]; then
|
||||||
|
|
|
@ -458,6 +458,32 @@ struct Mapping47 {
|
||||||
static const uptr kAppMemEnd = 0x00e000000000ull;
|
static const uptr kAppMemEnd = 0x00e000000000ull;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#elif SANITIZER_GO && defined(__aarch64__)
|
||||||
|
|
||||||
|
/* Go on linux/aarch64 (48-bit VMA)
|
||||||
|
0000 0000 1000 - 0000 1000 0000: executable
|
||||||
|
0000 1000 0000 - 00c0 0000 0000: -
|
||||||
|
00c0 0000 0000 - 00e0 0000 0000: heap
|
||||||
|
00e0 0000 0000 - 2000 0000 0000: -
|
||||||
|
2000 0000 0000 - 3000 0000 0000: shadow
|
||||||
|
3000 0000 0000 - 3000 0000 0000: -
|
||||||
|
3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
|
||||||
|
4000 0000 0000 - 6000 0000 0000: -
|
||||||
|
6000 0000 0000 - 6200 0000 0000: traces
|
||||||
|
6200 0000 0000 - 8000 0000 0000: -
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct Mapping48 {
|
||||||
|
static const uptr kMetaShadowBeg = 0x300000000000ull;
|
||||||
|
static const uptr kMetaShadowEnd = 0x400000000000ull;
|
||||||
|
static const uptr kTraceMemBeg = 0x600000000000ull;
|
||||||
|
static const uptr kTraceMemEnd = 0x620000000000ull;
|
||||||
|
static const uptr kShadowBeg = 0x200000000000ull;
|
||||||
|
static const uptr kShadowEnd = 0x300000000000ull;
|
||||||
|
static const uptr kAppMemBeg = 0x000000001000ull;
|
||||||
|
static const uptr kAppMemEnd = 0x00e000000000ull;
|
||||||
|
};
|
||||||
|
|
||||||
// Indicates the runtime will define the memory regions at runtime.
|
// Indicates the runtime will define the memory regions at runtime.
|
||||||
#define TSAN_RUNTIME_VMA 1
|
#define TSAN_RUNTIME_VMA 1
|
||||||
|
|
||||||
|
@ -525,8 +551,10 @@ template<int Type>
|
||||||
uptr MappingArchImpl(void) {
|
uptr MappingArchImpl(void) {
|
||||||
#if defined(__aarch64__) && !defined(__APPLE__)
|
#if defined(__aarch64__) && !defined(__APPLE__)
|
||||||
switch (vmaSize) {
|
switch (vmaSize) {
|
||||||
|
#if !SANITIZER_GO
|
||||||
case 39: return MappingImpl<Mapping39, Type>();
|
case 39: return MappingImpl<Mapping39, Type>();
|
||||||
case 42: return MappingImpl<Mapping42, Type>();
|
case 42: return MappingImpl<Mapping42, Type>();
|
||||||
|
#endif
|
||||||
case 48: return MappingImpl<Mapping48, Type>();
|
case 48: return MappingImpl<Mapping48, Type>();
|
||||||
}
|
}
|
||||||
DCHECK(0);
|
DCHECK(0);
|
||||||
|
@ -682,8 +710,10 @@ ALWAYS_INLINE
|
||||||
bool IsAppMem(uptr mem) {
|
bool IsAppMem(uptr mem) {
|
||||||
#if defined(__aarch64__) && !defined(__APPLE__)
|
#if defined(__aarch64__) && !defined(__APPLE__)
|
||||||
switch (vmaSize) {
|
switch (vmaSize) {
|
||||||
|
#if !SANITIZER_GO
|
||||||
case 39: return IsAppMemImpl<Mapping39>(mem);
|
case 39: return IsAppMemImpl<Mapping39>(mem);
|
||||||
case 42: return IsAppMemImpl<Mapping42>(mem);
|
case 42: return IsAppMemImpl<Mapping42>(mem);
|
||||||
|
#endif
|
||||||
case 48: return IsAppMemImpl<Mapping48>(mem);
|
case 48: return IsAppMemImpl<Mapping48>(mem);
|
||||||
}
|
}
|
||||||
DCHECK(0);
|
DCHECK(0);
|
||||||
|
@ -713,8 +743,10 @@ ALWAYS_INLINE
|
||||||
bool IsShadowMem(uptr mem) {
|
bool IsShadowMem(uptr mem) {
|
||||||
#if defined(__aarch64__) && !defined(__APPLE__)
|
#if defined(__aarch64__) && !defined(__APPLE__)
|
||||||
switch (vmaSize) {
|
switch (vmaSize) {
|
||||||
|
#if !SANITIZER_GO
|
||||||
case 39: return IsShadowMemImpl<Mapping39>(mem);
|
case 39: return IsShadowMemImpl<Mapping39>(mem);
|
||||||
case 42: return IsShadowMemImpl<Mapping42>(mem);
|
case 42: return IsShadowMemImpl<Mapping42>(mem);
|
||||||
|
#endif
|
||||||
case 48: return IsShadowMemImpl<Mapping48>(mem);
|
case 48: return IsShadowMemImpl<Mapping48>(mem);
|
||||||
}
|
}
|
||||||
DCHECK(0);
|
DCHECK(0);
|
||||||
|
@ -744,8 +776,10 @@ ALWAYS_INLINE
|
||||||
bool IsMetaMem(uptr mem) {
|
bool IsMetaMem(uptr mem) {
|
||||||
#if defined(__aarch64__) && !defined(__APPLE__)
|
#if defined(__aarch64__) && !defined(__APPLE__)
|
||||||
switch (vmaSize) {
|
switch (vmaSize) {
|
||||||
|
#if !SANITIZER_GO
|
||||||
case 39: return IsMetaMemImpl<Mapping39>(mem);
|
case 39: return IsMetaMemImpl<Mapping39>(mem);
|
||||||
case 42: return IsMetaMemImpl<Mapping42>(mem);
|
case 42: return IsMetaMemImpl<Mapping42>(mem);
|
||||||
|
#endif
|
||||||
case 48: return IsMetaMemImpl<Mapping48>(mem);
|
case 48: return IsMetaMemImpl<Mapping48>(mem);
|
||||||
}
|
}
|
||||||
DCHECK(0);
|
DCHECK(0);
|
||||||
|
@ -785,8 +819,10 @@ ALWAYS_INLINE
|
||||||
uptr MemToShadow(uptr x) {
|
uptr MemToShadow(uptr x) {
|
||||||
#if defined(__aarch64__) && !defined(__APPLE__)
|
#if defined(__aarch64__) && !defined(__APPLE__)
|
||||||
switch (vmaSize) {
|
switch (vmaSize) {
|
||||||
|
#if !SANITIZER_GO
|
||||||
case 39: return MemToShadowImpl<Mapping39>(x);
|
case 39: return MemToShadowImpl<Mapping39>(x);
|
||||||
case 42: return MemToShadowImpl<Mapping42>(x);
|
case 42: return MemToShadowImpl<Mapping42>(x);
|
||||||
|
#endif
|
||||||
case 48: return MemToShadowImpl<Mapping48>(x);
|
case 48: return MemToShadowImpl<Mapping48>(x);
|
||||||
}
|
}
|
||||||
DCHECK(0);
|
DCHECK(0);
|
||||||
|
@ -828,8 +864,10 @@ ALWAYS_INLINE
|
||||||
u32 *MemToMeta(uptr x) {
|
u32 *MemToMeta(uptr x) {
|
||||||
#if defined(__aarch64__) && !defined(__APPLE__)
|
#if defined(__aarch64__) && !defined(__APPLE__)
|
||||||
switch (vmaSize) {
|
switch (vmaSize) {
|
||||||
|
#if !SANITIZER_GO
|
||||||
case 39: return MemToMetaImpl<Mapping39>(x);
|
case 39: return MemToMetaImpl<Mapping39>(x);
|
||||||
case 42: return MemToMetaImpl<Mapping42>(x);
|
case 42: return MemToMetaImpl<Mapping42>(x);
|
||||||
|
#endif
|
||||||
case 48: return MemToMetaImpl<Mapping48>(x);
|
case 48: return MemToMetaImpl<Mapping48>(x);
|
||||||
}
|
}
|
||||||
DCHECK(0);
|
DCHECK(0);
|
||||||
|
@ -884,8 +922,10 @@ ALWAYS_INLINE
|
||||||
uptr ShadowToMem(uptr s) {
|
uptr ShadowToMem(uptr s) {
|
||||||
#if defined(__aarch64__) && !defined(__APPLE__)
|
#if defined(__aarch64__) && !defined(__APPLE__)
|
||||||
switch (vmaSize) {
|
switch (vmaSize) {
|
||||||
|
#if !SANITIZER_GO
|
||||||
case 39: return ShadowToMemImpl<Mapping39>(s);
|
case 39: return ShadowToMemImpl<Mapping39>(s);
|
||||||
case 42: return ShadowToMemImpl<Mapping42>(s);
|
case 42: return ShadowToMemImpl<Mapping42>(s);
|
||||||
|
#endif
|
||||||
case 48: return ShadowToMemImpl<Mapping48>(s);
|
case 48: return ShadowToMemImpl<Mapping48>(s);
|
||||||
}
|
}
|
||||||
DCHECK(0);
|
DCHECK(0);
|
||||||
|
@ -923,8 +963,10 @@ ALWAYS_INLINE
|
||||||
uptr GetThreadTrace(int tid) {
|
uptr GetThreadTrace(int tid) {
|
||||||
#if defined(__aarch64__) && !defined(__APPLE__)
|
#if defined(__aarch64__) && !defined(__APPLE__)
|
||||||
switch (vmaSize) {
|
switch (vmaSize) {
|
||||||
|
#if !SANITIZER_GO
|
||||||
case 39: return GetThreadTraceImpl<Mapping39>(tid);
|
case 39: return GetThreadTraceImpl<Mapping39>(tid);
|
||||||
case 42: return GetThreadTraceImpl<Mapping42>(tid);
|
case 42: return GetThreadTraceImpl<Mapping42>(tid);
|
||||||
|
#endif
|
||||||
case 48: return GetThreadTraceImpl<Mapping48>(tid);
|
case 48: return GetThreadTraceImpl<Mapping48>(tid);
|
||||||
}
|
}
|
||||||
DCHECK(0);
|
DCHECK(0);
|
||||||
|
@ -957,8 +999,10 @@ ALWAYS_INLINE
|
||||||
uptr GetThreadTraceHeader(int tid) {
|
uptr GetThreadTraceHeader(int tid) {
|
||||||
#if defined(__aarch64__) && !defined(__APPLE__)
|
#if defined(__aarch64__) && !defined(__APPLE__)
|
||||||
switch (vmaSize) {
|
switch (vmaSize) {
|
||||||
|
#if !SANITIZER_GO
|
||||||
case 39: return GetThreadTraceHeaderImpl<Mapping39>(tid);
|
case 39: return GetThreadTraceHeaderImpl<Mapping39>(tid);
|
||||||
case 42: return GetThreadTraceHeaderImpl<Mapping42>(tid);
|
case 42: return GetThreadTraceHeaderImpl<Mapping42>(tid);
|
||||||
|
#endif
|
||||||
case 48: return GetThreadTraceHeaderImpl<Mapping48>(tid);
|
case 48: return GetThreadTraceHeaderImpl<Mapping48>(tid);
|
||||||
}
|
}
|
||||||
DCHECK(0);
|
DCHECK(0);
|
||||||
|
|
|
@ -212,11 +212,19 @@ void InitializePlatformEarly() {
|
||||||
vmaSize =
|
vmaSize =
|
||||||
(MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);
|
(MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);
|
||||||
#if defined(__aarch64__)
|
#if defined(__aarch64__)
|
||||||
|
# if !SANITIZER_GO
|
||||||
if (vmaSize != 39 && vmaSize != 42 && vmaSize != 48) {
|
if (vmaSize != 39 && vmaSize != 42 && vmaSize != 48) {
|
||||||
Printf("FATAL: ThreadSanitizer: unsupported VMA range\n");
|
Printf("FATAL: ThreadSanitizer: unsupported VMA range\n");
|
||||||
Printf("FATAL: Found %zd - Supported 39, 42 and 48\n", vmaSize);
|
Printf("FATAL: Found %zd - Supported 39, 42 and 48\n", vmaSize);
|
||||||
Die();
|
Die();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (vmaSize != 48) {
|
||||||
|
Printf("FATAL: ThreadSanitizer: unsupported VMA range\n");
|
||||||
|
Printf("FATAL: Found %zd - Supported 48\n", vmaSize);
|
||||||
|
Die();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#elif defined(__powerpc64__)
|
#elif defined(__powerpc64__)
|
||||||
# if !SANITIZER_GO
|
# if !SANITIZER_GO
|
||||||
if (vmaSize != 44 && vmaSize != 46 && vmaSize != 47) {
|
if (vmaSize != 44 && vmaSize != 46 && vmaSize != 47) {
|
||||||
|
|
Loading…
Reference in New Issue