Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -37,6 +37,7 @@ #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/MC/MCSectionMachO.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Debug.h" @@ -288,8 +289,7 @@ bool OrShadowOffset; }; -static ShadowMapping getShadowMapping(const Module &M, int LongSize) { - llvm::Triple TargetTriple(M.getTargetTriple()); +static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize) { bool IsAndroid = TargetTriple.getEnvironment() == llvm::Triple::Android; bool IsIOS = TargetTriple.isiOS(); bool IsFreeBSD = TargetTriple.isOSFreeBSD(); @@ -418,8 +418,8 @@ private: void initializeCallbacks(Module &M); - bool InstrumentGlobals(IRBuilder<> &IRB, Module &M); - bool ShouldInstrumentGlobal(GlobalVariable *G); + bool InstrumentGlobals(IRBuilder<> &IRB, Module &M, Triple &TargetTriple); + bool ShouldInstrumentGlobal(GlobalVariable *G, Triple &TargetTriple); void poisonOneInitializer(Function &GlobalInit, GlobalValue *ModuleName); void createInitializerPoisonCalls(Module &M, GlobalValue *ModuleName); size_t MinRedzoneSizeForGlobal() const { @@ -1015,7 +1015,8 @@ } } -bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) { +bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G, + Triple &TargetTriple) { Type *Ty = cast(G->getType())->getElementType(); DEBUG(dbgs() << "GLOBAL: " << *G << "\n"); @@ -1042,37 +1043,47 @@ if (G->hasSection()) { StringRef Section(G->getSection()); - // Ignore the globals from the __OBJC section. The ObjC runtime assumes - // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to - // them. - if (Section.startswith("__OBJC,") || - Section.startswith("__DATA, __objc_")) { - DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G << "\n"); - return false; - } - // See http://code.google.com/p/address-sanitizer/issues/detail?id=32 - // Constant CFString instances are compiled in the following way: - // -- the string buffer is emitted into - // __TEXT,__cstring,cstring_literals - // -- the constant NSConstantString structure referencing that buffer - // is placed into __DATA,__cfstring - // Therefore there's no point in placing redzones into __DATA,__cfstring. - // Moreover, it causes the linker to crash on OS X 10.7 - if (Section.startswith("__DATA,__cfstring")) { - DEBUG(dbgs() << "Ignoring CFString: " << *G << "\n"); - return false; - } - // The linker merges the contents of cstring_literals and removes the - // trailing zeroes. - if (Section.startswith("__TEXT,__cstring,cstring_literals")) { - DEBUG(dbgs() << "Ignoring a cstring literal: " << *G << "\n"); - return false; - } - if (Section.startswith("__TEXT,__objc_methname,cstring_literals")) { - DEBUG(dbgs() << "Ignoring objc_methname cstring global: " << *G << "\n"); - return false; - } + if (TargetTriple.isOSBinFormatMachO()) { + StringRef ParsedSegment, ParsedSection; + unsigned TAA = 0, StubSize = 0; + bool TAAParsed; + std::string ErrorCode = + MCSectionMachO::ParseSectionSpecifier(Section, ParsedSegment, + ParsedSection, TAA, TAAParsed, + StubSize); + if (!ErrorCode.empty()) { + report_fatal_error("Invalid section specifier '" + ParsedSection + + "': " + ErrorCode + "."); + } + + // Ignore the globals from the __OBJC section. The ObjC runtime assumes + // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to + // them. + if (ParsedSegment == "__OBJC" || + (ParsedSegment == "__DATA" && ParsedSection.startswith("__objc_"))) { + DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G << "\n"); + return false; + } + // See http://code.google.com/p/address-sanitizer/issues/detail?id=32 + // Constant CFString instances are compiled in the following way: + // -- the string buffer is emitted into + // __TEXT,__cstring,cstring_literals + // -- the constant NSConstantString structure referencing that buffer + // is placed into __DATA,__cfstring + // Therefore there's no point in placing redzones into __DATA,__cfstring. + // Moreover, it causes the linker to crash on OS X 10.7 + if (ParsedSegment == "__DATA" && ParsedSection == "__cfstring") { + DEBUG(dbgs() << "Ignoring CFString: " << *G << "\n"); + return false; + } + // The linker merges the contents of cstring_literals and removes the + // trailing zeroes. + if (ParsedSegment == "__TEXT" && (TAA & MachO::S_CSTRING_LITERALS)) { + DEBUG(dbgs() << "Ignoring a cstring literal: " << *G << "\n"); + return false; + } + } // Callbacks put into the CRT initializer/terminator sections // should not be instrumented. @@ -1113,13 +1124,14 @@ // This function replaces all global variables with new variables that have // trailing redzones. It also creates a function that poisons // redzones and inserts this function into llvm.global_ctors. -bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { +bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M, + Triple &TargetTriple) { GlobalsMD.init(M); SmallVector GlobalsToChange; for (auto &G : M.globals()) { - if (ShouldInstrumentGlobal(&G)) + if (ShouldInstrumentGlobal(&G, TargetTriple)) GlobalsToChange.push_back(&G); } @@ -1256,7 +1268,8 @@ C = &(M.getContext()); int LongSize = DL->getPointerSizeInBits(); IntptrTy = Type::getIntNTy(*C, LongSize); - Mapping = getShadowMapping(M, LongSize); + Triple TargetTriple(M.getTargetTriple()); + Mapping = getShadowMapping(TargetTriple, LongSize); initializeCallbacks(M); bool Changed = false; @@ -1266,7 +1279,7 @@ IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); if (ClGlobals) - Changed |= InstrumentGlobals(IRB, M); + Changed |= InstrumentGlobals(IRB, M, TargetTriple); return Changed; } @@ -1350,7 +1363,8 @@ AsanInitFunction->setLinkage(Function::ExternalLinkage); IRB.CreateCall(AsanInitFunction); - Mapping = getShadowMapping(M, LongSize); + Triple TargetTriple(M.getTargetTriple()); + Mapping = getShadowMapping(TargetTriple, LongSize); appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority); return true; Index: projects/compiler-rt/test/asan/TestCases/Darwin/objc-odr.mm =================================================================== --- projects/compiler-rt/test/asan/TestCases/Darwin/objc-odr.mm +++ projects/compiler-rt/test/asan/TestCases/Darwin/objc-odr.mm @@ -0,0 +1,23 @@ +// Regression test for +// https://code.google.com/p/address-sanitizer/issues/detail?id=360. + +// RUN: %clang_asan %s -o %t -framework Foundation +// RUN: %run %t 2>&1 | FileCheck %s + +#import + +void f() { + int y = 7; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + dispatch_sync(dispatch_get_main_queue(), ^{ + printf("num = %d\n", y); + }); + }); +} + +int main() { + NSLog(@"Hello world"); +} + +// CHECK-NOT: AddressSanitizer: odr-violation +// CHECK: Hello world