[PATCH] D15642: [asan] Use private aliases for global variables (LLVM part).
Maxim Ostapenko via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 18 08:11:24 PST 2015
m.ostapenko created this revision.
m.ostapenko added reviewers: kcc, eugenis, samsonov.
m.ostapenko added subscribers: ygribov, llvm-commits.
m.ostapenko set the repository for this revision to rL LLVM.
Hi!
As discussed in https://github.com/google/sanitizers/issues/398, with current implementation of poisoning globals we can have some CHECK failures or false positives in case of mixing instrumented and non-instrumented code due to ASan poisons innocent globals from non-sanitized binary/library. We can use private aliases to avoid such errors. In addition, to preserve ODR violation detection, we introduce new _asan_genXXX symbol for each instrumented global that indicates if this global was already registered. To detect ODR violation in runtime, we should only check the value of indicator and report an error if it's not equal to zero.
Repository:
rL LLVM
http://reviews.llvm.org/D15642
Files:
lib/Transforms/Instrumentation/AddressSanitizer.cpp
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<Constant *, 16> 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<PointerType>(G->getType());
Type *Ty = PtrTy->getElementType();
uint64_t SizeInBytes = DL.getTypeAllocSize(Ty);
@@ -1384,8 +1387,23 @@
SourceLoc = ConstantInt::get(IntptrTy, 0);
}
+ // Create local alias for NewGlobal to avoid crash on ODR between
+ // instrumented and non-instrumented libraries.
+ // https://github.com/google/sanitizers/issues/398
+ 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.
+ 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),
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15642.43228.patch
Type: text/x-patch
Size: 2754 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151218/63fe4a57/attachment.bin>
More information about the llvm-commits
mailing list