Remove ASan asm instrumentation.

Summary: It is incomplete and has no users AFAIK.

Reviewers: pcc, vitalybuka

Subscribers: srhines, kubamracek, mgorny, krytarowski, eraman, hiraditya, jdoerfert, #sanitizers, llvm-commits, thakis

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D59154

llvm-svn: 355870
This commit is contained in:
Evgeniy Stepanov 2019-03-11 21:50:10 +00:00
parent 4d20cc21c7
commit aedec3f684
21 changed files with 7 additions and 2041 deletions

View File

@ -74,10 +74,6 @@ set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
-fsanitize=address
"-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
)
if(CAN_TARGET_x86_64 OR CAN_TARGET_i386)
list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS -mllvm -asan-instrument-assembly)
endif()
if(NOT MSVC)
list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS --driver-mode=g++)
endif()
@ -142,7 +138,6 @@ set(ASAN_NOINST_TEST_SOURCES
set(ASAN_INST_TEST_SOURCES
${COMPILER_RT_GTEST_SOURCE}
asan_asm_test.cc
asan_globals_test.cc
asan_interface_test.cc
asan_internal_interface_test.cc

View File

@ -1,273 +0,0 @@
//===-- asan_asm_test.cc --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
//===----------------------------------------------------------------------===//
#include "asan_test_utils.h"
#if defined(__linux__) && \
(!defined(ASAN_SHADOW_SCALE) || ASAN_SHADOW_SCALE == 3)
// Assembly instrumentation is broken on x86 Android (x86 + PIC + shared runtime
// library). See https://github.com/google/sanitizers/issues/353
#if defined(__x86_64__) || \
(defined(__i386__) && defined(__SSE2__) && !defined(__ANDROID__))
#include <emmintrin.h>
namespace {
template<typename T> void asm_write(T *ptr, T val);
template<typename T> T asm_read(T *ptr);
template<typename T> void asm_rep_movs(T *dst, T *src, size_t n);
} // End of anonymous namespace
#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
#if defined(__x86_64__)
namespace {
#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg) \
template<> void asm_write<Type>(Type *ptr, Type val) { \
__asm__( \
Mov " %[val], (%[ptr]) \n\t" \
: \
: [ptr] "r" (ptr), [val] Reg (val) \
: "memory" \
); \
}
#define DECLARE_ASM_READ(Type, Size, Mov, Reg) \
template<> Type asm_read<Type>(Type *ptr) { \
Type res; \
__asm__( \
Mov " (%[ptr]), %[res] \n\t" \
: [res] Reg (res) \
: [ptr] "r" (ptr) \
: "memory" \
); \
return res; \
}
#define DECLARE_ASM_REP_MOVS(Type, Movs) \
template <> \
void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) { \
__asm__("rep " Movs " \n\t" \
: "+D"(dst), "+S"(src), "+c"(size) \
: \
: "memory"); \
}
DECLARE_ASM_WRITE(U8, "8", "movq", "r");
DECLARE_ASM_READ(U8, "8", "movq", "=r");
DECLARE_ASM_REP_MOVS(U8, "movsq");
} // End of anonymous namespace
#endif // defined(__x86_64__)
#if defined(__i386__) && defined(__SSE2__) && !defined(__ANDROID__)
namespace {
#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg) \
template<> void asm_write<Type>(Type *ptr, Type val) { \
__asm__( \
Mov " %[val], (%[ptr]) \n\t" \
: \
: [ptr] "r" (ptr), [val] Reg (val) \
: "memory" \
); \
}
#define DECLARE_ASM_READ(Type, Size, Mov, Reg) \
template<> Type asm_read<Type>(Type *ptr) { \
Type res; \
__asm__( \
Mov " (%[ptr]), %[res] \n\t" \
: [res] Reg (res) \
: [ptr] "r" (ptr) \
: "memory" \
); \
return res; \
}
#define DECLARE_ASM_REP_MOVS(Type, Movs) \
template <> \
void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) { \
__asm__("rep " Movs " \n\t" \
: "+D"(dst), "+S"(src), "+c"(size) \
: \
: "memory"); \
}
} // End of anonymous namespace
#endif // defined(__i386__) && defined(__SSE2__)
#if defined(__x86_64__) || \
(defined(__i386__) && defined(__SSE2__) && !defined(__ANDROID__))
namespace {
DECLARE_ASM_WRITE(U1, "1", "movb", "r");
DECLARE_ASM_WRITE(U2, "2", "movw", "r");
DECLARE_ASM_WRITE(U4, "4", "movl", "r");
DECLARE_ASM_WRITE(__m128i, "16", "movaps", "x");
DECLARE_ASM_READ(U1, "1", "movb", "=r");
DECLARE_ASM_READ(U2, "2", "movw", "=r");
DECLARE_ASM_READ(U4, "4", "movl", "=r");
DECLARE_ASM_READ(__m128i, "16", "movaps", "=x");
DECLARE_ASM_REP_MOVS(U1, "movsb");
DECLARE_ASM_REP_MOVS(U2, "movsw");
DECLARE_ASM_REP_MOVS(U4, "movsl");
template<typename T> void TestAsmWrite(const char *DeathPattern) {
T *buf = new T;
EXPECT_DEATH(asm_write(&buf[1], static_cast<T>(0)), DeathPattern);
T var = 0x12;
asm_write(&var, static_cast<T>(0x21));
ASSERT_EQ(static_cast<T>(0x21), var);
delete buf;
}
template<> void TestAsmWrite<__m128i>(const char *DeathPattern) {
char *buf = new char[16];
char *p = buf + 16;
if (((uintptr_t) p % 16) != 0)
p = buf + 8;
assert(((uintptr_t) p % 16) == 0);
__m128i val = _mm_set1_epi16(0x1234);
EXPECT_DEATH(asm_write<__m128i>((__m128i*) p, val), DeathPattern);
__m128i var = _mm_set1_epi16(0x4321);
asm_write(&var, val);
ASSERT_EQ(0x1234, _mm_extract_epi16(var, 0));
delete [] buf;
}
template<typename T> void TestAsmRead(const char *DeathPattern) {
T *buf = new T;
EXPECT_DEATH(asm_read(&buf[1]), DeathPattern);
T var = 0x12;
ASSERT_EQ(static_cast<T>(0x12), asm_read(&var));
delete buf;
}
template<> void TestAsmRead<__m128i>(const char *DeathPattern) {
char *buf = new char[16];
char *p = buf + 16;
if (((uintptr_t) p % 16) != 0)
p = buf + 8;
assert(((uintptr_t) p % 16) == 0);
EXPECT_DEATH(asm_read<__m128i>((__m128i*) p), DeathPattern);
__m128i val = _mm_set1_epi16(0x1234);
ASSERT_EQ(0x1234, _mm_extract_epi16(asm_read(&val), 0));
delete [] buf;
}
U4 AsmLoad(U4 *a) {
U4 r;
__asm__("movl (%[a]), %[r] \n\t" : [r] "=r" (r) : [a] "r" (a) : "memory");
return r;
}
void AsmStore(U4 r, U4 *a) {
__asm__("movl %[r], (%[a]) \n\t" : : [a] "r" (a), [r] "r" (r) : "memory");
}
template <typename T>
void TestAsmRepMovs(const char *DeathPatternRead,
const char *DeathPatternWrite) {
T src_good[4] = { 0x0, 0x1, 0x2, 0x3 };
T dst_good[4] = {};
asm_rep_movs(dst_good, src_good, 4);
ASSERT_EQ(static_cast<T>(0x0), dst_good[0]);
ASSERT_EQ(static_cast<T>(0x1), dst_good[1]);
ASSERT_EQ(static_cast<T>(0x2), dst_good[2]);
ASSERT_EQ(static_cast<T>(0x3), dst_good[3]);
T dst_bad[3];
EXPECT_DEATH(asm_rep_movs(dst_bad, src_good, 4), DeathPatternWrite);
T src_bad[3] = { 0x0, 0x1, 0x2 };
EXPECT_DEATH(asm_rep_movs(dst_good, src_bad, 4), DeathPatternRead);
T* dp = dst_bad + 4;
T* sp = src_bad + 4;
asm_rep_movs(dp, sp, 0);
}
} // End of anonymous namespace
TEST(AddressSanitizer, asm_load_store) {
U4* buf = new U4[2];
EXPECT_DEATH(AsmLoad(&buf[3]), "READ of size 4");
EXPECT_DEATH(AsmStore(0x1234, &buf[3]), "WRITE of size 4");
delete [] buf;
}
TEST(AddressSanitizer, asm_rw) {
TestAsmWrite<U1>("WRITE of size 1");
TestAsmWrite<U2>("WRITE of size 2");
TestAsmWrite<U4>("WRITE of size 4");
#if defined(__x86_64__)
TestAsmWrite<U8>("WRITE of size 8");
#endif // defined(__x86_64__)
TestAsmWrite<__m128i>("WRITE of size 16");
TestAsmRead<U1>("READ of size 1");
TestAsmRead<U2>("READ of size 2");
TestAsmRead<U4>("READ of size 4");
#if defined(__x86_64__)
TestAsmRead<U8>("READ of size 8");
#endif // defined(__x86_64__)
TestAsmRead<__m128i>("READ of size 16");
}
TEST(AddressSanitizer, asm_flags) {
long magic = 0x1234;
long r = 0x0;
#if defined(__x86_64__) && !defined(__ILP32__)
__asm__("xorq %%rax, %%rax \n\t"
"movq (%[p]), %%rax \n\t"
"sete %%al \n\t"
"movzbq %%al, %[r] \n\t"
: [r] "=r"(r)
: [p] "r"(&magic)
: "rax", "memory");
#else
__asm__("xorl %%eax, %%eax \n\t"
"movl (%[p]), %%eax \n\t"
"sete %%al \n\t"
"movzbl %%al, %[r] \n\t"
: [r] "=r"(r)
: [p] "r"(&magic)
: "eax", "memory");
#endif // defined(__x86_64__) && !defined(__ILP32__)
ASSERT_EQ(0x1, r);
}
TEST(AddressSanitizer, asm_rep_movs) {
TestAsmRepMovs<U1>("READ of size 1", "WRITE of size 1");
TestAsmRepMovs<U2>("READ of size 2", "WRITE of size 2");
TestAsmRepMovs<U4>("READ of size 4", "WRITE of size 4");
#if defined(__x86_64__)
TestAsmRepMovs<U8>("READ of size 8", "WRITE of size 8");
#endif // defined(__x86_64__)
}
#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
#endif // defined(__linux__)

