X86AsmInstrumentation.cpp revision 280031
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 "X86RegisterInfo.h"
14#include "llvm/ADT/StringExtras.h"
15#include "llvm/ADT/Triple.h"
16#include "llvm/CodeGen/MachineValueType.h"
17#include "llvm/IR/Function.h"
18#include "llvm/MC/MCAsmInfo.h"
19#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCInstBuilder.h"
22#include "llvm/MC/MCInstrInfo.h"
23#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24#include "llvm/MC/MCStreamer.h"
25#include "llvm/MC/MCSubtargetInfo.h"
26#include "llvm/MC/MCTargetAsmParser.h"
27#include "llvm/MC/MCTargetOptions.h"
28#include "llvm/Support/CommandLine.h"
29#include <algorithm>
30#include <cassert>
31#include <vector>
32
33// Following comment describes how assembly instrumentation works.
34// Currently we have only AddressSanitizer instrumentation, but we're
35// planning to implement MemorySanitizer for inline assembly too. If
36// you're not familiar with AddressSanitizer algorithm, please, read
37// https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm.
38//
39// When inline assembly is parsed by an instance of X86AsmParser, all
40// instructions are emitted via EmitInstruction method. That's the
41// place where X86AsmInstrumentation analyzes an instruction and
42// decides, whether the instruction should be emitted as is or
43// instrumentation is required. The latter case happens when an
44// instruction reads from or writes to memory. Now instruction opcode
45// is explicitly checked, and if an instruction has a memory operand
46// (for instance, movq (%rsi, %rcx, 8), %rax) - it should be
47// instrumented.  There're also exist instructions that modify
48// memory but don't have an explicit memory operands, for instance,
49// movs.
50//
51// Let's consider at first 8-byte memory accesses when an instruction
52// has an explicit memory operand. In this case we need two registers -
53// AddressReg to compute address of a memory cells which are accessed
54// and ShadowReg to compute corresponding shadow address. So, we need
55// to spill both registers before instrumentation code and restore them
56// after instrumentation. Thus, in general, instrumentation code will
57// look like this:
58// PUSHF  # Store flags, otherwise they will be overwritten
59// PUSH AddressReg  # spill AddressReg
60// PUSH ShadowReg   # spill ShadowReg
61// LEA MemOp, AddressReg  # compute address of the memory operand
62// MOV AddressReg, ShadowReg
63// SHR ShadowReg, 3
64// # ShadowOffset(AddressReg >> 3) contains address of a shadow
65// # corresponding to MemOp.
66// CMP ShadowOffset(ShadowReg), 0  # test shadow value
67// JZ .Done  # when shadow equals to zero, everything is fine
68// MOV AddressReg, RDI
69// # Call __asan_report function with AddressReg as an argument
70// CALL __asan_report
71// .Done:
72// POP ShadowReg  # Restore ShadowReg
73// POP AddressReg  # Restore AddressReg
74// POPF  # Restore flags
75//
76// Memory accesses with different size (1-, 2-, 4- and 16-byte) are
77// handled in a similar manner, but small memory accesses (less than 8
78// byte) require an additional ScratchReg, which is used for shadow value.
79//
80// If, suppose, we're instrumenting an instruction like movs, only
81// contents of RDI, RDI + AccessSize * RCX, RSI, RSI + AccessSize *
82// RCX are checked.  In this case there're no need to spill and restore
83// AddressReg , ShadowReg or flags four times, they're saved on stack
84// just once, before instrumentation of these four addresses, and restored
85// at the end of the instrumentation.
86//
87// There exist several things which complicate this simple algorithm.
88// * Instrumented memory operand can have RSP as a base or an index
89//   register.  So we need to add a constant offset before computation
90//   of memory address, since flags, AddressReg, ShadowReg, etc. were
91//   already stored on stack and RSP was modified.
92// * Debug info (usually, DWARF) should be adjusted, because sometimes
93//   RSP is used as a frame register. So, we need to select some
94//   register as a frame register and temprorary override current CFA
95//   register.
96
97namespace llvm {
98namespace {
99
100static cl::opt<bool> ClAsanInstrumentAssembly(
101    "asan-instrument-assembly",
102    cl::desc("instrument assembly with AddressSanitizer checks"), cl::Hidden,
103    cl::init(false));
104
105const int64_t MinAllowedDisplacement = std::numeric_limits<int32_t>::min();
106const int64_t MaxAllowedDisplacement = std::numeric_limits<int32_t>::max();
107
108int64_t ApplyDisplacementBounds(int64_t Displacement) {
109  return std::max(std::min(MaxAllowedDisplacement, Displacement),
110                  MinAllowedDisplacement);
111}
112
113void CheckDisplacementBounds(int64_t Displacement) {
114  assert(Displacement >= MinAllowedDisplacement &&
115         Displacement <= MaxAllowedDisplacement);
116}
117
118bool IsStackReg(unsigned Reg) { return Reg == X86::RSP || Reg == X86::ESP; }
119
120bool IsSmallMemAccess(unsigned AccessSize) { return AccessSize < 8; }
121
122std::string FuncName(unsigned AccessSize, bool IsWrite) {
123  return std::string("__asan_report_") + (IsWrite ? "store" : "load") +
124         utostr(AccessSize);
125}
126
127class X86AddressSanitizer : public X86AsmInstrumentation {
128public:
129  struct RegisterContext {
130  private:
131    enum RegOffset {
132      REG_OFFSET_ADDRESS = 0,
133      REG_OFFSET_SHADOW,
134      REG_OFFSET_SCRATCH
135    };
136
137  public:
138    RegisterContext(unsigned AddressReg, unsigned ShadowReg,
139                    unsigned ScratchReg) {
140      BusyRegs.push_back(convReg(AddressReg, MVT::i64));
141      BusyRegs.push_back(convReg(ShadowReg, MVT::i64));
142      BusyRegs.push_back(convReg(ScratchReg, MVT::i64));
143    }
144
145    unsigned AddressReg(MVT::SimpleValueType VT) const {
146      return convReg(BusyRegs[REG_OFFSET_ADDRESS], VT);
147    }
148
149    unsigned ShadowReg(MVT::SimpleValueType VT) const {
150      return convReg(BusyRegs[REG_OFFSET_SHADOW], VT);
151    }
152
153    unsigned ScratchReg(MVT::SimpleValueType VT) const {
154      return convReg(BusyRegs[REG_OFFSET_SCRATCH], VT);
155    }
156
157    void AddBusyReg(unsigned Reg) {
158      if (Reg != X86::NoRegister)
159        BusyRegs.push_back(convReg(Reg, MVT::i64));
160    }
161
162    void AddBusyRegs(const X86Operand &Op) {
163      AddBusyReg(Op.getMemBaseReg());
164      AddBusyReg(Op.getMemIndexReg());
165    }
166
167    unsigned ChooseFrameReg(MVT::SimpleValueType VT) const {
168      static const MCPhysReg Candidates[] = { X86::RBP, X86::RAX, X86::RBX,
169                                              X86::RCX, X86::RDX, X86::RDI,
170                                              X86::RSI };
171      for (unsigned Reg : Candidates) {
172        if (!std::count(BusyRegs.begin(), BusyRegs.end(), Reg))
173          return convReg(Reg, VT);
174      }
175      return X86::NoRegister;
176    }
177
178  private:
179    unsigned convReg(unsigned Reg, MVT::SimpleValueType VT) const {
180      return Reg == X86::NoRegister ? Reg : getX86SubSuperRegister(Reg, VT);
181    }
182
183    std::vector<unsigned> BusyRegs;
184  };
185
186  X86AddressSanitizer(const MCSubtargetInfo &STI)
187      : X86AsmInstrumentation(STI), RepPrefix(false), OrigSPOffset(0) {}
188
189  virtual ~X86AddressSanitizer() {}
190
191  // X86AsmInstrumentation implementation:
192  virtual void InstrumentAndEmitInstruction(const MCInst &Inst,
193                                            OperandVector &Operands,
194                                            MCContext &Ctx,
195                                            const MCInstrInfo &MII,
196                                            MCStreamer &Out) override {
197    InstrumentMOVS(Inst, Operands, Ctx, MII, Out);
198    if (RepPrefix)
199      EmitInstruction(Out, MCInstBuilder(X86::REP_PREFIX));
200
201    InstrumentMOV(Inst, Operands, Ctx, MII, Out);
202
203    RepPrefix = (Inst.getOpcode() == X86::REP_PREFIX);
204    if (!RepPrefix)
205      EmitInstruction(Out, Inst);
206  }
207
208  // Adjusts up stack and saves all registers used in instrumentation.
209  virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx,
210                                            MCContext &Ctx,
211                                            MCStreamer &Out) = 0;
212
213  // Restores all registers used in instrumentation and adjusts stack.
214  virtual void InstrumentMemOperandEpilogue(const RegisterContext &RegCtx,
215                                            MCContext &Ctx,
216                                            MCStreamer &Out) = 0;
217
218  virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize,
219                                         bool IsWrite,
220                                         const RegisterContext &RegCtx,
221                                         MCContext &Ctx, MCStreamer &Out) = 0;
222  virtual void InstrumentMemOperandLarge(X86Operand &Op, unsigned AccessSize,
223                                         bool IsWrite,
224                                         const RegisterContext &RegCtx,
225                                         MCContext &Ctx, MCStreamer &Out) = 0;
226
227  virtual void InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx,
228                                  MCStreamer &Out) = 0;
229
230  void InstrumentMemOperand(X86Operand &Op, unsigned AccessSize, bool IsWrite,
231                            const RegisterContext &RegCtx, MCContext &Ctx,
232                            MCStreamer &Out);
233  void InstrumentMOVSBase(unsigned DstReg, unsigned SrcReg, unsigned CntReg,
234                          unsigned AccessSize, MCContext &Ctx, MCStreamer &Out);
235
236  void InstrumentMOVS(const MCInst &Inst, OperandVector &Operands,
237                      MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
238  void InstrumentMOV(const MCInst &Inst, OperandVector &Operands,
239                     MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
240
241protected:
242  void EmitLabel(MCStreamer &Out, MCSymbol *Label) { Out.EmitLabel(Label); }
243
244  void EmitLEA(X86Operand &Op, MVT::SimpleValueType VT, unsigned Reg,
245               MCStreamer &Out) {
246    assert(VT == MVT::i32 || VT == MVT::i64);
247    MCInst Inst;
248    Inst.setOpcode(VT == MVT::i32 ? X86::LEA32r : X86::LEA64r);
249    Inst.addOperand(MCOperand::CreateReg(getX86SubSuperRegister(Reg, VT)));
250    Op.addMemOperands(Inst, 5);
251    EmitInstruction(Out, Inst);
252  }
253
254  void ComputeMemOperandAddress(X86Operand &Op, MVT::SimpleValueType VT,
255                                unsigned Reg, MCContext &Ctx, MCStreamer &Out);
256
257  // Creates new memory operand with Displacement added to an original
258  // displacement. Residue will contain a residue which could happen when the
259  // total displacement exceeds 32-bit limitation.
260  std::unique_ptr<X86Operand> AddDisplacement(X86Operand &Op,
261                                              int64_t Displacement,
262                                              MCContext &Ctx, int64_t *Residue);
263
264  bool is64BitMode() const {
265    return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
266  }
267  bool is32BitMode() const {
268    return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
269  }
270  bool is16BitMode() const {
271    return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
272  }
273
274  unsigned getPointerWidth() {
275    if (is16BitMode()) return 16;
276    if (is32BitMode()) return 32;
277    if (is64BitMode()) return 64;
278    llvm_unreachable("invalid mode");
279  }
280
281  // True when previous instruction was actually REP prefix.
282  bool RepPrefix;
283
284  // Offset from the original SP register.
285  int64_t OrigSPOffset;
286};
287
288void X86AddressSanitizer::InstrumentMemOperand(
289    X86Operand &Op, unsigned AccessSize, bool IsWrite,
290    const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) {
291  assert(Op.isMem() && "Op should be a memory operand.");
292  assert((AccessSize & (AccessSize - 1)) == 0 && AccessSize <= 16 &&
293         "AccessSize should be a power of two, less or equal than 16.");
294  // FIXME: take into account load/store alignment.
295  if (IsSmallMemAccess(AccessSize))
296    InstrumentMemOperandSmall(Op, AccessSize, IsWrite, RegCtx, Ctx, Out);
297  else
298    InstrumentMemOperandLarge(Op, AccessSize, IsWrite, RegCtx, Ctx, Out);
299}
300
301void X86AddressSanitizer::InstrumentMOVSBase(unsigned DstReg, unsigned SrcReg,
302                                             unsigned CntReg,
303                                             unsigned AccessSize,
304                                             MCContext &Ctx, MCStreamer &Out) {
305  // FIXME: check whole ranges [DstReg .. DstReg + AccessSize * (CntReg - 1)]
306  // and [SrcReg .. SrcReg + AccessSize * (CntReg - 1)].
307  RegisterContext RegCtx(X86::RDX /* AddressReg */, X86::RAX /* ShadowReg */,
308                         IsSmallMemAccess(AccessSize)
309                             ? X86::RBX
310                             : X86::NoRegister /* ScratchReg */);
311  RegCtx.AddBusyReg(DstReg);
312  RegCtx.AddBusyReg(SrcReg);
313  RegCtx.AddBusyReg(CntReg);
314
315  InstrumentMemOperandPrologue(RegCtx, Ctx, Out);
316
317  // Test (%SrcReg)
318  {
319    const MCExpr *Disp = MCConstantExpr::Create(0, Ctx);
320    std::unique_ptr<X86Operand> Op(X86Operand::CreateMem(
321        getPointerWidth(), 0, Disp, SrcReg, 0, AccessSize, SMLoc(), SMLoc()));
322    InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, RegCtx, Ctx,
323                         Out);
324  }
325
326  // Test -1(%SrcReg, %CntReg, AccessSize)
327  {
328    const MCExpr *Disp = MCConstantExpr::Create(-1, Ctx);
329    std::unique_ptr<X86Operand> Op(X86Operand::CreateMem(
330        getPointerWidth(), 0, Disp, SrcReg, CntReg, AccessSize, SMLoc(),
331        SMLoc()));
332    InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, RegCtx, Ctx,
333                         Out);
334  }
335
336  // Test (%DstReg)
337  {
338    const MCExpr *Disp = MCConstantExpr::Create(0, Ctx);
339    std::unique_ptr<X86Operand> Op(X86Operand::CreateMem(
340        getPointerWidth(), 0, Disp, DstReg, 0, AccessSize, SMLoc(), SMLoc()));
341    InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, RegCtx, Ctx, Out);
342  }
343
344  // Test -1(%DstReg, %CntReg, AccessSize)
345  {
346    const MCExpr *Disp = MCConstantExpr::Create(-1, Ctx);
347    std::unique_ptr<X86Operand> Op(X86Operand::CreateMem(
348        getPointerWidth(), 0, Disp, DstReg, CntReg, AccessSize, SMLoc(),
349        SMLoc()));
350    InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, RegCtx, Ctx, Out);
351  }
352
353  InstrumentMemOperandEpilogue(RegCtx, Ctx, Out);
354}
355
356void X86AddressSanitizer::InstrumentMOVS(const MCInst &Inst,
357                                         OperandVector &Operands,
358                                         MCContext &Ctx, const MCInstrInfo &MII,
359                                         MCStreamer &Out) {
360  // Access size in bytes.
361  unsigned AccessSize = 0;
362
363  switch (Inst.getOpcode()) {
364  case X86::MOVSB:
365    AccessSize = 1;
366    break;
367  case X86::MOVSW:
368    AccessSize = 2;
369    break;
370  case X86::MOVSL:
371    AccessSize = 4;
372    break;
373  case X86::MOVSQ:
374    AccessSize = 8;
375    break;
376  default:
377    return;
378  }
379
380  InstrumentMOVSImpl(AccessSize, Ctx, Out);
381}
382
383void X86AddressSanitizer::InstrumentMOV(const MCInst &Inst,
384                                        OperandVector &Operands, MCContext &Ctx,
385                                        const MCInstrInfo &MII,
386                                        MCStreamer &Out) {
387  // Access size in bytes.
388  unsigned AccessSize = 0;
389
390  switch (Inst.getOpcode()) {
391  case X86::MOV8mi:
392  case X86::MOV8mr:
393  case X86::MOV8rm:
394    AccessSize = 1;
395    break;
396  case X86::MOV16mi:
397  case X86::MOV16mr:
398  case X86::MOV16rm:
399    AccessSize = 2;
400    break;
401  case X86::MOV32mi:
402  case X86::MOV32mr:
403  case X86::MOV32rm:
404    AccessSize = 4;
405    break;
406  case X86::MOV64mi32:
407  case X86::MOV64mr:
408  case X86::MOV64rm:
409    AccessSize = 8;
410    break;
411  case X86::MOVAPDmr:
412  case X86::MOVAPSmr:
413  case X86::MOVAPDrm:
414  case X86::MOVAPSrm:
415    AccessSize = 16;
416    break;
417  default:
418    return;
419  }
420
421  const bool IsWrite = MII.get(Inst.getOpcode()).mayStore();
422
423  for (unsigned Ix = 0; Ix < Operands.size(); ++Ix) {
424    assert(Operands[Ix]);
425    MCParsedAsmOperand &Op = *Operands[Ix];
426    if (Op.isMem()) {
427      X86Operand &MemOp = static_cast<X86Operand &>(Op);
428      RegisterContext RegCtx(
429          X86::RDI /* AddressReg */, X86::RAX /* ShadowReg */,
430          IsSmallMemAccess(AccessSize) ? X86::RCX
431                                       : X86::NoRegister /* ScratchReg */);
432      RegCtx.AddBusyRegs(MemOp);
433      InstrumentMemOperandPrologue(RegCtx, Ctx, Out);
434      InstrumentMemOperand(MemOp, AccessSize, IsWrite, RegCtx, Ctx, Out);
435      InstrumentMemOperandEpilogue(RegCtx, Ctx, Out);
436    }
437  }
438}
439
440void X86AddressSanitizer::ComputeMemOperandAddress(X86Operand &Op,
441                                                   MVT::SimpleValueType VT,
442                                                   unsigned Reg, MCContext &Ctx,
443                                                   MCStreamer &Out) {
444  int64_t Displacement = 0;
445  if (IsStackReg(Op.getMemBaseReg()))
446    Displacement -= OrigSPOffset;
447  if (IsStackReg(Op.getMemIndexReg()))
448    Displacement -= OrigSPOffset * Op.getMemScale();
449
450  assert(Displacement >= 0);
451
452  // Emit Op as is.
453  if (Displacement == 0) {
454    EmitLEA(Op, VT, Reg, Out);
455    return;
456  }
457
458  int64_t Residue;
459  std::unique_ptr<X86Operand> NewOp =
460      AddDisplacement(Op, Displacement, Ctx, &Residue);
461  EmitLEA(*NewOp, VT, Reg, Out);
462
463  while (Residue != 0) {
464    const MCConstantExpr *Disp =
465        MCConstantExpr::Create(ApplyDisplacementBounds(Residue), Ctx);
466    std::unique_ptr<X86Operand> DispOp =
467        X86Operand::CreateMem(getPointerWidth(), 0, Disp, Reg, 0, 1, SMLoc(),
468                              SMLoc());
469    EmitLEA(*DispOp, VT, Reg, Out);
470    Residue -= Disp->getValue();
471  }
472}
473
474std::unique_ptr<X86Operand>
475X86AddressSanitizer::AddDisplacement(X86Operand &Op, int64_t Displacement,
476                                     MCContext &Ctx, int64_t *Residue) {
477  assert(Displacement >= 0);
478
479  if (Displacement == 0 ||
480      (Op.getMemDisp() && Op.getMemDisp()->getKind() != MCExpr::Constant)) {
481    *Residue = Displacement;
482    return X86Operand::CreateMem(Op.getMemModeSize(), Op.getMemSegReg(),
483                                 Op.getMemDisp(), Op.getMemBaseReg(),
484                                 Op.getMemIndexReg(), Op.getMemScale(),
485                                 SMLoc(), SMLoc());
486  }
487
488  int64_t OrigDisplacement =
489      static_cast<const MCConstantExpr *>(Op.getMemDisp())->getValue();
490  CheckDisplacementBounds(OrigDisplacement);
491  Displacement += OrigDisplacement;
492
493  int64_t NewDisplacement = ApplyDisplacementBounds(Displacement);
494  CheckDisplacementBounds(NewDisplacement);
495
496  *Residue = Displacement - NewDisplacement;
497  const MCExpr *Disp = MCConstantExpr::Create(NewDisplacement, Ctx);
498  return X86Operand::CreateMem(Op.getMemModeSize(), Op.getMemSegReg(), Disp,
499                               Op.getMemBaseReg(), Op.getMemIndexReg(),
500                               Op.getMemScale(), SMLoc(), SMLoc());
501}
502
503class X86AddressSanitizer32 : public X86AddressSanitizer {
504public:
505  static const long kShadowOffset = 0x20000000;
506
507  X86AddressSanitizer32(const MCSubtargetInfo &STI)
508      : X86AddressSanitizer(STI) {}
509
510  virtual ~X86AddressSanitizer32() {}
511
512  unsigned GetFrameReg(const MCContext &Ctx, MCStreamer &Out) {
513    unsigned FrameReg = GetFrameRegGeneric(Ctx, Out);
514    if (FrameReg == X86::NoRegister)
515      return FrameReg;
516    return getX86SubSuperRegister(FrameReg, MVT::i32);
517  }
518
519  void SpillReg(MCStreamer &Out, unsigned Reg) {
520    EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(Reg));
521    OrigSPOffset -= 4;
522  }
523
524  void RestoreReg(MCStreamer &Out, unsigned Reg) {
525    EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(Reg));
526    OrigSPOffset += 4;
527  }
528
529  void StoreFlags(MCStreamer &Out) {
530    EmitInstruction(Out, MCInstBuilder(X86::PUSHF32));
531    OrigSPOffset -= 4;
532  }
533
534  void RestoreFlags(MCStreamer &Out) {
535    EmitInstruction(Out, MCInstBuilder(X86::POPF32));
536    OrigSPOffset += 4;
537  }
538
539  virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx,
540                                            MCContext &Ctx,
541                                            MCStreamer &Out) override {
542    unsigned LocalFrameReg = RegCtx.ChooseFrameReg(MVT::i32);
543    assert(LocalFrameReg != X86::NoRegister);
544
545    const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
546    unsigned FrameReg = GetFrameReg(Ctx, Out);
547    if (MRI && FrameReg != X86::NoRegister) {
548      SpillReg(Out, LocalFrameReg);
549      if (FrameReg == X86::ESP) {
550        Out.EmitCFIAdjustCfaOffset(4 /* byte size of the LocalFrameReg */);
551        Out.EmitCFIRelOffset(
552            MRI->getDwarfRegNum(LocalFrameReg, true /* IsEH */), 0);
553      }
554      EmitInstruction(
555          Out,
556          MCInstBuilder(X86::MOV32rr).addReg(LocalFrameReg).addReg(FrameReg));
557      Out.EmitCFIRememberState();
558      Out.EmitCFIDefCfaRegister(
559          MRI->getDwarfRegNum(LocalFrameReg, true /* IsEH */));
560    }
561
562    SpillReg(Out, RegCtx.AddressReg(MVT::i32));
563    SpillReg(Out, RegCtx.ShadowReg(MVT::i32));
564    if (RegCtx.ScratchReg(MVT::i32) != X86::NoRegister)
565      SpillReg(Out, RegCtx.ScratchReg(MVT::i32));
566    StoreFlags(Out);
567  }
568
569  virtual void InstrumentMemOperandEpilogue(const RegisterContext &RegCtx,
570                                            MCContext &Ctx,
571                                            MCStreamer &Out) override {
572    unsigned LocalFrameReg = RegCtx.ChooseFrameReg(MVT::i32);
573    assert(LocalFrameReg != X86::NoRegister);
574
575    RestoreFlags(Out);
576    if (RegCtx.ScratchReg(MVT::i32) != X86::NoRegister)
577      RestoreReg(Out, RegCtx.ScratchReg(MVT::i32));
578    RestoreReg(Out, RegCtx.ShadowReg(MVT::i32));
579    RestoreReg(Out, RegCtx.AddressReg(MVT::i32));
580
581    unsigned FrameReg = GetFrameReg(Ctx, Out);
582    if (Ctx.getRegisterInfo() && FrameReg != X86::NoRegister) {
583      RestoreReg(Out, LocalFrameReg);
584      Out.EmitCFIRestoreState();
585      if (FrameReg == X86::ESP)
586        Out.EmitCFIAdjustCfaOffset(-4 /* byte size of the LocalFrameReg */);
587    }
588  }
589
590  virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize,
591                                         bool IsWrite,
592                                         const RegisterContext &RegCtx,
593                                         MCContext &Ctx,
594                                         MCStreamer &Out) override;
595  virtual void InstrumentMemOperandLarge(X86Operand &Op, unsigned AccessSize,
596                                         bool IsWrite,
597                                         const RegisterContext &RegCtx,
598                                         MCContext &Ctx,
599                                         MCStreamer &Out) override;
600  virtual void InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx,
601                                  MCStreamer &Out) override;
602
603private:
604  void EmitCallAsanReport(unsigned AccessSize, bool IsWrite, MCContext &Ctx,
605                          MCStreamer &Out, const RegisterContext &RegCtx) {
606    EmitInstruction(Out, MCInstBuilder(X86::CLD));
607    EmitInstruction(Out, MCInstBuilder(X86::MMX_EMMS));
608
609    EmitInstruction(Out, MCInstBuilder(X86::AND64ri8)
610                             .addReg(X86::ESP)
611                             .addReg(X86::ESP)
612                             .addImm(-16));
613    EmitInstruction(
614        Out, MCInstBuilder(X86::PUSH32r).addReg(RegCtx.AddressReg(MVT::i32)));
615
616    const std::string &Fn = FuncName(AccessSize, IsWrite);
617    MCSymbol *FnSym = Ctx.GetOrCreateSymbol(StringRef(Fn));
618    const MCSymbolRefExpr *FnExpr =
619        MCSymbolRefExpr::Create(FnSym, MCSymbolRefExpr::VK_PLT, Ctx);
620    EmitInstruction(Out, MCInstBuilder(X86::CALLpcrel32).addExpr(FnExpr));
621  }
622};
623
624void X86AddressSanitizer32::InstrumentMemOperandSmall(
625    X86Operand &Op, unsigned AccessSize, bool IsWrite,
626    const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) {
627  unsigned AddressRegI32 = RegCtx.AddressReg(MVT::i32);
628  unsigned ShadowRegI32 = RegCtx.ShadowReg(MVT::i32);
629  unsigned ShadowRegI8 = RegCtx.ShadowReg(MVT::i8);
630
631  assert(RegCtx.ScratchReg(MVT::i32) != X86::NoRegister);
632  unsigned ScratchRegI32 = RegCtx.ScratchReg(MVT::i32);
633
634  ComputeMemOperandAddress(Op, MVT::i32, AddressRegI32, Ctx, Out);
635
636  EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ShadowRegI32).addReg(
637                           AddressRegI32));
638  EmitInstruction(Out, MCInstBuilder(X86::SHR32ri)
639                           .addReg(ShadowRegI32)
640                           .addReg(ShadowRegI32)
641                           .addImm(3));
642
643  {
644    MCInst Inst;
645    Inst.setOpcode(X86::MOV8rm);
646    Inst.addOperand(MCOperand::CreateReg(ShadowRegI8));
647    const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
648    std::unique_ptr<X86Operand> Op(
649        X86Operand::CreateMem(getPointerWidth(), 0, Disp, ShadowRegI32, 0, 1,
650                              SMLoc(), SMLoc()));
651    Op->addMemOperands(Inst, 5);
652    EmitInstruction(Out, Inst);
653  }
654
655  EmitInstruction(
656      Out, MCInstBuilder(X86::TEST8rr).addReg(ShadowRegI8).addReg(ShadowRegI8));
657  MCSymbol *DoneSym = Ctx.CreateTempSymbol();
658  const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
659  EmitInstruction(Out, MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
660
661  EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ScratchRegI32).addReg(
662                           AddressRegI32));
663  EmitInstruction(Out, MCInstBuilder(X86::AND32ri)
664                           .addReg(ScratchRegI32)
665                           .addReg(ScratchRegI32)
666                           .addImm(7));
667
668  switch (AccessSize) {
669  default: llvm_unreachable("Incorrect access size");
670  case 1:
671    break;
672  case 2: {
673    const MCExpr *Disp = MCConstantExpr::Create(1, Ctx);
674    std::unique_ptr<X86Operand> Op(
675        X86Operand::CreateMem(getPointerWidth(), 0, Disp, ScratchRegI32, 0, 1,
676                              SMLoc(), SMLoc()));
677    EmitLEA(*Op, MVT::i32, ScratchRegI32, Out);
678    break;
679  }
680  case 4:
681    EmitInstruction(Out, MCInstBuilder(X86::ADD32ri8)
682                             .addReg(ScratchRegI32)
683                             .addReg(ScratchRegI32)
684                             .addImm(3));
685    break;
686  }
687
688  EmitInstruction(
689      Out,
690      MCInstBuilder(X86::MOVSX32rr8).addReg(ShadowRegI32).addReg(ShadowRegI8));
691  EmitInstruction(Out, MCInstBuilder(X86::CMP32rr).addReg(ScratchRegI32).addReg(
692                           ShadowRegI32));
693  EmitInstruction(Out, MCInstBuilder(X86::JL_1).addExpr(DoneExpr));
694
695  EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
696  EmitLabel(Out, DoneSym);
697}
698
699void X86AddressSanitizer32::InstrumentMemOperandLarge(
700    X86Operand &Op, unsigned AccessSize, bool IsWrite,
701    const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) {
702  unsigned AddressRegI32 = RegCtx.AddressReg(MVT::i32);
703  unsigned ShadowRegI32 = RegCtx.ShadowReg(MVT::i32);
704
705  ComputeMemOperandAddress(Op, MVT::i32, AddressRegI32, Ctx, Out);
706
707  EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ShadowRegI32).addReg(
708                           AddressRegI32));
709  EmitInstruction(Out, MCInstBuilder(X86::SHR32ri)
710                           .addReg(ShadowRegI32)
711                           .addReg(ShadowRegI32)
712                           .addImm(3));
713  {
714    MCInst Inst;
715    switch (AccessSize) {
716    default: llvm_unreachable("Incorrect access size");
717    case 8:
718      Inst.setOpcode(X86::CMP8mi);
719      break;
720    case 16:
721      Inst.setOpcode(X86::CMP16mi);
722      break;
723    }
724    const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
725    std::unique_ptr<X86Operand> Op(
726        X86Operand::CreateMem(getPointerWidth(), 0, Disp, ShadowRegI32, 0, 1,
727                              SMLoc(), SMLoc()));
728    Op->addMemOperands(Inst, 5);
729    Inst.addOperand(MCOperand::CreateImm(0));
730    EmitInstruction(Out, Inst);
731  }
732  MCSymbol *DoneSym = Ctx.CreateTempSymbol();
733  const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
734  EmitInstruction(Out, MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
735
736  EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
737  EmitLabel(Out, DoneSym);
738}
739
740void X86AddressSanitizer32::InstrumentMOVSImpl(unsigned AccessSize,
741                                               MCContext &Ctx,
742                                               MCStreamer &Out) {
743  StoreFlags(Out);
744
745  // No need to test when ECX is equals to zero.
746  MCSymbol *DoneSym = Ctx.CreateTempSymbol();
747  const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
748  EmitInstruction(
749      Out, MCInstBuilder(X86::TEST32rr).addReg(X86::ECX).addReg(X86::ECX));
750  EmitInstruction(Out, MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
751
752  // Instrument first and last elements in src and dst range.
753  InstrumentMOVSBase(X86::EDI /* DstReg */, X86::ESI /* SrcReg */,
754                     X86::ECX /* CntReg */, AccessSize, Ctx, Out);
755
756  EmitLabel(Out, DoneSym);
757  RestoreFlags(Out);
758}
759
760class X86AddressSanitizer64 : public X86AddressSanitizer {
761public:
762  static const long kShadowOffset = 0x7fff8000;
763
764  X86AddressSanitizer64(const MCSubtargetInfo &STI)
765      : X86AddressSanitizer(STI) {}
766
767  virtual ~X86AddressSanitizer64() {}
768
769  unsigned GetFrameReg(const MCContext &Ctx, MCStreamer &Out) {
770    unsigned FrameReg = GetFrameRegGeneric(Ctx, Out);
771    if (FrameReg == X86::NoRegister)
772      return FrameReg;
773    return getX86SubSuperRegister(FrameReg, MVT::i64);
774  }
775
776  void SpillReg(MCStreamer &Out, unsigned Reg) {
777    EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(Reg));
778    OrigSPOffset -= 8;
779  }
780
781  void RestoreReg(MCStreamer &Out, unsigned Reg) {
782    EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(Reg));
783    OrigSPOffset += 8;
784  }
785
786  void StoreFlags(MCStreamer &Out) {
787    EmitInstruction(Out, MCInstBuilder(X86::PUSHF64));
788    OrigSPOffset -= 8;
789  }
790
791  void RestoreFlags(MCStreamer &Out) {
792    EmitInstruction(Out, MCInstBuilder(X86::POPF64));
793    OrigSPOffset += 8;
794  }
795
796  virtual void InstrumentMemOperandPrologue(const RegisterContext &RegCtx,
797                                            MCContext &Ctx,
798                                            MCStreamer &Out) override {
799    unsigned LocalFrameReg = RegCtx.ChooseFrameReg(MVT::i64);
800    assert(LocalFrameReg != X86::NoRegister);
801
802    const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
803    unsigned FrameReg = GetFrameReg(Ctx, Out);
804    if (MRI && FrameReg != X86::NoRegister) {
805      SpillReg(Out, X86::RBP);
806      if (FrameReg == X86::RSP) {
807        Out.EmitCFIAdjustCfaOffset(8 /* byte size of the LocalFrameReg */);
808        Out.EmitCFIRelOffset(
809            MRI->getDwarfRegNum(LocalFrameReg, true /* IsEH */), 0);
810      }
811      EmitInstruction(
812          Out,
813          MCInstBuilder(X86::MOV64rr).addReg(LocalFrameReg).addReg(FrameReg));
814      Out.EmitCFIRememberState();
815      Out.EmitCFIDefCfaRegister(
816          MRI->getDwarfRegNum(LocalFrameReg, true /* IsEH */));
817    }
818
819    EmitAdjustRSP(Ctx, Out, -128);
820    SpillReg(Out, RegCtx.ShadowReg(MVT::i64));
821    SpillReg(Out, RegCtx.AddressReg(MVT::i64));
822    if (RegCtx.ScratchReg(MVT::i64) != X86::NoRegister)
823      SpillReg(Out, RegCtx.ScratchReg(MVT::i64));
824    StoreFlags(Out);
825  }
826
827  virtual void InstrumentMemOperandEpilogue(const RegisterContext &RegCtx,
828                                            MCContext &Ctx,
829                                            MCStreamer &Out) override {
830    unsigned LocalFrameReg = RegCtx.ChooseFrameReg(MVT::i64);
831    assert(LocalFrameReg != X86::NoRegister);
832
833    RestoreFlags(Out);
834    if (RegCtx.ScratchReg(MVT::i64) != X86::NoRegister)
835      RestoreReg(Out, RegCtx.ScratchReg(MVT::i64));
836    RestoreReg(Out, RegCtx.AddressReg(MVT::i64));
837    RestoreReg(Out, RegCtx.ShadowReg(MVT::i64));
838    EmitAdjustRSP(Ctx, Out, 128);
839
840    unsigned FrameReg = GetFrameReg(Ctx, Out);
841    if (Ctx.getRegisterInfo() && FrameReg != X86::NoRegister) {
842      RestoreReg(Out, LocalFrameReg);
843      Out.EmitCFIRestoreState();
844      if (FrameReg == X86::RSP)
845        Out.EmitCFIAdjustCfaOffset(-8 /* byte size of the LocalFrameReg */);
846    }
847  }
848
849  virtual void InstrumentMemOperandSmall(X86Operand &Op, unsigned AccessSize,
850                                         bool IsWrite,
851                                         const RegisterContext &RegCtx,
852                                         MCContext &Ctx,
853                                         MCStreamer &Out) override;
854  virtual void InstrumentMemOperandLarge(X86Operand &Op, unsigned AccessSize,
855                                         bool IsWrite,
856                                         const RegisterContext &RegCtx,
857                                         MCContext &Ctx,
858                                         MCStreamer &Out) override;
859  virtual void InstrumentMOVSImpl(unsigned AccessSize, MCContext &Ctx,
860                                  MCStreamer &Out) override;
861
862private:
863  void EmitAdjustRSP(MCContext &Ctx, MCStreamer &Out, long Offset) {
864    const MCExpr *Disp = MCConstantExpr::Create(Offset, Ctx);
865    std::unique_ptr<X86Operand> Op(
866        X86Operand::CreateMem(getPointerWidth(), 0, Disp, X86::RSP, 0, 1,
867                              SMLoc(), SMLoc()));
868    EmitLEA(*Op, MVT::i64, X86::RSP, Out);
869    OrigSPOffset += Offset;
870  }
871
872  void EmitCallAsanReport(unsigned AccessSize, bool IsWrite, MCContext &Ctx,
873                          MCStreamer &Out, const RegisterContext &RegCtx) {
874    EmitInstruction(Out, MCInstBuilder(X86::CLD));
875    EmitInstruction(Out, MCInstBuilder(X86::MMX_EMMS));
876
877    EmitInstruction(Out, MCInstBuilder(X86::AND64ri8)
878                             .addReg(X86::RSP)
879                             .addReg(X86::RSP)
880                             .addImm(-16));
881
882    if (RegCtx.AddressReg(MVT::i64) != X86::RDI) {
883      EmitInstruction(Out, MCInstBuilder(X86::MOV64rr).addReg(X86::RDI).addReg(
884                               RegCtx.AddressReg(MVT::i64)));
885    }
886    const std::string &Fn = FuncName(AccessSize, IsWrite);
887    MCSymbol *FnSym = Ctx.GetOrCreateSymbol(StringRef(Fn));
888    const MCSymbolRefExpr *FnExpr =
889        MCSymbolRefExpr::Create(FnSym, MCSymbolRefExpr::VK_PLT, Ctx);
890    EmitInstruction(Out, MCInstBuilder(X86::CALL64pcrel32).addExpr(FnExpr));
891  }
892};
893
894void X86AddressSanitizer64::InstrumentMemOperandSmall(
895    X86Operand &Op, unsigned AccessSize, bool IsWrite,
896    const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) {
897  unsigned AddressRegI64 = RegCtx.AddressReg(MVT::i64);
898  unsigned AddressRegI32 = RegCtx.AddressReg(MVT::i32);
899  unsigned ShadowRegI64 = RegCtx.ShadowReg(MVT::i64);
900  unsigned ShadowRegI32 = RegCtx.ShadowReg(MVT::i32);
901  unsigned ShadowRegI8 = RegCtx.ShadowReg(MVT::i8);
902
903  assert(RegCtx.ScratchReg(MVT::i32) != X86::NoRegister);
904  unsigned ScratchRegI32 = RegCtx.ScratchReg(MVT::i32);
905
906  ComputeMemOperandAddress(Op, MVT::i64, AddressRegI64, Ctx, Out);
907
908  EmitInstruction(Out, MCInstBuilder(X86::MOV64rr).addReg(ShadowRegI64).addReg(
909                           AddressRegI64));
910  EmitInstruction(Out, MCInstBuilder(X86::SHR64ri)
911                           .addReg(ShadowRegI64)
912                           .addReg(ShadowRegI64)
913                           .addImm(3));
914  {
915    MCInst Inst;
916    Inst.setOpcode(X86::MOV8rm);
917    Inst.addOperand(MCOperand::CreateReg(ShadowRegI8));
918    const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
919    std::unique_ptr<X86Operand> Op(
920        X86Operand::CreateMem(getPointerWidth(), 0, Disp, ShadowRegI64, 0, 1,
921                              SMLoc(), SMLoc()));
922    Op->addMemOperands(Inst, 5);
923    EmitInstruction(Out, Inst);
924  }
925
926  EmitInstruction(
927      Out, MCInstBuilder(X86::TEST8rr).addReg(ShadowRegI8).addReg(ShadowRegI8));
928  MCSymbol *DoneSym = Ctx.CreateTempSymbol();
929  const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
930  EmitInstruction(Out, MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
931
932  EmitInstruction(Out, MCInstBuilder(X86::MOV32rr).addReg(ScratchRegI32).addReg(
933                           AddressRegI32));
934  EmitInstruction(Out, MCInstBuilder(X86::AND32ri)
935                           .addReg(ScratchRegI32)
936                           .addReg(ScratchRegI32)
937                           .addImm(7));
938
939  switch (AccessSize) {
940  default: llvm_unreachable("Incorrect access size");
941  case 1:
942    break;
943  case 2: {
944    const MCExpr *Disp = MCConstantExpr::Create(1, Ctx);
945    std::unique_ptr<X86Operand> Op(
946        X86Operand::CreateMem(getPointerWidth(), 0, Disp, ScratchRegI32, 0, 1,
947                              SMLoc(), SMLoc()));
948    EmitLEA(*Op, MVT::i32, ScratchRegI32, Out);
949    break;
950  }
951  case 4:
952    EmitInstruction(Out, MCInstBuilder(X86::ADD32ri8)
953                             .addReg(ScratchRegI32)
954                             .addReg(ScratchRegI32)
955                             .addImm(3));
956    break;
957  }
958
959  EmitInstruction(
960      Out,
961      MCInstBuilder(X86::MOVSX32rr8).addReg(ShadowRegI32).addReg(ShadowRegI8));
962  EmitInstruction(Out, MCInstBuilder(X86::CMP32rr).addReg(ScratchRegI32).addReg(
963                           ShadowRegI32));
964  EmitInstruction(Out, MCInstBuilder(X86::JL_1).addExpr(DoneExpr));
965
966  EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
967  EmitLabel(Out, DoneSym);
968}
969
970void X86AddressSanitizer64::InstrumentMemOperandLarge(
971    X86Operand &Op, unsigned AccessSize, bool IsWrite,
972    const RegisterContext &RegCtx, MCContext &Ctx, MCStreamer &Out) {
973  unsigned AddressRegI64 = RegCtx.AddressReg(MVT::i64);
974  unsigned ShadowRegI64 = RegCtx.ShadowReg(MVT::i64);
975
976  ComputeMemOperandAddress(Op, MVT::i64, AddressRegI64, Ctx, Out);
977
978  EmitInstruction(Out, MCInstBuilder(X86::MOV64rr).addReg(ShadowRegI64).addReg(
979                           AddressRegI64));
980  EmitInstruction(Out, MCInstBuilder(X86::SHR64ri)
981                           .addReg(ShadowRegI64)
982                           .addReg(ShadowRegI64)
983                           .addImm(3));
984  {
985    MCInst Inst;
986    switch (AccessSize) {
987    default: llvm_unreachable("Incorrect access size");
988    case 8:
989      Inst.setOpcode(X86::CMP8mi);
990      break;
991    case 16:
992      Inst.setOpcode(X86::CMP16mi);
993      break;
994    }
995    const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
996    std::unique_ptr<X86Operand> Op(
997        X86Operand::CreateMem(getPointerWidth(), 0, Disp, ShadowRegI64, 0, 1,
998                              SMLoc(), SMLoc()));
999    Op->addMemOperands(Inst, 5);
1000    Inst.addOperand(MCOperand::CreateImm(0));
1001    EmitInstruction(Out, Inst);
1002  }
1003
1004  MCSymbol *DoneSym = Ctx.CreateTempSymbol();
1005  const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
1006  EmitInstruction(Out, MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
1007
1008  EmitCallAsanReport(AccessSize, IsWrite, Ctx, Out, RegCtx);
1009  EmitLabel(Out, DoneSym);
1010}
1011
1012void X86AddressSanitizer64::InstrumentMOVSImpl(unsigned AccessSize,
1013                                               MCContext &Ctx,
1014                                               MCStreamer &Out) {
1015  StoreFlags(Out);
1016
1017  // No need to test when RCX is equals to zero.
1018  MCSymbol *DoneSym = Ctx.CreateTempSymbol();
1019  const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
1020  EmitInstruction(
1021      Out, MCInstBuilder(X86::TEST64rr).addReg(X86::RCX).addReg(X86::RCX));
1022  EmitInstruction(Out, MCInstBuilder(X86::JE_1).addExpr(DoneExpr));
1023
1024  // Instrument first and last elements in src and dst range.
1025  InstrumentMOVSBase(X86::RDI /* DstReg */, X86::RSI /* SrcReg */,
1026                     X86::RCX /* CntReg */, AccessSize, Ctx, Out);
1027
1028  EmitLabel(Out, DoneSym);
1029  RestoreFlags(Out);
1030}
1031
1032} // End anonymous namespace
1033
1034X86AsmInstrumentation::X86AsmInstrumentation(const MCSubtargetInfo &STI)
1035    : STI(STI), InitialFrameReg(0) {}
1036
1037X86AsmInstrumentation::~X86AsmInstrumentation() {}
1038
1039void X86AsmInstrumentation::InstrumentAndEmitInstruction(
1040    const MCInst &Inst, OperandVector &Operands, MCContext &Ctx,
1041    const MCInstrInfo &MII, MCStreamer &Out) {
1042  EmitInstruction(Out, Inst);
1043}
1044
1045void X86AsmInstrumentation::EmitInstruction(MCStreamer &Out,
1046                                            const MCInst &Inst) {
1047  Out.EmitInstruction(Inst, STI);
1048}
1049
1050unsigned X86AsmInstrumentation::GetFrameRegGeneric(const MCContext &Ctx,
1051                                                   MCStreamer &Out) {
1052  if (!Out.getNumFrameInfos()) // No active dwarf frame
1053    return X86::NoRegister;
1054  const MCDwarfFrameInfo &Frame = Out.getDwarfFrameInfos().back();
1055  if (Frame.End) // Active dwarf frame is closed
1056    return X86::NoRegister;
1057  const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
1058  if (!MRI) // No register info
1059    return X86::NoRegister;
1060
1061  if (InitialFrameReg) {
1062    // FrameReg is set explicitly, we're instrumenting a MachineFunction.
1063    return InitialFrameReg;
1064  }
1065
1066  return MRI->getLLVMRegNum(Frame.CurrentCfaRegister, true /* IsEH */);
1067}
1068
1069X86AsmInstrumentation *
1070CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions,
1071                            const MCContext &Ctx, const MCSubtargetInfo &STI) {
1072  Triple T(STI.getTargetTriple());
1073  const bool hasCompilerRTSupport = T.isOSLinux();
1074  if (ClAsanInstrumentAssembly && hasCompilerRTSupport &&
1075      MCOptions.SanitizeAddress) {
1076    if ((STI.getFeatureBits() & X86::Mode32Bit) != 0)
1077      return new X86AddressSanitizer32(STI);
1078    if ((STI.getFeatureBits() & X86::Mode64Bit) != 0)
1079      return new X86AddressSanitizer64(STI);
1080  }
1081  return new X86AsmInstrumentation(STI);
1082}
1083
1084} // End llvm namespace
1085