mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-26 07:29:55 +00:00
DataFlowSanitizer; LLVM changes.
DataFlowSanitizer is a generalised dynamic data flow analysis. Unlike other Sanitizer tools, this tool is not designed to detect a specific class of bugs on its own. Instead, it provides a generic dynamic data flow analysis framework to be used by clients to help detect application-specific issues within their own code. Differential Revision: http://llvm-reviews.chandlerc.com/D965 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187923 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9c2c660e12
commit
6fa33f5dd9
@ -122,6 +122,7 @@ void initializeAddressSanitizerPass(PassRegistry&);
|
||||
void initializeAddressSanitizerModulePass(PassRegistry&);
|
||||
void initializeMemorySanitizerPass(PassRegistry&);
|
||||
void initializeThreadSanitizerPass(PassRegistry&);
|
||||
void initializeDataFlowSanitizerPass(PassRegistry&);
|
||||
void initializeEarlyCSEPass(PassRegistry&);
|
||||
void initializeExpandISelPseudosPass(PassRegistry&);
|
||||
void initializeFindUsedTypesPass(PassRegistry&);
|
||||
|
@ -16,6 +16,20 @@
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
inline void *getDFSanArgTLSPtrForJIT() {
|
||||
extern __thread __attribute__((tls_model("initial-exec")))
|
||||
void *__dfsan_arg_tls;
|
||||
return (void *)&__dfsan_arg_tls;
|
||||
}
|
||||
|
||||
inline void *getDFSanRetValTLSPtrForJIT() {
|
||||
extern __thread __attribute__((tls_model("initial-exec")))
|
||||
void *__dfsan_retval_tls;
|
||||
return (void *)&__dfsan_retval_tls;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ModulePass;
|
||||
@ -74,6 +88,17 @@ FunctionPass *createMemorySanitizerPass(bool TrackOrigins = false,
|
||||
// Insert ThreadSanitizer (race detection) instrumentation
|
||||
FunctionPass *createThreadSanitizerPass(StringRef BlacklistFile = StringRef());
|
||||
|
||||
// Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation
|
||||
ModulePass *createDataFlowSanitizerPass(void *(*getArgTLS)() = 0,
|
||||
void *(*getRetValTLS)() = 0);
|
||||
|
||||
#ifdef __GNUC__
|
||||
inline ModulePass *createDataFlowSanitizerPassForJIT() {
|
||||
return createDataFlowSanitizerPass(getDFSanArgTLSPtrForJIT,
|
||||
getDFSanRetValTLSPtrForJIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
// BoundsChecking - This pass instruments the code to perform run-time bounds
|
||||
// checking on loads, stores, and other memory intrinsics.
|
||||
FunctionPass *createBoundsCheckingPass();
|
||||
|
@ -1,6 +1,7 @@
|
||||
add_llvm_library(LLVMInstrumentation
|
||||
AddressSanitizer.cpp
|
||||
BoundsChecking.cpp
|
||||
DataFlowSanitizer.cpp
|
||||
DebugIR.cpp
|
||||
EdgeProfiling.cpp
|
||||
GCOVProfiling.cpp
|
||||
|
1006
lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
Normal file
1006
lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,7 @@ void llvm::initializeInstrumentation(PassRegistry &Registry) {
|
||||
initializePathProfilerPass(Registry);
|
||||
initializeMemorySanitizerPass(Registry);
|
||||
initializeThreadSanitizerPass(Registry);
|
||||
initializeDataFlowSanitizerPass(Registry);
|
||||
}
|
||||
|
||||
/// LLVMInitializeInstrumentation - C binding for
|
||||
|
62
test/Instrumentation/DataFlowSanitizer/arith.ll
Normal file
62
test/Instrumentation/DataFlowSanitizer/arith.ll
Normal file
@ -0,0 +1,62 @@
|
||||
; RUN: opt < %s -dfsan -S | 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"
|
||||
|
||||
define i8 @add(i8 %a, i8 %b) {
|
||||
; CHECK: @add
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: add i8
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i8
|
||||
%c = add i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
||||
|
||||
define i8 @sub(i8 %a, i8 %b) {
|
||||
; CHECK: @sub
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: sub i8
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i8
|
||||
%c = sub i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
||||
|
||||
define i8 @mul(i8 %a, i8 %b) {
|
||||
; CHECK: @mul
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: mul i8
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i8
|
||||
%c = mul i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
||||
|
||||
define i8 @sdiv(i8 %a, i8 %b) {
|
||||
; CHECK: @sdiv
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: sdiv i8
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i8
|
||||
%c = sdiv i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
||||
|
||||
define i8 @udiv(i8 %a, i8 %b) {
|
||||
; CHECK: @udiv
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: udiv i8
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i8
|
||||
%c = udiv i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
23
test/Instrumentation/DataFlowSanitizer/call.ll
Normal file
23
test/Instrumentation/DataFlowSanitizer/call.ll
Normal file
@ -0,0 +1,23 @@
|
||||
; RUN: opt < %s -dfsan -S | 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"
|
||||
|
||||
; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [64 x i16]
|
||||
; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global i16
|
||||
|
||||
declare i32 @f(i32)
|
||||
declare float @llvm.sqrt.f32(float)
|
||||
|
||||
; CHECK: @call
|
||||
define i32 @call() {
|
||||
; CHECK: store{{.*}}__dfsan_arg_tls
|
||||
; CHECK: call{{.*}}@f
|
||||
; CHECK: load{{.*}}__dfsan_retval_tls
|
||||
%r = call i32 @f(i32 0)
|
||||
|
||||
; CHECK-NOT: store{{.*}}__dfsan_arg_tls
|
||||
%i = call float @llvm.sqrt.f32(float -1.0)
|
||||
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i32
|
||||
ret i32 %r
|
||||
}
|
1
test/Instrumentation/DataFlowSanitizer/lit.local.cfg
Normal file
1
test/Instrumentation/DataFlowSanitizer/lit.local.cfg
Normal file
@ -0,0 +1 @@
|
||||
config.suffixes = ['.ll', '.c', '.cpp']
|
81
test/Instrumentation/DataFlowSanitizer/load.ll
Normal file
81
test/Instrumentation/DataFlowSanitizer/load.ll
Normal file
@ -0,0 +1,81 @@
|
||||
; RUN: opt < %s -dfsan -S | 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"
|
||||
|
||||
define i8 @load8(i8* %p) {
|
||||
; CHECK: @load8
|
||||
; CHECK: ptrtoint
|
||||
; CHECK: and
|
||||
; CHECK: mul
|
||||
; CHECK: inttoptr
|
||||
; CHECK: load
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i8
|
||||
%a = load i8* %p
|
||||
ret i8 %a
|
||||
}
|
||||
|
||||
define i16 @load16(i16* %p) {
|
||||
; CHECK: @load16
|
||||
; CHECK: ptrtoint
|
||||
; CHECK: and
|
||||
; CHECK: mul
|
||||
; CHECK: inttoptr
|
||||
; CHECK: load
|
||||
; CHECK: load
|
||||
; CHECK: icmp ne
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i16
|
||||
%a = load i16* %p
|
||||
ret i16 %a
|
||||
}
|
||||
|
||||
define i32 @load32(i32* %p) {
|
||||
; CHECK: @load32
|
||||
; CHECK: ptrtoint
|
||||
; CHECK: and
|
||||
; CHECK: mul
|
||||
; CHECK: inttoptr
|
||||
; CHECK: bitcast
|
||||
; CHECK: load
|
||||
; CHECK: trunc
|
||||
; CHECK: shl
|
||||
; CHECK: lshr
|
||||
; CHECK: or
|
||||
; CHECK: icmp eq
|
||||
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i32
|
||||
|
||||
; CHECK: call{{.*}}__dfsan_union_load
|
||||
|
||||
%a = load i32* %p
|
||||
ret i32 %a
|
||||
}
|
||||
|
||||
define i64 @load64(i64* %p) {
|
||||
; CHECK: @load64
|
||||
; CHECK: ptrtoint
|
||||
; CHECK: and
|
||||
; CHECK: mul
|
||||
; CHECK: inttoptr
|
||||
; CHECK: bitcast
|
||||
; CHECK: load
|
||||
; CHECK: trunc
|
||||
; CHECK: shl
|
||||
; CHECK: lshr
|
||||
; CHECK: or
|
||||
; CHECK: icmp eq
|
||||
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i64
|
||||
|
||||
; CHECK: call{{.*}}__dfsan_union_load
|
||||
|
||||
; CHECK: getelementptr
|
||||
; CHECK: load
|
||||
; CHECK: icmp eq
|
||||
|
||||
%a = load i64* %p
|
||||
ret i64 %a
|
||||
}
|
75
test/Instrumentation/DataFlowSanitizer/store.ll
Normal file
75
test/Instrumentation/DataFlowSanitizer/store.ll
Normal file
@ -0,0 +1,75 @@
|
||||
; RUN: opt < %s -dfsan -S | 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"
|
||||
|
||||
define void @store8(i8 %v, i8* %p) {
|
||||
; CHECK: @store8
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: ptrtoint
|
||||
; CHECK: and
|
||||
; CHECK: mul
|
||||
; CHECK: inttoptr
|
||||
; CHECK: getelementptr
|
||||
; CHECK: store
|
||||
; CHECK: store
|
||||
store i8 %v, i8* %p
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @store16(i16 %v, i16* %p) {
|
||||
; CHECK: @store16
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: ptrtoint
|
||||
; CHECK: and
|
||||
; CHECK: mul
|
||||
; CHECK: inttoptr
|
||||
; CHECK: getelementptr
|
||||
; CHECK: store
|
||||
; CHECK: getelementptr
|
||||
; CHECK: store
|
||||
; CHECK: store
|
||||
store i16 %v, i16* %p
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @store32(i32 %v, i32* %p) {
|
||||
; CHECK: @store32
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: ptrtoint
|
||||
; CHECK: and
|
||||
; CHECK: mul
|
||||
; CHECK: inttoptr
|
||||
; CHECK: getelementptr
|
||||
; CHECK: store
|
||||
; CHECK: getelementptr
|
||||
; CHECK: store
|
||||
; CHECK: getelementptr
|
||||
; CHECK: store
|
||||
; CHECK: getelementptr
|
||||
; CHECK: store
|
||||
; CHECK: store
|
||||
store i32 %v, i32* %p
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @store64(i64 %v, i64* %p) {
|
||||
; CHECK: @store64
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: ptrtoint
|
||||
; CHECK: and
|
||||
; CHECK: mul
|
||||
; CHECK: inttoptr
|
||||
; CHECK: insertelement
|
||||
; CHECK: insertelement
|
||||
; CHECK: insertelement
|
||||
; CHECK: insertelement
|
||||
; CHECK: insertelement
|
||||
; CHECK: insertelement
|
||||
; CHECK: insertelement
|
||||
; CHECK: insertelement
|
||||
; CHECK: bitcast
|
||||
; CHECK: getelementptr
|
||||
; CHECK: store
|
||||
; CHECK: store
|
||||
store i64 %v, i64* %p
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user