View File

@ -1,33 +0,0 @@
// Check that a stack unwinding algorithm works corretly even with the assembly
// instrumentation.
// REQUIRES: x86_64-target-arch, shadow-scale-3
// RUN: %clangxx_asan -g -O1 %s -fno-inline-functions -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -mllvm -asan-instrument-assembly -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -g -O1 %s -fno-inline-functions -fomit-frame-pointer -momit-leaf-frame-pointer -mllvm -asan-instrument-assembly -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -g0 -O1 %s -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-exceptions -fno-inline-functions -fomit-frame-pointer -momit-leaf-frame-pointer -mllvm -asan-instrument-assembly -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-nounwind
#include <cstddef>
// CHECK: READ of size 4
// CHECK-NEXT: {{#0 0x[0-9a-fA-F]+ in foo}}
// CHECK-NEXT: {{#1 0x[0-9a-fA-F]+ in main}}
// CHECK-nounwind: READ of size 4
// CHECK-nounwind-NEXT: {{#0 0x[0-9a-fA-F]+ in foo}}
__attribute__((noinline)) int foo(size_t n, int *buffer) {
int r;
__asm__("movl (%[buffer], %[n], 4), %[r] \n\t"
: [r] "=r"(r)
: [buffer] "r"(buffer), [n] "r"(n)
: "memory");
return r;
}
int main() {
const size_t n = 16;
int *buffer = new int[n];
foo(n, buffer);
delete[] buffer;
return 0;
}

