diff --git a/clang/test/CodeGen/asan_globals_symbols.cpp b/clang/test/CodeGen/asan_globals_symbols.cpp new file mode 100644 index 0000000000000..d53afb2433b17 --- /dev/null +++ b/clang/test/CodeGen/asan_globals_symbols.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -S -x c++ -std=c++11 -triple x86_64-linux \ +// RUN: -fsanitize=address -o %t.out %s +// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-A + +// CHECK-A: myGlobal: +// CHECK-A: .size myGlobal, 4 +// CHECK-A: myGlobal__sanitized_padded_global: +// CHECK-A .size myGlobal__sanitized_padded_global, 32 + +int myGlobal; + +int main() { + myGlobal = 0; + return 0; +} diff --git a/clang/test/CodeGen/asan_globals_symbols_ir_attribute.cpp b/clang/test/CodeGen/asan_globals_symbols_ir_attribute.cpp new file mode 100644 index 0000000000000..f8ba5eb737696 --- /dev/null +++ b/clang/test/CodeGen/asan_globals_symbols_ir_attribute.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -fsanitize=address -emit-llvm -o - | FileCheck -check-prefix=CHECK-ASAN %s + +// CHECK-ASAN: @myGlobal1 = global { i32, [28 x i8] } zeroinitializer, align 32 #[[ATTR0:[0-9]+]] +// CHECK-ASAN: @myGlobal2 = global i32 0, no_sanitize_address, align 4 +// CHECK-NOT: #[[ATTR1:[0-9]+]] +// CHECK-ASAN: attributes #[[ATTR0]] = { sanitized_padded_global } + +int myGlobal1; +int __attribute__((no_sanitize("address"))) myGlobal2; + +int main() { + myGlobal1 = 0; + myGlobal2 = 0; + return 0; +} diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 7df1c82bf357f..cf1bdde6fc342 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -801,6 +801,19 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { // sections and expected to be contiguous (e.g. ObjC metadata). const Align Alignment = getGVAlignment(GV, DL); + // Identify globals with "SanitizedPaddedGlobal" attribute and extract + // the actual global variable size. + uint64_t ActualSize = 0; + if (GV->hasAttribute(Attribute::SanitizedPaddedGlobal)) { + StructType *ST = dyn_cast(GV->getValueType()); + if (ST && ST->getNumElements() == 2) { + auto *ET0 = ST->getElementType(0); + if (ET0 && isa(ST->getElementType(1))) { + ActualSize = DL.getTypeAllocSize(ET0); + } + } + } + for (const HandlerInfo &HI : Handlers) { NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName, HI.TimerGroupDescription, @@ -911,6 +924,18 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { MCSymbol *EmittedInitSym = GVSym; + if (GV->hasAttribute(Attribute::SanitizedPaddedGlobal)) { + OutStreamer->switchSection(TheSection); + emitLinkage(GV, EmittedInitSym); + OutStreamer->emitLabel(EmittedInitSym); + if (MAI->hasDotTypeDotSizeDirective()) + OutStreamer->emitELFSize(EmittedInitSym, + MCConstantExpr::create(ActualSize, OutContext)); + EmittedInitSym = OutContext.getOrCreateSymbol( + GVSym->getName() + Twine("__sanitized_padded_global")); + emitVisibility(EmittedInitSym, GV->getVisibility(), !GV->isDeclaration()); + } + OutStreamer->switchSection(TheSection); emitLinkage(GV, EmittedInitSym); @@ -918,7 +943,8 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { OutStreamer->emitLabel(EmittedInitSym); MCSymbol *LocalAlias = getSymbolPreferLocal(*GV); - if (LocalAlias != EmittedInitSym) + if ((LocalAlias != EmittedInitSym) && + !GV->hasAttribute(Attribute::SanitizedPaddedGlobal)) OutStreamer->emitLabel(LocalAlias); emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer()); diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index caab98c732eee..a0dbc5224b3eb 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -2496,6 +2496,9 @@ void ModuleAddressSanitizer::instrumentGlobals(IRBuilder<> &IRB, Module &M, // zero so we can copy the metadata over as is. NewGlobal->copyMetadata(G, 0); + // Attach "SanitizedPaddedGlobal" attribute to the new global. + NewGlobal->addAttribute(Attribute::SanitizedPaddedGlobal); + Value *Indices2[2]; Indices2[0] = IRB.getInt32(0); Indices2[1] = IRB.getInt32(0); diff --git a/llvm/test/Instrumentation/AddressSanitizer/debug-info-global-var.ll b/llvm/test/Instrumentation/AddressSanitizer/debug-info-global-var.ll index 0b516e0174d6d..2815c1f04bff1 100644 --- a/llvm/test/Instrumentation/AddressSanitizer/debug-info-global-var.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/debug-info-global-var.ll @@ -2,7 +2,7 @@ source_filename = "version.c" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.12.0" -; CHECK: @version = constant { [5 x i8], [27 x i8] } {{.*}}, !dbg ![[GV:.*]] +; CHECK: @version = constant { [5 x i8], [27 x i8] } {{.*}}, !dbg ![[GV:.*]] {{.*}} @version = constant [5 x i8] c"4.00\00", align 1, !dbg !0