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