View File

@ -384,9 +384,6 @@ public:
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc) = 0;
/// Sets frame register corresponding to the current MachineFunction.
virtual void SetFrameRegister(unsigned RegNo) {}
/// ParseInstruction - Parse one assembly instruction.
///
/// The parser is positioned following the instruction name. The target

View File

@ -38,9 +38,6 @@ public:
AsmInstrumentationAddress
};
/// Enables AddressSanitizer instrumentation at machine level.
bool SanitizeAddress : 1;
bool MCRelaxAll : 1;
bool MCNoExecStack : 1;
bool MCFatalWarnings : 1;

View File

@ -18,15 +18,6 @@
#include "llvm/Support/CommandLine.h"
using namespace llvm;
static cl::opt<MCTargetOptions::AsmInstrumentation> AsmInstrumentation(
"asm-instrumentation", cl::desc("Instrumentation of inline assembly and "
"assembly source files"),
cl::init(MCTargetOptions::AsmInstrumentationNone),
cl::values(clEnumValN(MCTargetOptions::AsmInstrumentationNone, "none",
"no instrumentation at all"),
clEnumValN(MCTargetOptions::AsmInstrumentationAddress, "address",
"instrument instructions with memory arguments")));
static cl::opt<bool> RelaxAll("mc-relax-all",
cl::desc("When used with filetype=obj, "
"relax all fixups in the emitted object file"));
@ -62,8 +53,6 @@ ABIName("target-abi", cl::Hidden,
static MCTargetOptions InitMCTargetOptionsFromFlags() {
MCTargetOptions Options;
Options.SanitizeAddress =
(AsmInstrumentation == MCTargetOptions::AsmInstrumentationAddress);
Options.MCRelaxAll = RelaxAll;
Options.MCIncrementalLinkerCompatible = IncrementalLinkerCompatible;
Options.MCPIECopyRelocations = PIECopyRelocations;

View File

@ -157,10 +157,6 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
// assembly.
if (Dialect == InlineAsm::AD_Intel)
Parser->getLexer().setLexMasmIntegers(true);
if (MF) {
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
TAP->SetFrameRegister(TRI->getFrameRegister(*MF));
}
emitInlineAsmStart();
// Don't implicitly switch to the text section before the asm.
@ -527,11 +523,6 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
else
EmitMSInlineAsmStr(AsmStr, MI, MMI, InlineAsmVariant, AP, LocCookie, OS);
// Reset SanitizeAddress based on the function's attribute.
MCTargetOptions MCOptions = TM.Options.MCOptions;
MCOptions.SanitizeAddress =
MF->getFunction().hasFnAttribute(Attribute::SanitizeAddress);
// Emit warnings if we use reserved registers on the clobber list, as
// that might give surprising results.
std::vector<std::string> RestrRegs;
@ -570,7 +561,7 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
SrcMgr.PrintMessage(Loc, SourceMgr::DK_Note, Note);
}
EmitInlineAsm(OS.str(), getSubtargetInfo(), MCOptions, LocMD,
EmitInlineAsm(OS.str(), getSubtargetInfo(), TM.Options.MCOptions, LocMD,
MI->getInlineAsmDialect());
// Emit the #NOAPP end marker. This has to happen even if verbose-asm isn't

View File

@ -12,12 +12,11 @@
using namespace llvm;
MCTargetOptions::MCTargetOptions()
: SanitizeAddress(false), MCRelaxAll(false), MCNoExecStack(false),
MCFatalWarnings(false), MCNoWarn(false), MCNoDeprecatedWarn(false),
MCSaveTempLabels(false), MCUseDwarfDirectory(false),
MCIncrementalLinkerCompatible(false), MCPIECopyRelocations(false),
ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
PreserveAsmComments(true) {}
: MCRelaxAll(false), MCNoExecStack(false), MCFatalWarnings(false),
MCNoWarn(false), MCNoDeprecatedWarn(false), MCSaveTempLabels(false),
MCUseDwarfDirectory(false), MCIncrementalLinkerCompatible(false),
MCPIECopyRelocations(false), ShowMCEncoding(false), ShowMCInst(false),
AsmVerbose(false), PreserveAsmComments(true) {}
StringRef MCTargetOptions::getABIName() const {
return ABIName;

View File

@ -1,4 +1,3 @@
add_llvm_library(LLVMX86AsmParser
X86AsmInstrumentation.cpp
X86AsmParser.cpp
)

File diff suppressed because it is too large Load Diff

View File

@ -1,65 +0,0 @@
//===- X86AsmInstrumentation.h - Instrument X86 inline assembly -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86ASMINSTRUMENTATION_H
#define LLVM_LIB_TARGET_X86_ASMPARSER_X86ASMINSTRUMENTATION_H
#include "llvm/ADT/SmallVector.h"
#include <memory>
namespace llvm {
class MCContext;
class MCInst;
class MCInstrInfo;
class MCParsedAsmOperand;
class MCStreamer;
class MCSubtargetInfo;
class MCTargetOptions;
class X86AsmInstrumentation;
X86AsmInstrumentation *
CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions,
const MCContext &Ctx,
const MCSubtargetInfo *&STI);
class X86AsmInstrumentation {
public:
virtual ~X86AsmInstrumentation();
// Sets frame register corresponding to a current frame.
void SetInitialFrameRegister(unsigned RegNo) {
InitialFrameReg = RegNo;
}
// Tries to instrument and emit instruction.
virtual void InstrumentAndEmitInstruction(
const MCInst &Inst,
SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> &Operands,
MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
protected:
friend X86AsmInstrumentation *
CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions,
const MCContext &Ctx,
const MCSubtargetInfo *&STI);
X86AsmInstrumentation(const MCSubtargetInfo *&STI);
unsigned GetFrameRegGeneric(const MCContext &Ctx, MCStreamer &Out);
void EmitInstruction(MCStreamer &Out, const MCInst &Inst);
const MCSubtargetInfo *&STI;
unsigned InitialFrameReg = 0;
};
} // end namespace llvm
#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86ASMINSTRUMENTATION_H

View File

@ -10,7 +10,6 @@
#include "MCTargetDesc/X86BaseInfo.h"
#include "MCTargetDesc/X86MCExpr.h"
#include "MCTargetDesc/X86TargetStreamer.h"
#include "X86AsmInstrumentation.h"
#include "X86AsmParserCommon.h"
#include "X86Operand.h"
#include "llvm/ADT/STLExtras.h"
@ -70,7 +69,6 @@ static const char OpPrecedence[] = {
class X86AsmParser : public MCTargetAsmParser {
ParseInstructionInfo *InstInfo;
std::unique_ptr<X86AsmInstrumentation> Instrumentation;
bool Code16GCC;
private:
@ -951,14 +949,10 @@ public:
// Initialize the set of available features.
setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
Instrumentation.reset(
CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
}
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
void SetFrameRegister(unsigned RegNo) override;
bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
@ -1193,10 +1187,6 @@ bool X86AsmParser::ParseRegister(unsigned &RegNo,
return false;
}
void X86AsmParser::SetFrameRegister(unsigned RegNo) {
Instrumentation->SetInitialFrameRegister(RegNo);
}
std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
bool Parse32 = is32BitMode() || Code16GCC;
unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
@ -2866,8 +2856,7 @@ static const char *getSubtargetFeatureName(uint64_t Val);
void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
MCStreamer &Out) {
Instrumentation->InstrumentAndEmitInstruction(
Inst, Operands, getContext(), MII, Out);
Out.EmitInstruction(Inst, getSTI());
}
bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,

View File

@ -1,20 +0,0 @@
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asm-instrumentation=address -asan-instrument-assembly | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK-LABEL: mov_no_attr
; CHECK-NOT: callq __asan_report_load8@PLT
; CHECK-NOT: callq __asan_report_store8@PLT
define void @mov_no_attr(i64* %dst, i64* %src) {
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)
ret void
}
; CHECK-LABEL: mov_sanitize
; CHECK: callq __asan_report_load8@PLT
; CHECK: callq __asan_report_store8@PLT
define void @mov_sanitize(i64* %dst, i64* %src) sanitize_address {
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)
ret void
}

View File

@ -1,54 +0,0 @@
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asm-instrumentation=address -asan-instrument-assembly | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK-LABEL: mov8b_rbp
; CHECK: pushq %rbp
; CHECK-NOT: .cfi_adjust_cfa_offset 8
; CHECK: movq %rbp, %rbp
; CHECK: .cfi_remember_state
; CHECK: .cfi_def_cfa_register %rbp
; CHECK: leaq -128(%rsp)
; CHECK: callq __asan_report_load8@PLT
; CHECK: leaq 128(%rsp)
; CHECK: popq %rbp
; CHECK: .cfi_restore_state
; CHECK-NOT: .cfi_adjust_cfa_offset -8
; CHECK: retq
define void @mov8b_rbp(i64* %dst, i64* %src) #0 {
entry:
tail call void asm sideeffect "movq ($0), %rax \0A\09movq %rax, ($1) \0A\09", "r,r,~{rax},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %src, i64* %dst)
ret void
}
; CHECK-LABEL: mov8b_rsp
; CHECK: pushq %rbp
; CHECK: .cfi_adjust_cfa_offset 8
; CHECK: movq %rsp, %rbp
; CHECK: .cfi_remember_state
; CHECK: .cfi_def_cfa_register %rbp
; CHECK: leaq -128(%rsp)
; CHECK: callq __asan_report_load8@PLT
; CHECK: leaq 128(%rsp)
; CHECK: popq %rbp
; CHECK: .cfi_restore_state
; CHECK: .cfi_adjust_cfa_offset -8
; CHECK: retq
define void @mov8b_rsp(i64* %dst, i64* %src) #1 {
entry:
tail call void asm sideeffect "movq ($0), %rax \0A\09movq %rax, ($1) \0A\09", "r,r,~{rax},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %src, i64* %dst)
ret void
}
; CHECK-LABEL: mov8b_rsp_no_cfi
; CHECK-NOT: .cfi{{[a-z_]+}}
define void @mov8b_rsp_no_cfi(i64* %dst, i64* %src) #2 {
entry:
tail call void asm sideeffect "movq ($0), %rax \0A\09movq %rax, ($1) \0A\09", "r,r,~{rax},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %src, i64* %dst)
ret void
}
attributes #0 = { nounwind sanitize_address uwtable "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" }
attributes #1 = { nounwind sanitize_address uwtable "no-frame-pointer-elim"="false" }
attributes #2 = { nounwind sanitize_address "no-frame-pointer-elim"="false" }

