Index: include/llvm/Transforms/Utils/ModuleUtils.h =================================================================== --- include/llvm/Transforms/Utils/ModuleUtils.h +++ include/llvm/Transforms/Utils/ModuleUtils.h @@ -15,6 +15,7 @@ #define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include // for std::pair namespace llvm { @@ -56,7 +57,8 @@ /// respectively. std::pair createSanitizerCtorAndInitFunctions( Module &M, StringRef CtorName, StringRef InitName, - ArrayRef InitArgTypes, ArrayRef InitArgs); + ArrayRef InitArgTypes, ArrayRef InitArgs, + StringRef VersionCheckName = StringRef()); } // End llvm namespace #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -90,7 +90,9 @@ "__asan_unregister_globals"; static const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init"; static const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init"; -static const char *const kAsanInitName = "__asan_init_v5"; +static const char *const kAsanInitName = "__asan_init"; +static const char *const kAsanVersionCheckName = + "__asan_version_mismatch_check_v6"; static const char *const kAsanPtrCmp = "__sanitizer_ptr_cmp"; static const char *const kAsanPtrSub = "__sanitizer_ptr_sub"; static const char *const kAsanHandleNoReturnName = "__asan_handle_no_return"; @@ -1457,9 +1459,9 @@ if (!CompileKernel) { std::tie(AsanCtorFunction, AsanInitFunction) = - createSanitizerCtorAndInitFunctions(M, kAsanModuleCtorName, kAsanInitName, - /*InitArgTypes=*/{}, - /*InitArgs=*/{}); + createSanitizerCtorAndInitFunctions( + M, kAsanModuleCtorName, kAsanInitName, + /*InitArgTypes=*/{}, /*InitArgs=*/{}, kAsanVersionCheckName); appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority); } Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel); Index: lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- lib/Transforms/Utils/ModuleUtils.cpp +++ lib/Transforms/Utils/ModuleUtils.cpp @@ -107,7 +107,8 @@ std::pair llvm::createSanitizerCtorAndInitFunctions( Module &M, StringRef CtorName, StringRef InitName, - ArrayRef InitArgTypes, ArrayRef InitArgs) { + ArrayRef InitArgTypes, ArrayRef InitArgs, + StringRef VersionCheckName) { assert(!InitName.empty() && "Expected init function name"); assert(InitArgTypes.size() == InitArgTypes.size() && "Sanitizer's init function expects different number of arguments"); @@ -122,6 +123,13 @@ AttributeSet())); InitFunction->setLinkage(Function::ExternalLinkage); IRB.CreateCall(InitFunction, InitArgs); + if (!VersionCheckName.empty()) { + Function *VersionCheckFunction = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false), + AttributeSet())); + IRB.CreateCall(VersionCheckFunction, {}); + } return std::make_pair(Ctor, InitFunction); } Index: projects/compiler-rt/lib/asan/asan_init_version.h =================================================================== --- projects/compiler-rt/lib/asan/asan_init_version.h +++ projects/compiler-rt/lib/asan/asan_init_version.h @@ -27,8 +27,8 @@ // v3=>v4: added '__asan_global_source_location' to __asan_global. // v4=>v5: changed the semantics and format of __asan_stack_malloc_ and // __asan_stack_free_ functions. - #define __asan_init __asan_init_v5 - #define __asan_init_name "__asan_init_v5" + // v5=>v6: changed the name of the version check symbol + #define __asan_version_mismatch_check __asan_version_mismatch_check_v6 } #endif // ASAN_INIT_VERSION_H Index: projects/compiler-rt/lib/asan/asan_interface_internal.h =================================================================== --- projects/compiler-rt/lib/asan/asan_interface_internal.h +++ projects/compiler-rt/lib/asan/asan_interface_internal.h @@ -27,10 +27,14 @@ extern "C" { // This function should be called at the very beginning of the process, // before any instrumented code is executed and before any call to malloc. - // Please note that __asan_init is a macro that is replaced with - // __asan_init_vXXX at compile-time. SANITIZER_INTERFACE_ATTRIBUTE void __asan_init(); + // This function exists purely to get a linker/loader error when using + // incompatible versions of instrumentation and runtime library. Please note + // that __asan_version_mismatch_check is a macro that is replaced with + // __asan_version_mismatch_check_vXXX at compile-time. + SANITIZER_INTERFACE_ATTRIBUTE void __asan_version_mismatch_check(); + // This structure is used to describe the source location of a place where // global was defined. struct __asan_global_source_location { Index: projects/compiler-rt/lib/asan/asan_rtl.cc =================================================================== --- projects/compiler-rt/lib/asan/asan_rtl.cc +++ projects/compiler-rt/lib/asan/asan_rtl.cc @@ -578,3 +578,7 @@ AsanActivate(); AsanInitInternal(); } + +void __asan_version_mismatch_check() { + // Do nothing. +} Index: projects/compiler-rt/lib/asan/asan_win_dll_thunk.cc =================================================================== --- projects/compiler-rt/lib/asan/asan_win_dll_thunk.cc +++ projects/compiler-rt/lib/asan/asan_win_dll_thunk.cc @@ -210,7 +210,7 @@ // __asan_init is expected to be called by only one thread. if (fn) return; - fn = (fntype)getRealProcAddressOrDie(__asan_init_name); + fn = (fntype)getRealProcAddressOrDie("__asan_init"); fn(); __asan_option_detect_stack_use_after_return = (__asan_should_detect_stack_use_after_return() != 0); Index: projects/compiler-rt/test/asan/TestCases/Darwin/interface_symbols_darwin.c =================================================================== --- projects/compiler-rt/test/asan/TestCases/Darwin/interface_symbols_darwin.c +++ projects/compiler-rt/test/asan/TestCases/Darwin/interface_symbols_darwin.c @@ -8,7 +8,7 @@ // RUN: nm -g `%clang_asan %s -fsanitize=address -### 2>&1 | grep "libclang_rt.asan_osx_dynamic.dylib" | sed -e 's/.*"\(.*libclang_rt.asan_osx_dynamic.dylib\)".*/\1/'` \ // RUN: | grep " T " | sed "s/.* T //" \ // RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" \ -// RUN: | sed -E "s/__asan_init_v[0-9]+/__asan_init/" \ +// RUN: | sed -E "s/__asan_version_mismatch_check_v[0-9]+/__asan_version_mismatch_check/" \ // RUN: | grep -v "__asan_default_options" \ // RUN: | grep -v "__asan_on_error" > %t.symbols Index: projects/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.c =================================================================== --- projects/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.c +++ projects/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.c @@ -3,7 +3,7 @@ // RUN: %clang_asan -O2 %s -o %t.exe // RUN: nm -D %t.exe | grep " T " | sed "s/.* T //" \ // RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" \ -// RUN: | sed -E "s/__asan_init_v[0-9]+/__asan_init/" \ +// RUN: | sed -E "s/__asan_version_mismatch_check_v[0-9]+/__asan_version_mismatch_check/" \ // RUN: | grep -v "__asan_default_options" \ // RUN: | grep -v "__asan_stack_" \ // RUN: | grep -v "__asan_on_error" > %t.symbols