Index: include/llvm/MC/MCTargetAsmParser.h =================================================================== --- include/llvm/MC/MCTargetAsmParser.h +++ include/llvm/MC/MCTargetAsmParser.h @@ -14,12 +14,13 @@ #include "llvm/MC/MCParser/MCAsmParserExtension.h" namespace llvm { -class MCStreamer; -class StringRef; -class SMLoc; class AsmToken; -class MCParsedAsmOperand; class MCInst; +class MCParsedAsmOperand; +class MCStreamer; +class MachineFunction; +class SMLoc; +class StringRef; template class SmallVectorImpl; enum AsmRewriteKind { @@ -97,6 +98,9 @@ /// ms-style inline assembly. MCAsmParserSemaCallback *SemaCallback; + /// Current MachineFunction. + const MachineFunction *MF; + public: virtual ~MCTargetAsmParser(); @@ -110,6 +114,13 @@ SemaCallback = Callback; } + void setMachineFunction(const MachineFunction *MF) { + this->MF = MF; + onMachineFunctionSet(); + } + + virtual void onMachineFunctionSet() {} + virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0; Index: lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -139,6 +139,7 @@ if (!TAP) report_fatal_error("Inline asm not supported by this streamer because" " we don't have an asm parser for this target\n"); + TAP->setMachineFunction(MF); Parser->setAssemblerDialect(Dialect); Parser->setTargetParser(*TAP.get()); Index: lib/MC/MCParser/MCTargetAsmParser.cpp =================================================================== --- lib/MC/MCParser/MCTargetAsmParser.cpp +++ lib/MC/MCParser/MCTargetAsmParser.cpp @@ -11,7 +11,7 @@ using namespace llvm; MCTargetAsmParser::MCTargetAsmParser() - : AvailableFeatures(0), ParsingInlineAsm(false) + : AvailableFeatures(0), ParsingInlineAsm(false), MF(NULL) { } Index: lib/Target/X86/AsmParser/X86AsmInstrumentation.h =================================================================== --- lib/Target/X86/AsmParser/X86AsmInstrumentation.h +++ lib/Target/X86/AsmParser/X86AsmInstrumentation.h @@ -11,9 +11,11 @@ #define X86_ASM_INSTRUMENTATION_H #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Compiler.h" namespace llvm { +class MachineFunction; class MCContext; class MCInst; class MCParsedAsmOperand; @@ -22,9 +24,14 @@ class X86AsmInstrumentation; -X86AsmInstrumentation *CreateX86AsmInstrumentation(MCSubtargetInfo &STI); +X86AsmInstrumentation * +CreateX86AsmInstrumentation(const MachineFunction *MF, MCSubtargetInfo &STI); class X86AsmInstrumentation { +private: + X86AsmInstrumentation(const X86AsmInstrumentation &) LLVM_DELETED_FUNCTION; + void operator=(const X86AsmInstrumentation &) LLVM_DELETED_FUNCTION; + public: virtual ~X86AsmInstrumentation(); @@ -36,9 +43,12 @@ protected: friend X86AsmInstrumentation * - CreateX86AsmInstrumentation(MCSubtargetInfo &STI); + CreateX86AsmInstrumentation(const MachineFunction *MF, MCSubtargetInfo &STI); + + X86AsmInstrumentation(const MachineFunction *MF, MCSubtargetInfo &STI); - X86AsmInstrumentation(); + const MachineFunction *MF; + MCSubtargetInfo &STI; }; } // End llvm namespace Index: lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp +++ lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp @@ -11,21 +11,31 @@ #include "X86AsmInstrumentation.h" #include "X86Operand.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/Function.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstBuilder.h" +#include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" -#include "llvm/MC/MCParser/MCParsedAsmOperand.h" +#include "llvm/Transforms/Utils/SpecialCaseList.h" +#include namespace llvm { namespace { -static cl::opt ClAsanInstrumentInlineAssembly( - "asan-instrument-inline-assembly", cl::desc("instrument inline assembly"), - cl::Hidden, cl::init(false)); +static cl::opt ClAsanNoInstrumentInlineAssembly( + "asan-no-instrument-inline-assembly", + cl::desc("don't instrument inline assembly"), cl::Hidden, cl::init(false)); + +static cl::opt ClBlacklistFile("asan-asm-blacklist", + cl::desc("File containing the list of objects to ignore " + "during instrumentation"), + cl::Hidden); bool IsStackReg(unsigned Reg) { return Reg == X86::RSP || Reg == X86::ESP || Reg == X86::SP; @@ -38,13 +48,18 @@ class X86AddressSanitizer : public X86AsmInstrumentation { public: - X86AddressSanitizer(MCSubtargetInfo &sti) : STI(sti) {} + X86AddressSanitizer(const MachineFunction *MF, MCSubtargetInfo &STI) + : X86AsmInstrumentation(MF, STI), + BL(SpecialCaseList::createOrDie(ClBlacklistFile)) {} virtual ~X86AddressSanitizer() {} // X86AsmInstrumentation implementation: virtual void InstrumentInstruction( const MCInst &Inst, SmallVectorImpl &Operands, MCContext &Ctx, MCStreamer &Out) override { + const Function *F = MF->getFunction(); + if (BL->isIn(*F)) + return; InstrumentMOV(Inst, Operands, Ctx, Out); } @@ -63,7 +78,7 @@ } protected: - MCSubtargetInfo &STI; + std::unique_ptr BL; }; void X86AddressSanitizer::InstrumentMemOperand( @@ -144,7 +159,8 @@ class X86AddressSanitizer32 : public X86AddressSanitizer { public: - X86AddressSanitizer32(MCSubtargetInfo &sti) : X86AddressSanitizer(sti) {} + X86AddressSanitizer32(const MachineFunction *MF, MCSubtargetInfo &STI) + : X86AddressSanitizer(MF, STI) {} virtual ~X86AddressSanitizer32() {} virtual void InstrumentMemOperandImpl(X86Operand *Op, unsigned AccessSize, @@ -179,7 +195,8 @@ class X86AddressSanitizer64 : public X86AddressSanitizer { public: - X86AddressSanitizer64(MCSubtargetInfo &sti) : X86AddressSanitizer(sti) {} + X86AddressSanitizer64(const MachineFunction *MF, MCSubtargetInfo &STI) + : X86AddressSanitizer(MF, STI) {} virtual ~X86AddressSanitizer64() {} virtual void InstrumentMemOperandImpl(X86Operand *Op, unsigned AccessSize, @@ -216,21 +233,30 @@ } // End anonymous namespace -X86AsmInstrumentation::X86AsmInstrumentation() {} +X86AsmInstrumentation::X86AsmInstrumentation(const MachineFunction *MF, + MCSubtargetInfo &STI) + : MF(MF), STI(STI) {} X86AsmInstrumentation::~X86AsmInstrumentation() {} void X86AsmInstrumentation::InstrumentInstruction( const MCInst &Inst, SmallVectorImpl &Operands, MCContext &Ctx, MCStreamer &Out) {} -X86AsmInstrumentation *CreateX86AsmInstrumentation(MCSubtargetInfo &STI) { - if (ClAsanInstrumentInlineAssembly) { +X86AsmInstrumentation * +CreateX86AsmInstrumentation(const MachineFunction *MF, MCSubtargetInfo &STI) { + if (!MF) + return new X86AsmInstrumentation(MF, STI); + const Function *F = MF->getFunction(); + if (!F) + return new X86AsmInstrumentation(MF, STI); + if (F->hasFnAttribute(Attribute::SanitizeAddress) && + !ClAsanNoInstrumentInlineAssembly) { if ((STI.getFeatureBits() & X86::Mode32Bit) != 0) - return new X86AddressSanitizer32(STI); + return new X86AddressSanitizer32(MF, STI); if ((STI.getFeatureBits() & X86::Mode64Bit) != 0) - return new X86AddressSanitizer64(STI); + return new X86AddressSanitizer64(MF, STI); } - return new X86AsmInstrumentation(); + return new X86AsmInstrumentation(MF, STI); } } // End llvm namespace Index: lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmParser.cpp +++ lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -715,8 +715,13 @@ // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); - Instrumentation.reset(CreateX86AsmInstrumentation(STI)); + Instrumentation.reset(CreateX86AsmInstrumentation(MF, STI)); } + + void onMachineFunctionSet() override { + Instrumentation.reset(CreateX86AsmInstrumentation(MF, STI)); + } + bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; bool Index: test/Instrumentation/AddressSanitizer/X86/asm_attr.ll =================================================================== --- /dev/null +++ test/Instrumentation/AddressSanitizer/X86/asm_attr.ll @@ -0,0 +1,29 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asan-asm-blacklist=%s.blacklist | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK-LABEL: mov_no_attr +; CHECK-NOT: callq __sanitizer_sanitize_load8@PLT +; CHECK-NOT: callq __sanitizer_sanitize_store8@PLT +define void @mov_no_attr(i64* %dst, i64* %src) { + tail call void asm sideeffect "movq ($1), %rax \0A\09movq %rax, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i64* %dst, i64* %src) + ret void +} + +; CHECK-LABEL: mov_blacklist +; CHECK-NOT: callq __sanitizer_sanitize_load8@PLT +; CHECK-NOT: callq __sanitizer_sanitize_store8@PLT +define void @mov_blacklist(i64* %dst, i64* %src) sanitize_address { + tail call void asm sideeffect "movq ($1), %rax \0A\09movq %rax, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i64* %dst, i64* %src) + ret void +} + +; CHECK-LABEL: mov_sanitize +; CHECK: callq __sanitizer_sanitize_load8@PLT +; CHECK: callq __sanitizer_sanitize_store8@PLT +define void @mov_sanitize(i64* %dst, i64* %src) sanitize_address { + tail call void asm sideeffect "movq ($1), %rax \0A\09movq %rax, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i64* %dst, i64* %src) + ret void +} + Index: test/Instrumentation/AddressSanitizer/X86/asm_attr.ll.blacklist =================================================================== --- /dev/null +++ test/Instrumentation/AddressSanitizer/X86/asm_attr.ll.blacklist @@ -0,0 +1 @@ +fun:*_blacklist Index: test/Instrumentation/AddressSanitizer/X86/asm_mov.ll =================================================================== --- test/Instrumentation/AddressSanitizer/X86/asm_mov.ll +++ test/Instrumentation/AddressSanitizer/X86/asm_mov.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asan-instrument-inline-assembly | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -113,7 +113,7 @@ ret void } -attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #0 = { nounwind uwtable sanitize_address "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { nounwind } !0 = metadata !{i32 98, i32 122, i32 160}