View File

@ -1,52 +0,0 @@
# The test verifies that correct DWARF directives are emitted when
# assembly files are instrumented.
# RUN: llvm-mc %s -triple=i386-unknown-linux-gnu -asm-instrumentation=address -asan-instrument-assembly | FileCheck %s
# CHECK-LABEL: load4b_cfa_rbp
# CHECK: pushl %ebx
# CHECK-NOT: .cfi_adjust_cfa_offset 8
# CHECK: movl %ebp, %ebx
# CHECK: .cfi_remember_state
# CHECK: .cfi_def_cfa_register %ebx
# CHECK: popl %ebx
# CHECK: .cfi_restore_state
# CHECK-NOT: .cfi_adjust_cfa_offset -8
# CHECK: retl
.text
.globl load4b_cfa_rbp
.type load4b_cfa_rbp,@function
swap_cfa_rbp: # @swap_cfa_rbp
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset %ebp, -8
movl %esp, %ebp
.cfi_def_cfa_register %ebp
movl 8(%ebp), %eax
popl %ebp
retl
.cfi_endproc
# CHECK-LABEL: load4b_cfa_rsp
# CHECK: pushl %ebx
# CHECK: .cfi_adjust_cfa_offset 4
# CHECK: movl %esp, %ebx
# CHECK: .cfi_remember_state
# CHECK: .cfi_def_cfa_register %ebx
# CHECK: popl %ebx
# CHECK: .cfi_restore_state
# CHECK: retl
.globl load4b_cfa_rsp
.type load4b_cfa_rsp,@function
swap_cfa_rsp: # @swap_cfa_rsp
.cfi_startproc
pushl %ebp
.cfi_offset %ebp, 0
movl %esp, %ebp
movl 8(%ebp), %eax
popl %ebp
retl
.cfi_endproc

