Add ASan metadata globals to @llvm.compiler.used under COFF

Summary:
This matches ELF.

This makes the number of ASan failures under the new pass manager on
Windows go from 18 to 1.

Under the old pass manager, the ASan module pass was one of the very
last things run, so these globals didn't get removed due to GlobalOpt.
But with the NPM the ASan module pass that adds these globals are run
much earlier in the pipeline and GlobalOpt ends up removing them.

Reviewers: vitalybuka, hans

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D81175
This commit is contained in:
Arthur Eubanks 2020-06-04 09:48:42 -07:00
parent f59311e31d
commit 8133e289b6
2 changed files with 13 additions and 2 deletions

View File

@ -2036,11 +2036,15 @@ void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
assert(ExtendedGlobals.size() == MetadataInitializers.size()); assert(ExtendedGlobals.size() == MetadataInitializers.size());
auto &DL = M.getDataLayout(); auto &DL = M.getDataLayout();
SmallVector<GlobalValue *, 16> MetadataGlobals(ExtendedGlobals.size());
for (size_t i = 0; i < ExtendedGlobals.size(); i++) { for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
Constant *Initializer = MetadataInitializers[i]; Constant *Initializer = MetadataInitializers[i];
GlobalVariable *G = ExtendedGlobals[i]; GlobalVariable *G = ExtendedGlobals[i];
GlobalVariable *Metadata = GlobalVariable *Metadata =
CreateMetadataGlobal(M, Initializer, G->getName()); CreateMetadataGlobal(M, Initializer, G->getName());
MDNode *MD = MDNode::get(M.getContext(), ValueAsMetadata::get(G));
Metadata->setMetadata(LLVMContext::MD_associated, MD);
MetadataGlobals[i] = Metadata;
// The MSVC linker always inserts padding when linking incrementally. We // The MSVC linker always inserts padding when linking incrementally. We
// cope with that by aligning each struct to its size, which must be a power // cope with that by aligning each struct to its size, which must be a power
@ -2052,6 +2056,11 @@ void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
SetComdatForGlobalMetadata(G, Metadata, ""); SetComdatForGlobalMetadata(G, Metadata, "");
} }
// Update llvm.compiler.used, adding the new metadata globals. This is
// needed so that during LTO these variables stay alive.
if (!MetadataGlobals.empty())
appendToCompilerUsed(M, MetadataGlobals);
} }
void ModuleAddressSanitizer::InstrumentGlobalsELF( void ModuleAddressSanitizer::InstrumentGlobalsELF(

View File

@ -17,8 +17,10 @@ $mystr = comdat any
; CHECK: @dead_global = global { i32, [60 x i8] } { i32 42, [60 x i8] zeroinitializer }, comdat, align 32 ; CHECK: @dead_global = global { i32, [60 x i8] } { i32 42, [60 x i8] zeroinitializer }, comdat, align 32
; CHECK: @private_str = internal constant { [8 x i8], [56 x i8] } { [8 x i8] c"private\00", [56 x i8] zeroinitializer }, comdat, align 32 ; CHECK: @private_str = internal constant { [8 x i8], [56 x i8] } { [8 x i8] c"private\00", [56 x i8] zeroinitializer }, comdat, align 32
; CHECK: @__asan_global_dead_global = private global { {{.*}} }, section ".ASAN$GL", comdat($dead_global), align 64 ; CHECK: @__asan_global_dead_global = private global { {{.*}} }, section ".ASAN$GL", comdat($dead_global), align 64, !associated
; CHECK: @__asan_global_private_str = private global { {{.*}} }, section ".ASAN$GL", comdat($private_str), align 64 ; CHECK: @__asan_global_private_str = private global { {{.*}} }, section ".ASAN$GL", comdat($private_str), align 64, !associated
; CHECK: @llvm.compiler.used {{.*}} @__asan_global_dead_global {{.*}} @__asan_global_private_str {{.*}} section "llvm.metadata"
@dead_global = local_unnamed_addr global i32 42, align 4 @dead_global = local_unnamed_addr global i32 42, align 4
@mystr = linkonce_odr unnamed_addr constant [5 x i8] c"main\00", comdat, align 1 @mystr = linkonce_odr unnamed_addr constant [5 x i8] c"main\00", comdat, align 1