From bf7cc396c61127de08fb92eb558c68c3b2552c12 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Fri, 14 Mar 2014 08:58:04 +0000 Subject: AddressSanitizer instrumentation for MOV and MOVAPS. This is an initial version of *Sanitizer instrumentation of assembly code. Patch by Yuri Gorshenin. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203908 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/AsmParser/CMakeLists.txt | 1 + lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp | 236 +++++++++++++++++++++ lib/Target/X86/AsmParser/X86AsmInstrumentation.h | 46 ++++ lib/Target/X86/AsmParser/X86AsmParser.cpp | 24 ++- .../AddressSanitizer/X86/asm_mov.ll | 123 +++++++++++ .../Instrumentation/AddressSanitizer/X86/asm_mov.s | 76 +++++++ .../X86/asm_mov_no_instrumentation.s | 44 ++++ 7 files changed, 547 insertions(+), 3 deletions(-) create mode 100644 lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp create mode 100644 lib/Target/X86/AsmParser/X86AsmInstrumentation.h create mode 100644 test/Instrumentation/AddressSanitizer/X86/asm_mov.ll create mode 100644 test/Instrumentation/AddressSanitizer/X86/asm_mov.s create mode 100644 test/Instrumentation/AddressSanitizer/X86/asm_mov_no_instrumentation.s diff --git a/lib/Target/X86/AsmParser/CMakeLists.txt b/lib/Target/X86/AsmParser/CMakeLists.txt index 14544267bf..b022a41b19 100644 --- a/lib/Target/X86/AsmParser/CMakeLists.txt +++ b/lib/Target/X86/AsmParser/CMakeLists.txt @@ -1,3 +1,4 @@ add_llvm_library(LLVMX86AsmParser + X86AsmInstrumentation.cpp X86AsmParser.cpp ) diff --git a/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp b/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp new file mode 100644 index 0000000000..db292284b5 --- /dev/null +++ b/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp @@ -0,0 +1,236 @@ +//===-- X86AsmInstrumentation.cpp - Instrument X86 inline assembly C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/X86BaseInfo.h" +#include "X86AsmInstrumentation.h" +#include "X86Operand.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstBuilder.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Compiler.h" +#include "llvm/MC/MCParser/MCParsedAsmOperand.h" + +namespace llvm { +namespace { + +static cl::opt ClAsanInstrumentInlineAssembly( + "asan-instrument-inline-assembly", cl::desc("instrument inline assembly"), + cl::Hidden, cl::init(false)); + +bool IsStackReg(unsigned Reg) { + return Reg == X86::RSP || Reg == X86::ESP || Reg == X86::SP; +} + +std::string FuncName(unsigned AccessSize, bool IsWrite) { + return std::string("__sanitizer_sanitize_") + (IsWrite ? "store" : "load") + + (utostr(AccessSize)); +} + +class X86AddressSanitizer : public X86AsmInstrumentation { +public: + X86AddressSanitizer(MCSubtargetInfo &sti) : STI(sti) {} + virtual ~X86AddressSanitizer() {} + + // X86AsmInstrumentation implementation: + virtual void InstrumentInstruction( + const MCInst &Inst, SmallVectorImpl &Operands, + MCContext &Ctx, MCStreamer &Out) override { + InstrumentMOV(Inst, Operands, Ctx, Out); + } + + // Should be implemented differently in x86_32 and x86_64 subclasses. + virtual void InstrumentMemOperandImpl(X86Operand *Op, unsigned AccessSize, + bool IsWrite, MCContext &Ctx, + MCStreamer &Out) = 0; + + void InstrumentMemOperand(MCParsedAsmOperand *Op, unsigned AccessSize, + bool IsWrite, MCContext &Ctx, MCStreamer &Out); + void InstrumentMOV(const MCInst &Inst, + SmallVectorImpl &Operands, + MCContext &Ctx, MCStreamer &Out); + void EmitInstruction(MCStreamer &Out, const MCInst &Inst) { + Out.EmitInstruction(Inst, STI); + } + +protected: + MCSubtargetInfo &STI; +}; + +void X86AddressSanitizer::InstrumentMemOperand( + MCParsedAsmOperand *Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx, + MCStreamer &Out) { + assert(Op && Op->isMem() && "Op should be a memory operand."); + assert((AccessSize & (AccessSize - 1)) == 0 && AccessSize <= 16 && + "AccessSize should be a power of two, less or equal than 16."); + + X86Operand *MemOp = static_cast(Op); + // FIXME: get rid of this limitation. + if (IsStackReg(MemOp->getMemBaseReg()) || IsStackReg(MemOp->getMemIndexReg())) + return; + + InstrumentMemOperandImpl(MemOp, AccessSize, IsWrite, Ctx, Out); +} + +void X86AddressSanitizer::InstrumentMOV( + const MCInst &Inst, SmallVectorImpl &Operands, + MCContext &Ctx, MCStreamer &Out) { + // Access size in bytes. + unsigned AccessSize = 0; + unsigned long OpIx = Operands.size(); + switch (Inst.getOpcode()) { + case X86::MOV8mi: + case X86::MOV8mr: + AccessSize = 1; + OpIx = 2; + break; + case X86::MOV8rm: + AccessSize = 1; + OpIx = 1; + break; + case X86::MOV16mi: + case X86::MOV16mr: + AccessSize = 2; + OpIx = 2; + break; + case X86::MOV16rm: + AccessSize = 2; + OpIx = 1; + break; + case X86::MOV32mi: + case X86::MOV32mr: + AccessSize = 4; + OpIx = 2; + break; + case X86::MOV32rm: + AccessSize = 4; + OpIx = 1; + break; + case X86::MOV64mi32: + case X86::MOV64mr: + AccessSize = 8; + OpIx = 2; + break; + case X86::MOV64rm: + AccessSize = 8; + OpIx = 1; + break; + case X86::MOVAPDmr: + case X86::MOVAPSmr: + AccessSize = 16; + OpIx = 2; + break; + case X86::MOVAPDrm: + case X86::MOVAPSrm: + AccessSize = 16; + OpIx = 1; + break; + } + if (OpIx >= Operands.size()) + return; + + const bool IsWrite = (OpIx != 1); + InstrumentMemOperand(Operands[OpIx], AccessSize, IsWrite, Ctx, Out); +} + +class X86AddressSanitizer32 : public X86AddressSanitizer { +public: + X86AddressSanitizer32(MCSubtargetInfo &sti) : X86AddressSanitizer(sti) {} + virtual ~X86AddressSanitizer32() {} + + virtual void InstrumentMemOperandImpl(X86Operand *Op, unsigned AccessSize, + bool IsWrite, MCContext &Ctx, + MCStreamer &Out) override; +}; + +void X86AddressSanitizer32::InstrumentMemOperandImpl( + X86Operand *Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx, + MCStreamer &Out) { + // FIXME: emit .cfi directives for correct stack unwinding. + EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX)); + { + MCInst Inst; + Inst.setOpcode(X86::LEA32r); + Inst.addOperand(MCOperand::CreateReg(X86::EAX)); + Op->addMemOperands(Inst, 5); + EmitInstruction(Out, Inst); + } + EmitInstruction(Out, MCInstBuilder(X86::PUSH32r).addReg(X86::EAX)); + { + const std::string Func = FuncName(AccessSize, IsWrite); + const MCSymbol *FuncSym = Ctx.GetOrCreateSymbol(StringRef(Func)); + const MCSymbolRefExpr *FuncExpr = + MCSymbolRefExpr::Create(FuncSym, MCSymbolRefExpr::VK_PLT, Ctx); + EmitInstruction(Out, MCInstBuilder(X86::CALLpcrel32).addExpr(FuncExpr)); + } + EmitInstruction(Out, MCInstBuilder(X86::ADD32ri).addReg(X86::ESP) + .addReg(X86::ESP).addImm(4)); + EmitInstruction(Out, MCInstBuilder(X86::POP32r).addReg(X86::EAX)); +} + +class X86AddressSanitizer64 : public X86AddressSanitizer { +public: + X86AddressSanitizer64(MCSubtargetInfo &sti) : X86AddressSanitizer(sti) {} + virtual ~X86AddressSanitizer64() {} + + virtual void InstrumentMemOperandImpl(X86Operand *Op, unsigned AccessSize, + bool IsWrite, MCContext &Ctx, + MCStreamer &Out) override; +}; + +void X86AddressSanitizer64::InstrumentMemOperandImpl( + X86Operand *Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx, + MCStreamer &Out) { + // FIXME: emit .cfi directives for correct stack unwinding. + // Set %rsp below current red zone (128 bytes wide) + EmitInstruction(Out, MCInstBuilder(X86::SUB64ri32).addReg(X86::RSP) + .addReg(X86::RSP).addImm(128)); + EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RDI)); + { + MCInst Inst; + Inst.setOpcode(X86::LEA64r); + Inst.addOperand(MCOperand::CreateReg(X86::RDI)); + Op->addMemOperands(Inst, 5); + EmitInstruction(Out, Inst); + } + { + const std::string Func = FuncName(AccessSize, IsWrite); + const MCSymbol *FuncSym = Ctx.GetOrCreateSymbol(StringRef(Func)); + const MCSymbolRefExpr *FuncExpr = + MCSymbolRefExpr::Create(FuncSym, MCSymbolRefExpr::VK_PLT, Ctx); + EmitInstruction(Out, MCInstBuilder(X86::CALL64pcrel32).addExpr(FuncExpr)); + } + EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RDI)); + EmitInstruction(Out, MCInstBuilder(X86::ADD64ri32).addReg(X86::RSP) + .addReg(X86::RSP).addImm(128)); +} + +} // End anonymous namespace + +X86AsmInstrumentation::X86AsmInstrumentation() {} +X86AsmInstrumentation::~X86AsmInstrumentation() {} + +void X86AsmInstrumentation::InstrumentInstruction( + const MCInst &Inst, SmallVectorImpl &Operands, + MCContext &Ctx, MCStreamer &Out) {} + +X86AsmInstrumentation *CreateX86AsmInstrumentation(MCSubtargetInfo &STI) { + if (ClAsanInstrumentInlineAssembly) { + if ((STI.getFeatureBits() & X86::Mode32Bit) != 0) + return new X86AddressSanitizer32(STI); + if ((STI.getFeatureBits() & X86::Mode64Bit) != 0) + return new X86AddressSanitizer64(STI); + } + return new X86AsmInstrumentation(); +} + +} // End llvm namespace diff --git a/lib/Target/X86/AsmParser/X86AsmInstrumentation.h b/lib/Target/X86/AsmParser/X86AsmInstrumentation.h new file mode 100644 index 0000000000..c783a788d4 --- /dev/null +++ b/lib/Target/X86/AsmParser/X86AsmInstrumentation.h @@ -0,0 +1,46 @@ +//===- X86AsmInstrumentation.h - Instrument X86 inline assembly *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef X86_ASM_INSTRUMENTATION_H +#define X86_ASM_INSTRUMENTATION_H + +#include "llvm/ADT/SmallVector.h" + +namespace llvm { + +class MCContext; +class MCInst; +class MCParsedAsmOperand; +class MCStreamer; +class MCSubtargetInfo; + +class X86AsmInstrumentation; + +X86AsmInstrumentation *CreateX86AsmInstrumentation(MCSubtargetInfo &STI); + +class X86AsmInstrumentation { +public: + virtual ~X86AsmInstrumentation(); + + // Instruments Inst. Should be called just before the original + // instruction is sent to Out. + virtual void InstrumentInstruction( + const MCInst &Inst, SmallVectorImpl &Operands, + MCContext &Ctx, MCStreamer &Out); + +protected: + friend X86AsmInstrumentation * + CreateX86AsmInstrumentation(MCSubtargetInfo &STI); + + X86AsmInstrumentation(); +}; + +} // End llvm namespace + +#endif // X86_ASM_INSTRUMENTATION_H diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 0336c161ca..9eddc74a9e 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "MCTargetDesc/X86BaseInfo.h" +#include "X86AsmInstrumentation.h" #include "X86AsmParserCommon.h" #include "X86Operand.h" #include "llvm/ADT/APFloat.h" @@ -30,6 +31,7 @@ #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" +#include using namespace llvm; @@ -54,6 +56,7 @@ class X86AsmParser : public MCTargetAsmParser { MCSubtargetInfo &STI; MCAsmParser &Parser; ParseInstructionInfo *InstInfo; + std::unique_ptr Instrumentation; private: SMLoc consumeToken() { SMLoc Result = Parser.getTok().getLoc(); @@ -650,6 +653,12 @@ private: bool processInstruction(MCInst &Inst, const SmallVectorImpl &Ops); + /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds + /// instrumentation around Inst. + void EmitInstruction(MCInst &Inst, + SmallVectorImpl &Operands, + MCStreamer &Out); + bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, SmallVectorImpl &Operands, MCStreamer &Out, unsigned &ErrorInfo, @@ -706,6 +715,7 @@ public: // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); + Instrumentation.reset(CreateX86AsmInstrumentation(STI)); } bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; @@ -2239,6 +2249,14 @@ processInstruction(MCInst &Inst, } static const char *getSubtargetFeatureName(unsigned Val); + +void X86AsmParser::EmitInstruction( + MCInst &Inst, SmallVectorImpl &Operands, + MCStreamer &Out) { + Instrumentation->InstrumentInstruction(Inst, Operands, getContext(), Out); + Out.EmitInstruction(Inst, STI); +} + bool X86AsmParser:: MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, SmallVectorImpl &Operands, @@ -2261,7 +2279,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, Inst.setOpcode(X86::WAIT); Inst.setLoc(IDLoc); if (!MatchingInlineAsm) - Out.EmitInstruction(Inst, STI); + EmitInstruction(Inst, Operands, Out); const char *Repl = StringSwitch(Op->getToken()) @@ -2297,7 +2315,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, Inst.setLoc(IDLoc); if (!MatchingInlineAsm) - Out.EmitInstruction(Inst, STI); + EmitInstruction(Inst, Operands, Out); Opcode = Inst.getOpcode(); return false; case Match_MissingFeature: { @@ -2384,7 +2402,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, if (NumSuccessfulMatches == 1) { Inst.setLoc(IDLoc); if (!MatchingInlineAsm) - Out.EmitInstruction(Inst, STI); + EmitInstruction(Inst, Operands, Out); Opcode = Inst.getOpcode(); return false; } diff --git a/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll b/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll new file mode 100644 index 0000000000..7af8139955 --- /dev/null +++ b/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll @@ -0,0 +1,123 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asan-instrument-inline-assembly | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK-LABEL: mov1b +; CHECK: subq $128, %rsp +; CHECK-NEXT: pushq %rdi +; CHECK-NEXT: leaq {{.*}}, %rdi +; CHECK-NEXT: callq __sanitizer_sanitize_load1@PLT +; CHECK-NEXT: popq %rdi +; CHECK-NEXT: addq $128, %rsp + +; CHECK: subq $128, %rsp +; CHECK-NEXT: pushq %rdi +; CHECK-NEXT: leaq {{.*}}, %rdi +; CHECK-NEXT: callq __sanitizer_sanitize_store1@PLT +; CHECK-NEXT: popq %rdi +; CHECK-NEXT: addq $128, %rsp + +; CHECK: movb {{.*}}, {{.*}} +define void @mov1b(i8* %dst, i8* %src) #0 { +entry: + tail call void asm sideeffect "movb ($1), %al \0A\09movb %al, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i8* %dst, i8* %src) #1, !srcloc !0 + ret void +} + +; CHECK-LABEL: mov2b +; CHECK: subq $128, %rsp +; CHECK-NEXT: pushq %rdi +; CHECK-NEXT: leaq {{.*}}, %rdi +; CHECK-NEXT: callq __sanitizer_sanitize_load2@PLT +; CHECK-NEXT: popq %rdi +; CHECK-NEXT: addq $128, %rsp + +; CHECK: subq $128, %rsp +; CHECK-NEXT: pushq %rdi +; CHECK-NEXT: leaq {{.*}}, %rdi +; CHECK-NEXT: callq __sanitizer_sanitize_store2@PLT +; CHECK-NEXT: popq %rdi +; CHECK-NEXT: addq $128, %rsp + +; CHECK: movw {{.*}}, {{.*}} +define void @mov2b(i16* %dst, i16* %src) #0 { +entry: + tail call void asm sideeffect "movw ($1), %ax \0A\09movw %ax, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i16* %dst, i16* %src) #1, !srcloc !1 + ret void +} + +; CHECK-LABEL: mov4b +; CHECK: subq $128, %rsp +; CHECK-NEXT: pushq %rdi +; CHECK-NEXT: leaq {{.*}}, %rdi +; CHECK-NEXT: callq __sanitizer_sanitize_load4@PLT +; CHECK-NEXT: popq %rdi +; CHECK-NEXT: addq $128, %rsp + +; CHECK: subq $128, %rsp +; CHECK-NEXT: pushq %rdi +; CHECK-NEXT: leaq {{.*}}, %rdi +; CHECK-NEXT: callq __sanitizer_sanitize_store4@PLT +; CHECK-NEXT: popq %rdi +; CHECK-NEXT: addq $128, %rsp + +; CHECK: movl {{.*}}, {{.*}} +define void @mov4b(i32* %dst, i32* %src) #0 { +entry: + tail call void asm sideeffect "movl ($1), %eax \0A\09movl %eax, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %dst, i32* %src) #1, !srcloc !2 + ret void +} + +; CHECK-LABEL: mov8b +; CHECK: subq $128, %rsp +; CHECK-NEXT: pushq %rdi +; CHECK-NEXT: leaq {{.*}}, %rdi +; CHECK-NEXT: callq __sanitizer_sanitize_load8@PLT +; CHECK-NEXT: popq %rdi +; CHECK-NEXT: addq $128, %rsp + +; CHECK: subq $128, %rsp +; CHECK-NEXT: pushq %rdi +; CHECK-NEXT: leaq {{.*}}, %rdi +; CHECK-NEXT: callq __sanitizer_sanitize_store8@PLT +; CHECK-NEXT: popq %rdi +; CHECK-NEXT: addq $128, %rsp + +; CHECK: movq {{.*}}, {{.*}} +define void @mov8b(i64* %dst, i64* %src) #0 { +entry: + 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) #1, !srcloc !3 + ret void +} + +; CHECK-LABEL: mov16b +; CHECK: subq $128, %rsp +; CHECK-NEXT: pushq %rdi +; CHECK-NEXT: leaq {{.*}}, %rdi +; CHECK-NEXT: callq __sanitizer_sanitize_load16@PLT +; CHECK-NEXT: popq %rdi +; CHECK-NEXT: addq $128, %rsp + +; CHECK: subq $128, %rsp +; CHECK-NEXT: pushq %rdi +; CHECK-NEXT: leaq {{.*}}, %rdi +; CHECK-NEXT: callq __sanitizer_sanitize_store16@PLT +; CHECK-NEXT: popq %rdi +; CHECK-NEXT: addq $128, %rsp + +; CHECK: movaps {{.*}}, {{.*}} +define void @mov16b(<2 x i64>* %dst, <2 x i64>* %src) #0 { +entry: + tail call void asm sideeffect "movaps ($1), %xmm0 \0A\09movaps %xmm0, ($0) \0A\09", "r,r,~{memory},~{xmm0},~{dirflag},~{fpsr},~{flags}"(<2 x i64>* %dst, <2 x i64>* %src) #1, !srcloc !4 + ret void +} + +attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind } + +!0 = metadata !{i32 98, i32 122, i32 160} +!1 = metadata !{i32 305, i32 329, i32 367} +!2 = metadata !{i32 512, i32 537, i32 576} +!3 = metadata !{i32 721, i32 746, i32 785} +!4 = metadata !{i32 929, i32 957, i32 999} diff --git a/test/Instrumentation/AddressSanitizer/X86/asm_mov.s b/test/Instrumentation/AddressSanitizer/X86/asm_mov.s new file mode 100644 index 0000000000..9001067247 --- /dev/null +++ b/test/Instrumentation/AddressSanitizer/X86/asm_mov.s @@ -0,0 +1,76 @@ +# RUN: llvm-mc %s -triple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asan-instrument-inline-assembly | FileCheck %s + + .text + .globl mov1b + .align 16, 0x90 + .type mov1b,@function +# CHECK-LABEL: mov1b: +# +# CHECK: subq $128, %rsp +# CHECK-NEXT: pushq %rdi +# CHECK-NEXT: leaq (%rsi), %rdi +# CHECK-NEXT: callq __sanitizer_sanitize_load1@PLT +# CHECK-NEXT: popq %rdi +# CHECK-NEXT: addq $128, %rsp +# +# CHECK-NEXT: movb (%rsi), %al +# +# CHECK-NEXT: subq $128, %rsp +# CHECK-NEXT: pushq %rdi +# CHECK-NEXT: leaq (%rdi), %rdi +# CHECK-NEXT: callq __sanitizer_sanitize_store1@PLT +# CHECK-NEXT: popq %rdi +# CHECK-NEXT: addq $128, %rsp +# +# CHECK-NEXT: movb %al, (%rdi) +mov1b: # @mov1b + .cfi_startproc +# BB#0: + #APP + movb (%rsi), %al + movb %al, (%rdi) + + #NO_APP + retq +.Ltmp0: + .size mov1b, .Ltmp0-mov1b + .cfi_endproc + + .globl mov16b + .align 16, 0x90 + .type mov16b,@function +# CHECK-LABEL: mov16b: +# +# CHECK: subq $128, %rsp +# CHECK-NEXT: pushq %rdi +# CHECK-NEXT: leaq (%rsi), %rdi +# CHECK-NEXT: callq __sanitizer_sanitize_load16@PLT +# CHECK-NEXT: popq %rdi +# CHECK-NEXT: addq $128, %rsp +# +# CHECK-NEXT: movaps (%rsi), %xmm0 +# +# CHECK-NEXT: subq $128, %rsp +# CHECK-NEXT: pushq %rdi +# CHECK-NEXT: leaq (%rdi), %rdi +# CHECK-NEXT: callq __sanitizer_sanitize_store16@PLT +# CHECK-NEXT: popq %rdi +# CHECK-NEXT: addq $128, %rsp +# +# CHECK-NEXT: movaps %xmm0, (%rdi) +mov16b: # @mov16b + .cfi_startproc +# BB#0: + #APP + movaps (%rsi), %xmm0 + movaps %xmm0, (%rdi) + + #NO_APP + retq +.Ltmp1: + .size mov16b, .Ltmp1-mov16b + .cfi_endproc + + + .ident "clang version 3.5 " + .section ".note.GNU-stack","",@progbits diff --git a/test/Instrumentation/AddressSanitizer/X86/asm_mov_no_instrumentation.s b/test/Instrumentation/AddressSanitizer/X86/asm_mov_no_instrumentation.s new file mode 100644 index 0000000000..a9ef4df9d3 --- /dev/null +++ b/test/Instrumentation/AddressSanitizer/X86/asm_mov_no_instrumentation.s @@ -0,0 +1,44 @@ +# RUN: llvm-mc %s -triple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 | FileCheck %s + + .text + .globl mov1b + .align 16, 0x90 + .type mov1b,@function +# CHECK-LABEL: mov1b +# CHECK-NOT: callq __sanitizer_sanitize_load1@PLT +# CHECK-NOT: callq __sanitizer_sanitize_store1@PLT +mov1b: # @mov1b + .cfi_startproc +# BB#0: + #APP + movb (%rsi), %al + movb %al, (%rdi) + + #NO_APP + retq +.Ltmp0: + .size mov1b, .Ltmp0-mov1b + .cfi_endproc + + .globl mov16b + .align 16, 0x90 + .type mov16b,@function +# CHECK-LABEL: mov16b +# CHECK-NOT: callq __sanitizer_sanitize_load16@PLT +# CHECK-NOT: callq __sanitizer_sanitize_store16@PLT +mov16b: # @mov16b + .cfi_startproc +# BB#0: + #APP + movaps (%rsi), %xmm0 + movaps %xmm0, (%rdi) + + #NO_APP + retq +.Ltmp1: + .size mov16b, .Ltmp1-mov16b + .cfi_endproc + + + .ident "clang version 3.5 " + .section ".note.GNU-stack","",@progbits -- cgit v1.2.3