View File

@ -1,152 +0,0 @@
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asm-instrumentation=address -asan-instrument-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: leaq -128(%rsp), %rsp
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: pushq %rdi
; CHECK-NEXT: pushq %rcx
; CHECK-NEXT: pushfq
; CHECK-NEXT: leaq {{.*}}, %rdi
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: shrq $3, %rax
; CHECK-NEXT: movb 2147450880(%rax), %al
; CHECK-NEXT: testb %al, %al
; CHECK-NEXT: je [[A:.*]]
; CHECK-NEXT: movl %edi, %ecx
; CHECK-NEXT: andl $7, %ecx
; CHECK-NEXT: movsbl %al, %eax
; CHECK-NEXT: cmpl %eax, %ecx
; CHECK-NEXT: jl {{.*}}
; CHECK-NEXT: cld
; CHECK-NEXT: emms
; CHECK-NEXT: andq $-16, %rsp
; CHECK-NEXT: callq __asan_report_load1@PLT
; CHECK-NEXT: [[A]]:
; CHECK-NEXT: popfq
; CHECK-NEXT: popq %rcx
; CHECK-NEXT: popq %rdi
; CHECK-NEXT: popq %rax
; CHECK-NEXT: leaq 128(%rsp), %rsp
; CHECK: leaq -128(%rsp), %rsp
; CHECK: callq __asan_report_store1@PLT
; CHECK: leaq 128(%rsp), %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: leaq -128(%rsp), %rsp
; CHECK: leal 1(%ecx), %ecx
; CHECK: callq __asan_report_load2@PLT
; CHECK: leaq 128(%rsp), %rsp
; CHECK: leaq -128(%rsp), %rsp
; CHECK: leal 1(%ecx), %ecx
; CHECK: callq __asan_report_store2@PLT
; CHECK: leaq 128(%rsp), %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: leaq -128(%rsp), %rsp
; CHECK: addl $3, %ecx
; CHECK: callq __asan_report_load4@PLT
; CHECK: leaq 128(%rsp), %rsp
; CHECK: leaq -128(%rsp), %rsp
; CHECK: addl $3, %ecx
; CHECK: callq __asan_report_store4@PLT
; CHECK: leaq 128(%rsp), %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: leaq -128(%rsp), %rsp
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: pushq %rdi
; CHECK-NEXT: pushfq
; CHECK-NEXT: leaq {{.*}}, %rdi
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: shrq $3, %rax
; CHECK-NEXT: cmpb $0, 2147450880(%rax)
; CHECK-NEXT: je [[A:.*]]
; CHECK-NEXT: cld
; CHECK-NEXT: emms
; CHECK-NEXT: andq $-16, %rsp
; CHECK-NEXT: callq __asan_report_load8@PLT
; CHECK-NEXT: [[A]]:
; CHECK-NEXT: popfq
; CHECK-NEXT: popq %rdi
; CHECK-NEXT: popq %rax
; CHECK-NEXT: leaq 128(%rsp), %rsp
; CHECK: leaq -128(%rsp), %rsp
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: pushq %rdi
; CHECK-NEXT: pushfq
; CHECK-NEXT: leaq {{.*}}, %rdi
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: shrq $3, %rax
; CHECK-NEXT: cmpb $0, 2147450880(%rax)
; CHECK-NEXT: je [[A:.*]]
; CHECK-NEXT: cld
; CHECK-NEXT: emms
; CHECK-NEXT: andq $-16, %rsp
; CHECK-NEXT: callq __asan_report_store8@PLT
; CHECK-NEXT: [[A]]:
; CHECK-NEXT: popfq
; CHECK-NEXT: popq %rdi
; CHECK-NEXT: popq %rax
; CHECK-NEXT: leaq 128(%rsp), %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: leaq -128(%rsp), %rsp
; CHECK: cmpw $0, 2147450880(%rax)
; CHECK: callq __asan_report_load16@PLT
; CHECK: leaq 128(%rsp), %rsp
; CHECK: leaq -128(%rsp), %rsp
; CHECK: cmpw $0, 2147450880(%rax)
; CHECK: callq __asan_report_store16@PLT
; CHECK: leaq 128(%rsp), %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 sanitize_address "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 = !{i32 98, i32 122, i32 160}
!1 = !{i32 305, i32 329, i32 367}
!2 = !{i32 512, i32 537, i32 576}
!3 = !{i32 721, i32 746, i32 785}
!4 = !{i32 929, i32 957, i32 999}

