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
IsStackReg(unsigned Reg)35 bool IsStackReg(unsigned Reg) {
36 return Reg == X86::RSP || Reg == X86::ESP || Reg == X86::SP;
37 }
38
FuncName(unsigned AccessSize,bool IsWrite)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:
X86AddressSanitizer(const MCSubtargetInfo & STI)46 X86AddressSanitizer(const MCSubtargetInfo &STI) : STI(STI) {}
~X86AddressSanitizer()47 virtual ~X86AddressSanitizer() {}
48
49 // X86AsmInstrumentation implementation:
InstrumentInstruction(const MCInst & Inst,OperandVector & Operands,MCContext & Ctx,const MCInstrInfo & MII,MCStreamer & Out)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);
EmitInstruction(MCStreamer & Out,const MCInst & Inst)68 void EmitInstruction(MCStreamer &Out, const MCInst &Inst) {
69 Out.EmitInstruction(Inst, STI);
70 }
71
EmitLabel(MCStreamer & Out,MCSymbol * Label)72 void EmitLabel(MCStreamer &Out, MCSymbol *Label) { Out.EmitLabel(Label); }
73
74 protected:
75 const MCSubtargetInfo &STI;
76 };
77
InstrumentMemOperand(MCParsedAsmOperand & Op,unsigned AccessSize,bool IsWrite,MCContext & Ctx,MCStreamer & Out)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
InstrumentMOV(const MCInst & Inst,OperandVector & Operands,MCContext & Ctx,const MCInstrInfo & MII,MCStreamer & Out)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
X86AddressSanitizer32(const MCSubtargetInfo & STI)147 X86AddressSanitizer32(const MCSubtargetInfo &STI)
148 : X86AddressSanitizer(STI) {}
~X86AddressSanitizer32()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:
EmitCallAsanReport(MCContext & Ctx,MCStreamer & Out,unsigned AccessSize,bool IsWrite,unsigned AddressReg)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
InstrumentMemOperandSmallImpl(X86Operand & Op,unsigned AccessSize,bool IsWrite,MCContext & Ctx,MCStreamer & Out)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
InstrumentMemOperandLargeImpl(X86Operand & Op,unsigned AccessSize,bool IsWrite,MCContext & Ctx,MCStreamer & Out)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
X86AddressSanitizer64(const MCSubtargetInfo & STI)313 X86AddressSanitizer64(const MCSubtargetInfo &STI)
314 : X86AddressSanitizer(STI) {}
~X86AddressSanitizer64()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:
EmitAdjustRSP(MCContext & Ctx,MCStreamer & Out,long Offset)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
EmitCallAsanReport(MCContext & Ctx,MCStreamer & Out,unsigned AccessSize,bool IsWrite)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
InstrumentMemOperandSmallImpl(X86Operand & Op,unsigned AccessSize,bool IsWrite,MCContext & Ctx,MCStreamer & Out)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
InstrumentMemOperandLargeImpl(X86Operand & Op,unsigned AccessSize,bool IsWrite,MCContext & Ctx,MCStreamer & Out)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
X86AsmInstrumentation()485 X86AsmInstrumentation::X86AsmInstrumentation() {}
~X86AsmInstrumentation()486 X86AsmInstrumentation::~X86AsmInstrumentation() {}
487
InstrumentInstruction(const MCInst & Inst,OperandVector & Operands,MCContext & Ctx,const MCInstrInfo & MII,MCStreamer & Out)488 void X86AsmInstrumentation::InstrumentInstruction(
489 const MCInst &Inst, OperandVector &Operands, MCContext &Ctx,
490 const MCInstrInfo &MII, MCStreamer &Out) {}
491
492 X86AsmInstrumentation *
CreateX86AsmInstrumentation(const MCTargetOptions & MCOptions,const MCContext & Ctx,const MCSubtargetInfo & STI)493 CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions,
494 const MCContext &Ctx, const MCSubtargetInfo &STI) {
495 Triple T(STI.getTargetTriple());
496 const bool hasCompilerRTSupport = T.isOSLinux();
497 if (ClAsanInstrumentAssembly && hasCompilerRTSupport &&
498 MCOptions.SanitizeAddress) {
499 if ((STI.getFeatureBits() & X86::Mode32Bit) != 0)
500 return new X86AddressSanitizer32(STI);
501 if ((STI.getFeatureBits() & X86::Mode64Bit) != 0)
502 return new X86AddressSanitizer64(STI);
503 }
504 return new X86AsmInstrumentation();
505 }
506
507 } // End llvm namespace
508