summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-05-08 09:55:24 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-05-08 09:55:24 +0000
commit9661ec0ec398a3526ce95e94b98e2adb49e68f8b (patch)
tree871ac3cea7db70afb4bd863eeb76b75ba4e64957 /llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
parentac030ffb69e21869a4e42639a955b01364b9975b (diff)
downloadbcm5719-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.cpp40
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
OpenPOWER on IntegriCloud