Index: include/llvm/MC/MCTargetAsmParser.h =================================================================== --- include/llvm/MC/MCTargetAsmParser.h +++ include/llvm/MC/MCTargetAsmParser.h @@ -123,6 +123,8 @@ virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0; + virtual void SetFrameRegister(unsigned RegNo) {} + /// ParseInstruction - Parse one assembly instruction. /// /// The parser is positioned following the instruction name. The target Index: lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -33,6 +33,7 @@ #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; @@ -146,6 +147,10 @@ " we don't have an asm parser for this target\n"); Parser->setAssemblerDialect(Dialect); Parser->setTargetParser(*TAP.get()); + if (MF) { + const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); + TAP->SetFrameRegister(TRI->getFrameRegister(*MF)); + } // Don't implicitly switch to the text section before the asm. int Res = Parser->Run(/*NoInitialTextSection*/ true, Index: lib/Target/X86/AsmParser/X86AsmInstrumentation.h =================================================================== --- lib/Target/X86/AsmParser/X86AsmInstrumentation.h +++ lib/Target/X86/AsmParser/X86AsmInstrumentation.h @@ -34,6 +34,10 @@ public: virtual ~X86AsmInstrumentation(); + void SetFrameRegister(unsigned RegNo) { + FrameReg = RegNo; + } + // Tries to instrument and emit instruction. virtual void InstrumentAndEmitInstruction( const MCInst &Inst, @@ -50,6 +54,8 @@ void EmitInstruction(MCStreamer &Out, const MCInst &Inst); const MCSubtargetInfo &STI; + + unsigned FrameReg; }; } // End llvm namespace Index: lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp +++ lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp @@ -25,6 +25,7 @@ #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/TargetRegistry.h" namespace llvm { namespace { @@ -293,7 +294,9 @@ static const long kShadowOffset = 0x20000000; X86AddressSanitizer32(const MCSubtargetInfo &STI) - : X86AddressSanitizer(STI) {} + : X86AddressSanitizer(STI), + RegisterInfo(TheX86_32Target.createMCRegInfo(STI.getTargetTriple())) {} + virtual ~X86AddressSanitizer32() {} virtual void StoreFlags(MCStreamer &Out) override { @@ -307,6 +310,21 @@ virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) override { + if (FrameReg != X86::NoRegister) { + EmitInstruction( + Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EBP)); + if (FrameReg == X86::ESP) { + Out.EmitCFIAdjustCfaOffset(4 /* byte size of the FrameReg */); + Out.EmitCFIRelOffset( + RegisterInfo->getDwarfRegNum(X86::EBP, true /* IsEH */), 0); + } + EmitInstruction( + Out, MCInstBuilder(X86::MOV32rr).addReg(X86::EBP).addReg(FrameReg)); + Out.EmitCFIRememberState(); + Out.EmitCFIDefCfaRegister( + RegisterInfo->getDwarfRegNum(X86::EBP, true /* IsEH */)); + } + EmitInstruction( Out, MCInstBuilder(X86::PUSH32r).addReg(RegCtx.addressReg(MVT::i32))); EmitInstruction( @@ -330,6 +348,14 @@ Out, MCInstBuilder(X86::POP32r).addReg(RegCtx.shadowReg(MVT::i32))); EmitInstruction( Out, MCInstBuilder(X86::POP32r).addReg(RegCtx.addressReg(MVT::i32))); + + if (FrameReg != X86::NoRegister) { + EmitInstruction( + Out, MCInstBuilder(X86::POP32r).addReg(X86::EBP)); + Out.EmitCFIRestoreState(); + if (FrameReg == X86::ESP) + Out.EmitCFIAdjustCfaOffset(-4 /* byte size of the FrameReg */); + } } virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize, @@ -364,6 +390,8 @@ MCSymbolRefExpr::Create(FnSym, MCSymbolRefExpr::VK_PLT, Ctx); EmitInstruction(Out, MCInstBuilder(X86::CALLpcrel32).addExpr(FnExpr)); } + + std::unique_ptr RegisterInfo; }; void X86AddressSanitizer32::InstrumentMemOperandSmall( @@ -525,7 +553,8 @@ static const long kShadowOffset = 0x7fff8000; X86AddressSanitizer64(const MCSubtargetInfo &STI) - : X86AddressSanitizer(STI) {} + : X86AddressSanitizer(STI), + RegisterInfo(TheX86_64Target.createMCRegInfo(STI.getTargetTriple())) {} virtual ~X86AddressSanitizer64() {} virtual void StoreFlags(MCStreamer &Out) override { @@ -539,6 +568,21 @@ virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) override { + if (FrameReg != X86::NoRegister) { + EmitInstruction( + Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RBP)); + if (FrameReg == X86::RSP) { + Out.EmitCFIAdjustCfaOffset(8 /* byte size of the FrameReg */); + Out.EmitCFIRelOffset( + RegisterInfo->getDwarfRegNum(X86::RBP, true /* IsEH */), 0); + } + EmitInstruction( + Out, MCInstBuilder(X86::MOV64rr).addReg(X86::RBP).addReg(FrameReg)); + Out.EmitCFIRememberState(); + Out.EmitCFIDefCfaRegister( + RegisterInfo->getDwarfRegNum(X86::RBP, true /* IsEH */)); + } + EmitAdjustRSP(Ctx, Out, -128); EmitInstruction( Out, MCInstBuilder(X86::PUSH64r).addReg(RegCtx.shadowReg(MVT::i64))); @@ -564,6 +608,14 @@ EmitInstruction( Out, MCInstBuilder(X86::POP64r).addReg(RegCtx.shadowReg(MVT::i64))); EmitAdjustRSP(Ctx, Out, 128); + + if (FrameReg != X86::NoRegister) { + EmitInstruction( + Out, MCInstBuilder(X86::POP64r).addReg(X86::RBP)); + Out.EmitCFIRestoreState(); + if (FrameReg == X86::RSP) + Out.EmitCFIAdjustCfaOffset(-8 /* byte size of the FrameReg */); + } } virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize, @@ -612,6 +664,8 @@ MCSymbolRefExpr::Create(FnSym, MCSymbolRefExpr::VK_PLT, Ctx); EmitInstruction(Out, MCInstBuilder(X86::CALL64pcrel32).addExpr(FnExpr)); } + + std::unique_ptr RegisterInfo; }; void X86AddressSanitizer64::InstrumentMemOperandSmall( @@ -771,7 +825,7 @@ } // End anonymous namespace X86AsmInstrumentation::X86AsmInstrumentation(const MCSubtargetInfo &STI) - : STI(STI) {} + : STI(STI), FrameReg(X86::NoRegister) {} X86AsmInstrumentation::~X86AsmInstrumentation() {} Index: lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmParser.cpp +++ lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -788,6 +788,8 @@ bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; + void SetFrameRegister(unsigned RegNo) override; + bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) override; @@ -970,6 +972,10 @@ return false; } +void X86AsmParser::SetFrameRegister(unsigned RegNo) { + Instrumentation->SetFrameRegister(RegNo); +} + std::unique_ptr X86AsmParser::DefaultMemSIOperand(SMLoc Loc) { unsigned basereg = is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);