Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -101,6 +101,7 @@ static const char *const kAsanStackMallocNameTemplate = "__asan_stack_malloc_"; static const char *const kAsanStackFreeNameTemplate = "__asan_stack_free_"; static const char *const kAsanGenPrefix = "__asan_gen_"; +static const char *const kODRGenPrefix = "__odr_gen_"; static const char *const kSanCovGenPrefix = "__sancov_gen_"; static const char *const kAsanPoisonStackMemoryName = "__asan_poison_stack_memory"; @@ -815,7 +816,8 @@ static bool GlobalWasGeneratedByAsan(GlobalVariable *G) { return G->getName().find(kAsanGenPrefix) == 0 || - G->getName().find(kSanCovGenPrefix) == 0; + G->getName().find(kSanCovGenPrefix) == 0 || + G->getName().find(kODRGenPrefix) == 0; } Value *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) { @@ -1307,6 +1309,7 @@ // A global is described by a structure // size_t beg; + // size_t odr_indicator; // size_t size; // size_t size_with_redzone; // const char *name; @@ -1316,7 +1319,7 @@ // We initialize an array of such structures and pass it to a run-time call. StructType *GlobalStructTy = StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy, - IntptrTy, IntptrTy, nullptr); + IntptrTy, IntptrTy, IntptrTy, nullptr); SmallVector Initializers(n); bool HasDynamicallyInitializedGlobals = false; @@ -1332,10 +1335,11 @@ GlobalVariable *G = GlobalsToChange[i]; auto MD = GlobalsMD.get(G); + StringRef NameForGlobal = G->getName(); // Create string holding the global name (use global name from metadata // if it's available, otherwise just write the name of global variable). GlobalVariable *Name = createPrivateGlobalForString( - M, MD.Name.empty() ? G->getName() : MD.Name, + M, MD.Name.empty() ? NameForGlobal : MD.Name, /*AllowMerging*/ true); PointerType *PtrTy = cast(G->getType()); @@ -1384,8 +1388,24 @@ SourceLoc = ConstantInt::get(IntptrTy, 0); } + // Create local alias for NewGlobal to avoid crash on ODR between + // instrumented and non-instrumented libraries. + auto *GA = GlobalAlias::create( + GlobalValue::InternalLinkage, NameForGlobal + M.getName(), NewGlobal); + + // With local aliases, we need to provide another externally visible symbol + // _odr_genXXX to detect ODR violation. + auto *ODRIndicatorSym = + new GlobalVariable(M, IRB.getInt8Ty(), false, Linkage, + Constant::getNullValue(IRB.getInt8Ty()), + kODRGenPrefix + NameForGlobal, nullptr, + NewGlobal->getThreadLocalMode()); + + ODRIndicatorSym->copyAttributesFrom(NewGlobal); + Initializers[i] = ConstantStruct::get( - GlobalStructTy, ConstantExpr::getPointerCast(NewGlobal, IntptrTy), + GlobalStructTy, ConstantExpr::getPointerCast(GA, IntptrTy), + ConstantExpr::getPointerCast(ODRIndicatorSym, IntptrTy), ConstantInt::get(IntptrTy, SizeInBytes), ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize), ConstantExpr::getPointerCast(Name, IntptrTy),