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