1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[dfsan] Add a flag about whether to propagate offset labels at gep

DFSan has flags to control flows between pointers and objects referred
by pointers. For example,

a = *p;
L(a) = L(*p)        when -dfsan-combine-pointer-labels-on-load = false
L(a) = L(*p) + L(p) when -dfsan-combine-pointer-labels-on-load = true

*p = b;
L(*p) = L(b)        when -dfsan-combine-pointer-labels-on-store = false
L(*p) = L(b) + L(p) when -dfsan-combine-pointer-labels-on-store = true
The question is what to do with p += c.

In practice we found many confusing flows if we propagate labels from c
to p. So a new flag works like this

p += c;
L(p) = L(p)        when -dfsan-propagate-via-pointer-arithmetic = false
L(p) = L(p) + L(c) when -dfsan-propagate-via-pointer-arithmetic = true

Reviewed-by: gbalats

Differential Revision: https://reviews.llvm.org/D103176
This commit is contained in:
Jianzhou Zhao 2021-05-26 22:51:54 +00:00
parent b50ce5b1a4
commit 034e3da912
2 changed files with 40 additions and 1 deletions

View File

@ -201,6 +201,14 @@ static cl::opt<bool> ClCombinePointerLabelsOnStore(
"storing in memory."),
cl::Hidden, cl::init(false));
// Controls whether the pass propagates labels of offsets in GEP instructions.
static cl::opt<bool> ClCombineOffsetLabelsOnGEP(
"dfsan-combine-offset-labels-on-gep",
cl::desc(
"Combine the label of the offset with the label of the pointer when "
"doing pointer arithmetic."),
cl::Hidden, cl::init(true));
static cl::opt<bool> ClDebugNonzeroLabels(
"dfsan-debug-nonzero-labels",
cl::desc("Insert calls to __dfsan_nonzero_label on observing a parameter, "
@ -2778,7 +2786,17 @@ void DFSanVisitor::visitCmpInst(CmpInst &CI) {
}
void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
visitInstOperands(GEPI);
if (ClCombineOffsetLabelsOnGEP) {
visitInstOperands(GEPI);
return;
}
// Only propagate shadow/origin of base pointer value but ignore those of
// offset operands.
Value *BasePointer = GEPI.getPointerOperand();
DFSF.setShadow(&GEPI, DFSF.getShadow(BasePointer));
if (DFSF.DFS.shouldTrackOrigins())
DFSF.setOrigin(&GEPI, DFSF.getOrigin(BasePointer));
}
void DFSanVisitor::visitExtractElementInst(ExtractElementInst &I) {

View File

@ -0,0 +1,21 @@
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-combine-offset-labels-on-gep=false -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
; RUN: opt < %s -dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-fast-8-labels=true -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"
target triple = "x86_64-unknown-linux-gnu"
; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]]
; CHECK: @__dfsan_shadow_width_bits = weak_odr constant i32 [[#SBITS:]]
define i32* @gepop([10 x [20 x i32]]* %p, i32 %a, i32 %b, i32 %c) {
; CHECK: @"dfs$gepop"
; CHECK_ORIGIN: %[[#PO:]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align [[ALIGN_O:4]]
; CHECK: %[[#PS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN_S:2]]
; CHECK: %e = getelementptr [10 x [20 x i32]], [10 x [20 x i32]]* %p, i32 %a, i32 %b, i32 %c
; CHECK: store i[[#SBITS]] %[[#PS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN_S]]
; CHECK_ORIGIN: store i32 %[[#PO]], i32* @__dfsan_retval_origin_tls, align [[ALIGN_O]]
%e = getelementptr [10 x [20 x i32]], [10 x [20 x i32]]* %p, i32 %a, i32 %b, i32 %c
ret i32* %e
}