Home | History | Annotate | Download | only in AsmParser
      1 //===-- X86AsmInstrumentation.cpp - Instrument X86 inline assembly C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "MCTargetDesc/X86BaseInfo.h"
     11 #include "X86AsmInstrumentation.h"
     12 #include "X86Operand.h"
     13 #include "llvm/ADT/StringExtras.h"
     14 #include "llvm/ADT/Triple.h"
     15 #include "llvm/IR/Function.h"
     16 #include "llvm/MC/MCContext.h"
     17 #include "llvm/MC/MCInst.h"
     18 #include "llvm/MC/MCInstBuilder.h"
     19 #include "llvm/MC/MCInstrInfo.h"
     20 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
     21 #include "llvm/MC/MCStreamer.h"
     22 #include "llvm/MC/MCSubtargetInfo.h"
     23 #include "llvm/MC/MCTargetAsmParser.h"
     24 #include "llvm/MC/MCTargetOptions.h"
     25 #include "llvm/Support/CommandLine.h"
     26 
     27 namespace llvm {
     28 namespace {
     29 
     30 static cl::opt<bool> ClAsanInstrumentAssembly(
     31     "asan-instrument-assembly",
     32     cl::desc("instrument assembly with AddressSanitizer checks"), cl::Hidden,
     33     cl::init(false));
     34 
     35 bool IsStackReg(unsigned Reg) {
     36   return Reg == X86::RSP || Reg == X86::ESP || Reg == X86::SP;
     37 }
     38 
     39 std::string FuncName(unsigned AccessSize, bool IsWrite) {
     40   return std::string("__asan_report_") + (IsWrite ? "store" : "load") +
     41          utostr(AccessSize);
     42 }
     43 
     44 class X86AddressSanitizer : public X86AsmInstrumentation {
     45 public:
     46   X86AddressSanitizer(const MCSubtargetInfo &STI) : STI(STI) {}
     47   virtual ~X86AddressSanitizer() {}
     48 
     49   // X86AsmInstrumentation implementation:
     50   virtual void InstrumentInstruction(
     51       const MCInst &Inst, OperandVector &Operands, MCContext &Ctx,
     52       const MCInstrInfo &MII, MCStreamer &Out) override {
     53     InstrumentMOV(Inst, Operands, Ctx, MII, Out);
     54   }
     55 
     56   // Should be implemented differently in x86_32 and x86_64 subclasses.
     57   virtual void InstrumentMemOperandSmallImpl(
     58       X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
     59       MCStreamer &Out) = 0;
     60   virtual void InstrumentMemOperandLargeImpl(
     61       X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
     62       MCStreamer &Out) = 0;
     63 
     64   void InstrumentMemOperand(MCParsedAsmOperand &Op, unsigned AccessSize,
     65                             bool IsWrite, MCContext &Ctx, MCStreamer &Out);
     66   void InstrumentMOV(const MCInst &Inst, OperandVector &Operands,
     67                      MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
     68   void EmitInstruction(MCStreamer &Out, const MCInst &Inst) {
     69     Out.EmitInstruction(Inst, STI);
     70   }
     71 
     72   void EmitLabel(MCStreamer &Out, MCSymbol *Label) { Out.EmitLabel(Label); }
     73 
     74 protected:
     75   const MCSubtargetInfo &STI;
     76 };
     77 
     78 void X86AddressSanitizer::InstrumentMemOperand(
     79     MCParsedAsmOperand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
     80     MCStreamer &Out) {
     81   assert(Op.isMem() && "Op should be a memory operand.");
     82   assert((AccessSize & (AccessSize - 1)) == 0 && AccessSize <= 16 &&
     83          "AccessSize should be a power of two, less or equal than 16.");
     84 
     85   X86Operand &MemOp = static_cast<X86Operand &>(Op);
     86   // FIXME: get rid of this limitation.
     87   if (IsStackReg(MemOp.getMemBaseReg()) || IsStackReg(MemOp.getMemIndexReg()))
     88     return;
     89 
     90   // FIXME: take into account load/store alignment.
     91   if (AccessSize < 8)
     92     InstrumentMemOperandSmallImpl(MemOp, AccessSize, IsWrite, Ctx, Out);
     93   else
     94     InstrumentMemOperandLargeImpl(MemOp, AccessSize, IsWrite, Ctx, Out);
     95 }
     96 
     97 void X86AddressSanitizer::InstrumentMOV(
     98     const MCInst &Inst, OperandVector &Operands, MCContext &Ctx,
     99     const MCInstrInfo &MII, MCStreamer &Out) {
    100   // Access size in bytes.
    101   unsigned AccessSize = 0;
    102 
    103   switch (Inst.getOpcode()) {
    104   case X86::MOV8mi:
    105   case X86::MOV8mr:
    106   case X86::MOV8rm:
    107     AccessSize = 1;
    108     break;
    109   case X86::MOV16mi:
    110   case X86::MOV16mr:
    111   case X86::MOV16rm:
    112     AccessSize = 2;
    113     break;
    114   case X86::MOV32mi:
    115   case X86::MOV32mr:
    116   case X86::MOV32rm:
    117     AccessSize = 4;
    118     break;
    119   case X86::MOV64mi32:
    120   case X86::MOV64mr:
    121   case X86::MOV64rm:
    122     AccessSize = 8;
    123     break;
    124   case X86::MOVAPDmr:
    125   case X86::MOVAPSmr:
    126   case X86::MOVAPDrm:
    127   case X86::MOVAPSrm:
    128     AccessSize = 16;
    129     break;
    130   default:
    131     return;
    132   }
    133 
    134   const bool IsWrite = MII.get(Inst.getOpcode()).mayStore();
    135   for (unsigned Ix = 0; Ix < Operands.size(); ++Ix) {
    136     assert(Operands[Ix]);
    137     MCParsedAsmOperand &Op = *Operands[Ix];
    138     if (Op.isMem())
    139       InstrumentMemOperand(Op, AccessSize, IsWrite, Ctx, Out);
    140   }
    141 }
    142 
    143 class X86AddressSanitizer32 : public X86AddressSanitizer {
    144 public:
    145   static const long kShadowOffset = 0x20000000;
    146 
    147   X86AddressSanitizer32(const MCSubtargetInfo &STI)
    148       : X86AddressSanitizer(STI) {}
    149   virtual ~X86AddressSanitizer32() {}
    150 
    151   virtual void InstrumentMemOperandSmallImpl(
    152       X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
    153       MCStreamer &Out) override;
    154   virtual void InstrumentMemOperandLargeImpl(
    155       X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
    156       MCStreamer &Out) override;
    157 
    158  private:
    159   void EmitCallAsanReport(MCContext &Ctx, MCStreamer &Out, unsigned AccessSize,
    160                           bool IsWrite, unsigned AddressReg) {
    161     EmitInstruction(Out, MCInstBuilder(X86::CLD));
    162     EmitInstruction(Out, MCInstBuilder(X86::MMX_EMMS));
    163 
    164     EmitInstruction(Out, MCInstBuilder(X86::AND64ri8).addReg(X86::ESP)
    165                              .addReg(X86::ESP).addImm(-16));
    166     EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(AddressReg));
    167 
    168 
    169     const std::string& Fn = FuncName(AccessSize, IsWrite);
    170     MCSymbol *FnSym = Ctx.GetOrCreateSymbol(StringRef(Fn));
    171     const MCSymbolRefExpr *FnExpr =
    172         MCSymbolRefExpr::Create(FnSym, MCSymbolRefExpr::VK_PLT, Ctx);
    173     EmitInstruction(Out, MCInstBuilder(X86::CALLpcrel32).addExpr(FnExpr));
    174   }
    175 };
    176 
    177 void X86AddressSanitizer32::InstrumentMemOperandSmallImpl(
    178     X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
    179     MCStreamer &Out) {
    180   EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX));
    181   EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::ECX));
    182   EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EDX));
    183   EmitInstruction(Out, MCInstBuilder(X86::PUSHF32));
    184 
    185   {
    186     MCInst Inst;
    187     Inst.setOpcode(X86::LEA32r);
    188     Inst.addOperand(MCOperand::CreateReg(X86::EAX));
    189     Op.addMemOperands(Inst, 5);
    190     EmitInstruction(Out, Inst);
    191   }
    192 
    193   EmitInstruction(
    194       Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EAX));
    195   EmitInstruction(Out, MCInstBuilder(X86::SHR32ri).addReg(X86::ECX)
    196                            .addReg(X86::ECX).addImm(3));
    197 
    198   {
    199     MCInst Inst;
    200     Inst.setOpcode(X86::MOV8rm);
    201     Inst.addOperand(MCOperand::CreateReg(X86::CL));
    202     const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
    203     std::unique_ptr<X86Operand> Op(
    204         X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc()));
    205     Op->addMemOperands(Inst, 5);
    206     EmitInstruction(Out, Inst);
    207   }
    208 
    209   EmitInstruction(Out,
    210                   MCInstBuilder(X86::TEST8rr).addReg(X86::CL).addReg(X86::CL));
    211   MCSymbol *DoneSym = Ctx.CreateTempSymbol();
    212   const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
    213   EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
    214 
    215   EmitInstruction(
    216       Out, MCInstBuilder(X86::MOV32rr).addReg(X86::EDX).addReg(X86::EAX));
    217   EmitInstruction(Out, MCInstBuilder(X86::AND32ri).addReg(X86::EDX)
    218                            .addReg(X86::EDX).addImm(7));
    219 
    220   switch (AccessSize) {
    221   case 1:
    222     break;
    223   case 2: {
    224     MCInst Inst;
    225     Inst.setOpcode(X86::LEA32r);
    226     Inst.addOperand(MCOperand::CreateReg(X86::EDX));
    227 
    228     const MCExpr *Disp = MCConstantExpr::Create(1, Ctx);
    229     std::unique_ptr<X86Operand> Op(
    230         X86Operand::CreateMem(0, Disp, X86::EDX, 0, 1, SMLoc(), SMLoc()));
    231     Op->addMemOperands(Inst, 5);
    232     EmitInstruction(Out, Inst);
    233     break;
    234   }
    235   case 4:
    236     EmitInstruction(Out, MCInstBuilder(X86::ADD32ri8).addReg(X86::EDX)
    237                              .addReg(X86::EDX).addImm(3));
    238     break;
    239   default:
    240     assert(false && "Incorrect access size");
    241     break;
    242   }
    243 
    244   EmitInstruction(
    245       Out, MCInstBuilder(X86::MOVSX32rr8).addReg(X86::ECX).addReg(X86::CL));
    246   EmitInstruction(
    247       Out, MCInstBuilder(X86::CMP32rr).addReg(X86::EDX).addReg(X86::ECX));
    248   EmitInstruction(Out, MCInstBuilder(X86::JL_4).addExpr(DoneExpr));
    249 
    250   EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite, X86::EAX);
    251   EmitLabel(Out, DoneSym);
    252 
    253   EmitInstruction(Out, MCInstBuilder(X86::POPF32));
    254   EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EDX));
    255   EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::ECX));
    256   EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EAX));
    257 }
    258 
    259 void X86AddressSanitizer32::InstrumentMemOperandLargeImpl(
    260     X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
    261     MCStreamer &Out) {
    262   EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX));
    263   EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::ECX));
    264   EmitInstruction(Out, MCInstBuilder(X86::PUSHF32));
    265 
    266   {
    267     MCInst Inst;
    268     Inst.setOpcode(X86::LEA32r);
    269     Inst.addOperand(MCOperand::CreateReg(X86::EAX));
    270     Op.addMemOperands(Inst, 5);
    271     EmitInstruction(Out, Inst);
    272   }
    273   EmitInstruction(
    274       Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EAX));
    275   EmitInstruction(Out, MCInstBuilder(X86::SHR32ri).addReg(X86::ECX)
    276                            .addReg(X86::ECX).addImm(3));
    277   {
    278     MCInst Inst;
    279     switch (AccessSize) {
    280       case 8:
    281         Inst.setOpcode(X86::CMP8mi);
    282         break;
    283       case 16:
    284         Inst.setOpcode(X86::CMP16mi);
    285         break;
    286       default:
    287         assert(false && "Incorrect access size");
    288         break;
    289     }
    290     const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
    291     std::unique_ptr<X86Operand> Op(
    292         X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc()));
    293     Op->addMemOperands(Inst, 5);
    294     Inst.addOperand(MCOperand::CreateImm(0));
    295     EmitInstruction(Out, Inst);
    296   }
    297   MCSymbol *DoneSym = Ctx.CreateTempSymbol();
    298   const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
    299   EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
    300 
    301   EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite, X86::EAX);
    302   EmitLabel(Out, DoneSym);
    303 
    304   EmitInstruction(Out, MCInstBuilder(X86::POPF32));
    305   EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::ECX));
    306   EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EAX));
    307 }
    308 
    309 class X86AddressSanitizer64 : public X86AddressSanitizer {
    310 public:
    311   static const long kShadowOffset = 0x7fff8000;
    312 
    313   X86AddressSanitizer64(const MCSubtargetInfo &STI)
    314       : X86AddressSanitizer(STI) {}
    315   virtual ~X86AddressSanitizer64() {}
    316 
    317   virtual void InstrumentMemOperandSmallImpl(
    318       X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
    319       MCStreamer &Out) override;
    320   virtual void InstrumentMemOperandLargeImpl(
    321       X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
    322       MCStreamer &Out) override;
    323 
    324 private:
    325   void EmitAdjustRSP(MCContext &Ctx, MCStreamer &Out, long Offset) {
    326     MCInst Inst;
    327     Inst.setOpcode(X86::LEA64r);
    328     Inst.addOperand(MCOperand::CreateReg(X86::RSP));
    329 
    330     const MCExpr *Disp = MCConstantExpr::Create(Offset, Ctx);
    331     std::unique_ptr<X86Operand> Op(
    332         X86Operand::CreateMem(0, Disp, X86::RSP, 0, 1, SMLoc(), SMLoc()));
    333     Op->addMemOperands(Inst, 5);
    334     EmitInstruction(Out, Inst);
    335   }
    336 
    337   void EmitCallAsanReport(MCContext &Ctx, MCStreamer &Out, unsigned AccessSize,
    338                           bool IsWrite) {
    339     EmitInstruction(Out, MCInstBuilder(X86::CLD));
    340     EmitInstruction(Out, MCInstBuilder(X86::MMX_EMMS));
    341 
    342     EmitInstruction(Out, MCInstBuilder(X86::AND64ri8).addReg(X86::RSP)
    343                              .addReg(X86::RSP).addImm(-16));
    344 
    345     const std::string& Fn = FuncName(AccessSize, IsWrite);
    346     MCSymbol *FnSym = Ctx.GetOrCreateSymbol(StringRef(Fn));
    347     const MCSymbolRefExpr *FnExpr =
    348         MCSymbolRefExpr::Create(FnSym, MCSymbolRefExpr::VK_PLT, Ctx);
    349     EmitInstruction(Out, MCInstBuilder(X86::CALL64pcrel32).addExpr(FnExpr));
    350   }
    351 };
    352 
    353 void X86AddressSanitizer64::InstrumentMemOperandSmallImpl(
    354     X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
    355     MCStreamer &Out) {
    356   EmitAdjustRSP(Ctx, Out, -128);
    357   EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RAX));
    358   EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RCX));
    359   EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RDI));
    360   EmitInstruction(Out, MCInstBuilder(X86::PUSHF64));
    361   {
    362     MCInst Inst;
    363     Inst.setOpcode(X86::LEA64r);
    364     Inst.addOperand(MCOperand::CreateReg(X86::RDI));
    365     Op.addMemOperands(Inst, 5);
    366     EmitInstruction(Out, Inst);
    367   }
    368   EmitInstruction(
    369       Out, MCInstBuilder(X86::MOV64rr).addReg(X86::RAX).addReg(X86::RDI));
    370   EmitInstruction(Out, MCInstBuilder(X86::SHR64ri).addReg(X86::RAX)
    371                            .addReg(X86::RAX).addImm(3));
    372   {
    373     MCInst Inst;
    374     Inst.setOpcode(X86::MOV8rm);
    375     Inst.addOperand(MCOperand::CreateReg(X86::AL));
    376     const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
    377     std::unique_ptr<X86Operand> Op(
    378         X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc()));
    379     Op->addMemOperands(Inst, 5);
    380     EmitInstruction(Out, Inst);
    381   }
    382 
    383   EmitInstruction(Out,
    384                   MCInstBuilder(X86::TEST8rr).addReg(X86::AL).addReg(X86::AL));
    385   MCSymbol *DoneSym = Ctx.CreateTempSymbol();
    386   const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
    387   EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
    388 
    389   EmitInstruction(
    390       Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EDI));
    391   EmitInstruction(Out, MCInstBuilder(X86::AND32ri).addReg(X86::ECX)
    392                            .addReg(X86::ECX).addImm(7));
    393 
    394   switch (AccessSize) {
    395   case 1:
    396     break;
    397   case 2: {
    398     MCInst Inst;
    399     Inst.setOpcode(X86::LEA32r);
    400     Inst.addOperand(MCOperand::CreateReg(X86::ECX));
    401 
    402     const MCExpr *Disp = MCConstantExpr::Create(1, Ctx);
    403     std::unique_ptr<X86Operand> Op(
    404         X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc()));
    405     Op->addMemOperands(Inst, 5);
    406     EmitInstruction(Out, Inst);
    407     break;
    408   }
    409   case 4:
    410     EmitInstruction(Out, MCInstBuilder(X86::ADD32ri8).addReg(X86::ECX)
    411                              .addReg(X86::ECX).addImm(3));
    412     break;
    413   default:
    414     assert(false && "Incorrect access size");
    415     break;
    416   }
    417 
    418   EmitInstruction(
    419       Out, MCInstBuilder(X86::MOVSX32rr8).addReg(X86::EAX).addReg(X86::AL));
    420   EmitInstruction(
    421       Out, MCInstBuilder(X86::CMP32rr).addReg(X86::ECX).addReg(X86::EAX));
    422   EmitInstruction(Out, MCInstBuilder(X86::JL_4).addExpr(DoneExpr));
    423 
    424   EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite);
    425   EmitLabel(Out, DoneSym);
    426 
    427   EmitInstruction(Out, MCInstBuilder(X86::POPF64));
    428   EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RDI));
    429   EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RCX));
    430   EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RAX));
    431   EmitAdjustRSP(Ctx, Out, 128);
    432 }
    433 
    434 void X86AddressSanitizer64::InstrumentMemOperandLargeImpl(
    435     X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
    436     MCStreamer &Out) {
    437   EmitAdjustRSP(Ctx, Out, -128);
    438   EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RAX));
    439   EmitInstruction(Out, MCInstBuilder(X86::PUSHF64));
    440 
    441   {
    442     MCInst Inst;
    443     Inst.setOpcode(X86::LEA64r);
    444     Inst.addOperand(MCOperand::CreateReg(X86::RAX));
    445     Op.addMemOperands(Inst, 5);
    446     EmitInstruction(Out, Inst);
    447   }
    448   EmitInstruction(Out, MCInstBuilder(X86::SHR64ri).addReg(X86::RAX)
    449                            .addReg(X86::RAX).addImm(3));
    450   {
    451     MCInst Inst;
    452     switch (AccessSize) {
    453     case 8:
    454       Inst.setOpcode(X86::CMP8mi);
    455       break;
    456     case 16:
    457       Inst.setOpcode(X86::CMP16mi);
    458       break;
    459     default:
    460       assert(false && "Incorrect access size");
    461       break;
    462     }
    463     const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
    464     std::unique_ptr<X86Operand> Op(
    465         X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc()));
    466     Op->addMemOperands(Inst, 5);
    467     Inst.addOperand(MCOperand::CreateImm(0));
    468     EmitInstruction(Out, Inst);
    469   }
    470 
    471   MCSymbol *DoneSym = Ctx.CreateTempSymbol();
    472   const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
    473   EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
    474 
    475   EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite);
    476   EmitLabel(Out, DoneSym);
    477 
    478   EmitInstruction(Out, MCInstBuilder(X86::POPF64));
    479   EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RAX));
    480   EmitAdjustRSP(Ctx, Out, 128);
    481 }
    482 
    483 } // End anonymous namespace
    484 
    485 X86AsmInstrumentation::X86AsmInstrumentation() {}
    486 X86AsmInstrumentation::~X86AsmInstrumentation() {}
    487 
    488 void X86AsmInstrumentation::InstrumentInstruction(
    489     const MCInst &Inst, OperandVector &Operands, MCContext &Ctx,
    490     const MCInstrInfo &MII, MCStreamer &Out) {}
    491 
    492 X86AsmInstrumentation *
    493 CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions,
    494                             const MCContext &Ctx, const MCSubtargetInfo &STI) {
    495   Triple T(STI.getTargetTriple());
    496   const bool hasCompilerRTSupport = T.isOSLinux();
    497   if (ClAsanInstrumentAssembly && hasCompilerRTSupport &&
    498       MCOptions.SanitizeAddress) {
    499     if ((STI.getFeatureBits() & X86::Mode32Bit) != 0)
    500       return new X86AddressSanitizer32(STI);
    501     if ((STI.getFeatureBits() & X86::Mode64Bit) != 0)
    502       return new X86AddressSanitizer64(STI);
    503   }
    504   return new X86AsmInstrumentation();
    505 }
    506 
    507 } // End llvm namespace
    508