diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-05-08 09:55:24 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-05-08 09:55:24 +0000 |
commit | 9661ec0ec398a3526ce95e94b98e2adb49e68f8b (patch) | |
tree | 871ac3cea7db70afb4bd863eeb76b75ba4e64957 /llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp | |
parent | ac030ffb69e21869a4e42639a955b01364b9975b (diff) | |
download | bcm5719-llvm-9661ec0ec398a3526ce95e94b98e2adb49e68f8b.tar.gz bcm5719-llvm-9661ec0ec398a3526ce95e94b98e2adb49e68f8b.zip |
[asan] Preserve flags in asm instrumentation.
Patch by Yuri Gorshenin.
llvm-svn: 208296
Diffstat (limited to 'llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp')
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp index 95e4ccccb9d..303bbf249b5 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp @@ -177,13 +177,26 @@ public: MCStreamer &Out) override; }; -void X86AddressSanitizer64::InstrumentMemOperandImpl( - X86Operand *Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx, - MCStreamer &Out) { +void X86AddressSanitizer64::InstrumentMemOperandImpl(X86Operand *Op, + unsigned AccessSize, + bool IsWrite, + MCContext &Ctx, + MCStreamer &Out) { // FIXME: emit .cfi directives for correct stack unwinding. - // Set %rsp below current red zone (128 bytes wide) - EmitInstruction(Out, MCInstBuilder(X86::SUB64ri32).addReg(X86::RSP) - .addReg(X86::RSP).addImm(128)); + + // Set %rsp below current red zone (128 bytes wide) using LEA instruction to + // preserve flags. + { + MCInst Inst; + Inst.setOpcode(X86::LEA64r); + Inst.addOperand(MCOperand::CreateReg(X86::RSP)); + + const MCExpr *Disp = MCConstantExpr::Create(-128, Ctx); + X86Operand *Op = + X86Operand::CreateMem(0, Disp, X86::RSP, 0, 1, SMLoc(), SMLoc()); + Op->addMemOperands(Inst, 5); + EmitInstruction(Out, Inst); + } EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RDI)); { MCInst Inst; @@ -200,8 +213,19 @@ void X86AddressSanitizer64::InstrumentMemOperandImpl( EmitInstruction(Out, MCInstBuilder(X86::CALL64pcrel32).addExpr(FuncExpr)); } EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RDI)); - EmitInstruction(Out, MCInstBuilder(X86::ADD64ri32).addReg(X86::RSP) - .addReg(X86::RSP).addImm(128)); + + // Restore old %rsp value. + { + MCInst Inst; + Inst.setOpcode(X86::LEA64r); + Inst.addOperand(MCOperand::CreateReg(X86::RSP)); + + const MCExpr *Disp = MCConstantExpr::Create(128, Ctx); + X86Operand *Op = + X86Operand::CreateMem(0, Disp, X86::RSP, 0, 1, SMLoc(), SMLoc()); + Op->addMemOperands(Inst, 5); + EmitInstruction(Out, Inst); + } } } // End anonymous namespace |