llvm.org GIT mirror llvm / 5ba71b0
[asan] Generate asm instrumentation in MC. Generate entire ASan asm instrumentation in MC without relying on runtime helper functions. Patch by Yuri Gorshenin. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212455 91177308-0d34-0410-b5e6-96231b3b80d8 Evgeniy Stepanov 6 years ago
6 changed file(s) with 410 addition(s) and 166 deletion(s). Raw diff Collapse all Expand all
3636 }
3737
3838 std::string FuncName(unsigned AccessSize, bool IsWrite) {
39 return std::string("__sanitizer_sanitize_") + (IsWrite ? "store" : "load") +
40 (utostr(AccessSize));
39 return std::string("__asan_report_") + (IsWrite ? "store" : "load") +
40 utostr(AccessSize);
4141 }
4242
4343 class X86AddressSanitizer : public X86AsmInstrumentation {
4646 virtual ~X86AddressSanitizer() {}
4747
4848 // X86AsmInstrumentation implementation:
49 virtual void InstrumentInstruction(const MCInst &Inst,
50 OperandVector &Operands, MCContext &Ctx,
51 const MCInstrInfo &MII,
52 MCStreamer &Out) override {
49 virtual void InstrumentInstruction(
50 const MCInst &Inst, OperandVector &Operands, MCContext &Ctx,
51 const MCInstrInfo &MII, MCStreamer &Out) override {
5352 InstrumentMOV(Inst, Operands, Ctx, MII, Out);
5453 }
5554
5655 // Should be implemented differently in x86_32 and x86_64 subclasses.
57 virtual void InstrumentMemOperandImpl(X86Operand &Op, unsigned AccessSize,
58 bool IsWrite, MCContext &Ctx,
59 MCStreamer &Out) = 0;
56 virtual void InstrumentMemOperandSmallImpl(
57 X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
58 MCStreamer &Out) = 0;
59 virtual void InstrumentMemOperandLargeImpl(
60 X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
61 MCStreamer &Out) = 0;
6062
6163 void InstrumentMemOperand(MCParsedAsmOperand &Op, unsigned AccessSize,
6264 bool IsWrite, MCContext &Ctx, MCStreamer &Out);
6668 Out.EmitInstruction(Inst, STI);
6769 }
6870
71 void EmitLabel(MCStreamer &Out, MCSymbol *Label) { Out.EmitLabel(Label); }
72
6973 protected:
7074 const MCSubtargetInfo &STI;
7175 };
7276
73 void X86AddressSanitizer::InstrumentMemOperand(MCParsedAsmOperand &Op,
74 unsigned AccessSize,
75 bool IsWrite, MCContext &Ctx,
76 MCStreamer &Out) {
77 void X86AddressSanitizer::InstrumentMemOperand(
78 MCParsedAsmOperand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
79 MCStreamer &Out) {
7780 assert(Op.isMem() && "Op should be a memory operand.");
7881 assert((AccessSize & (AccessSize - 1)) == 0 && AccessSize <= 16 &&
7982 "AccessSize should be a power of two, less or equal than 16.");
8386 if (IsStackReg(MemOp.getMemBaseReg()) || IsStackReg(MemOp.getMemIndexReg()))
8487 return;
8588
86 InstrumentMemOperandImpl(MemOp, AccessSize, IsWrite, Ctx, Out);
87 }
88
89 void X86AddressSanitizer::InstrumentMOV(const MCInst &Inst,
90 OperandVector &Operands, MCContext &Ctx,
91 const MCInstrInfo &MII,
92 MCStreamer &Out) {
89 // FIXME: take into account load/store alignment.
90 if (AccessSize < 8)
91 InstrumentMemOperandSmallImpl(MemOp, AccessSize, IsWrite, Ctx, Out);
92 else
93 InstrumentMemOperandLargeImpl(MemOp, AccessSize, IsWrite, Ctx, Out);
94 }
95
96 void X86AddressSanitizer::InstrumentMOV(
97 const MCInst &Inst, OperandVector &Operands, MCContext &Ctx,
98 const MCInstrInfo &MII, MCStreamer &Out) {
9399 // Access size in bytes.
94100 unsigned AccessSize = 0;
95101
135141
136142 class X86AddressSanitizer32 : public X86AddressSanitizer {
137143 public:
144 static const long kShadowOffset = 0x20000000;
145
138146 X86AddressSanitizer32(const MCSubtargetInfo &STI)
139147 : X86AddressSanitizer(STI) {}
140148 virtual ~X86AddressSanitizer32() {}
141149
142 virtual void InstrumentMemOperandImpl(X86Operand &Op, unsigned AccessSize,
143 bool IsWrite, MCContext &Ctx,
144 MCStreamer &Out) override;
150 virtual void InstrumentMemOperandSmallImpl(
151 X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
152 MCStreamer &Out) override;
153 virtual void InstrumentMemOperandLargeImpl(
154 X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
155 MCStreamer &Out) override;
156
157 private:
158 void EmitCallAsanReport(MCContext &Ctx, MCStreamer &Out, unsigned AccessSize,
159 bool IsWrite, unsigned AddressReg) {
160 EmitInstruction(Out, MCInstBuilder(X86::CLD));
161 EmitInstruction(Out, MCInstBuilder(X86::MMX_EMMS));
162
163 EmitInstruction(Out, MCInstBuilder(X86::AND64ri8).addReg(X86::ESP)
164 .addReg(X86::ESP).addImm(-16));
165 EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(AddressReg));
166
167
168 const std::string& Fn = FuncName(AccessSize, IsWrite);
169 MCSymbol *FnSym = Ctx.GetOrCreateSymbol(StringRef(Fn));
170 const MCSymbolRefExpr *FnExpr =
171 MCSymbolRefExpr::Create(FnSym, MCSymbolRefExpr::VK_PLT, Ctx);
172 EmitInstruction(Out, MCInstBuilder(X86::CALLpcrel32).addExpr(FnExpr));
173 }
145174 };
146175
147 void X86AddressSanitizer32::InstrumentMemOperandImpl(X86Operand &Op,
148 unsigned AccessSize,
149 bool IsWrite,
150 MCContext &Ctx,
151 MCStreamer &Out) {
152 // FIXME: emit .cfi directives for correct stack unwinding.
176 void X86AddressSanitizer32::InstrumentMemOperandSmallImpl(
177 X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
178 MCStreamer &Out) {
153179 EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX));
180 EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::ECX));
181 EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EDX));
182 EmitInstruction(Out, MCInstBuilder(X86::PUSHF32));
183
154184 {
155185 MCInst Inst;
156186 Inst.setOpcode(X86::LEA32r);
158188 Op.addMemOperands(Inst, 5);
159189 EmitInstruction(Out, Inst);
160190 }
191
192 EmitInstruction(
193 Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EAX));
194 EmitInstruction(Out, MCInstBuilder(X86::SHR32ri).addReg(X86::ECX)
195 .addReg(X86::ECX).addImm(3));
196
197 {
198 MCInst Inst;
199 Inst.setOpcode(X86::MOV8rm);
200 Inst.addOperand(MCOperand::CreateReg(X86::CL));
201 const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
202 std::unique_ptr Op(
203 X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc()));
204 Op->addMemOperands(Inst, 5);
205 EmitInstruction(Out, Inst);
206 }
207
208 EmitInstruction(Out,
209 MCInstBuilder(X86::TEST8rr).addReg(X86::CL).addReg(X86::CL));
210 MCSymbol *DoneSym = Ctx.CreateTempSymbol();
211 const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
212 EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
213
214 EmitInstruction(
215 Out, MCInstBuilder(X86::MOV32rr).addReg(X86::EDX).addReg(X86::EAX));
216 EmitInstruction(Out, MCInstBuilder(X86::AND32ri).addReg(X86::EDX)
217 .addReg(X86::EDX).addImm(7));
218
219 switch (AccessSize) {
220 case 1:
221 break;
222 case 2: {
223 MCInst Inst;
224 Inst.setOpcode(X86::LEA32r);
225 Inst.addOperand(MCOperand::CreateReg(X86::EDX));
226
227 const MCExpr *Disp = MCConstantExpr::Create(1, Ctx);
228 std::unique_ptr Op(
229 X86Operand::CreateMem(0, Disp, X86::EDX, 0, 1, SMLoc(), SMLoc()));
230 Op->addMemOperands(Inst, 5);
231 EmitInstruction(Out, Inst);
232 break;
233 }
234 case 4:
235 EmitInstruction(Out, MCInstBuilder(X86::ADD32ri8).addReg(X86::EDX)
236 .addReg(X86::EDX).addImm(3));
237 break;
238 default:
239 assert(false && "Incorrect access size");
240 break;
241 }
242
243 EmitInstruction(
244 Out, MCInstBuilder(X86::MOVSX32rr8).addReg(X86::ECX).addReg(X86::CL));
245 EmitInstruction(
246 Out, MCInstBuilder(X86::CMP32rr).addReg(X86::EDX).addReg(X86::ECX));
247 EmitInstruction(Out, MCInstBuilder(X86::JL_4).addExpr(DoneExpr));
248
249 EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite, X86::EAX);
250 EmitLabel(Out, DoneSym);
251
252 EmitInstruction(Out, MCInstBuilder(X86::POPF32));
253 EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EDX));
254 EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::ECX));
255 EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EAX));
256 }
257
258 void X86AddressSanitizer32::InstrumentMemOperandLargeImpl(
259 X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
260 MCStreamer &Out) {
161261 EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX));
162 {
163 const std::string Func = FuncName(AccessSize, IsWrite);
164 const MCSymbol *FuncSym = Ctx.GetOrCreateSymbol(StringRef(Func));
165 const MCSymbolRefExpr *FuncExpr =
166 MCSymbolRefExpr::Create(FuncSym, MCSymbolRefExpr::VK_PLT, Ctx);
167 EmitInstruction(Out, MCInstBuilder(X86::CALLpcrel32).addExpr(FuncExpr));
168 }
169 EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EAX));
262 EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::ECX));
263 EmitInstruction(Out, MCInstBuilder(X86::PUSHF32));
264
265 {
266 MCInst Inst;
267 Inst.setOpcode(X86::LEA32r);
268 Inst.addOperand(MCOperand::CreateReg(X86::EAX));
269 Op.addMemOperands(Inst, 5);
270 EmitInstruction(Out, Inst);
271 }
272 EmitInstruction(
273 Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EAX));
274 EmitInstruction(Out, MCInstBuilder(X86::SHR32ri).addReg(X86::ECX)
275 .addReg(X86::ECX).addImm(3));
276 {
277 MCInst Inst;
278 switch (AccessSize) {
279 case 8:
280 Inst.setOpcode(X86::CMP8mi);
281 break;
282 case 16:
283 Inst.setOpcode(X86::CMP16mi);
284 break;
285 default:
286 assert(false && "Incorrect access size");
287 break;
288 }
289 const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
290 std::unique_ptr Op(
291 X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc()));
292 Op->addMemOperands(Inst, 5);
293 Inst.addOperand(MCOperand::CreateImm(0));
294 EmitInstruction(Out, Inst);
295 }
296 MCSymbol *DoneSym = Ctx.CreateTempSymbol();
297 const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
298 EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
299
300 EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite, X86::EAX);
301 EmitLabel(Out, DoneSym);
302
303 EmitInstruction(Out, MCInstBuilder(X86::POPF32));
304 EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::ECX));
170305 EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EAX));
171306 }
172307
173308 class X86AddressSanitizer64 : public X86AddressSanitizer {
174309 public:
310 static const long kShadowOffset = 0x7fff8000;
311
175312 X86AddressSanitizer64(const MCSubtargetInfo &STI)
176313 : X86AddressSanitizer(STI) {}
177314 virtual ~X86AddressSanitizer64() {}
178315
179 virtual void InstrumentMemOperandImpl(X86Operand &Op, unsigned AccessSize,
180 bool IsWrite, MCContext &Ctx,
181 MCStreamer &Out) override;
182 };
183
184 void X86AddressSanitizer64::InstrumentMemOperandImpl(X86Operand &Op,
185 unsigned AccessSize,
186 bool IsWrite,
187 MCContext &Ctx,
188 MCStreamer &Out) {
189 // FIXME: emit .cfi directives for correct stack unwinding.
190
191 // Set %rsp below current red zone (128 bytes wide) using LEA instruction to
192 // preserve flags.
193 {
316 virtual void InstrumentMemOperandSmallImpl(
317 X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
318 MCStreamer &Out) override;
319 virtual void InstrumentMemOperandLargeImpl(
320 X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
321 MCStreamer &Out) override;
322
323 private:
324 void EmitAdjustRSP(MCContext &Ctx, MCStreamer &Out, long Offset) {
194325 MCInst Inst;
195326 Inst.setOpcode(X86::LEA64r);
196327 Inst.addOperand(MCOperand::CreateReg(X86::RSP));
197328
198 const MCExpr *Disp = MCConstantExpr::Create(-128, Ctx);
329 const MCExpr *Disp = MCConstantExpr::Create(Offset, Ctx);
199330 std::unique_ptr Op(
200331 X86Operand::CreateMem(0, Disp, X86::RSP, 0, 1, SMLoc(), SMLoc()));
201332 Op->addMemOperands(Inst, 5);
202333 EmitInstruction(Out, Inst);
203334 }
335
336 void EmitCallAsanReport(MCContext &Ctx, MCStreamer &Out, unsigned AccessSize,
337 bool IsWrite) {
338 EmitInstruction(Out, MCInstBuilder(X86::CLD));
339 EmitInstruction(Out, MCInstBuilder(X86::MMX_EMMS));
340
341 EmitInstruction(Out, MCInstBuilder(X86::AND64ri8).addReg(X86::RSP)
342 .addReg(X86::RSP).addImm(-16));
343
344 const std::string& Fn = FuncName(AccessSize, IsWrite);
345 MCSymbol *FnSym = Ctx.GetOrCreateSymbol(StringRef(Fn));
346 const MCSymbolRefExpr *FnExpr =
347 MCSymbolRefExpr::Create(FnSym, MCSymbolRefExpr::VK_PLT, Ctx);
348 EmitInstruction(Out, MCInstBuilder(X86::CALL64pcrel32).addExpr(FnExpr));
349 }
350 };
351
352 void X86AddressSanitizer64::InstrumentMemOperandSmallImpl(
353 X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
354 MCStreamer &Out) {
355 EmitAdjustRSP(Ctx, Out, -128);
356 EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RAX));
357 EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RCX));
204358 EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RDI));
359 EmitInstruction(Out, MCInstBuilder(X86::PUSHF64));
205360 {
206361 MCInst Inst;
207362 Inst.setOpcode(X86::LEA64r);
209364 Op.addMemOperands(Inst, 5);
210365 EmitInstruction(Out, Inst);
211366 }
212 {
213 const std::string Func = FuncName(AccessSize, IsWrite);
214 const MCSymbol *FuncSym = Ctx.GetOrCreateSymbol(StringRef(Func));
215 const MCSymbolRefExpr *FuncExpr =
216 MCSymbolRefExpr::Create(FuncSym, MCSymbolRefExpr::VK_PLT, Ctx);
217 EmitInstruction(Out, MCInstBuilder(X86::CALL64pcrel32).addExpr(FuncExpr));
218 }
367 EmitInstruction(
368 Out, MCInstBuilder(X86::MOV64rr).addReg(X86::RAX).addReg(X86::RDI));
369 EmitInstruction(Out, MCInstBuilder(X86::SHR64ri).addReg(X86::RAX)
370 .addReg(X86::RAX).addImm(3));
371 {
372 MCInst Inst;
373 Inst.setOpcode(X86::MOV8rm);
374 Inst.addOperand(MCOperand::CreateReg(X86::AL));
375 const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
376 std::unique_ptr Op(
377 X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc()));
378 Op->addMemOperands(Inst, 5);
379 EmitInstruction(Out, Inst);
380 }
381
382 EmitInstruction(Out,
383 MCInstBuilder(X86::TEST8rr).addReg(X86::AL).addReg(X86::AL));
384 MCSymbol *DoneSym = Ctx.CreateTempSymbol();
385 const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
386 EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
387
388 EmitInstruction(
389 Out, MCInstBuilder(X86::MOV32rr).addReg(X86::ECX).addReg(X86::EDI));
390 EmitInstruction(Out, MCInstBuilder(X86::AND32ri).addReg(X86::ECX)
391 .addReg(X86::ECX).addImm(7));
392
393 switch (AccessSize) {
394 case 1:
395 break;
396 case 2: {
397 MCInst Inst;
398 Inst.setOpcode(X86::LEA32r);
399 Inst.addOperand(MCOperand::CreateReg(X86::ECX));
400
401 const MCExpr *Disp = MCConstantExpr::Create(1, Ctx);
402 std::unique_ptr Op(
403 X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc()));
404 Op->addMemOperands(Inst, 5);
405 EmitInstruction(Out, Inst);
406 break;
407 }
408 case 4:
409 EmitInstruction(Out, MCInstBuilder(X86::ADD32ri8).addReg(X86::ECX)
410 .addReg(X86::ECX).addImm(3));
411 break;
412 default:
413 assert(false && "Incorrect access size");
414 break;
415 }
416
417 EmitInstruction(
418 Out, MCInstBuilder(X86::MOVSX32rr8).addReg(X86::EAX).addReg(X86::AL));
419 EmitInstruction(
420 Out, MCInstBuilder(X86::CMP32rr).addReg(X86::ECX).addReg(X86::EAX));
421 EmitInstruction(Out, MCInstBuilder(X86::JL_4).addExpr(DoneExpr));
422
423 EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite);
424 EmitLabel(Out, DoneSym);
425
426 EmitInstruction(Out, MCInstBuilder(X86::POPF64));
219427 EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RDI));
220
221 // Restore old %rsp value.
428 EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RCX));
429 EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RAX));
430 EmitAdjustRSP(Ctx, Out, 128);
431 }
432
433 void X86AddressSanitizer64::InstrumentMemOperandLargeImpl(
434 X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
435 MCStreamer &Out) {
436 EmitAdjustRSP(Ctx, Out, -128);
437 EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RAX));
438 EmitInstruction(Out, MCInstBuilder(X86::PUSHF64));
439
222440 {
223441 MCInst Inst;
224442 Inst.setOpcode(X86::LEA64r);
225 Inst.addOperand(MCOperand::CreateReg(X86::RSP));
226
227 const MCExpr *Disp = MCConstantExpr::Create(128, Ctx);
228 std::unique_ptr Op(
229 X86Operand::CreateMem(0, Disp, X86::RSP, 0, 1, SMLoc(), SMLoc()));
230 Op->addMemOperands(Inst, 5);
231 EmitInstruction(Out, Inst);
232 }
443 Inst.addOperand(MCOperand::CreateReg(X86::RAX));
444 Op.addMemOperands(Inst, 5);
445 EmitInstruction(Out, Inst);
446 }
447 EmitInstruction(Out, MCInstBuilder(X86::SHR64ri).addReg(X86::RAX)
448 .addReg(X86::RAX).addImm(3));
449 {
450 MCInst Inst;
451 switch (AccessSize) {
452 case 8:
453 Inst.setOpcode(X86::CMP8mi);
454 break;
455 case 16:
456 Inst.setOpcode(X86::CMP16mi);
457 break;
458 default:
459 assert(false && "Incorrect access size");
460 break;
461 }
462 const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
463 std::unique_ptr Op(
464 X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc()));
465 Op->addMemOperands(Inst, 5);
466 Inst.addOperand(MCOperand::CreateImm(0));
467 EmitInstruction(Out, Inst);
468 }
469
470 MCSymbol *DoneSym = Ctx.CreateTempSymbol();
471 const MCExpr *DoneExpr = MCSymbolRefExpr::Create(DoneSym, Ctx);
472 EmitInstruction(Out, MCInstBuilder(X86::JE_4).addExpr(DoneExpr));
473
474 EmitCallAsanReport(Ctx, Out, AccessSize, IsWrite);
475 EmitLabel(Out, DoneSym);
476
477 EmitInstruction(Out, MCInstBuilder(X86::POPF64));
478 EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RAX));
479 EmitAdjustRSP(Ctx, Out, 128);
233480 }
234481
235482 } // End anonymous namespace
237484 X86AsmInstrumentation::X86AsmInstrumentation() {}
238485 X86AsmInstrumentation::~X86AsmInstrumentation() {}
239486
240 void X86AsmInstrumentation::InstrumentInstruction(const MCInst &Inst,
241 OperandVector &Operands,
242 MCContext &Ctx,
243 const MCInstrInfo &MII,
244 MCStreamer &Out) {}
487 void X86AsmInstrumentation::InstrumentInstruction(
488 const MCInst &Inst, OperandVector &Operands, MCContext &Ctx,
489 const MCInstrInfo &MII, MCStreamer &Out) {}
245490
246491 X86AsmInstrumentation *
247492 CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions,
33 target triple = "x86_64-unknown-linux-gnu"
44
55 ; CHECK-LABEL: mov_no_attr
6 ; CHECK-NOT: callq __sanitizer_sanitize_load8@PLT
7 ; CHECK-NOT: callq __sanitizer_sanitize_store8@PLT
6 ; CHECK-NOT: callq __asan_report_load@PLT
7 ; CHECK-NOT: callq __asan_report_store@PLT
88 define void @mov_no_attr(i64* %dst, i64* %src) {
99 tail call void asm sideeffect "movq ($1), %rax \0A\09movq %rax, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i64* %dst, i64* %src)
1010 ret void
1111 }
1212
1313 ; CHECK-LABEL: mov_sanitize
14 ; CHECK: callq __sanitizer_sanitize_load8@PLT
15 ; CHECK: callq __sanitizer_sanitize_store8@PLT
14 ; CHECK: callq __asan_report_load8@PLT
15 ; CHECK: callq __asan_report_store8@PLT
1616 define void @mov_sanitize(i64* %dst, i64* %src) sanitize_address {
1717 tail call void asm sideeffect "movq ($1), %rax \0A\09movq %rax, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i64* %dst, i64* %src)
1818 ret void
44
55 ; CHECK-LABEL: mov1b
66 ; CHECK: leaq -128(%rsp), %rsp
7 ; CHECK-NEXT: pushq %rax
8 ; CHECK-NEXT: pushq %rcx
79 ; CHECK-NEXT: pushq %rdi
10 ; CHECK-NEXT: pushfq
811 ; CHECK-NEXT: leaq {{.*}}, %rdi
9 ; CHECK-NEXT: callq __sanitizer_sanitize_load1@PLT
12 ; CHECK-NEXT: movq %rdi, %rax
13 ; CHECK-NEXT: shrq $3, %rax
14 ; CHECK-NEXT: movb 2147450880(%rax), %al
15 ; CHECK-NEXT: testb %al, %al
16 ; CHECK-NEXT: je [[A:.*]]
17 ; CHECK-NEXT: movl %edi, %ecx
18 ; CHECK-NEXT: andl $7, %ecx
19 ; CHECK-NEXT: movsbl %al, %eax
20 ; CHECK-NEXT: cmpl %eax, %ecx
21 ; CHECK-NEXT: jl {{.*}}
22 ; CHECK-NEXT: cld
23 ; CHECK-NEXT: emms
24 ; CHECK-NEXT: andq $-16, %rsp
25 ; CHECK-NEXT: callq __asan_report_load1@PLT
26 ; CHECK-NEXT: [[A]]:
27 ; CHECK-NEXT: popfq
1028 ; CHECK-NEXT: popq %rdi
29 ; CHECK-NEXT: popq %rcx
30 ; CHECK-NEXT: popq %rax
1131 ; CHECK-NEXT: leaq 128(%rsp), %rsp
1232
1333 ; CHECK: leaq -128(%rsp), %rsp
14 ; CHECK-NEXT: pushq %rdi
15 ; CHECK-NEXT: leaq {{.*}}, %rdi
16 ; CHECK-NEXT: callq __sanitizer_sanitize_store1@PLT
17 ; CHECK-NEXT: popq %rdi
18 ; CHECK-NEXT: leaq 128(%rsp), %rsp
34 ; CHECK: callq __asan_report_store1@PLT
35 ; CHECK: leaq 128(%rsp), %rsp
1936
2037 ; CHECK: movb {{.*}}, {{.*}}
2138 define void @mov1b(i8* %dst, i8* %src) #0 {
2643
2744 ; CHECK-LABEL: mov2b
2845 ; CHECK: leaq -128(%rsp), %rsp
29 ; CHECK-NEXT: pushq %rdi
30 ; CHECK-NEXT: leaq {{.*}}, %rdi
31 ; CHECK-NEXT: callq __sanitizer_sanitize_load2@PLT
32 ; CHECK-NEXT: popq %rdi
33 ; CHECK-NEXT: leaq 128(%rsp), %rsp
46 ; CHECK: leal 1(%ecx), %ecx
47 ; CHECK: callq __asan_report_load2@PLT
48 ; CHECK: leaq 128(%rsp), %rsp
3449
3550 ; CHECK: leaq -128(%rsp), %rsp
36 ; CHECK-NEXT: pushq %rdi
37 ; CHECK-NEXT: leaq {{.*}}, %rdi
38 ; CHECK-NEXT: callq __sanitizer_sanitize_store2@PLT
39 ; CHECK-NEXT: popq %rdi
40 ; CHECK-NEXT: leaq 128(%rsp), %rsp
51 ; CHECK: leal 1(%ecx), %ecx
52 ; CHECK: callq __asan_report_store2@PLT
53 ; CHECK: leaq 128(%rsp), %rsp
4154
4255 ; CHECK: movw {{.*}}, {{.*}}
4356 define void @mov2b(i16* %dst, i16* %src) #0 {
4861
4962 ; CHECK-LABEL: mov4b
5063 ; CHECK: leaq -128(%rsp), %rsp
51 ; CHECK-NEXT: pushq %rdi
52 ; CHECK-NEXT: leaq {{.*}}, %rdi
53 ; CHECK-NEXT: callq __sanitizer_sanitize_load4@PLT
54 ; CHECK-NEXT: popq %rdi
55 ; CHECK-NEXT: leaq 128(%rsp), %rsp
64 ; CHECK: addl $3, %ecx
65 ; CHECK: callq __asan_report_load4@PLT
66 ; CHECK: leaq 128(%rsp), %rsp
5667
5768 ; CHECK: leaq -128(%rsp), %rsp
58 ; CHECK-NEXT: pushq %rdi
59 ; CHECK-NEXT: leaq {{.*}}, %rdi
60 ; CHECK-NEXT: callq __sanitizer_sanitize_store4@PLT
61 ; CHECK-NEXT: popq %rdi
62 ; CHECK-NEXT: leaq 128(%rsp), %rsp
69 ; CHECK: addl $3, %ecx
70 ; CHECK: callq __asan_report_store4@PLT
71 ; CHECK: leaq 128(%rsp), %rsp
6372
6473 ; CHECK: movl {{.*}}, {{.*}}
6574 define void @mov4b(i32* %dst, i32* %src) #0 {
7079
7180 ; CHECK-LABEL: mov8b
7281 ; CHECK: leaq -128(%rsp), %rsp
73 ; CHECK-NEXT: pushq %rdi
74 ; CHECK-NEXT: leaq {{.*}}, %rdi
75 ; CHECK-NEXT: callq __sanitizer_sanitize_load8@PLT
76 ; CHECK-NEXT: popq %rdi
82 ; CHECK-NEXT: pushq %rax
83 ; CHECK-NEXT: pushfq
84 ; CHECK-NEXT: leaq {{.*}}, %rax
85 ; CHECK-NEXT: shrq $3, %rax
86 ; CHECK-NEXT: cmpb $0, 2147450880(%rax)
87 ; CHECK-NEXT: je [[A:.*]]
88 ; CHECK-NEXT: cld
89 ; CHECK-NEXT: emms
90 ; CHECK-NEXT: andq $-16, %rsp
91 ; CHECK-NEXT: callq __asan_report_load8@PLT
92 ; CHECK-NEXT: [[A]]:
93 ; CHECK-NEXT: popfq
94 ; CHECK-NEXT: popq %rax
7795 ; CHECK-NEXT: leaq 128(%rsp), %rsp
7896
7997 ; CHECK: leaq -128(%rsp), %rsp
80 ; CHECK-NEXT: pushq %rdi
81 ; CHECK-NEXT: leaq {{.*}}, %rdi
82 ; CHECK-NEXT: callq __sanitizer_sanitize_store8@PLT
83 ; CHECK-NEXT: popq %rdi
98 ; CHECK-NEXT: pushq %rax
99 ; CHECK-NEXT: pushfq
100 ; CHECK-NEXT: leaq {{.*}}, %rax
101 ; CHECK-NEXT: shrq $3, %rax
102 ; CHECK-NEXT: cmpb $0, 2147450880(%rax)
103 ; CHECK-NEXT: je [[A:.*]]
104 ; CHECK-NEXT: cld
105 ; CHECK-NEXT: emms
106 ; CHECK-NEXT: andq $-16, %rsp
107 ; CHECK-NEXT: callq __asan_report_store8@PLT
108 ; CHECK-NEXT: [[A]]:
109 ; CHECK-NEXT: popfq
110 ; CHECK-NEXT: popq %rax
84111 ; CHECK-NEXT: leaq 128(%rsp), %rsp
85112
86113 ; CHECK: movq {{.*}}, {{.*}}
92119
93120 ; CHECK-LABEL: mov16b
94121 ; CHECK: leaq -128(%rsp), %rsp
95 ; CHECK-NEXT: pushq %rdi
96 ; CHECK-NEXT: leaq {{.*}}, %rdi
97 ; CHECK-NEXT: callq __sanitizer_sanitize_load16@PLT
98 ; CHECK-NEXT: popq %rdi
99 ; CHECK-NEXT: leaq 128(%rsp), %rsp
122 ; CHECK: cmpw $0, 2147450880(%rax)
123 ; CHECK: callq __asan_report_load16@PLT
124 ; CHECK: leaq 128(%rsp), %rsp
100125
101126 ; CHECK: leaq -128(%rsp), %rsp
102 ; CHECK-NEXT: pushq %rdi
103 ; CHECK-NEXT: leaq {{.*}}, %rdi
104 ; CHECK-NEXT: callq __sanitizer_sanitize_store16@PLT
105 ; CHECK-NEXT: popq %rdi
106 ; CHECK-NEXT: leaq 128(%rsp), %rsp
127 ; CHECK: cmpw $0, 2147450880(%rax)
128 ; CHECK: callq __asan_report_store16@PLT
129 ; CHECK: leaq 128(%rsp), %rsp
107130
108131 ; CHECK: movaps {{.*}}, {{.*}}
109132 define void @mov16b(<2 x i64>* %dst, <2 x i64>* %src) #0 {
66 # CHECK-LABEL: mov1b:
77 #
88 # CHECK: leaq -128(%rsp), %rsp
9 # CHECK-NEXT: pushq %rdi
10 # CHECK-NEXT: leaq (%rsi), %rdi
11 # CHECK-NEXT: callq __sanitizer_sanitize_load1@PLT
12 # CHECK-NEXT: popq %rdi
13 # CHECK-NEXT: leaq 128(%rsp), %rsp
9 # CHECK: callq __asan_report_load1@PLT
10 # CHECK: leaq 128(%rsp), %rsp
1411 #
1512 # CHECK-NEXT: movb (%rsi), %al
1613 #
1714 # CHECK-NEXT: leaq -128(%rsp), %rsp
18 # CHECK-NEXT: pushq %rdi
19 # CHECK-NEXT: leaq (%rdi), %rdi
20 # CHECK-NEXT: callq __sanitizer_sanitize_store1@PLT
21 # CHECK-NEXT: popq %rdi
22 # CHECK-NEXT: leaq 128(%rsp), %rsp
15 # CHECK: callq __asan_report_store1@PLT
16 # CHECK: leaq 128(%rsp), %rsp
2317 #
2418 # CHECK-NEXT: movb %al, (%rdi)
2519 mov1b: # @mov1b
4135 # CHECK-LABEL: mov16b:
4236 #
4337 # CHECK: leaq -128(%rsp), %rsp
44 # CHECK-NEXT: pushq %rdi
45 # CHECK-NEXT: leaq (%rsi), %rdi
46 # CHECK-NEXT: callq __sanitizer_sanitize_load16@PLT
47 # CHECK-NEXT: popq %rdi
48 # CHECK-NEXT: leaq 128(%rsp), %rsp
38 # CHECK: callq __asan_report_load16@PLT
39 # CHECK: leaq 128(%rsp), %rsp
4940 #
5041 # CHECK-NEXT: movaps (%rsi), %xmm0
5142 #
5243 # CHECK-NEXT: leaq -128(%rsp), %rsp
53 # CHECK-NEXT: pushq %rdi
54 # CHECK-NEXT: leaq (%rdi), %rdi
55 # CHECK-NEXT: callq __sanitizer_sanitize_store16@PLT
56 # CHECK-NEXT: popq %rdi
57 # CHECK-NEXT: leaq 128(%rsp), %rsp
44 # CHECK: callq __asan_report_store16@PLT
45 # CHECK: leaq 128(%rsp), %rsp
5846 #
5947 # CHECK-NEXT: movaps %xmm0, (%rdi)
6048 mov16b: # @mov16b
44 .align 16, 0x90
55 .type mov1b,@function
66 # CHECK-LABEL: mov1b
7 # CHECK-NOT: callq __sanitizer_sanitize_load1@PLT
8 # CHECK-NOT: callq __sanitizer_sanitize_store1@PLT
7 # CHECK-NOT: callq __asan_report_load1@PLT
8 # CHECK-NOT: callq __asan_report_store1@PLT
99 mov1b: # @mov1b
1010 .cfi_startproc
1111 # BB#0:
66 # CHECK-LABEL: swap:
77 #
88 # CHECK: leaq -128(%rsp), %rsp
9 # CHECK-NEXT: pushq %rdi
10 # CHECK-NEXT: leaq (%rcx), %rdi
11 # CHECK-NEXT: callq __sanitizer_sanitize_load8@PLT
12 # CHECK-NEXT: popq %rdi
13 # CHECK-NEXT: leaq 128(%rsp), %rsp
9 # CHECK: callq __asan_report_load8@PLT
10 # CHECK: leaq 128(%rsp), %rsp
1411 #
1512 # CHECK-NEXT: movq (%rcx), %rax
1613 #
1714 # CHECK-NEXT: leaq -128(%rsp), %rsp
18 # CHECK-NEXT: pushq %rdi
19 # CHECK-NEXT: leaq (%rdx), %rdi
20 # CHECK-NEXT: callq __sanitizer_sanitize_load8@PLT
21 # CHECK-NEXT: popq %rdi
22 # CHECK-NEXT: leaq 128(%rsp), %rsp
15 # CHECK: callq __asan_report_load8@PLT
16 # CHECK: leaq 128(%rsp), %rsp
2317 #
2418 # CHECK-NEXT: movq (%rdx), %rbx
2519 #
26 # CHECK: leaq -128(%rsp), %rsp
27 # CHECK-NEXT: pushq %rdi
28 # CHECK-NEXT: leaq (%rcx), %rdi
29 # CHECK-NEXT: callq __sanitizer_sanitize_store8@PLT
30 # CHECK-NEXT: popq %rdi
31 # CHECK-NEXT: leaq 128(%rsp), %rsp
20 # CHECK-NEXT: leaq -128(%rsp), %rsp
21 # CHECK: callq __asan_report_store8@PLT
22 # CHECK: leaq 128(%rsp), %rsp
3223 #
3324 # CHECK-NEXT: movq %rbx, (%rcx)
3425 #
3526 # CHECK-NEXT: leaq -128(%rsp), %rsp
36 # CHECK-NEXT: pushq %rdi
37 # CHECK-NEXT: leaq (%rdx), %rdi
38 # CHECK-NEXT: callq __sanitizer_sanitize_store8@PLT
39 # CHECK-NEXT: popq %rdi
40 # CHECK-NEXT: leaq 128(%rsp), %rsp
27 # CHECK: callq __asan_report_store8@PLT
28 # CHECK: leaq 128(%rsp), %rsp
4129 #
4230 # CHECK-NEXT: movq %rax, (%rdx)
4331 swap: # @swap