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