View File

@ -1,64 +0,0 @@
# RUN: llvm-mc %s -triple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asm-instrumentation=address -asan-instrument-assembly | FileCheck %s
.text
.globl mov1b
.align 16, 0x90
.type mov1b,@function
# CHECK-LABEL: mov1b:
#
# CHECK: leaq -128(%rsp), %rsp
# CHECK: callq __asan_report_load1@PLT
# CHECK: leaq 128(%rsp), %rsp
#
# CHECK: movb (%rsi), %al
#
# CHECK: leaq -128(%rsp), %rsp
# CHECK: callq __asan_report_store1@PLT
# CHECK: leaq 128(%rsp), %rsp
#
# CHECK: 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: leaq -128(%rsp), %rsp
# CHECK: callq __asan_report_load16@PLT
# CHECK: leaq 128(%rsp), %rsp
#
# CHECK: movaps (%rsi), %xmm0
#
# CHECK: leaq -128(%rsp), %rsp
# CHECK: callq __asan_report_store16@PLT
# CHECK: leaq 128(%rsp), %rsp
#
# CHECK: 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

View File

@ -1,85 +0,0 @@
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asm-instrumentation=address -asan-instrument-assembly | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK-LABEL: rep_movs_1b
; CHECK: pushfq
; CHECK-NEXT: testq %rcx, %rcx
; CHECK-NEXT: je [[B:.*]]
; CHECK: leaq -128(%rsp), %rsp
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: pushq %rdx
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: pushfq
; CHECK: leaq (%rsi), %rdx
; CHECK: movq %rdx, %rdi
; CHECK-NEXT: callq __asan_report_load1@PLT
; CHECK: leaq -1(%rsi,%rcx), %rdx
; CHECK: movq %rdx, %rdi
; CHECK-NEXT: callq __asan_report_load1@PLT
; CHECK: leaq (%rdi), %rdx
; CHECK: movq %rdx, %rdi
; CHECK-NEXT: callq __asan_report_store1@PLT
; CHECK: leaq -1(%rdi,%rcx), %rdx
; CHECK: movq %rdx, %rdi
; CHECK-NEXT: callq __asan_report_store1@PLT
; CHECK: popfq
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: popq %rdx
; CHECK-NEXT: popq %rax
; CHECK-NEXT: leaq 128(%rsp), %rsp
; CHECK: [[B]]:
; CHECK-NEXT: popfq
; CHECK: rep movsb (%rsi), %es:(%rdi)
; Function Attrs: nounwind sanitize_address uwtable
define void @rep_movs_1b(i8* %dst, i8* %src, i64 %n) #0 {
entry:
tail call void asm sideeffect "rep movsb \0A\09", "{si},{di},{cx},~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %src, i8* %dst, i64 %n) #1
ret void
}
; CHECK-LABEL: rep_movs_8b
; CHECK: pushfq
; CHECK-NEXT: testq %rcx, %rcx
; CHECK-NEXT: je [[Q:.*]]
; CHECK: leaq (%rsi), %rdx
; CHECK: movq %rdx, %rdi
; CHECK-NEXT: callq __asan_report_load8@PLT
; CHECK: leaq -1(%rsi,%rcx,8), %rdx
; CHECK: movq %rdx, %rdi
; CHECK-NEXT: callq __asan_report_load8@PLT
; CHECK: leaq (%rdi), %rdx
; CHECK: movq %rdx, %rdi
; CHECK-NEXT: callq __asan_report_store8@PLT
; CHECK: leaq -1(%rdi,%rcx,8), %rdx
; CHECK: movq %rdx, %rdi
; CHECK-NEXT: callq __asan_report_store8@PLT
; CHECK: [[Q]]:
; CHECK-NEXT: popfq
; CHECK: rep movsq (%rsi), %es:(%rdi)
; Function Attrs: nounwind sanitize_address uwtable
define void @rep_movs_8b(i64* %dst, i64* %src, i64 %n) #0 {
entry:
tail call void asm sideeffect "rep movsq \0A\09", "{si},{di},{cx},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %src, i64* %dst, i64 %n) #1
ret void
}
attributes #0 = { nounwind sanitize_address uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }

