Skip to content

Commit 8103b07

Browse files
committed
[sanitizer coverage] add a basic default implementation of callbacks for -fsanitize-coverage=inline-8bit-counters,pc-table
[sanitizer coverage] add a basic default implementation of callbacks for -fsanitize-coverage=inline-8bit-counters,pc-table Reviewed By: kostik Differential Revision: https://reviews.llvm.org/D108405
1 parent d7e2e97 commit 8103b07

File tree

5 files changed

+81
-7
lines changed

5 files changed

+81
-7
lines changed

compiler-rt/lib/dfsan/dfsan_custom.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2489,7 +2489,8 @@ pid_t __dfso_fork(dfsan_label *ret_label, dfsan_origin *ret_origin) {
24892489
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32 *) {}
24902490
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, u32 *,
24912491
u32 *) {}
2492-
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, void) {}
2492+
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, const uptr *beg,
2493+
const uptr *end) {}
24932494
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, void) {}
24942495

24952496
SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp, void) {}

compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,44 @@ class TracePcGuardController {
151151

152152
static TracePcGuardController pc_guard_controller;
153153

154+
// A basic default implementation of callbacks for
155+
// -fsanitize-coverage=inline-8bit-counters,pc-table.
156+
// Use TOOL_OPTIONS (UBSAN_OPTIONS, etc) to dump the coverage data:
157+
// * cov_8bit_counters_out=PATH to dump the 8bit counters.
158+
// * cov_pcs_out=PATH to dump the pc table.
159+
//
160+
// Most users will still need to define their own callbacks for greater
161+
// flexibility.
162+
namespace SingletonCounterCoverage {
163+
164+
static char *counters_start, *counters_end;
165+
166+
static void DumpCoverage() {
167+
const char* file_path = common_flags()->cov_8bit_counters_out;
168+
if (!file_path || !internal_strlen(file_path))
169+
return;
170+
fd_t fd = OpenFile(file_path);
171+
FileCloser file_closer(fd);
172+
WriteToFile(fd, counters_start, counters_end - counters_start);
173+
}
174+
175+
static void Cov8bitCountersInit(char* beg, char* end) {
176+
counters_start = beg;
177+
counters_end = end;
178+
Atexit(DumpCoverage);
179+
}
180+
181+
static void CovPcsInit(const uptr* pcs_beg, const uptr* pcs_end) {
182+
const char* file_path = common_flags()->cov_pcs_out;
183+
if (!file_path || !internal_strlen(file_path))
184+
return;
185+
fd_t fd = OpenFile(file_path);
186+
FileCloser file_closer(fd);
187+
WriteToFile(fd, pcs_beg, (pcs_end - pcs_beg) * sizeof(uptr));
188+
}
189+
190+
} // namespace SingletonCounterCoverage
191+
154192
} // namespace
155193
} // namespace __sancov
156194

@@ -191,7 +229,9 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() {
191229
SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_reset() {
192230
__sancov::pc_guard_controller.Reset();
193231
}
194-
// Default empty implementations (weak). Users should redefine them.
232+
// Default implementations (weak).
233+
// Either empty or very simple.
234+
// Most users should redefine them.
195235
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_cmp, void) {}
196236
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_cmp1, void) {}
197237
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_cmp2, void) {}
@@ -206,9 +246,15 @@ SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_div4, void) {}
206246
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_div8, void) {}
207247
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_gep, void) {}
208248
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, void) {}
209-
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_8bit_counters_init, void) {}
249+
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_8bit_counters_init,
250+
char* start, char* end) {
251+
__sancov::SingletonCounterCoverage::Cov8bitCountersInit(start, end);
252+
}
210253
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_bool_flag_init, void) {}
211-
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, void) {}
254+
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, const uptr* beg,
255+
const uptr* end) {
256+
__sancov::SingletonCounterCoverage::CovPcsInit(beg, end);
257+
}
212258
} // extern "C"
213259
// Weak definition for code instrumented with -fsanitize-coverage=stack-depth
214260
// and later linked with code containing a strong definition.

compiler-rt/lib/sanitizer_common/sanitizer_flags.inc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ COMMON_FLAG(
160160
COMMON_FLAG(const char *, coverage_dir, ".",
161161
"Target directory for coverage dumps. Defaults to the current "
162162
"directory.")
163+
COMMON_FLAG(const char *, cov_8bit_counters_out, "",
164+
"If non-empty, write 8bit counters to this file. ")
165+
COMMON_FLAG(const char *, cov_pcs_out, "",
166+
"If non-empty, write the coverage pc table to this file. ")
163167
COMMON_FLAG(bool, full_address_space, false,
164168
"Sanitize complete address space; "
165169
"by default kernel area on 32-bit platforms will not be sanitized")

compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,13 @@ extern "C" {
111111
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
112112
void __sanitizer_cov_trace_pc_guard_init(__sanitizer::u32*,
113113
__sanitizer::u32*);
114-
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
115-
void __sanitizer_cov_8bit_counters_init();
114+
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void
115+
__sanitizer_cov_8bit_counters_init(char *, char *);
116116
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void
117117
__sanitizer_cov_bool_flag_init();
118118
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void
119-
__sanitizer_cov_pcs_init();
119+
__sanitizer_cov_pcs_init(const __sanitizer::uptr *,
120+
const __sanitizer::uptr *);
120121
} // extern "C"
121122

122123
#endif // SANITIZER_INTERFACE_INTERNAL_H
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Tests the default implementation of callbacks for
2+
// -fsanitize-coverage=inline-8bit-counters,pc-table
3+
4+
// REQUIRES: has_sancovcc,stable-runtime,linux,x86_64-target-arch
5+
6+
// RUN: %clangxx -O0 %s -fsanitize-coverage=inline-8bit-counters,pc-table -o %t
7+
// RUN: rm -f %t-counters %t-pcs
8+
// RUN: env %tool_options="cov_8bit_counters_out=%t-counters cov_pcs_out=%t-pcs" %run %t 2>&1 | FileCheck %s
9+
10+
// Check the file sizes
11+
// RUN: wc -c %t-counters | grep "^2 "
12+
// RUN: wc -c %t-pcs | grep "^32 "
13+
14+
#include <stdio.h>
15+
16+
__attribute__((noinline)) void foo() {}
17+
int main() {
18+
foo();
19+
foo();
20+
fprintf(stderr, "PASS\n");
21+
// CHECK: PASS
22+
}

0 commit comments

Comments
 (0)