Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1307,6 +1307,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 +1317,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,12 +1333,14 @@ 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()); Type *Ty = PtrTy->getElementType(); uint64_t SizeInBytes = DL.getTypeAllocSize(Ty); @@ -1384,8 +1387,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 + // _asan_genXXX to detect ODR violation. However, if we hide global symbol + // via -fvisibility=hidden, use PrivateLinkage to avoid false positives. + if (NewGlobal->hasHiddenVisibility()) Linkage = GlobalValue::PrivateLinkage; + auto *ODRIndicatorSym = + new GlobalVariable(M, IRB.getInt8Ty(), false, Linkage, + Constant::getNullValue(IRB.getInt8Ty()), + kAsanGenPrefix + NameForGlobal, nullptr, + NewGlobal->getThreadLocalMode()); + 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),