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;
};
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)
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();
}
}
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);
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)
NewGlobal->takeName(G);
G->eraseFromParent();
- auto MD = GlobalsMD.get(G);
-
Initializers[i] = ConstantStruct::get(
GlobalStructTy, ConstantExpr::getPointerCast(NewGlobal, IntptrTy),
ConstantInt::get(IntptrTy, SizeInBytes),
@.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
!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)"}
!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
@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 {