View File

@ -1,45 +0,0 @@
# The test verifies that memory references through %rsp are correctly
# adjusted after instrumentation.
# RUN: llvm-mc %s -triple=x86_64-unknown-linux-gnu -asm-instrumentation=address -asan-instrument-assembly | FileCheck %s
# CHECK-LABEL: rsp_access
# CHECK: leaq -128(%rsp), %rsp
# CHECK: pushq %rax
# CHECK: pushq %rdi
# CHECK: pushfq
# CHECK: leaq 160(%rsp), %rdi
# CHECK: callq __asan_report_load8@PLT
# CHECK: popfq
# CHECK: popq %rdi
# CHECK: popq %rax
# CHECK: leaq 128(%rsp), %rsp
# CHECK: movq 8(%rsp), %rax
# CHECK: retq
.text
.globl rsp_access
.type rsp_access,@function
rsp_access:
movq 8(%rsp), %rax
retq
# CHECK-LABEL: rsp_32bit_access
# CHECK: leaq -128(%rsp), %rsp
# CHECK: pushq %rax
# CHECK: pushq %rdi
# CHECK: pushfq
# CHECK: leaq 2147483647(%rsp), %rdi
# CHECK: leaq 145(%rdi), %rdi
# CHECK: callq __asan_report_load8@PLT
# CHECK: popfq
# CHECK: popq %rdi
# CHECK: popq %rax
# CHECK: leaq 128(%rsp), %rsp
# CHECK: movq 2147483640(%rsp), %rax
# CHECK: retq
.globl rsp_32bit_access
.type rsp_32bit_access,@function
rsp_32bit_access:
movq 2147483640(%rsp), %rax
retq

