summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp2
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp42
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h4
-rw-r--r--clang/test/CodeGen/asan-globals.cpp24
-rw-r--r--compiler-rt/test/asan/TestCases/global-location.cc2
-rw-r--r--llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp29
-rw-r--r--llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll20
-rw-r--r--llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll2
-rw-r--r--llvm/test/Instrumentation/AddressSanitizer/instrument_initializer_metadata.ll8
9 files changed, 86 insertions, 47 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 9bd61d7164f..91f80419304 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -345,7 +345,7 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
DMEntry = castedAddr;
CGM.setStaticLocalDeclAddress(&D, castedAddr);
- CGM.reportGlobalToASan(var, D.getLocation());
+ CGM.reportGlobalToASan(var, D);
// Emit global variable debug descriptor for static vars.
CGDebugInfo *DI = getDebugInfo();
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 2f87392c360..66ac524f2b9 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1952,7 +1952,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
if (NeedsGlobalCtor || NeedsGlobalDtor)
EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
- reportGlobalToASan(GV, D->getLocation(), NeedsGlobalCtor);
+ reportGlobalToASan(GV, *D, NeedsGlobalCtor);
// Emit global variable debug information.
if (CGDebugInfo *DI = getModuleDebugInfo())
@@ -1961,24 +1961,25 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
}
void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
- SourceLocation Loc, bool IsDynInit) {
+ SourceLocation Loc, StringRef Name,
+ bool IsDynInit) {
if (!LangOpts.Sanitize.Address)
return;
IsDynInit &= !SanitizerBL.isIn(*GV, "init");
bool IsBlacklisted = SanitizerBL.isIn(*GV);
- llvm::LLVMContext &LLVMCtx = TheModule.getContext();
-
llvm::GlobalVariable *LocDescr = nullptr;
+ llvm::GlobalVariable *GlobalName = nullptr;
if (!IsBlacklisted) {
- // Don't generate source location if a global is blacklisted - it won't
- // be instrumented anyway.
+ // Don't generate source location and global name if it is blacklisted -
+ // it won't be instrumented anyway.
PresumedLoc PLoc = Context.getSourceManager().getPresumedLoc(Loc);
if (PLoc.isValid()) {
llvm::Constant *LocData[] = {
GetAddrOfConstantCString(PLoc.getFilename()),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(LLVMCtx), PLoc.getLine()),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(LLVMCtx),
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+ PLoc.getLine()),
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
PLoc.getColumn()),
};
auto LocStruct = llvm::ConstantStruct::getAnon(LocData);
@@ -1990,14 +1991,17 @@ void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
// the optimizer before the ASan instrumentation pass.
addCompilerUsedGlobal(LocDescr);
}
+ if (!Name.empty()) {
+ GlobalName = GetAddrOfConstantCString(Name);
+ // GlobalName shouldn't be removed by the optimizer.
+ addCompilerUsedGlobal(GlobalName);
+ }
}
llvm::Value *GlobalMetadata[] = {
- GV,
- LocDescr,
- llvm::ConstantInt::get(llvm::Type::getInt1Ty(LLVMCtx), IsDynInit),
- llvm::ConstantInt::get(llvm::Type::getInt1Ty(LLVMCtx), IsBlacklisted)
- };
+ GV, LocDescr, GlobalName,
+ llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit),
+ llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsBlacklisted)};
llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata);
llvm::NamedMDNode *AsanGlobals =
@@ -2005,6 +2009,16 @@ void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
AsanGlobals->addOperand(ThisGlobal);
}
+void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
+ const VarDecl &D, bool IsDynInit) {
+ if (!LangOpts.Sanitize.Address)
+ return;
+ std::string QualName;
+ llvm::raw_string_ostream OS(QualName);
+ D.printQualifiedName(OS);
+ reportGlobalToASan(GV, D.getLocation(), OS.str(), IsDynInit);
+}
+
static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
// Don't give variables common linkage if -fno-common was specified unless it
// was overridden by a NoCommon attribute.
@@ -2810,7 +2824,7 @@ CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) {
if (Entry)
Entry->setValue(GV);
- reportGlobalToASan(GV, S->getStrTokenLoc(0));
+ reportGlobalToASan(GV, S->getStrTokenLoc(0), "<string literal>");
return GV;
}
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 34254697467..d6b694a8824 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1015,8 +1015,10 @@ public:
return SanitizerBL;
}
- void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
+ void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D,
bool IsDynInit = false);
+ void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
+ StringRef Name, bool IsDynInit = false);
void addDeferredVTable(const CXXRecordDecl *RD) {
DeferredVTables.push_back(RD);
diff --git a/clang/test/CodeGen/asan-globals.cpp b/clang/test/CodeGen/asan-globals.cpp
index 2702f1d4500..d9ecc646154 100644
--- a/clang/test/CodeGen/asan-globals.cpp
+++ b/clang/test/CodeGen/asan-globals.cpp
@@ -6,27 +6,31 @@
int global;
// CHECK: [[GLOBAL_LOC:@.asan_loc_descr[0-9]*]] = private unnamed_addr constant {{.*}} i32 [[@LINE-1]], i32 5
+// CHECK: [[GLOBAL_NAME:@.str[0-9]+]] = private unnamed_addr constant {{.*}} c"global\00"
int dyn_init_global = global;
// CHECK: [[DYN_INIT_LOC:@.asan_loc_descr[0-9]*]] = {{.*}} i32 [[@LINE-1]], i32 5
+// CHECK: [[DYN_INIT_NAME:@.str[0-9]+]] = private unnamed_addr constant {{.*}} c"dyn_init_global\00"
int blacklisted_global;
void func() {
static int static_var = 0;
// CHECK: [[STATIC_LOC:@.asan_loc_descr[0-9]*]] = {{.*}} i32 [[@LINE-1]], i32 14
+ // CHECK: [[STATIC_NAME:@.str[0-9]+]] = private unnamed_addr constant {{.*}} c"static_var\00"
const char *literal = "Hello, world!";
// CHECK: [[LITERAL_LOC:@.asan_loc_descr[0-9]*]] = {{.*}} i32 [[@LINE-1]], i32 25
+ // CHECK: [[LITERAL_NAME:@.str[0-9]+]] = private unnamed_addr constant {{.*}} c"<string literal>\00"
}
// CHECK: !llvm.asan.globals = !{![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
-// CHECK: ![[GLOBAL]] = metadata !{{{.*}} [[GLOBAL_LOC]], i1 false, i1 false}
-// CHECK: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} [[DYN_INIT_LOC]], i1 true, i1 false}
-// CHECK: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, i1 false, i1 true}
-// CHECK: ![[STATIC_VAR]] = metadata !{{{.*}} [[STATIC_LOC]], i1 false, i1 false}
-// CHECK: ![[LITERAL]] = metadata !{{{.*}} [[LITERAL_LOC]], i1 false, i1 false}
+// CHECK: ![[GLOBAL]] = metadata !{{{.*}} [[GLOBAL_LOC]], {{.*}} [[GLOBAL_NAME]], i1 false, i1 false}
+// CHECK: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} [[DYN_INIT_LOC]], {{.*}} [[DYN_INIT_NAME]], i1 true, i1 false}
+// CHECK: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, null, i1 false, i1 true}
+// CHECK: ![[STATIC_VAR]] = metadata !{{{.*}} [[STATIC_LOC]], {{.*}} [[STATIC_NAME]], i1 false, i1 false}
+// CHECK: ![[LITERAL]] = metadata !{{{.*}} [[LITERAL_LOC]], {{.*}} [[LITERAL_NAME]], i1 false, i1 false}
// BLACKLIST-SRC: !llvm.asan.globals = !{![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
-// BLACKLIST-SRC: ![[GLOBAL]] = metadata !{{{.*}} null, i1 false, i1 true}
-// BLACKLIST-SRC: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} null, i1 true, i1 true}
-// BLACKLIST-SRC: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, i1 false, i1 true}
-// BLACKLIST-SRC: ![[STATIC_VAR]] = metadata !{{{.*}} null, i1 false, i1 true}
-// BLACKLIST-SRC: ![[LITERAL]] = metadata !{{{.*}} null, i1 false, i1 true}
+// BLACKLIST-SRC: ![[GLOBAL]] = metadata !{{{.*}} null, null, i1 false, i1 true}
+// BLACKLIST-SRC: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} null, null, i1 true, i1 true}
+// BLACKLIST-SRC: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, null, i1 false, i1 true}
+// BLACKLIST-SRC: ![[STATIC_VAR]] = metadata !{{{.*}} null, null, i1 false, i1 true}
+// BLACKLIST-SRC: ![[LITERAL]] = metadata !{{{.*}} null, null, i1 false, i1 true}
diff --git a/compiler-rt/test/asan/TestCases/global-location.cc b/compiler-rt/test/asan/TestCases/global-location.cc
index 54f205593b3..2f72bede446 100644
--- a/compiler-rt/test/asan/TestCases/global-location.cc
+++ b/compiler-rt/test/asan/TestCases/global-location.cc
@@ -27,7 +27,7 @@ int main(int argc, char **argv) {
case 'c': return C::array[one * 11];
case 'f':
static int array[10];
- // FUNC_STATIC: 0x{{.*}} is located 4 bytes to the right of global variable 'main::array' defined in '{{.*}}global-location.cc:[[@LINE-1]]:16' {{.*}} of size 40
+ // FUNC_STATIC: 0x{{.*}} is located 4 bytes to the right of global variable 'array' defined in '{{.*}}global-location.cc:[[@LINE-1]]:16' {{.*}} of size 40
memset(array, 0, 10);
return array[one * 11];
case 'l':
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 17cfd92ff27..e42839c9c6b 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -216,8 +216,11 @@ namespace {
class GlobalsMetadata {
public:
struct Entry {
- Entry() : SourceLoc(nullptr), IsDynInit(false), IsBlacklisted(false) {}
+ Entry()
+ : SourceLoc(nullptr), Name(nullptr), IsDynInit(false),
+ IsBlacklisted(false) {}
GlobalVariable *SourceLoc;
+ GlobalVariable *Name;
bool IsDynInit;
bool IsBlacklisted;
};
@@ -232,7 +235,7 @@ class GlobalsMetadata {
return;
for (auto MDN : Globals->operands()) {
// Metadata node contains the global and the fields of "Entry".
- assert(MDN->getNumOperands() == 4);
+ assert(MDN->getNumOperands() == 5);
Value *V = MDN->getOperand(0);
// The optimizer may optimize away a global entirely.
if (!V)
@@ -246,9 +249,14 @@ class GlobalsMetadata {
E.SourceLoc = GVLoc;
addSourceLocationGlobal(GVLoc);
}
- ConstantInt *IsDynInit = cast<ConstantInt>(MDN->getOperand(2));
+ if (Value *Name = MDN->getOperand(2)) {
+ GlobalVariable *GVName = cast<GlobalVariable>(Name);
+ E.Name = GVName;
+ InstrumentationGlobals.insert(GVName);
+ }
+ ConstantInt *IsDynInit = cast<ConstantInt>(MDN->getOperand(3));
E.IsDynInit |= IsDynInit->isOne();
- ConstantInt *IsBlacklisted = cast<ConstantInt>(MDN->getOperand(3));
+ ConstantInt *IsBlacklisted = cast<ConstantInt>(MDN->getOperand(4));
E.IsBlacklisted |= IsBlacklisted->isOne();
}
}
@@ -1049,6 +1057,14 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
for (size_t i = 0; i < n; i++) {
static const uint64_t kMaxGlobalRedzone = 1 << 18;
GlobalVariable *G = GlobalsToChange[i];
+
+ auto MD = GlobalsMD.get(G);
+ // Create string holding the global name unless it was provided by
+ // the metadata.
+ GlobalVariable *Name =
+ MD.Name ? MD.Name : createPrivateGlobalForString(M, G->getName(),
+ /*AllowMerging*/ true);
+
PointerType *PtrTy = cast<PointerType>(G->getType());
Type *Ty = PtrTy->getElementType();
uint64_t SizeInBytes = DL->getTypeAllocSize(Ty);
@@ -1070,9 +1086,6 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
NewTy, G->getInitializer(),
Constant::getNullValue(RightRedZoneTy), NULL);
- GlobalVariable *Name =
- createPrivateGlobalForString(M, G->getName(), /*AllowMerging*/true);
-
// Create a new global variable with enough space for a redzone.
GlobalValue::LinkageTypes Linkage = G->getLinkage();
if (G->isConstant() && Linkage == GlobalValue::PrivateLinkage)
@@ -1092,8 +1105,6 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
NewGlobal->takeName(G);
G->eraseFromParent();
- auto MD = GlobalsMD.get(G);
-
Initializers[i] = ConstantStruct::get(
GlobalStructTy, ConstantExpr::getPointerCast(NewGlobal, IntptrTy),
ConstantInt::get(IntptrTy, SizeInBytes),
diff --git a/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll b/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll
index 9641c3ed4d7..4dcd53b3ad8 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll
@@ -18,12 +18,20 @@ target triple = "x86_64-unknown-linux-gnu"
@.asan_loc_descr2 = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* @.str1, i32 12, i32 14 }
@.asan_loc_descr4 = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* @.str1, i32 14, i32 25 }
+; Global names:
+@.str2 = private unnamed_addr constant [7 x i8] c"global\00", align 1
+@.str3 = private unnamed_addr constant [16 x i8] c"dyn_init_global\00", align 1
+@.str4 = private unnamed_addr constant [11 x i8] c"static_var\00", align 1
+@.str5 = private unnamed_addr constant [17 x i8] c"<string literal>\00", align 1
+
; Check that globals were instrumented, but sanitizer location descriptors weren't:
; CHECK: @global = global { i32, [60 x i8] } zeroinitializer, align 32
; CHECK: @.str = internal unnamed_addr constant { [14 x i8], [50 x i8] } { [14 x i8] c"Hello, world!\00", [50 x i8] zeroinitializer }, align 32
; CHECK: @.asan_loc_descr = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* @.str1, i32 5, i32 5 }
+; CHECK: @.str2 = private unnamed_addr constant [7 x i8] c"global\00", align 1
-; Check that location decriptors were passed into __asan_register_globals:
+; Check that location decriptors and global names were passed into __asan_register_globals:
+; CHECK: i64 ptrtoint ([7 x i8]* @.str2 to i64)
; CHECK: i64 ptrtoint ({ [22 x i8]*, i32, i32 }* @.asan_loc_descr to i64)
; Function Attrs: nounwind sanitize_address
@@ -55,9 +63,9 @@ attributes #1 = { nounwind sanitize_address "less-precise-fpmad"="false" "no-fra
!llvm.asan.globals = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}
-!0 = metadata !{i32* @global, { [22 x i8]*, i32, i32 }* @.asan_loc_descr, i1 false, i1 false}
-!1 = metadata !{i32* @dyn_init_global, { [22 x i8]*, i32, i32 }* @.asan_loc_descr1, i1 true, i1 false}
-!2 = metadata !{i32* @blacklisted_global, null, i1 false, i1 true}
-!3 = metadata !{i32* @_ZZ4funcvE10static_var, { [22 x i8]*, i32, i32 }* @.asan_loc_descr2, i1 false, i1 false}
-!4 = metadata !{[14 x i8]* @.str, { [22 x i8]*, i32, i32 }* @.asan_loc_descr4, i1 false, i1 false}
+!0 = metadata !{i32* @global, { [22 x i8]*, i32, i32 }* @.asan_loc_descr, [7 x i8]* @.str2, i1 false, i1 false}
+!1 = metadata !{i32* @dyn_init_global, { [22 x i8]*, i32, i32 }* @.asan_loc_descr1, [16 x i8]* @.str3, i1 true, i1 false}
+!2 = metadata !{i32* @blacklisted_global, null, null, i1 false, i1 true}
+!3 = metadata !{i32* @_ZZ4funcvE10static_var, { [22 x i8]*, i32, i32 }* @.asan_loc_descr2, [11 x i8]* @.str4, i1 false, i1 false}
+!4 = metadata !{[14 x i8]* @.str, { [22 x i8]*, i32, i32 }* @.asan_loc_descr4, [17 x i8]* @.str5, i1 false, i1 false}
!5 = metadata !{metadata !"clang version 3.5.0 (211282)"}
diff --git a/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll b/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
index 816ab291566..80791d9a905 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
@@ -69,7 +69,7 @@ entry:
!llvm.asan.globals = !{!0}
-!0 = metadata !{[10 x i32]* @GlobDy, null, i1 true, i1 false}
+!0 = metadata !{[10 x i32]* @GlobDy, null, null, i1 true, i1 false}
; CHECK-LABEL: define internal void @asan.module_ctor
; CHECK-NOT: ret
diff --git a/llvm/test/Instrumentation/AddressSanitizer/instrument_initializer_metadata.ll b/llvm/test/Instrumentation/AddressSanitizer/instrument_initializer_metadata.ll
index 83ff53f6f51..c119879351a 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/instrument_initializer_metadata.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/instrument_initializer_metadata.ll
@@ -7,10 +7,10 @@ target triple = "x86_64-unknown-linux-gnu"
@YYY = global i32 0, align 4 ; W/o dynamic initializer.
; Clang will emit the following metadata identifying @xxx as dynamically
; initialized.
-!0 = metadata !{i32* @xxx, null, i1 true, i1 false}
-!1 = metadata !{i32* @XXX, null, i1 true, i1 false}
-!2 = metadata !{i32* @yyy, null, i1 false, i1 false}
-!3 = metadata !{i32* @YYY, null, i1 false, i1 false}
+!0 = metadata !{i32* @xxx, null, null, i1 true, i1 false}
+!1 = metadata !{i32* @XXX, null, null, i1 true, i1 false}
+!2 = metadata !{i32* @yyy, null, null, i1 false, i1 false}
+!3 = metadata !{i32* @YYY, null, null, i1 false, i1 false}
!llvm.asan.globals = !{!0, !1, !2, !3}
define i32 @initializer() uwtable {
OpenPOWER on IntegriCloud