#include "X86AsmInstrumentation.h"
#include "X86Operand.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/IR/Function.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
+#include "llvm/MC/MCInstrInfo.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/MC/MCTargetOptions.h"
namespace llvm {
namespace {
-static cl::opt<bool> ClAsanInstrumentInlineAssembly(
- "asan-instrument-inline-assembly", cl::desc("instrument inline assembly"),
- cl::Hidden, cl::init(false));
-
bool IsStackReg(unsigned Reg) {
return Reg == X86::RSP || Reg == X86::ESP || Reg == X86::SP;
}
class X86AddressSanitizer : public X86AsmInstrumentation {
public:
- X86AddressSanitizer(MCSubtargetInfo &sti) : STI(sti) {}
+ X86AddressSanitizer(const MCSubtargetInfo &STI) : STI(STI) {}
virtual ~X86AddressSanitizer() {}
// X86AsmInstrumentation implementation:
virtual void InstrumentInstruction(
const MCInst &Inst, SmallVectorImpl<MCParsedAsmOperand *> &Operands,
- MCContext &Ctx, MCStreamer &Out) override {
- InstrumentMOV(Inst, Operands, Ctx, Out);
+ MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out) override {
+ InstrumentMOV(Inst, Operands, Ctx, MII, Out);
}
// Should be implemented differently in x86_32 and x86_64 subclasses.
bool IsWrite, MCContext &Ctx, MCStreamer &Out);
void InstrumentMOV(const MCInst &Inst,
SmallVectorImpl<MCParsedAsmOperand *> &Operands,
- MCContext &Ctx, MCStreamer &Out);
+ MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
void EmitInstruction(MCStreamer &Out, const MCInst &Inst) {
Out.EmitInstruction(Inst, STI);
}
protected:
- MCSubtargetInfo &STI;
+ const MCSubtargetInfo &STI;
};
void X86AddressSanitizer::InstrumentMemOperand(
void X86AddressSanitizer::InstrumentMOV(
const MCInst &Inst, SmallVectorImpl<MCParsedAsmOperand *> &Operands,
- MCContext &Ctx, MCStreamer &Out) {
+ MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out) {
// Access size in bytes.
unsigned AccessSize = 0;
- unsigned long OpIx = Operands.size();
+
switch (Inst.getOpcode()) {
case X86::MOV8mi:
case X86::MOV8mr:
- AccessSize = 1;
- OpIx = 2;
- break;
case X86::MOV8rm:
AccessSize = 1;
- OpIx = 1;
break;
case X86::MOV16mi:
case X86::MOV16mr:
- AccessSize = 2;
- OpIx = 2;
- break;
case X86::MOV16rm:
AccessSize = 2;
- OpIx = 1;
break;
case X86::MOV32mi:
case X86::MOV32mr:
- AccessSize = 4;
- OpIx = 2;
- break;
case X86::MOV32rm:
AccessSize = 4;
- OpIx = 1;
break;
case X86::MOV64mi32:
case X86::MOV64mr:
- AccessSize = 8;
- OpIx = 2;
- break;
case X86::MOV64rm:
AccessSize = 8;
- OpIx = 1;
break;
case X86::MOVAPDmr:
case X86::MOVAPSmr:
- AccessSize = 16;
- OpIx = 2;
- break;
case X86::MOVAPDrm:
case X86::MOVAPSrm:
AccessSize = 16;
- OpIx = 1;
break;
- }
- if (OpIx >= Operands.size())
+ default:
return;
+ }
- const bool IsWrite = (OpIx != 1);
- InstrumentMemOperand(Operands[OpIx], AccessSize, IsWrite, Ctx, Out);
+ const bool IsWrite = MII.get(Inst.getOpcode()).mayStore();
+ for (unsigned Ix = 0; Ix < Operands.size(); ++Ix) {
+ MCParsedAsmOperand *Op = Operands[Ix];
+ if (Op && Op->isMem())
+ InstrumentMemOperand(Op, AccessSize, IsWrite, Ctx, Out);
+ }
}
class X86AddressSanitizer32 : public X86AddressSanitizer {
public:
- X86AddressSanitizer32(MCSubtargetInfo &sti) : X86AddressSanitizer(sti) {}
+ X86AddressSanitizer32(const MCSubtargetInfo &STI)
+ : X86AddressSanitizer(STI) {}
virtual ~X86AddressSanitizer32() {}
virtual void InstrumentMemOperandImpl(X86Operand *Op, unsigned AccessSize,
class X86AddressSanitizer64 : public X86AddressSanitizer {
public:
- X86AddressSanitizer64(MCSubtargetInfo &sti) : X86AddressSanitizer(sti) {}
+ X86AddressSanitizer64(const MCSubtargetInfo &STI)
+ : X86AddressSanitizer(STI) {}
virtual ~X86AddressSanitizer64() {}
virtual void InstrumentMemOperandImpl(X86Operand *Op, unsigned AccessSize,
void X86AsmInstrumentation::InstrumentInstruction(
const MCInst &Inst, SmallVectorImpl<MCParsedAsmOperand *> &Operands,
- MCContext &Ctx, MCStreamer &Out) {}
+ MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out) {}
-X86AsmInstrumentation *CreateX86AsmInstrumentation(MCSubtargetInfo &STI) {
- if (ClAsanInstrumentInlineAssembly) {
+X86AsmInstrumentation *
+CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions, const MCContext &Ctx,
+ const MCSubtargetInfo &STI) {
+ if (MCOptions.SanitizeAddress) {
if ((STI.getFeatureBits() & X86::Mode32Bit) != 0)
return new X86AddressSanitizer32(STI);
if ((STI.getFeatureBits() & X86::Mode64Bit) != 0)