[llvm-branch-commits] [compiler-rt] 82655c1 - [MSan] Tweak CopyOrigin
Author: Jianzhou Zhao Date: 2021-01-13T01:22:05Z New Revision: 82655c151450e0103a3aa60725639da607f9220c URL: https://github.com/llvm/llvm-project/commit/82655c151450e0103a3aa60725639da607f9220c DIFF: https://github.com/llvm/llvm-project/commit/82655c151450e0103a3aa60725639da607f9220c.diff LOG: [MSan] Tweak CopyOrigin There could be some mis-alignments when copying origins not aligned. I believe inaligned memcpy is rare so the cases do not matter too much in practice. 1) About the change at line 50 Let dst be (void*)5, then d=5, beg=4 so we need to write 3 (4+4-5) bytes from 5 to 7. 2) About the change around line 77. Let dst be (void*)5, because of lines 50-55, the bytes from 5-7 were already writen. So the aligned copy is from 8. Reviewed-by: eugenis Differential Revision: https://reviews.llvm.org/D94552 Added: Modified: compiler-rt/lib/msan/msan_poisoning.cpp Removed: diff --git a/compiler-rt/lib/msan/msan_poisoning.cpp b/compiler-rt/lib/msan/msan_poisoning.cpp index ef3c74e0a35a..8f58432d528a 100644 --- a/compiler-rt/lib/msan/msan_poisoning.cpp +++ b/compiler-rt/lib/msan/msan_poisoning.cpp @@ -47,7 +47,7 @@ void CopyOrigin(const void *dst, const void *src, uptr size, uptr beg = d & ~3UL; // Copy left unaligned origin if that memory is poisoned. if (beg < d) { -u32 o = GetOriginIfPoisoned((uptr)src, d - beg); +u32 o = GetOriginIfPoisoned((uptr)src, beg + 4 - d); if (o) { if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack); *(u32 *)MEM_TO_ORIGIN(beg) = o; @@ -71,12 +71,13 @@ void CopyOrigin(const void *dst, const void *src, uptr size, if (beg < end) { // Align src up. uptr s = ((uptr)src + 3) & ~3UL; +uptr aligned_beg = ((uptr)dst + 3) & ~3UL; // FIXME: factor out to msan_copy_origin_aligned if (__msan_get_track_origins() > 1) { u32 *src = (u32 *)MEM_TO_ORIGIN(s); u32 *src_s = (u32 *)MEM_TO_SHADOW(s); - u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - beg)); - u32 *dst = (u32 *)MEM_TO_ORIGIN(beg); + u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - aligned_beg)); + u32 *dst = (u32 *)MEM_TO_ORIGIN(aligned_beg); u32 src_o = 0; u32 dst_o = 0; for (; src < src_end; ++src, ++src_s, ++dst) { @@ -88,8 +89,9 @@ void CopyOrigin(const void *dst, const void *src, uptr size, *dst = dst_o; } } else { - REAL(memcpy)((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s), - end - beg); + REAL(memcpy) + ((void *)MEM_TO_ORIGIN(aligned_beg), (void *)MEM_TO_ORIGIN(s), + end - aligned_beg); } } } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [compiler-rt] 0b99385 - [MSan] Partially revert some changes from D94552
Author: Jianzhou Zhao Date: 2021-01-13T07:03:17Z New Revision: 0b99385e151c7cb674d6d29acfe92680f7148434 URL: https://github.com/llvm/llvm-project/commit/0b99385e151c7cb674d6d29acfe92680f7148434 DIFF: https://github.com/llvm/llvm-project/commit/0b99385e151c7cb674d6d29acfe92680f7148434.diff LOG: [MSan] Partially revert some changes from D94552 Because of line 55, actually aligned_beg always equals to beg. Added: Modified: compiler-rt/lib/msan/msan_poisoning.cpp Removed: diff --git a/compiler-rt/lib/msan/msan_poisoning.cpp b/compiler-rt/lib/msan/msan_poisoning.cpp index 8f58432d528a..d121d45a1951 100644 --- a/compiler-rt/lib/msan/msan_poisoning.cpp +++ b/compiler-rt/lib/msan/msan_poisoning.cpp @@ -71,13 +71,12 @@ void CopyOrigin(const void *dst, const void *src, uptr size, if (beg < end) { // Align src up. uptr s = ((uptr)src + 3) & ~3UL; -uptr aligned_beg = ((uptr)dst + 3) & ~3UL; // FIXME: factor out to msan_copy_origin_aligned if (__msan_get_track_origins() > 1) { u32 *src = (u32 *)MEM_TO_ORIGIN(s); u32 *src_s = (u32 *)MEM_TO_SHADOW(s); - u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - aligned_beg)); - u32 *dst = (u32 *)MEM_TO_ORIGIN(aligned_beg); + u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - beg)); + u32 *dst = (u32 *)MEM_TO_ORIGIN(beg); u32 src_o = 0; u32 dst_o = 0; for (; src < src_end; ++src, ++src_s, ++dst) { @@ -89,9 +88,8 @@ void CopyOrigin(const void *dst, const void *src, uptr size, *dst = dst_o; } } else { - REAL(memcpy) - ((void *)MEM_TO_ORIGIN(aligned_beg), (void *)MEM_TO_ORIGIN(s), - end - aligned_beg); + REAL(memcpy)((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s), + end - beg); } } } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [compiler-rt] f86db34 - [MSan] Move origins for overlapped memory transfer
Author: Jianzhou Zhao Date: 2021-01-21T02:11:26Z New Revision: f86db34defc323135106dc12e9fa888003cdcbd7 URL: https://github.com/llvm/llvm-project/commit/f86db34defc323135106dc12e9fa888003cdcbd7 DIFF: https://github.com/llvm/llvm-project/commit/f86db34defc323135106dc12e9fa888003cdcbd7.diff LOG: [MSan] Move origins for overlapped memory transfer Reviewed-by: eugenis Differential Revision: https://reviews.llvm.org/D94572 Added: compiler-rt/test/msan/chained_origin_memmove.cpp Modified: compiler-rt/lib/msan/msan_poisoning.cpp Removed: diff --git a/compiler-rt/lib/msan/msan_poisoning.cpp b/compiler-rt/lib/msan/msan_poisoning.cpp index d121d45a1951..a92b0565cfa8 100644 --- a/compiler-rt/lib/msan/msan_poisoning.cpp +++ b/compiler-rt/lib/msan/msan_poisoning.cpp @@ -94,23 +94,98 @@ void CopyOrigin(const void *dst, const void *src, uptr size, } } +void ReverseCopyOrigin(const void *dst, const void *src, uptr size, + StackTrace *stack) { + if (!MEM_IS_APP(dst) || !MEM_IS_APP(src)) +return; + + uptr d = (uptr)dst; + uptr end = (d + size) & ~3UL; + + // Copy right unaligned origin if that memory is poisoned. + if (end < d + size) { +u32 o = GetOriginIfPoisoned((uptr)src + (end - d), (d + size) - end); +if (o) { + if (__msan_get_track_origins() > 1) +o = ChainOrigin(o, stack); + *(u32 *)MEM_TO_ORIGIN(end) = o; +} + } + + uptr beg = d & ~3UL; + + if (beg + 4 < end) { +// Align src up. +uptr s = ((uptr)src + 3) & ~3UL; +if (__msan_get_track_origins() > 1) { + u32 *src = (u32 *)MEM_TO_ORIGIN(s + end - beg - 4); + u32 *src_s = (u32 *)MEM_TO_SHADOW(s + end - beg - 4); + u32 *src_begin = (u32 *)MEM_TO_ORIGIN(s); + u32 *dst = (u32 *)MEM_TO_ORIGIN(end - 4); + u32 src_o = 0; + u32 dst_o = 0; + for (; src >= src_begin; --src, --src_s, --dst) { +if (!*src_s) + continue; +if (*src != src_o) { + src_o = *src; + dst_o = ChainOrigin(src_o, stack); +} +*dst = dst_o; + } +} else { + REAL(memmove) + ((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s), end - beg - 4); +} + } + + // Copy left unaligned origin if that memory is poisoned. + if (beg < d) { +u32 o = GetOriginIfPoisoned((uptr)src, beg + 4 - d); +if (o) { + if (__msan_get_track_origins() > 1) +o = ChainOrigin(o, stack); + *(u32 *)MEM_TO_ORIGIN(beg) = o; +} + } +} + +void MoveOrigin(const void *dst, const void *src, uptr size, +StackTrace *stack) { + // If destination origin range overlaps with source origin range, move + // origins by coping origins in a reverse order; otherwise, copy origins in + // a normal order. + uptr src_aligned_beg = reinterpret_cast(src) & ~3UL; + uptr src_aligned_end = (reinterpret_cast(src) + size) & ~3UL; + uptr dst_aligned_beg = reinterpret_cast(dst) & ~3UL; + if (dst_aligned_beg < src_aligned_end && dst_aligned_beg >= src_aligned_beg) +return ReverseCopyOrigin(dst, src, size, stack); + return CopyOrigin(dst, src, size, stack); +} + void MoveShadowAndOrigin(const void *dst, const void *src, uptr size, StackTrace *stack) { if (!MEM_IS_APP(dst)) return; if (!MEM_IS_APP(src)) return; if (src == dst) return; + // MoveOrigin transfers origins by refering to their shadows. So we + // need to move origins before moving shadows. + if (__msan_get_track_origins()) +MoveOrigin(dst, src, size, stack); REAL(memmove)((void *)MEM_TO_SHADOW((uptr)dst), (void *)MEM_TO_SHADOW((uptr)src), size); - if (__msan_get_track_origins()) CopyOrigin(dst, src, size, stack); } void CopyShadowAndOrigin(const void *dst, const void *src, uptr size, StackTrace *stack) { if (!MEM_IS_APP(dst)) return; if (!MEM_IS_APP(src)) return; + // Because origin's range is slightly larger than app range, memcpy may also + // cause overlapped origin ranges. REAL(memcpy)((void *)MEM_TO_SHADOW((uptr)dst), (void *)MEM_TO_SHADOW((uptr)src), size); - if (__msan_get_track_origins()) CopyOrigin(dst, src, size, stack); + if (__msan_get_track_origins()) +MoveOrigin(dst, src, size, stack); } void CopyMemory(void *dst, const void *src, uptr size, StackTrace *stack) { diff --git a/compiler-rt/test/msan/chained_origin_memmove.cpp b/compiler-rt/test/msan/chained_origin_memmove.cpp new file mode 100644 index ..af6935767bc9 --- /dev/null +++ b/compiler-rt/test/msan/chained_origin_memmove.cpp @@ -0,0 +1,57 @@ +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -DOFFSET=0 -O3 %s -o %t && \ +// RUN: not %run %t >%t.out 2>&1 +// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z1 --check-prefix=CHECK-%short-stack < %t.out + +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -DOFFSE
[llvm-branch-commits] [llvm] 405ea2b - [msan] Replace 8 by kShadowTLSAlignment
Author: Jianzhou Zhao Date: 2020-12-02T01:09:49Z New Revision: 405ea2b93d96f7014e60eeb84040b35372d448e7 URL: https://github.com/llvm/llvm-project/commit/405ea2b93d96f7014e60eeb84040b35372d448e7 DIFF: https://github.com/llvm/llvm-project/commit/405ea2b93d96f7014e60eeb84040b35372d448e7.diff LOG: [msan] Replace 8 by kShadowTLSAlignment Reviewed-by: eugenis Differential Revision: https://reviews.llvm.org/D92275 Added: Modified: llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp Removed: diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 188403b54b53..5ff4c45f681c 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -3708,7 +3708,7 @@ struct MemorySanitizerVisitor : public InstVisitor { (void)Store; assert(Size != 0 && Store != nullptr); LLVM_DEBUG(dbgs() << " Param:" << *Store << "\n"); - ArgOffset += alignTo(Size, 8); + ArgOffset += alignTo(Size, kShadowTLSAlignment); } LLVM_DEBUG(dbgs() << " done with call args\n"); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [compiler-rt] 6fa0662 - [dfsan] Add test cases for struct/pair
Author: Jianzhou Zhao Date: 2020-12-02T21:25:23Z New Revision: 6fa06628a728ac161b3f61a2a2fb749cd8e4b41b URL: https://github.com/llvm/llvm-project/commit/6fa06628a728ac161b3f61a2a2fb749cd8e4b41b DIFF: https://github.com/llvm/llvm-project/commit/6fa06628a728ac161b3f61a2a2fb749cd8e4b41b.diff LOG: [dfsan] Add test cases for struct/pair This is a child diff of D92261. This locks down the behavior before the change. Added: compiler-rt/test/dfsan/pair.cpp compiler-rt/test/dfsan/struct.c Modified: Removed: diff --git a/compiler-rt/test/dfsan/pair.cpp b/compiler-rt/test/dfsan/pair.cpp new file mode 100644 index ..830fe393b17b --- /dev/null +++ b/compiler-rt/test/dfsan/pair.cpp @@ -0,0 +1,138 @@ +// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -o %t && %run %t + +#include +#include +#include +#include + +__attribute__((noinline)) +std::pair +make_pair(int *p, int i) { return {p, i}; } + +__attribute__((noinline)) +std::pair +copy_pair1(const std::pair &pair) { + return pair; +} + +__attribute__((noinline)) +std::pair +copy_pair2(std::pair *pair) { + return *pair; +} + +__attribute__((noinline)) +std::pair +copy_pair3(std::pair &&pair) { + return std::move(pair); +} + +__attribute__((noinline)) +std::pair +return_ptr_and_i32(const char *p, uint32_t res) { + for (uint32_t i = 2; i < 5; i++) { +uint32_t byte = static_cast(p[i]); +res += (byte - 1) << (7 * i); +if (byte < 128) { + return {p + i + 1, res}; +} + } + return {nullptr, 0}; +} + +__attribute__((noinline)) +std::pair +return_ptr_and_i64(const char *p, uint32_t res32) { + uint64_t res = res32; + for (uint32_t i = 2; i < 10; i++) { +uint64_t byte = static_cast(p[i]); +res += (byte - 1) << (7 * i); +if (byte < 128) { + return {p + i + 1, res}; +} + } + return {nullptr, 0}; +} + +void test_simple_constructors() { + int i = 1; + int *ptr = NULL; + dfsan_set_label(8, &i, sizeof(i)); + dfsan_set_label(2, &ptr, sizeof(ptr)); + + std::pair pair1 = make_pair(ptr, i); + int i1 = pair1.second; + int *ptr1 = pair1.first; + + assert(dfsan_read_label(&i1, sizeof(i1)) == 10); + assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10); + + std::pair pair2 = copy_pair1(pair1); + int i2 = pair2.second; + int *ptr2 = pair2.first; + + assert(dfsan_read_label(&i2, sizeof(i2)) == 10); + assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 10); + + std::pair pair3 = copy_pair2(&pair1); + int i3 = pair3.second; + int *ptr3 = pair3.first; + + assert(dfsan_read_label(&i3, sizeof(i3)) == 10); + assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 10); + + std::pair pair4 = copy_pair3(std::move(pair1)); + int i4 = pair4.second; + int *ptr4 = pair4.first; + + assert(dfsan_read_label(&i4, sizeof(i4)) == 10); + assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 10); +} + +void test_branches() { + uint32_t res = 4; + dfsan_set_label(8, &res, sizeof(res)); + + char p[100]; + const char *q = p; + dfsan_set_label(2, &q, sizeof(q)); + + { +std::fill_n(p, 100, static_cast(128)); + +{ + std::pair r = return_ptr_and_i32(q, res); + assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0); + assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0); +} + +{ + std::pair r = return_ptr_and_i64(q, res); + assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0); + assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0); +} + } + + { +std::fill_n(p, 100, 0); + +{ + std::pair r = return_ptr_and_i32(q, res); + assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10); + assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10); +} + +{ + std::pair r = return_ptr_and_i64(q, res); + assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10); + assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10); +} + } +} + +int main(void) { + test_simple_constructors(); + test_branches(); + + return 0; +} diff --git a/compiler-rt/test/dfsan/struct.c b/compiler-rt/test/dfsan/struct.c new file mode 100644 index ..6441ad4de163 --- /dev/null +++ b/compiler-rt/test/dfsan/struct.c @@ -0,0 +1,77 @@ +// RUN: %clang_dfsan %s -o %t && %run %t + +#include +#include + +typedef struct Pair { + int i; + char *ptr; +} Pair; + +__attribute__((noinline)) +Pair make_pair(int i, char *ptr) { + Pair pair; + pair.i = i; + pair.ptr = ptr; + return pair; +} + +__attribute__((noinline)) +Pair copy_pair1(const Pair *pair0) { + Pair pair; + pair.i = pair0->i; + pair.ptr = pair0->ptr; + return pair; +} + +__attribute__((noinline)) +Pair copy_pair2(const Pair pair0) { + Pair pair; + pair.i = pair0.i; + pair.ptr = pair0.ptr; + return pair; +} + +int main(void) { + int i = 1; + char *ptr = NULL; + dfsan_label
[llvm-branch-commits] [llvm] baa005c - [dfsan] Add a test case for phi
Author: Jianzhou Zhao Date: 2020-12-02T21:29:44Z New Revision: baa005c96ce610e9ee91ef55a3a1b1eacd5a0a27 URL: https://github.com/llvm/llvm-project/commit/baa005c96ce610e9ee91ef55a3a1b1eacd5a0a27 DIFF: https://github.com/llvm/llvm-project/commit/baa005c96ce610e9ee91ef55a3a1b1eacd5a0a27.diff LOG: [dfsan] Add a test case for phi Added: llvm/test/Instrumentation/DataFlowSanitizer/phi.ll Modified: Removed: diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/phi.ll b/llvm/test/Instrumentation/DataFlowSanitizer/phi.ll new file mode 100644 index ..08c457f3bfc7 --- /dev/null +++ b/llvm/test/Instrumentation/DataFlowSanitizer/phi.ll @@ -0,0 +1,24 @@ +; 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" +target triple = "x86_64-unknown-linux-gnu" + +define {i32, i32} @test({i32, i32} %a, i1 %c) { + ; CHECK: [[E0:%.*]] = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 0), align 2 + ; CHECK: [[E3:%.*]] = phi i16 [ [[E0]], %T ], [ [[E0]], %F ] + ; CHECK: store i16 [[E3]], i16* @__dfsan_retval_tls, align 2 + +entry: + br i1 %c, label %T, label %F + +T: + %at = insertvalue {i32, i32} %a, i32 1, 0 + br label %done + +F: + %af = insertvalue {i32, i32} %a, i32 1, 1 + br label %done + +done: + %b = phi {i32, i32} [%at, %T], [%af, %F] + ret {i32, i32} %b +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 838ecf2 - [dfsan] Test loading global ptrs
Author: Jianzhou Zhao Date: 2020-12-02T21:35:41Z New Revision: 838ecf2ea483ce6986a1d38208555155bbc53bba URL: https://github.com/llvm/llvm-project/commit/838ecf2ea483ce6986a1d38208555155bbc53bba DIFF: https://github.com/llvm/llvm-project/commit/838ecf2ea483ce6986a1d38208555155bbc53bba.diff LOG: [dfsan] Test loading global ptrs This covers a branch in the loadShadow method. Reviewed-by: morehouse Differential Revision: https://reviews.llvm.org/D92460 Added: Modified: llvm/test/Instrumentation/DataFlowSanitizer/load.ll Removed: diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/load.ll b/llvm/test/Instrumentation/DataFlowSanitizer/load.ll index 5bb3984227df..9cdf69d11ddb 100644 --- a/llvm/test/Instrumentation/DataFlowSanitizer/load.ll +++ b/llvm/test/Instrumentation/DataFlowSanitizer/load.ll @@ -166,3 +166,12 @@ define i64 @load64(i64* %p) { %a = load i64, i64* %p ret i64 %a } + +@X = constant i1 1 +define i1 @load_global() { + ; NO_COMBINE_PTR_LABEL: @"dfs$load_global" + ; NO_COMBINE_PTR_LABEL: store i16 0, i16* @__dfsan_retval_tls, align 2 + + %a = load i1, i1* @X + ret i1 %a +} \ No newline at end of file ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] dad5d95 - [dfsan] Rename CachedCombinedShadow to be CachedShadow
Author: Jianzhou Zhao Date: 2020-12-02T21:39:16Z New Revision: dad5d9588335d6e4232b7c263da24ae2676673da URL: https://github.com/llvm/llvm-project/commit/dad5d9588335d6e4232b7c263da24ae2676673da DIFF: https://github.com/llvm/llvm-project/commit/dad5d9588335d6e4232b7c263da24ae2676673da.diff LOG: [dfsan] Rename CachedCombinedShadow to be CachedShadow At D92261, this type will be used to cache both combined shadow and converted shadow values. Reviewed-by: morehouse Differential Revision: https://reviews.llvm.org/D92458 Added: Modified: llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp Removed: diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index 4fd6308fcc49..46f4becb511f 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -428,12 +428,12 @@ struct DFSanFunction { std::vector NonZeroChecks; bool AvoidNewBlocks; - struct CachedCombinedShadow { -BasicBlock *Block; + struct CachedShadow { +BasicBlock *Block; // The block where Shadow is defined. Value *Shadow; }; - DenseMap, CachedCombinedShadow> - CachedCombinedShadows; + /// Maps a value to its latest shadow value in terms of domination tree. + DenseMap, CachedShadow> CachedShadows; DenseMap> ShadowElements; DFSanFunction(DataFlowSanitizer &DFS, Function *F, bool IsNativeABI) @@ -1145,7 +1145,7 @@ Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) { auto Key = std::make_pair(V1, V2); if (V1 > V2) std::swap(Key.first, Key.second); - CachedCombinedShadow &CCS = CachedCombinedShadows[Key]; + CachedShadow &CCS = CachedShadows[Key]; if (CCS.Block && DT.dominates(CCS.Block, Pos->getParent())) return CCS.Shadow; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] bd726d2 - [dfsan] Rename ShadowTy/ZeroShadow with prefix Primitive
Author: Jianzhou Zhao Date: 2020-12-03T05:31:01Z New Revision: bd726d2796b1a5d2c936b5708bfb49a4b7fb89de URL: https://github.com/llvm/llvm-project/commit/bd726d2796b1a5d2c936b5708bfb49a4b7fb89de DIFF: https://github.com/llvm/llvm-project/commit/bd726d2796b1a5d2c936b5708bfb49a4b7fb89de.diff LOG: [dfsan] Rename ShadowTy/ZeroShadow with prefix Primitive This is a child diff of D92261. After supporting field/index-level shadow, the existing shadow with type i16 works for only primitive types. Reviewed-by: morehouse Differential Revision: https://reviews.llvm.org/D92459 Added: Modified: llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp Removed: diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index 46f4becb511f..9dad9817acea 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -354,10 +354,13 @@ class DataFlowSanitizer { Module *Mod; LLVMContext *Ctx; Type *Int8Ptr; - IntegerType *ShadowTy; - PointerType *ShadowPtrTy; + /// The shadow type for all primitive types. Until we support field/index + /// level shadow values, aggregate and vector types also use this shadow + /// type. + IntegerType *PrimitiveShadowTy; + PointerType *PrimitiveShadowPtrTy; IntegerType *IntptrTy; - ConstantInt *ZeroShadow; + ConstantInt *ZeroPrimitiveShadow; ConstantInt *ShadowPtrMask; ConstantInt *ShadowPtrMul; Constant *ArgTLS; @@ -504,12 +507,12 @@ DataFlowSanitizer::DataFlowSanitizer( FunctionType *DataFlowSanitizer::getArgsFunctionType(FunctionType *T) { SmallVector ArgTypes(T->param_begin(), T->param_end()); - ArgTypes.append(T->getNumParams(), ShadowTy); + ArgTypes.append(T->getNumParams(), PrimitiveShadowTy); if (T->isVarArg()) -ArgTypes.push_back(ShadowPtrTy); +ArgTypes.push_back(PrimitiveShadowPtrTy); Type *RetType = T->getReturnType(); if (!RetType->isVoidTy()) -RetType = StructType::get(RetType, ShadowTy); +RetType = StructType::get(RetType, PrimitiveShadowTy); return FunctionType::get(RetType, ArgTypes, T->isVarArg()); } @@ -518,10 +521,10 @@ FunctionType *DataFlowSanitizer::getTrampolineFunctionType(FunctionType *T) { SmallVector ArgTypes; ArgTypes.push_back(T->getPointerTo()); ArgTypes.append(T->param_begin(), T->param_end()); - ArgTypes.append(T->getNumParams(), ShadowTy); + ArgTypes.append(T->getNumParams(), PrimitiveShadowTy); Type *RetType = T->getReturnType(); if (!RetType->isVoidTy()) -ArgTypes.push_back(ShadowPtrTy); +ArgTypes.push_back(PrimitiveShadowPtrTy); return FunctionType::get(T->getReturnType(), ArgTypes, false); } @@ -547,12 +550,12 @@ TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) { } } for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) -ArgTypes.push_back(ShadowTy); +ArgTypes.push_back(PrimitiveShadowTy); if (T->isVarArg()) -ArgTypes.push_back(ShadowPtrTy); +ArgTypes.push_back(PrimitiveShadowPtrTy); Type *RetType = T->getReturnType(); if (!RetType->isVoidTy()) -ArgTypes.push_back(ShadowPtrTy); +ArgTypes.push_back(PrimitiveShadowPtrTy); return TransformedFunction( T, FunctionType::get(T->getReturnType(), ArgTypes, T->isVarArg()), ArgumentIndexMapping); @@ -570,10 +573,10 @@ bool DataFlowSanitizer::init(Module &M) { Mod = &M; Ctx = &M.getContext(); Int8Ptr = Type::getInt8PtrTy(*Ctx); - ShadowTy = IntegerType::get(*Ctx, ShadowWidthBits); - ShadowPtrTy = PointerType::getUnqual(ShadowTy); + PrimitiveShadowTy = IntegerType::get(*Ctx, ShadowWidthBits); + PrimitiveShadowPtrTy = PointerType::getUnqual(PrimitiveShadowTy); IntptrTy = DL.getIntPtrType(*Ctx); - ZeroShadow = ConstantInt::getSigned(ShadowTy, 0); + ZeroPrimitiveShadow = ConstantInt::getSigned(PrimitiveShadowTy, 0); ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidthBytes); if (IsX86_64) ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x7000LL); @@ -585,28 +588,30 @@ bool DataFlowSanitizer::init(Module &M) { else report_fatal_error("unsupported triple"); - Type *DFSanUnionArgs[2] = { ShadowTy, ShadowTy }; + Type *DFSanUnionArgs[2] = {PrimitiveShadowTy, PrimitiveShadowTy}; DFSanUnionFnTy = - FunctionType::get(ShadowTy, DFSanUnionArgs, /*isVarArg=*/ false); - Type *DFSanUnionLoadArgs[2] = { ShadowPtrTy, IntptrTy }; - DFSanUnionLoadFnTy = - FunctionType::get(ShadowTy, DFSanUnionLoadArgs, /*isVarArg=*/ false); + FunctionType::get(PrimitiveShadowTy, DFSanUnionArgs, /*isVarArg=*/false); + Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy}; + DFSanUnionLoadFnTy = FunctionType::get(PrimitiveShadowTy, DFSanUnionLoadArgs, + /*isVarArg=*/false); DFSanUni
[llvm-branch-commits] [llvm] 80e326a - [dfsan] Support passing non-i16 shadow values in TLS mode
Author: Jianzhou Zhao Date: 2020-12-04T02:45:07Z New Revision: 80e326a8c4cfae770c10d7bb3d0ae291011bd91f URL: https://github.com/llvm/llvm-project/commit/80e326a8c4cfae770c10d7bb3d0ae291011bd91f DIFF: https://github.com/llvm/llvm-project/commit/80e326a8c4cfae770c10d7bb3d0ae291011bd91f.diff LOG: [dfsan] Support passing non-i16 shadow values in TLS mode This is a child diff of D92261. It extended TLS arg/ret to work with aggregate types. For a function t foo(t1 a1, t2 a2, ... tn an) Its arguments shadow are saved in TLS args like a1_s, a2_s, ..., an_s TLS ret simply includes r_s. By calculating the type size of each shadow value, we can get their offset. This is similar to what MSan does. See __msan_retval_tls and __msan_param_tls from llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp. Note that this change does not add test cases for overflowed TLS arg/ret because this is hard to test w/o supporting aggregate shdow types. We will be adding them after supporting that. Reviewed-by: morehouse Differential Revision: https://reviews.llvm.org/D92440 Added: Modified: compiler-rt/lib/dfsan/dfsan.cpp llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp llvm/test/Instrumentation/DataFlowSanitizer/arith.ll llvm/test/Instrumentation/DataFlowSanitizer/call.ll llvm/test/Instrumentation/DataFlowSanitizer/callback.ll llvm/test/Instrumentation/DataFlowSanitizer/fast16labels.ll llvm/test/Instrumentation/DataFlowSanitizer/load.ll llvm/test/Instrumentation/DataFlowSanitizer/phi.ll llvm/test/Instrumentation/DataFlowSanitizer/select.ll Removed: diff --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp index db610857834c..c17bfe0ccb32 100644 --- a/compiler-rt/lib/dfsan/dfsan.cpp +++ b/compiler-rt/lib/dfsan/dfsan.cpp @@ -41,8 +41,15 @@ static dfsan_label_info __dfsan_label_info[kNumLabels]; Flags __dfsan::flags_data; -SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_retval_tls; -SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_arg_tls[64]; +// The size of TLS variables. These constants must be kept in sync with the ones +// in DataFlowSanitizer.cpp. +static const int kDFsanArgTlsSize = 800; +static const int kDFsanRetvalTlsSize = 800; + +SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u64 +__dfsan_retval_tls[kDFsanRetvalTlsSize / sizeof(u64)]; +SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u64 +__dfsan_arg_tls[kDFsanArgTlsSize / sizeof(u64)]; SANITIZER_INTERFACE_ATTRIBUTE uptr __dfsan_shadow_ptr_mask; diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index 9dad9817acea..fc784e72797c 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -106,6 +106,14 @@ using namespace llvm; +// This must be consistent with ShadowWidthBits. +static const Align kShadowTLSAlignment = Align(2); + +// The size of TLS variables. These constants must be kept in sync with the ones +// in dfsan.cpp. +static const unsigned kArgTLSSize = 800; +static const unsigned kRetvalTLSSize = 800; + // External symbol to be used when generating the shadow address for // architectures with multiple VMAs. Instead of using a constant integer // the runtime will set the external mask based on the VMA range. @@ -447,7 +455,14 @@ struct DFSanFunction { AvoidNewBlocks = F->size() > 1000; } - Value *getArgTLS(unsigned Index, Instruction *Pos); + /// Computes the shadow address for a given function argument. + /// + /// Shadow = ArgTLS+ArgOffset. + Value *getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB); + + /// Computes the shadow address for a retval. + Value *getRetvalTLS(IRBuilder<> &IRB); + Value *getShadow(Value *V); void setShadow(Instruction *I, Value *Shadow); Value *combineShadows(Value *V1, Value *V2, Instruction *Pos); @@ -456,6 +471,10 @@ struct DFSanFunction { Instruction *Pos); void storeShadow(Value *Addr, uint64_t Size, Align Alignment, Value *Shadow, Instruction *Pos); + +private: + /// Returns the shadow value of an argument A. + Value *getShadowForTLSArgument(Argument *A); }; class DFSanVisitor : public InstVisitor { @@ -816,13 +835,15 @@ bool DataFlowSanitizer::runImpl(Module &M) { bool Changed = false; - Type *ArgTLSTy = ArrayType::get(PrimitiveShadowTy, 64); + Type *ArgTLSTy = ArrayType::get(Type::getInt64Ty(*Ctx), kArgTLSSize / 8); ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy); if (GlobalVariable *G = dyn_cast(ArgTLS)) { Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel; G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel); } - RetvalTLS = Mod->getOrInsertGlobal("__dfsan_retval_tls", PrimitiveShadowTy); + Type *RetvalT
[llvm-branch-commits] [llvm] fa4c3f7 - [dfsan] Add a test case of storing zero
Author: Jianzhou Zhao Date: 2020-12-04T20:28:44Z New Revision: fa4c3f70ff0768a270b0620dc6d158ed1205ec4e URL: https://github.com/llvm/llvm-project/commit/fa4c3f70ff0768a270b0620dc6d158ed1205ec4e DIFF: https://github.com/llvm/llvm-project/commit/fa4c3f70ff0768a270b0620dc6d158ed1205ec4e.diff LOG: [dfsan] Add a test case of storing zero This covers a branch in storeShadow. Reviewed-by: morehouse Differential Revision: https://reviews.llvm.org/D92632 Added: Modified: llvm/test/Instrumentation/DataFlowSanitizer/store.ll Removed: diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/store.ll b/llvm/test/Instrumentation/DataFlowSanitizer/store.ll index a66cedf70b10..4560c3d7fb8f 100644 --- a/llvm/test/Instrumentation/DataFlowSanitizer/store.ll +++ b/llvm/test/Instrumentation/DataFlowSanitizer/store.ll @@ -158,3 +158,9 @@ define void @store64(i64 %v, i64* %p) { store i64 %v, i64* %p ret void } + +define void @store_zero(i32* %p) { + ; NO_COMBINE_PTR_LABEL: store i64 0, i64* {{.*}}, align 2 + store i32 0, i32* %p + ret void +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] a28db8b - [dfsan] Add empty APIs for field-level shadow
Author: Jianzhou Zhao Date: 2020-12-04T21:42:07Z New Revision: a28db8b27a232cffcb77d0f902d76ee07cd54c05 URL: https://github.com/llvm/llvm-project/commit/a28db8b27a232cffcb77d0f902d76ee07cd54c05 DIFF: https://github.com/llvm/llvm-project/commit/a28db8b27a232cffcb77d0f902d76ee07cd54c05.diff LOG: [dfsan] Add empty APIs for field-level shadow This is a child diff of D92261. This diff adds APIs that return shadow type/value/zero from origin objects. For the time being these APIs simply returns primitive shadow type/value/zero. The following diff will be implementing the conversion. As D92261 explains, some cases still use primitive shadow during the incremential changes. The cases include 1) alloca/load/store 2) custom function IO 3) vectors At the cases this diff does not use the new APIs, but uses primitive shadow objects explicitly. Reviewed-by: morehouse Differential Revision: https://reviews.llvm.org/D92629 Added: Modified: llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp Removed: diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index fc784e72797c..87cf67705324 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -419,6 +419,17 @@ class DataFlowSanitizer { bool init(Module &M); + /// Returns a zero constant with the shadow type of V's type. Until we support + /// field/index level shadow values, the following methods always return + /// primitive types, values or zero constants. + Constant *getZeroShadow(Value *V); + /// Checks if V is a zero shadow. + bool isZeroShadow(Value *V); + /// Returns the shadow type of OrigTy. + Type *getShadowTy(Type *OrigTy); + /// Returns the shadow type of of V's type. + Type *getShadowTy(Value *V); + public: DataFlowSanitizer(const std::vector &ABIListFiles); @@ -458,10 +469,10 @@ struct DFSanFunction { /// Computes the shadow address for a given function argument. /// /// Shadow = ArgTLS+ArgOffset. - Value *getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB); + Value *getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB); /// Computes the shadow address for a retval. - Value *getRetvalTLS(IRBuilder<> &IRB); + Value *getRetvalTLS(Type *T, IRBuilder<> &IRB); Value *getShadow(Value *V); void setShadow(Instruction *I, Value *Shadow); @@ -580,6 +591,20 @@ TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) { ArgumentIndexMapping); } +bool DataFlowSanitizer::isZeroShadow(Value *V) { + return ZeroPrimitiveShadow == V; +} + +Constant *DataFlowSanitizer::getZeroShadow(Value *V) { + return ZeroPrimitiveShadow; +} + +Type *DataFlowSanitizer::getShadowTy(Type *OrigTy) { return PrimitiveShadowTy; } + +Type *DataFlowSanitizer::getShadowTy(Value *V) { + return getShadowTy(V->getType()); +} + bool DataFlowSanitizer::init(Module &M) { Triple TargetTriple(M.getTargetTriple()); bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64; @@ -1075,17 +1100,17 @@ bool DataFlowSanitizer::runImpl(Module &M) { M.global_size() != InitialGlobalSize || M.size() != InitialModuleSize; } -Value *DFSanFunction::getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB) { +Value *DFSanFunction::getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB) { Value *Base = IRB.CreatePointerCast(DFS.ArgTLS, DFS.IntptrTy); if (ArgOffset) Base = IRB.CreateAdd(Base, ConstantInt::get(DFS.IntptrTy, ArgOffset)); - return IRB.CreateIntToPtr(Base, PointerType::get(DFS.PrimitiveShadowTy, 0), + return IRB.CreateIntToPtr(Base, PointerType::get(DFS.getShadowTy(T), 0), "_dfsarg"); } -Value *DFSanFunction::getRetvalTLS(IRBuilder<> &IRB) { +Value *DFSanFunction::getRetvalTLS(Type *T, IRBuilder<> &IRB) { return IRB.CreatePointerCast( - DFS.RetvalTLS, PointerType::get(DFS.PrimitiveShadowTy, 0), "_dfsret"); + DFS.RetvalTLS, PointerType::get(DFS.getShadowTy(T), 0), "_dfsret"); } Value *DFSanFunction::getShadowForTLSArgument(Argument *A) { @@ -1098,7 +1123,7 @@ Value *DFSanFunction::getShadowForTLSArgument(Argument *A) { continue; } -unsigned Size = DL.getTypeAllocSize(DFS.PrimitiveShadowTy); +unsigned Size = DL.getTypeAllocSize(DFS.getShadowTy(&FArg)); if (A != &FArg) { ArgOffset += alignTo(Size, kShadowTLSAlignment); if (ArgOffset > kArgTLSSize) @@ -,22 +1136,22 @@ Value *DFSanFunction::getShadowForTLSArgument(Argument *A) { Instruction *ArgTLSPos = &*F->getEntryBlock().begin(); IRBuilder<> IRB(ArgTLSPos); -Value *ArgShadowPtr = getArgTLS(ArgOffset, IRB); -return IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ArgShadowPtr, +Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB); +return IRB.CreateAlignedLoad
[llvm-branch-commits] [compiler-rt] ea98116 - [dfsan] Track field/index-level shadow values in variables
Author: Jianzhou Zhao Date: 2020-12-09T19:38:35Z New Revision: ea981165a4ef2d6e8be0655f04cc4b61604db6d4 URL: https://github.com/llvm/llvm-project/commit/ea981165a4ef2d6e8be0655f04cc4b61604db6d4 DIFF: https://github.com/llvm/llvm-project/commit/ea981165a4ef2d6e8be0655f04cc4b61604db6d4.diff LOG: [dfsan] Track field/index-level shadow values in variables * * The problem * See motivation examples in compiler-rt/test/dfsan/pair.cpp. The current DFSan always uses a 16bit shadow value for a variable with any type by combining all shadow values of all bytes of the variable. So it cannot distinguish two fields of a struct: each field's shadow value equals the combined shadow value of all fields. This introduces an overtaint issue. Consider a parsing function std::pair get_token(char* p); where p points to a buffer to parse, the returned pair includes the next token and the pointer to the position in the buffer after the token. If the token is tainted, then both the returned pointer and int ar tainted. If the parser keeps on using get_token for the rest parsing, all the following outputs are tainted because of the tainted pointer. The CL is the first change to address the issue. ** * The proposed improvement ** Eventually all fields and indices have their own shadow values in variables and memory. For example, variables with type {i1, i3}, [2 x i1], {[2 x i4], i8}, [2 x {i1, i1}] have shadow values with type {i16, i16}, [2 x i16], {[2 x i16], i16}, [2 x {i16, i16}] correspondingly; variables with primary type still have shadow values i16. *** * An potential implementation plan *** The idea is to adopt the change incrementially. 1) This CL Support field-level accuracy at variables/args/ret in TLS mode, load/store/alloca still use combined shadow values. After the alloca promotion and SSA construction phases (>=-O1), we assume alloca and memory operations are reduced. So if struct variables do not relate to memory, their tracking is accurate at field level. 2) Support field-level accuracy at alloca 3) Support field-level accuracy at load/store These two should make O0 and real memory access work. 4) Support vector if necessary. 5) Support Args mode if necessary. 6) Support passing more accurate shadow values via custom functions if necessary. *** * About this CL. *** The CL did the following 1) extended TLS arg/ret to work with aggregate types. This is similar to what MSan does. 2) implemented how to map between an original type/value/zero-const to its shadow type/value/zero-const. 3) extended (insert|extract)value to use field/index-level progagation. 4) for other instructions, propagation rules are combining inputs by or. The CL converts between aggragate and primary shadow values at the cases. 5) Custom function interfaces also need such a conversion because all existing custom functions use i16. It is unclear whether custome functions need more accurate shadow propagation yet. 6) Added test cases for aggregate type related cases. Reviewed-by: morehouse Differential Revision: https://reviews.llvm.org/D92261 Added: llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll llvm/test/Instrumentation/DataFlowSanitizer/array.ll llvm/test/Instrumentation/DataFlowSanitizer/struct.ll llvm/test/Instrumentation/DataFlowSanitizer/vector.ll Modified: compiler-rt/test/dfsan/pair.cpp compiler-rt/test/dfsan/struct.c llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp llvm/test/Instrumentation/DataFlowSanitizer/phi.ll llvm/test/Instrumentation/DataFlowSanitizer/store.ll Removed: diff --git a/compiler-rt/test/dfsan/pair.cpp b/compiler-rt/test/dfsan/pair.cpp index 830fe393b17b..52fa8bdde7e8 100644 --- a/compiler-rt/test/dfsan/pair.cpp +++ b/compiler-rt/test/dfsan/pair.cpp @@ -1,4 +1,5 @@ -// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -o %t && %run %t +// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O0 -DO0 -o %t && %run %t +// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O1 -o %t && %run %t #include #include @@ -64,29 +65,49 @@ void test_simple_constructors() { int i1 = pair1.second; int *ptr1 = pair1.first; +#ifdef O0 assert(dfsan_read_label(&i1, sizeof(i1)) == 10); assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10); +#else + assert(dfsan_read_label(&i1, sizeof(i1)) == 8); + assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 2); +#endif std::pair pair2 = copy_pair1(pair1); i