mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 12:46:51 +00:00

Use libclang_rt.atomic.so instead of the libatomic installed on the system if it is available. Differential Revision: https://reviews.llvm.org/D151680
152 lines
4.4 KiB
C
152 lines
4.4 KiB
C
// RUN: %clang_dfsan -g3 -DDATA_BYTES=3 %s -fno-exceptions %libatomic -o %t && %run %t
|
|
// RUN: %clang_dfsan -g3 -DDATA_BYTES=3 -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 %s -fno-exceptions %libatomic -o %t && %run %t
|
|
// RUN: %clang_dfsan -g3 -DDATA_BYTES=32 %s -fno-exceptions %libatomic -o %t && %run %t
|
|
// RUN: %clang_dfsan -g3 -DDATA_BYTES=32 -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 %s -fno-exceptions %libatomic -o %t && %run %t
|
|
|
|
#include <assert.h>
|
|
#include <sanitizer/dfsan_interface.h>
|
|
#include <stdatomic.h>
|
|
|
|
typedef struct __attribute((packed)) {
|
|
uint8_t val[DATA_BYTES];
|
|
} idata;
|
|
|
|
void test_idata_load() {
|
|
idata dest = {-1};
|
|
idata init = {0};
|
|
|
|
dfsan_label i_label = 2;
|
|
dfsan_set_label(i_label, &init, sizeof(init));
|
|
|
|
__atomic_load(&init, &dest, __ATOMIC_RELAXED);
|
|
|
|
dfsan_label read_label = dfsan_read_label(&dest, sizeof(dest));
|
|
assert(read_label == i_label);
|
|
#ifdef ORIGIN_TRACKING
|
|
dfsan_origin read_origin =
|
|
dfsan_read_origin_of_first_taint(&dest, sizeof(dest));
|
|
assert(read_origin != 0);
|
|
#endif
|
|
}
|
|
|
|
void test_idata_store() {
|
|
idata dest = {-1};
|
|
idata init = {0};
|
|
|
|
dfsan_label i_label = 2;
|
|
dfsan_set_label(i_label, &init, sizeof(init));
|
|
|
|
__atomic_store(&init, &dest, __ATOMIC_RELAXED);
|
|
|
|
dfsan_label read_label = dfsan_read_label(&dest, sizeof(dest));
|
|
assert(read_label == i_label);
|
|
#ifdef ORIGIN_TRACKING
|
|
dfsan_origin read_origin =
|
|
dfsan_read_origin_of_first_taint(&dest, sizeof(dest));
|
|
assert(read_origin != 0);
|
|
#endif
|
|
}
|
|
|
|
void test_idata_exchange() {
|
|
idata target = {-1};
|
|
idata init = {0};
|
|
idata dest = {3};
|
|
|
|
dfsan_label i_label = 1;
|
|
dfsan_set_label(i_label, &init, sizeof(init));
|
|
dfsan_label j_label = 2;
|
|
dfsan_set_label(j_label, &target, sizeof(target));
|
|
|
|
dfsan_label dest0_label = dfsan_read_label(&dest, sizeof(dest));
|
|
assert(dest0_label == 0);
|
|
#ifdef ORIGIN_TRACKING
|
|
dfsan_origin dest0_origin =
|
|
dfsan_read_origin_of_first_taint(&dest, sizeof(dest));
|
|
assert(dest0_origin == 0);
|
|
#endif
|
|
|
|
__atomic_exchange(&target, &init, &dest, __ATOMIC_RELAXED);
|
|
|
|
dfsan_label dest_label = dfsan_read_label(&dest, sizeof(dest));
|
|
assert(dest_label == j_label);
|
|
#ifdef ORIGIN_TRACKING
|
|
dfsan_origin dest_origin =
|
|
dfsan_read_origin_of_first_taint(&dest, sizeof(dest));
|
|
assert(dest_origin != 0);
|
|
#endif
|
|
|
|
dfsan_label target_label = dfsan_read_label(&target, sizeof(target));
|
|
assert(target_label == i_label);
|
|
#ifdef ORIGIN_TRACKING
|
|
dfsan_origin target_origin =
|
|
dfsan_read_origin_of_first_taint(&target, sizeof(target));
|
|
assert(target_origin != 0);
|
|
#endif
|
|
}
|
|
|
|
void test_idata_cmp_exchange_1() {
|
|
idata target = {0};
|
|
idata expected = {0}; // Target matches expected
|
|
idata desired = {3};
|
|
|
|
dfsan_label i_label = 1;
|
|
dfsan_set_label(i_label, &expected, sizeof(expected));
|
|
dfsan_label j_label = 2;
|
|
dfsan_set_label(j_label, &target, sizeof(target));
|
|
dfsan_label k_label = 4;
|
|
dfsan_set_label(k_label, &desired, sizeof(desired));
|
|
|
|
int r =
|
|
__atomic_compare_exchange(&target, &expected, &desired, /*weak=false*/ 0,
|
|
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
|
|
// Target matches expected => true
|
|
assert(r);
|
|
|
|
// Copy desired to target.
|
|
dfsan_label target_label = dfsan_read_label(&target, sizeof(target));
|
|
assert(target_label == k_label);
|
|
#ifdef ORIGIN_TRACKING
|
|
dfsan_origin target_origin =
|
|
dfsan_read_origin_of_first_taint(&target, sizeof(target));
|
|
assert(target_origin != 0);
|
|
#endif
|
|
}
|
|
|
|
void test_idata_cmp_exchange_2() {
|
|
idata target = {0};
|
|
idata expected = {-1}; // Target does not match expected
|
|
idata desired = {3};
|
|
|
|
dfsan_label i_label = 1;
|
|
dfsan_set_label(i_label, &expected, sizeof(expected));
|
|
dfsan_label j_label = 2;
|
|
dfsan_set_label(j_label, &target, sizeof(target));
|
|
dfsan_label k_label = 4;
|
|
dfsan_set_label(k_label, &desired, sizeof(desired));
|
|
|
|
int r =
|
|
__atomic_compare_exchange(&target, &expected, &desired, /*weak=false*/ 0,
|
|
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
|
|
// Target does not match expected => false
|
|
assert(!r);
|
|
|
|
// Copy target to expected
|
|
dfsan_label expected_label = dfsan_read_label(&expected, sizeof(expected));
|
|
assert(expected_label == j_label);
|
|
#ifdef ORIGIN_TRACKING
|
|
dfsan_origin expected_origin =
|
|
dfsan_read_origin_of_first_taint(&expected, sizeof(expected));
|
|
assert(expected_origin != 0);
|
|
#endif
|
|
}
|
|
|
|
int main() {
|
|
test_idata_load();
|
|
test_idata_store();
|
|
test_idata_exchange();
|
|
test_idata_cmp_exchange_1();
|
|
test_idata_cmp_exchange_2();
|
|
|
|
return 0;
|
|
}
|