View File

@ -1,59 +0,0 @@
# RUN: llvm-mc %s -x86-asm-syntax=intel -triple=x86_64-unknown-linux-gnu -asm-instrumentation=address -asan-instrument-assembly | FileCheck %s
.text
.globl swap
.align 16, 0x90
.type swap,@function
# CHECK-LABEL: swap:
#
# CHECK: leaq -128(%rsp), %rsp
# CHECK: callq __asan_report_load8@PLT
# CHECK: leaq 128(%rsp), %rsp
#
# CHECK: movq (%rcx), %rax
#
# CHECK: leaq -128(%rsp), %rsp
# CHECK: callq __asan_report_load8@PLT
# CHECK: leaq 128(%rsp), %rsp
#
# CHECK: movq (%rdx), %rbx
#
# CHECK: leaq -128(%rsp), %rsp
# CHECK: callq __asan_report_store8@PLT
# CHECK: leaq 128(%rsp), %rsp
#
# CHECK: movq %rbx, (%rcx)
#
# CHECK: leaq -128(%rsp), %rsp
# CHECK: callq __asan_report_store8@PLT
# CHECK: leaq 128(%rsp), %rsp
#
# CHECK: movq %rax, (%rdx)
swap: # @swap
.cfi_startproc
# %bb.0:
push rbx
.Ltmp0:
.cfi_def_cfa_offset 16
.Ltmp1:
.cfi_offset rbx, -16
mov rcx, rdi
mov rdx, rsi
#APP
mov rax, qword ptr [rcx]
mov rbx, qword ptr [rdx]
mov qword ptr [rcx], rbx
mov qword ptr [rdx], rax
#NO_APP
pop rbx
ret
.Ltmp2:
.size swap, .Ltmp2-swap
.cfi_endproc
.ident "clang version 3.5.0 "
.section ".note.GNU-stack","",@progbits

View File

@ -19,7 +19,6 @@ static_library("AsmParser") {
]
include_dirs = [ ".." ]
sources = [
"X86AsmInstrumentation.cpp",
"X86AsmParser.cpp",
]
}