forked from halide/Halide
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement SanitizerCoverage support (Refs. halide#6513)
Please refer to https://clang.llvm.org/docs/SanitizerCoverage.html TLDR: `ModuleSanitizerCoveragePass` instruments the IR by inserting calls to callbacks at certain constructs. What the callbacks should do is up to the implementation. They are effectively required for fuzzing to be effective, and are provided by e.g. libfuzzer. One huge caveat is `SanitizerCoverageOptions` which controls which which callbacks should actually be inserted. I just don't know what to do about it. Right now i have hardcoded the set that would have been enabled by `-fsanitize=fuzzer-no-link`, because the alternative, due to halide unflexibility, would be to introduce ~16 suboptions to control each one.
Showing
10 changed files
with
211 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
#include "HalideBuffer.h" | ||
#include "HalideRuntime.h" | ||
#include "sancov.h" | ||
|
||
#include <iostream> | ||
#include <limits> | ||
#include <type_traits> | ||
#include <vector> | ||
|
||
using namespace std; | ||
using namespace Halide::Runtime; | ||
|
||
bool seen_8bit_counters_init = false; | ||
bool seen_pcs_init = false; | ||
bool seen_trace_cmp1 = false; | ||
bool seen_trace_cmp4 = false; | ||
bool seen_trace_cmp8 = false; | ||
bool seen_trace_const_cmp1 = false; | ||
bool seen_trace_const_cmp2 = false; | ||
bool seen_trace_const_cmp4 = false; | ||
bool seen_trace_const_cmp8 = false; | ||
bool seen_trace_pc_indir = false; | ||
bool seen_trace_switch = false; | ||
|
||
// Used by -fsanitize-coverage=stack-depth to track stack depth | ||
__attribute__((tls_model("initial-exec"))) thread_local uintptr_t __sancov_lowest_stack; | ||
|
||
extern "C" void __sanitizer_cov_8bit_counters_init(uint8_t *Start, uint8_t *Stop) { | ||
seen_8bit_counters_init = true; | ||
} | ||
|
||
extern "C" void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg, | ||
const uintptr_t *pcs_end) { | ||
seen_pcs_init = true; | ||
} | ||
|
||
extern "C" void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) { | ||
seen_trace_cmp1 = true; | ||
} | ||
|
||
extern "C" void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) { | ||
seen_trace_cmp4 = true; | ||
} | ||
|
||
extern "C" void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) { | ||
seen_trace_cmp8 = true; | ||
} | ||
|
||
extern "C" void __sanitizer_cov_trace_const_cmp1(uint8_t Arg1, uint8_t Arg2) { | ||
seen_trace_const_cmp1 = true; | ||
} | ||
|
||
extern "C" void __sanitizer_cov_trace_const_cmp2(uint16_t Arg1, uint16_t Arg2) { | ||
seen_trace_const_cmp2 = true; | ||
} | ||
|
||
extern "C" void __sanitizer_cov_trace_const_cmp4(uint32_t Arg1, uint32_t Arg2) { | ||
seen_trace_const_cmp4 = true; | ||
} | ||
|
||
extern "C" void __sanitizer_cov_trace_const_cmp8(uint64_t Arg1, uint64_t Arg2) { | ||
seen_trace_const_cmp8 = true; | ||
} | ||
|
||
extern "C" void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases) { | ||
seen_trace_switch = true; | ||
} | ||
|
||
extern "C" void __sanitizer_cov_trace_pc_indir(uintptr_t Callee) { | ||
seen_trace_pc_indir = true; | ||
} | ||
|
||
template<typename T> | ||
void clear_out(T &image) { | ||
image.for_each_element([&](int x, int y, int c) { | ||
image(x, y, c) = -42; | ||
}); | ||
} | ||
|
||
template<typename T> | ||
void verify_out(const T &image) { | ||
image.for_each_element([&](int x, int y, int c) { | ||
int expected = 42 + c; | ||
int actual = image(x, y, c); | ||
if (actual != expected) { | ||
fprintf(stderr, "Failure @ %d %d %d: expected %d, got %d\n", x, y, c, expected, actual); | ||
exit(-1); | ||
} | ||
}); | ||
} | ||
|
||
void verify_coverage(bool should_have_seen) { | ||
if (seen_8bit_counters_init != true) { | ||
fprintf(stderr, "Failure @ seen_8bit_counters_init"); | ||
exit(-1); | ||
} | ||
if (seen_pcs_init != true) { | ||
fprintf(stderr, "Failure @ seen_pcs_init"); | ||
exit(-1); | ||
} | ||
if (seen_trace_cmp1 != false) { | ||
fprintf(stderr, "Failure @ seen_trace_cmp1"); | ||
exit(-1); | ||
} | ||
if (seen_trace_cmp4 != false) { | ||
fprintf(stderr, "Failure @ seen_trace_cmp4"); | ||
exit(-1); | ||
} | ||
if (seen_trace_cmp8 != false) { | ||
fprintf(stderr, "Failure @ seen_trace_cmp8"); | ||
exit(-1); | ||
} | ||
if (seen_trace_const_cmp1 != false) { | ||
fprintf(stderr, "Failure @ seen_trace_const_cmp1"); | ||
exit(-1); | ||
} | ||
if (seen_trace_const_cmp2 != false) { | ||
fprintf(stderr, "Failure @ seen_trace_const_cmp2"); | ||
exit(-1); | ||
} | ||
if (seen_trace_const_cmp4 != should_have_seen) { | ||
fprintf(stderr, "Failure @ seen_trace_const_cmp4"); | ||
exit(-1); | ||
} | ||
if (seen_trace_const_cmp8 != should_have_seen) { | ||
fprintf(stderr, "Failure @ seen_trace_const_cmp8"); | ||
exit(-1); | ||
} | ||
if (seen_trace_pc_indir != false) { | ||
fprintf(stderr, "Failure @ seen_trace_pc_indir"); | ||
exit(-1); | ||
} | ||
if (seen_trace_switch != should_have_seen) { | ||
fprintf(stderr, "Failure @ seen_trace_switch"); | ||
exit(-1); | ||
} | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
|
||
int main() { | ||
auto out = Buffer<uint8_t>(4, 4, 3); | ||
clear_out(out); | ||
verify_coverage(/*should_have_seen=*/false); | ||
if (sancov(out) != 0) { | ||
fprintf(stderr, "Failure!\n"); | ||
exit(-1); | ||
} | ||
verify_coverage(/*should_have_seen=*/true); | ||
verify_out(out); | ||
|
||
printf("Success!\n"); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include "Halide.h" | ||
|
||
namespace { | ||
|
||
class SANCOV : public Halide::Generator<SANCOV> { | ||
public: | ||
Output<Buffer<uint8_t>> output{"output", 3}; | ||
|
||
void generate() { | ||
// Currently the test just exercises Target::SANCOV | ||
output(x, y, c) = cast<uint8_t>(42 + c); | ||
} | ||
|
||
void schedule() { | ||
output.dim(0).set_stride(Expr()).set_extent(4).dim(1).set_extent(4).dim(2).set_extent(3); | ||
} | ||
|
||
private: | ||
// Currently the test just exercises Target::SANCOV | ||
Var x, y, c; | ||
}; | ||
|
||
} // namespace | ||
|
||
HALIDE_REGISTER_GENERATOR(SANCOV, sancov) |