From: Yuri Gorshenin Date: Mon, 1 Sep 2014 10:24:04 +0000 (+0000) Subject: Revert "[asan-assembly-instrumentation] Prologue and epilogue are moved out from... X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=c642ad95462bdab20d221ac373ed812a95f46d35 Revert "[asan-assembly-instrumentation] Prologue and epilogue are moved out from InstrumentMemOperand()." This reverts commit 895aa397038b8de86d83ac0997a70949a486e112. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216872 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/AsmParser/CMakeLists.txt b/lib/Target/X86/AsmParser/CMakeLists.txt index 2c1926edc26..b022a41b192 100644 --- a/lib/Target/X86/AsmParser/CMakeLists.txt +++ b/lib/Target/X86/AsmParser/CMakeLists.txt @@ -1,7 +1,4 @@ add_llvm_library(LLVMX86AsmParser X86AsmInstrumentation.cpp X86AsmParser.cpp - - LINK_LIBS - LLVMX86CodeGen ) diff --git a/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp b/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp index 3d0f72f3fa5..bea4f0c39b7 100644 --- a/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp +++ b/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp @@ -10,10 +10,8 @@ #include "MCTargetDesc/X86BaseInfo.h" #include "X86AsmInstrumentation.h" #include "X86Operand.h" -#include "X86RegisterInfo.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" -#include "llvm/CodeGen/MachineValueType.h" #include "llvm/IR/Function.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInst.h" @@ -38,8 +36,6 @@ bool IsStackReg(unsigned Reg) { return Reg == X86::RSP || Reg == X86::ESP || Reg == X86::SP; } -bool IsSmallMemAccess(unsigned AccessSize) { return AccessSize < 8; } - std::string FuncName(unsigned AccessSize, bool IsWrite) { return std::string("__asan_report_") + (IsWrite ? "store" : "load") + utostr(AccessSize); @@ -47,29 +43,6 @@ std::string FuncName(unsigned AccessSize, bool IsWrite) { class X86AddressSanitizer : public X86AsmInstrumentation { public: - struct RegisterContext { - RegisterContext(unsigned AddressReg, unsigned ShadowReg, - unsigned ScratchReg) - : AddressReg(AddressReg), ShadowReg(ShadowReg), ScratchReg(ScratchReg) { - } - - unsigned addressReg(MVT::SimpleValueType VT) const { - return getX86SubSuperRegister(AddressReg, VT); - } - - unsigned shadowReg(MVT::SimpleValueType VT) const { - return getX86SubSuperRegister(ShadowReg, VT); - } - - unsigned scratchReg(MVT::SimpleValueType VT) const { - return getX86SubSuperRegister(ScratchReg, VT); - } - - const unsigned AddressReg; - const unsigned ShadowReg; - const unsigned ScratchReg; - }; - X86AddressSanitizer(const MCSubtargetInfo &STI) : X86AsmInstrumentation(STI), RepPrefix(false) {} virtual ~X86AddressSanitizer() {} @@ -92,61 +65,51 @@ public: } // Should be implemented differently in x86_32 and x86_64 subclasses. - virtual void StoreFlags(MCStreamer &Out) = 0; - - virtual void RestoreFlags(MCStreamer &Out) = 0; - - // Adjusts up stack and saves all registers used in instrumentation. - virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx, - MCContext &Ctx, - MCStreamer &Out) = 0; - - // Restores all registers used in instrumentation and adjusts stack. - virtual void InstrumentMemOperandEpilogue(const RegisterContext &RegCtx, - MCContext &Ctx, - MCStreamer &Out) = 0; - - virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize, - bool IsWrite, - const RegisterContext &RegCtx, - MCContext &Ctx, MCStreamer &Out) = 0; - virtual void InstrumentMemOperandLarge(X86Operand &Op, unsigned AccessSize, - bool IsWrite, - const RegisterContext &RegCtx, - MCContext &Ctx, MCStreamer &Out) = 0; - + virtual void InstrumentMemOperandSmallImpl(X86Operand &Op, + unsigned AccessSize, bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) = 0; + virtual void InstrumentMemOperandLargeImpl(X86Operand &Op, + unsigned AccessSize, bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) = 0; virtual void InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx, MCStreamer &Out) = 0; - void InstrumentMemOperand(X86Operand &Op, unsigned AccessSize, bool IsWrite, - const RegisterContext &RegCtx, MCContext &Ctx, - MCStreamer &Out); + void InstrumentMemOperand(MCParsedAsmOperand &Op, unsigned AccessSize, + bool IsWrite, MCContext &Ctx, MCStreamer &Out); void InstrumentMOVSBase(unsigned DstReg, unsigned SrcReg, unsigned CntReg, unsigned AccessSize, MCContext &Ctx, MCStreamer &Out); - void InstrumentMOVS(const MCInst &Inst, OperandVector &Operands, MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out); void InstrumentMOV(const MCInst &Inst, OperandVector &Operands, MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out); -protected: void EmitLabel(MCStreamer &Out, MCSymbol *Label) { Out.EmitLabel(Label); } +protected: // True when previous instruction was actually REP prefix. bool RepPrefix; }; -void X86AddressSanitizer::InstrumentMemOperand( - X86Operand &Op, unsigned AccessSize, bool IsWrite, - const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) { +void X86AddressSanitizer::InstrumentMemOperand(MCParsedAsmOperand &Op, + unsigned AccessSize, + bool IsWrite, MCContext &Ctx, + MCStreamer &Out) { assert(Op.isMem() && "Op should be a memory operand."); assert((AccessSize & (AccessSize - 1)) == 0 && AccessSize <= 16 && "AccessSize should be a power of two, less or equal than 16."); + + X86Operand &MemOp = static_cast(Op); + // FIXME: get rid of this limitation. + if (IsStackReg(MemOp.getMemBaseReg()) || IsStackReg(MemOp.getMemIndexReg())) + return; + // FIXME: take into account load/store alignment. - if (IsSmallMemAccess(AccessSize)) - InstrumentMemOperandSmall(Op, AccessSize, IsWrite, RegCtx, Ctx, Out); + if (AccessSize < 8) + InstrumentMemOperandSmallImpl(MemOp, AccessSize, IsWrite, Ctx, Out); else - InstrumentMemOperandLarge(Op, AccessSize, IsWrite, RegCtx, Ctx, Out); + InstrumentMemOperandLargeImpl(MemOp, AccessSize, IsWrite, Ctx, Out); } void X86AddressSanitizer::InstrumentMOVSBase(unsigned DstReg, unsigned SrcReg, @@ -155,20 +118,16 @@ void X86AddressSanitizer::InstrumentMOVSBase(unsigned DstReg, unsigned SrcReg, MCContext &Ctx, MCStreamer &Out) { // FIXME: check whole ranges [DstReg .. DstReg + AccessSize * (CntReg - 1)] // and [SrcReg .. SrcReg + AccessSize * (CntReg - 1)]. - RegisterContext RegCtx(X86::RDX /* AddressReg */, X86::RAX /* ShadowReg */, - IsSmallMemAccess(AccessSize) - ? X86::RBX - : X86::NoRegister /* ScratchReg */); - InstrumentMemOperandPrologue(RegCtx, Ctx, Out); + // FIXME: extract prolog and epilogue from InstrumentMemOperand() + // and optimize this sequence of InstrumentMemOperand() calls. // Test (%SrcReg) { const MCExpr *Disp = MCConstantExpr::Create(0, Ctx); std::unique_ptr Op(X86Operand::CreateMem( 0, Disp, SrcReg, 0, AccessSize, SMLoc(), SMLoc())); - InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, RegCtx, Ctx, - Out); + InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, Ctx, Out); } // Test -1(%SrcReg, %CntReg, AccessSize) @@ -176,8 +135,7 @@ void X86AddressSanitizer::InstrumentMOVSBase(unsigned DstReg, unsigned SrcReg, const MCExpr *Disp = MCConstantExpr::Create(-1, Ctx); std::unique_ptr Op(X86Operand::CreateMem( 0, Disp, SrcReg, CntReg, AccessSize, SMLoc(), SMLoc())); - InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, RegCtx, Ctx, - Out); + InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, Ctx, Out); } // Test (%DstReg) @@ -185,7 +143,7 @@ void X86AddressSanitizer::InstrumentMOVSBase(unsigned DstReg, unsigned SrcReg, const MCExpr *Disp = MCConstantExpr::Create(0, Ctx); std::unique_ptr Op(X86Operand::CreateMem( 0, Disp, DstReg, 0, AccessSize, SMLoc(), SMLoc())); - InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, RegCtx, Ctx, Out); + InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, Ctx, Out); } // Test -1(%DstReg, %CntReg, AccessSize) @@ -193,10 +151,8 @@ void X86AddressSanitizer::InstrumentMOVSBase(unsigned DstReg, unsigned SrcReg, const MCExpr *Disp = MCConstantExpr::Create(-1, Ctx); std::unique_ptr Op(X86Operand::CreateMem( 0, Disp, DstReg, CntReg, AccessSize, SMLoc(), SMLoc())); - InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, RegCtx, Ctx, Out); + InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, Ctx, Out); } - - InstrumentMemOperandEpilogue(RegCtx, Ctx, Out); } void X86AddressSanitizer::InstrumentMOVS(const MCInst &Inst, @@ -265,26 +221,11 @@ void X86AddressSanitizer::InstrumentMOV(const MCInst &Inst, } const bool IsWrite = MII.get(Inst.getOpcode()).mayStore(); - RegisterContext RegCtx(X86::RDI /* AddressReg */, X86::RAX /* ShadowReg */, - IsSmallMemAccess(AccessSize) - ? X86::RCX - : X86::NoRegister /* ScratchReg */); - for (unsigned Ix = 0; Ix < Operands.size(); ++Ix) { assert(Operands[Ix]); MCParsedAsmOperand &Op = *Operands[Ix]; - if (Op.isMem()) { - X86Operand &MemOp = static_cast(Op); - // FIXME: get rid of this limitation. - if (IsStackReg(MemOp.getMemBaseReg()) || - IsStackReg(MemOp.getMemIndexReg())) { - continue; - } - - InstrumentMemOperandPrologue(RegCtx, Ctx, Out); - InstrumentMemOperand(MemOp, AccessSize, IsWrite, RegCtx, Ctx, Out); - InstrumentMemOperandEpilogue(RegCtx, Ctx, Out); - } + if (Op.isMem()) + InstrumentMemOperand(Op, AccessSize, IsWrite, Ctx, Out); } } @@ -296,58 +237,20 @@ public: : X86AddressSanitizer(STI) {} virtual ~X86AddressSanitizer32() {} - virtual void StoreFlags(MCStreamer &Out) override { - EmitInstruction(Out, MCInstBuilder(X86::PUSHF32)); - } - - virtual void RestoreFlags(MCStreamer &Out) override { - EmitInstruction(Out, MCInstBuilder(X86::POPF32)); - } - - virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx, - MCContext &Ctx, - MCStreamer &Out) override { - EmitInstruction( - Out, MCInstBuilder(X86::PUSH32r).addReg(RegCtx.addressReg(MVT::i32))); - EmitInstruction( - Out, MCInstBuilder(X86::PUSH32r).addReg(RegCtx.shadowReg(MVT::i32))); - if (RegCtx.ScratchReg != X86::NoRegister) { - EmitInstruction( - Out, MCInstBuilder(X86::PUSH32r).addReg(RegCtx.scratchReg(MVT::i32))); - } - StoreFlags(Out); - } - - virtual void InstrumentMemOperandEpilogue(const RegisterContext &RegCtx, - MCContext &Ctx, - MCStreamer &Out) override { - RestoreFlags(Out); - if (RegCtx.ScratchReg != X86::NoRegister) { - EmitInstruction( - Out, MCInstBuilder(X86::POP32r).addReg(RegCtx.scratchReg(MVT::i32))); - } - EmitInstruction( - Out, MCInstBuilder(X86::POP32r).addReg(RegCtx.shadowReg(MVT::i32))); - EmitInstruction( - Out, MCInstBuilder(X86::POP32r).addReg(RegCtx.addressReg(MVT::i32))); - } - - virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize, - bool IsWrite, - const RegisterContext &RegCtx, - MCContext &Ctx, - MCStreamer &Out) override; - virtual void InstrumentMemOperandLarge(X86Operand &Op, unsigned AccessSize, - bool IsWrite, - const RegisterContext &RegCtx, - MCContext &Ctx, - MCStreamer &Out) override; + virtual void InstrumentMemOperandSmallImpl(X86Operand &Op, + unsigned AccessSize, bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) override; + virtual void InstrumentMemOperandLargeImpl(X86Operand &Op, + unsigned AccessSize, bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) override; virtual void InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx, MCStreamer &Out) override; private: - void EmitCallAsanReport(unsigned AccessSize, bool IsWrite, MCContext &Ctx, - MCStreamer &Out, const RegisterContext &RegCtx) { + void EmitCallAsanReport(MCContext &Ctx, MCStreamer &Out, unsigned AccessSize, + bool IsWrite, unsigned AddressReg) { EmitInstruction(Out, MCInstBuilder(X86::CLD)); EmitInstruction(Out, MCInstBuilder(X86::MMX_EMMS)); @@ -355,8 +258,7 @@ private: .addReg(X86::ESP) .addReg(X86::ESP) .addImm(-16)); - EmitInstruction( - Out, MCInstBuilder(X86::PUSH32r).addReg(RegCtx.addressReg(MVT::i32))); + EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(AddressReg)); const std::string &Fn = FuncName(AccessSize, IsWrite); MCSymbol *FnSym = Ctx.GetOrCreateSymbol(StringRef(Fn)); @@ -366,54 +268,52 @@ private: } }; -void X86AddressSanitizer32::InstrumentMemOperandSmall( - X86Operand &Op, unsigned AccessSize, bool IsWrite, - const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) { - unsigned AddressRegI32 = RegCtx.addressReg(MVT::i32); - unsigned ShadowRegI32 = RegCtx.shadowReg(MVT::i32); - unsigned ShadowRegI8 = RegCtx.shadowReg(MVT::i8); - - assert(RegCtx.ScratchReg != X86::NoRegister); - unsigned ScratchRegI32 = RegCtx.scratchReg(MVT::i32); +void X86AddressSanitizer32::InstrumentMemOperandSmallImpl(X86Operand &Op, + unsigned AccessSize, + bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) { + EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX)); + EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::ECX)); + EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EDX)); + EmitInstruction(Out, MCInstBuilder(X86::PUSHF32)); { MCInst Inst; Inst.setOpcode(X86::LEA32r); - Inst.addOperand(MCOperand::CreateReg(AddressRegI32)); + Inst.addOperand(MCOperand::CreateReg(X86::EAX)); Op.addMemOperands(Inst, 5); EmitInstruction(Out, Inst); } - EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ShadowRegI32).addReg( - AddressRegI32)); - EmitInstruction(Out, MCInstBuilder(X86::SHR32ri) - .addReg(ShadowRegI32) - .addReg(ShadowRegI32) - .addImm(3)); + EmitInstruction( + Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EAX)); + EmitInstruction( + Out, + MCInstBuilder(X86::SHR32ri).addReg(X86::ECX).addReg(X86::ECX).addImm(3)); { MCInst Inst; Inst.setOpcode(X86::MOV8rm); - Inst.addOperand(MCOperand::CreateReg(ShadowRegI8)); + Inst.addOperand(MCOperand::CreateReg(X86::CL)); const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, ShadowRegI32, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc())); Op->addMemOperands(Inst, 5); EmitInstruction(Out, Inst); } - EmitInstruction( - Out, MCInstBuilder(X86::TEST8rr).addReg(ShadowRegI8).addReg(ShadowRegI8)); + EmitInstruction(Out, + MCInstBuilder(X86::TEST8rr).addReg(X86::CL).addReg(X86::CL)); MCSymbol *DoneSym = Ctx.CreateTempSymbol(); const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx); EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr)); - EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ScratchRegI32).addReg( - AddressRegI32)); - EmitInstruction(Out, MCInstBuilder(X86::AND32ri) - .addReg(ScratchRegI32) - .addReg(ScratchRegI32) - .addImm(7)); + EmitInstruction( + Out, MCInstBuilder(X86::MOV32rr).addReg(X86::EDX).addReg(X86::EAX)); + EmitInstruction( + Out, + MCInstBuilder(X86::AND32ri).addReg(X86::EDX).addReg(X86::EDX).addImm(7)); switch (AccessSize) { case 1: @@ -421,19 +321,19 @@ void X86AddressSanitizer32::InstrumentMemOperandSmall( case 2: { MCInst Inst; Inst.setOpcode(X86::LEA32r); - Inst.addOperand(MCOperand::CreateReg(ScratchRegI32)); + Inst.addOperand(MCOperand::CreateReg(X86::EDX)); const MCExpr *Disp = MCConstantExpr::Create(1, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, ScratchRegI32, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::EDX, 0, 1, SMLoc(), SMLoc())); Op->addMemOperands(Inst, 5); EmitInstruction(Out, Inst); break; } case 4: EmitInstruction(Out, MCInstBuilder(X86::ADD32ri8) - .addReg(ScratchRegI32) - .addReg(ScratchRegI32) + .addReg(X86::EDX) + .addReg(X86::EDX) .addImm(3)); break; default: @@ -442,36 +342,41 @@ void X86AddressSanitizer32::InstrumentMemOperandSmall( } EmitInstruction( - Out, - MCInstBuilder(X86::MOVSX32rr8).addReg(ShadowRegI32).addReg(ShadowRegI8)); - EmitInstruction(Out, MCInstBuilder(X86::CMP32rr).addReg(ScratchRegI32).addReg( - ShadowRegI32)); + Out, MCInstBuilder(X86::MOVSX32rr8).addReg(X86::ECX).addReg(X86::CL)); + EmitInstruction( + Out, MCInstBuilder(X86::CMP32rr).addReg(X86::EDX).addReg(X86::ECX)); EmitInstruction(Out, MCInstBuilder(X86::JL_4).addExpr(DoneExpr)); - EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx); + EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite, X86::EAX); EmitLabel(Out, DoneSym); + + EmitInstruction(Out, MCInstBuilder(X86::POPF32)); + EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EDX)); + EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::ECX)); + EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EAX)); } -void X86AddressSanitizer32::InstrumentMemOperandLarge( - X86Operand &Op, unsigned AccessSize, bool IsWrite, - const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) { - unsigned AddressRegI32 = RegCtx.addressReg(MVT::i32); - unsigned ShadowRegI32 = RegCtx.shadowReg(MVT::i32); +void X86AddressSanitizer32::InstrumentMemOperandLargeImpl(X86Operand &Op, + unsigned AccessSize, + bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) { + EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX)); + EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::ECX)); + EmitInstruction(Out, MCInstBuilder(X86::PUSHF32)); { MCInst Inst; Inst.setOpcode(X86::LEA32r); - Inst.addOperand(MCOperand::CreateReg(AddressRegI32)); + Inst.addOperand(MCOperand::CreateReg(X86::EAX)); Op.addMemOperands(Inst, 5); EmitInstruction(Out, Inst); } - - EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ShadowRegI32).addReg( - AddressRegI32)); - EmitInstruction(Out, MCInstBuilder(X86::SHR32ri) - .addReg(ShadowRegI32) - .addReg(ShadowRegI32) - .addImm(3)); + EmitInstruction( + Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EAX)); + EmitInstruction( + Out, + MCInstBuilder(X86::SHR32ri).addReg(X86::ECX).addReg(X86::ECX).addImm(3)); { MCInst Inst; switch (AccessSize) { @@ -487,7 +392,7 @@ void X86AddressSanitizer32::InstrumentMemOperandLarge( } const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, ShadowRegI32, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc())); Op->addMemOperands(Inst, 5); Inst.addOperand(MCOperand::CreateImm(0)); EmitInstruction(Out, Inst); @@ -496,14 +401,18 @@ void X86AddressSanitizer32::InstrumentMemOperandLarge( const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx); EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr)); - EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx); + EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite, X86::EAX); EmitLabel(Out, DoneSym); + + EmitInstruction(Out, MCInstBuilder(X86::POPF32)); + EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::ECX)); + EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EAX)); } void X86AddressSanitizer32::InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx, MCStreamer &Out) { - StoreFlags(Out); + EmitInstruction(Out, MCInstBuilder(X86::PUSHF32)); // No need to test when ECX is equals to zero. MCSymbol *DoneSym = Ctx.CreateTempSymbol(); @@ -517,7 +426,7 @@ void X86AddressSanitizer32::InstrumentMOVSImpl(unsigned AccessSize, X86::ECX /* CntReg */, AccessSize, Ctx, Out); EmitLabel(Out, DoneSym); - RestoreFlags(Out); + EmitInstruction(Out, MCInstBuilder(X86::POPF32)); } class X86AddressSanitizer64 : public X86AddressSanitizer { @@ -528,54 +437,14 @@ public: : X86AddressSanitizer(STI) {} virtual ~X86AddressSanitizer64() {} - virtual void StoreFlags(MCStreamer &Out) override { - EmitInstruction(Out, MCInstBuilder(X86::PUSHF64)); - } - - virtual void RestoreFlags(MCStreamer &Out) override { - EmitInstruction(Out, MCInstBuilder(X86::POPF64)); - } - - virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx, - MCContext &Ctx, - MCStreamer &Out) override { - EmitAdjustRSP(Ctx, Out, -128); - EmitInstruction( - Out, MCInstBuilder(X86::PUSH64r).addReg(RegCtx.shadowReg(MVT::i64))); - EmitInstruction( - Out, MCInstBuilder(X86::PUSH64r).addReg(RegCtx.addressReg(MVT::i64))); - if (RegCtx.ScratchReg != X86::NoRegister) { - EmitInstruction( - Out, MCInstBuilder(X86::PUSH64r).addReg(RegCtx.scratchReg(MVT::i64))); - } - StoreFlags(Out); - } - - virtual void InstrumentMemOperandEpilogue(const RegisterContext &RegCtx, - MCContext &Ctx, - MCStreamer &Out) override { - RestoreFlags(Out); - if (RegCtx.ScratchReg != X86::NoRegister) { - EmitInstruction( - Out, MCInstBuilder(X86::POP64r).addReg(RegCtx.scratchReg(MVT::i64))); - } - EmitInstruction( - Out, MCInstBuilder(X86::POP64r).addReg(RegCtx.addressReg(MVT::i64))); - EmitInstruction( - Out, MCInstBuilder(X86::POP64r).addReg(RegCtx.shadowReg(MVT::i64))); - EmitAdjustRSP(Ctx, Out, 128); - } - - virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize, - bool IsWrite, - const RegisterContext &RegCtx, - MCContext &Ctx, - MCStreamer &Out) override; - virtual void InstrumentMemOperandLarge(X86Operand &Op, unsigned AccessSize, - bool IsWrite, - const RegisterContext &RegCtx, - MCContext &Ctx, - MCStreamer &Out) override; + virtual void InstrumentMemOperandSmallImpl(X86Operand &Op, + unsigned AccessSize, bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) override; + virtual void InstrumentMemOperandLargeImpl(X86Operand &Op, + unsigned AccessSize, bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) override; virtual void InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx, MCStreamer &Out) override; @@ -592,8 +461,8 @@ private: EmitInstruction(Out, Inst); } - void EmitCallAsanReport(unsigned AccessSize, bool IsWrite, MCContext &Ctx, - MCStreamer &Out, const RegisterContext &RegCtx) { + void EmitCallAsanReport(MCContext &Ctx, MCStreamer &Out, unsigned AccessSize, + bool IsWrite) { EmitInstruction(Out, MCInstBuilder(X86::CLD)); EmitInstruction(Out, MCInstBuilder(X86::MMX_EMMS)); @@ -602,10 +471,6 @@ private: .addReg(X86::RSP) .addImm(-16)); - if (RegCtx.AddressReg != X86::RDI) { - EmitInstruction(Out, MCInstBuilder(X86::MOV64rr).addReg(X86::RDI).addReg( - RegCtx.addressReg(MVT::i64))); - } const std::string &Fn = FuncName(AccessSize, IsWrite); MCSymbol *FnSym = Ctx.GetOrCreateSymbol(StringRef(Fn)); const MCSymbolRefExpr *FnExpr = @@ -614,54 +479,50 @@ private: } }; -void X86AddressSanitizer64::InstrumentMemOperandSmall( - X86Operand &Op, unsigned AccessSize, bool IsWrite, - const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) { - unsigned AddressRegI64 = RegCtx.addressReg(MVT::i64); - unsigned AddressRegI32 = RegCtx.addressReg(MVT::i32); - unsigned ShadowRegI64 = RegCtx.shadowReg(MVT::i64); - unsigned ShadowRegI32 = RegCtx.shadowReg(MVT::i32); - unsigned ShadowRegI8 = RegCtx.shadowReg(MVT::i8); - - assert(RegCtx.ScratchReg != X86::NoRegister); - unsigned ScratchRegI32 = RegCtx.scratchReg(MVT::i32); - +void X86AddressSanitizer64::InstrumentMemOperandSmallImpl(X86Operand &Op, + unsigned AccessSize, + bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) { + EmitAdjustRSP(Ctx, Out, -128); + EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RAX)); + EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RCX)); + EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RDI)); + EmitInstruction(Out, MCInstBuilder(X86::PUSHF64)); { MCInst Inst; Inst.setOpcode(X86::LEA64r); - Inst.addOperand(MCOperand::CreateReg(AddressRegI64)); + Inst.addOperand(MCOperand::CreateReg(X86::RDI)); Op.addMemOperands(Inst, 5); EmitInstruction(Out, Inst); } - EmitInstruction(Out, MCInstBuilder(X86::MOV64rr).addReg(ShadowRegI64).addReg( - AddressRegI64)); - EmitInstruction(Out, MCInstBuilder(X86::SHR64ri) - .addReg(ShadowRegI64) - .addReg(ShadowRegI64) - .addImm(3)); + EmitInstruction( + Out, MCInstBuilder(X86::MOV64rr).addReg(X86::RAX).addReg(X86::RDI)); + EmitInstruction( + Out, + MCInstBuilder(X86::SHR64ri).addReg(X86::RAX).addReg(X86::RAX).addImm(3)); { MCInst Inst; Inst.setOpcode(X86::MOV8rm); - Inst.addOperand(MCOperand::CreateReg(ShadowRegI8)); + Inst.addOperand(MCOperand::CreateReg(X86::AL)); const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, ShadowRegI64, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc())); Op->addMemOperands(Inst, 5); EmitInstruction(Out, Inst); } - EmitInstruction( - Out, MCInstBuilder(X86::TEST8rr).addReg(ShadowRegI8).addReg(ShadowRegI8)); + EmitInstruction(Out, + MCInstBuilder(X86::TEST8rr).addReg(X86::AL).addReg(X86::AL)); MCSymbol *DoneSym = Ctx.CreateTempSymbol(); const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx); EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr)); - EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ScratchRegI32).addReg( - AddressRegI32)); - EmitInstruction(Out, MCInstBuilder(X86::AND32ri) - .addReg(ScratchRegI32) - .addReg(ScratchRegI32) - .addImm(7)); + EmitInstruction( + Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EDI)); + EmitInstruction( + Out, + MCInstBuilder(X86::AND32ri).addReg(X86::ECX).addReg(X86::ECX).addImm(7)); switch (AccessSize) { case 1: @@ -669,19 +530,19 @@ void X86AddressSanitizer64::InstrumentMemOperandSmall( case 2: { MCInst Inst; Inst.setOpcode(X86::LEA32r); - Inst.addOperand(MCOperand::CreateReg(ScratchRegI32)); + Inst.addOperand(MCOperand::CreateReg(X86::ECX)); const MCExpr *Disp = MCConstantExpr::Create(1, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, ScratchRegI32, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc())); Op->addMemOperands(Inst, 5); EmitInstruction(Out, Inst); break; } case 4: EmitInstruction(Out, MCInstBuilder(X86::ADD32ri8) - .addReg(ScratchRegI32) - .addReg(ScratchRegI32) + .addReg(X86::ECX) + .addReg(X86::ECX) .addImm(3)); break; default: @@ -690,35 +551,40 @@ void X86AddressSanitizer64::InstrumentMemOperandSmall( } EmitInstruction( - Out, - MCInstBuilder(X86::MOVSX32rr8).addReg(ShadowRegI32).addReg(ShadowRegI8)); - EmitInstruction(Out, MCInstBuilder(X86::CMP32rr).addReg(ScratchRegI32).addReg( - ShadowRegI32)); + Out, MCInstBuilder(X86::MOVSX32rr8).addReg(X86::EAX).addReg(X86::AL)); + EmitInstruction( + Out, MCInstBuilder(X86::CMP32rr).addReg(X86::ECX).addReg(X86::EAX)); EmitInstruction(Out, MCInstBuilder(X86::JL_4).addExpr(DoneExpr)); - EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx); + EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite); EmitLabel(Out, DoneSym); + + EmitInstruction(Out, MCInstBuilder(X86::POPF64)); + EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RDI)); + EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RCX)); + EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RAX)); + EmitAdjustRSP(Ctx, Out, 128); } -void X86AddressSanitizer64::InstrumentMemOperandLarge( - X86Operand &Op, unsigned AccessSize, bool IsWrite, - const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) { - unsigned AddressRegI64 = RegCtx.addressReg(MVT::i64); - unsigned ShadowRegI64 = RegCtx.shadowReg(MVT::i64); +void X86AddressSanitizer64::InstrumentMemOperandLargeImpl(X86Operand &Op, + unsigned AccessSize, + bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) { + EmitAdjustRSP(Ctx, Out, -128); + EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RAX)); + EmitInstruction(Out, MCInstBuilder(X86::PUSHF64)); { MCInst Inst; Inst.setOpcode(X86::LEA64r); - Inst.addOperand(MCOperand::CreateReg(AddressRegI64)); + Inst.addOperand(MCOperand::CreateReg(X86::RAX)); Op.addMemOperands(Inst, 5); EmitInstruction(Out, Inst); } - EmitInstruction(Out, MCInstBuilder(X86::MOV64rr).addReg(ShadowRegI64).addReg( - AddressRegI64)); - EmitInstruction(Out, MCInstBuilder(X86::SHR64ri) - .addReg(ShadowRegI64) - .addReg(ShadowRegI64) - .addImm(3)); + EmitInstruction( + Out, + MCInstBuilder(X86::SHR64ri).addReg(X86::RAX).addReg(X86::RAX).addImm(3)); { MCInst Inst; switch (AccessSize) { @@ -734,7 +600,7 @@ void X86AddressSanitizer64::InstrumentMemOperandLarge( } const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, ShadowRegI64, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc())); Op->addMemOperands(Inst, 5); Inst.addOperand(MCOperand::CreateImm(0)); EmitInstruction(Out, Inst); @@ -744,14 +610,18 @@ void X86AddressSanitizer64::InstrumentMemOperandLarge( const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx); EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr)); - EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx); + EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite); EmitLabel(Out, DoneSym); + + EmitInstruction(Out, MCInstBuilder(X86::POPF64)); + EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RAX)); + EmitAdjustRSP(Ctx, Out, 128); } void X86AddressSanitizer64::InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx, MCStreamer &Out) { - StoreFlags(Out); + EmitInstruction(Out, MCInstBuilder(X86::PUSHF64)); // No need to test when RCX is equals to zero. MCSymbol *DoneSym = Ctx.CreateTempSymbol(); @@ -765,7 +635,7 @@ void X86AddressSanitizer64::InstrumentMOVSImpl(unsigned AccessSize, X86::RCX /* CntReg */, AccessSize, Ctx, Out); EmitLabel(Out, DoneSym); - RestoreFlags(Out); + EmitInstruction(Out, MCInstBuilder(X86::POPF64)); } } // End anonymous namespace diff --git a/lib/Target/X86/AsmParser/X86AsmInstrumentation.h b/lib/Target/X86/AsmParser/X86AsmInstrumentation.h index 4b23b4b2c98..82c4956ee1b 100644 --- a/lib/Target/X86/AsmParser/X86AsmInstrumentation.h +++ b/lib/Target/X86/AsmParser/X86AsmInstrumentation.h @@ -37,7 +37,7 @@ public: // Tries to instrument and emit instruction. virtual void InstrumentAndEmitInstruction( const MCInst &Inst, - SmallVectorImpl > &Operands, + SmallVectorImpl> &Operands, MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out); protected: diff --git a/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll b/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll index 7f5d3b0f142..ad5e02e0d06 100644 --- a/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll +++ b/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll @@ -6,8 +6,8 @@ target triple = "x86_64-unknown-linux-gnu" ; CHECK-LABEL: mov1b ; CHECK: leaq -128(%rsp), %rsp ; CHECK-NEXT: pushq %rax -; CHECK-NEXT: pushq %rdi ; CHECK-NEXT: pushq %rcx +; CHECK-NEXT: pushq %rdi ; CHECK-NEXT: pushfq ; CHECK-NEXT: leaq {{.*}}, %rdi ; CHECK-NEXT: movq %rdi, %rax @@ -26,8 +26,8 @@ target triple = "x86_64-unknown-linux-gnu" ; CHECK-NEXT: callq __asan_report_load1@PLT ; CHECK-NEXT: [[A]]: ; CHECK-NEXT: popfq -; CHECK-NEXT: popq %rcx ; CHECK-NEXT: popq %rdi +; CHECK-NEXT: popq %rcx ; CHECK-NEXT: popq %rax ; CHECK-NEXT: leaq 128(%rsp), %rsp @@ -81,10 +81,8 @@ entry: ; CHECK-LABEL: mov8b ; CHECK: leaq -128(%rsp), %rsp ; CHECK-NEXT: pushq %rax -; CHECK-NEXT: pushq %rdi ; CHECK-NEXT: pushfq -; CHECK-NEXT: leaq {{.*}}, %rdi -; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: leaq {{.*}}, %rax ; CHECK-NEXT: shrq $3, %rax ; CHECK-NEXT: cmpb $0, 2147450880(%rax) ; CHECK-NEXT: je [[A:.*]] @@ -94,16 +92,13 @@ entry: ; CHECK-NEXT: callq __asan_report_load8@PLT ; CHECK-NEXT: [[A]]: ; CHECK-NEXT: popfq -; CHECK-NEXT: popq %rdi ; CHECK-NEXT: popq %rax ; CHECK-NEXT: leaq 128(%rsp), %rsp ; CHECK: leaq -128(%rsp), %rsp ; CHECK-NEXT: pushq %rax -; CHECK-NEXT: pushq %rdi ; CHECK-NEXT: pushfq -; CHECK-NEXT: leaq {{.*}}, %rdi -; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: leaq {{.*}}, %rax ; CHECK-NEXT: shrq $3, %rax ; CHECK-NEXT: cmpb $0, 2147450880(%rax) ; CHECK-NEXT: je [[A:.*]] @@ -113,7 +108,6 @@ entry: ; CHECK-NEXT: callq __asan_report_store8@PLT ; CHECK-NEXT: [[A]]: ; CHECK-NEXT: popfq -; CHECK-NEXT: popq %rdi ; CHECK-NEXT: popq %rax ; CHECK-NEXT: leaq 128(%rsp), %rsp diff --git a/test/Instrumentation/AddressSanitizer/X86/asm_rep_movs.ll b/test/Instrumentation/AddressSanitizer/X86/asm_rep_movs.ll index c3c2435fc87..136cd87dfab 100644 --- a/test/Instrumentation/AddressSanitizer/X86/asm_rep_movs.ll +++ b/test/Instrumentation/AddressSanitizer/X86/asm_rep_movs.ll @@ -8,33 +8,17 @@ target triple = "x86_64-unknown-linux-gnu" ; CHECK-NEXT: testq %rcx, %rcx ; CHECK-NEXT: je [[B:.*]] -; CHECK: leaq -128(%rsp), %rsp -; CHECK-NEXT: pushq %rax -; CHECK-NEXT: pushq %rdx -; CHECK-NEXT: pushq %rbx -; CHECK-NEXT: pushfq - -; CHECK: leaq (%rsi), %rdx -; CHECK: movq %rdx, %rdi -; CHECK-NEXT: callq __asan_report_load1@PLT - -; CHECK: leaq -1(%rsi,%rcx), %rdx -; CHECK: movq %rdx, %rdi -; CHECK-NEXT: callq __asan_report_load1@PLT - -; CHECK: leaq (%rdi), %rdx -; CHECK: movq %rdx, %rdi -; CHECK-NEXT: callq __asan_report_store1@PLT - -; CHECK: leaq -1(%rdi,%rcx), %rdx -; CHECK: movq %rdx, %rdi -; CHECK-NEXT: callq __asan_report_store1@PLT - -; CHECK: popfq -; CHECK-NEXT: popq %rbx -; CHECK-NEXT: popq %rdx -; CHECK-NEXT: popq %rax -; CHECK-NEXT: leaq 128(%rsp), %rsp +; CHECK: leaq (%rsi), {{.*}} +; CHECK: callq __asan_report_load1@PLT + +; CHECK: leaq -1(%rsi,%rcx), {{.*}} +; CHECK: callq __asan_report_load1@PLT + +; CHECK: leaq (%rdi), {{.*}} +; CHECK: callq __asan_report_store1@PLT + +; CHECK: leaq -1(%rdi,%rcx), {{.*}} +; CHECK: callq __asan_report_store1@PLT ; CHECK: [[B]]: ; CHECK-NEXT: popfq @@ -54,21 +38,17 @@ entry: ; CHECK-NEXT: testq %rcx, %rcx ; CHECK-NEXT: je [[Q:.*]] -; CHECK: leaq (%rsi), %rdx -; CHECK: movq %rdx, %rdi -; CHECK-NEXT: callq __asan_report_load8@PLT +; CHECK: leaq (%rsi), {{.*}} +; CHECK: callq __asan_report_load8@PLT -; CHECK: leaq -1(%rsi,%rcx,8), %rdx -; CHECK: movq %rdx, %rdi -; CHECK-NEXT: callq __asan_report_load8@PLT +; CHECK: leaq -1(%rsi,%rcx,8), {{.*}} +; CHECK: callq __asan_report_load8@PLT -; CHECK: leaq (%rdi), %rdx -; CHECK: movq %rdx, %rdi -; CHECK-NEXT: callq __asan_report_store8@PLT +; CHECK: leaq (%rdi), {{.*}} +; CHECK: callq __asan_report_store8@PLT -; CHECK: leaq -1(%rdi,%rcx,8), %rdx -; CHECK: movq %rdx, %rdi -; CHECK-NEXT: callq __asan_report_store8@PLT +; CHECK: leaq -1(%rdi,%rcx,8), {{.*}} +; CHECK: callq __asan_report_store8@PLT ; CHECK: [[Q]]: ; CHECK-NEXT: popfq