aboutsummaryrefslogtreecommitdiffstats
path: root/executor/executor.cc
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-12-06 15:41:32 +0100
committerDmitry Vyukov <dvyukov@google.com>2020-12-09 09:22:14 +0100
commit4e66c6f399b8e6de865c5c00e24ce7941ffc4b74 (patch)
tree94ec48b9ab148fa29ed538245f6583d2ad8afea1 /executor/executor.cc
parent716124b06a7c7d1e482f90d16f88db80dab0964b (diff)
executor: capture outgoing edges from interesting code
Currently we capture only incoming edges into the interesting code when code coverage filter is used. Also capture outgoing edges. For code without indirect calls this does not matter as we always get the same edge. But for code with indirect edges we can capture more interesting coverage, and presumably different indirect calls are quite important.
Diffstat (limited to 'executor/executor.cc')
-rw-r--r--executor/executor.cc16
1 files changed, 10 insertions, 6 deletions
diff --git a/executor/executor.cc b/executor/executor.cc
index 10bed012c..935a90be6 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -869,18 +869,22 @@ void write_coverage_signal(cover_t* cov, uint32* signal_count_pos, uint32* cover
// Currently it is code edges computed as xor of two subsequent basic block PCs.
cover_data_t* cover_data = ((cover_data_t*)cov->data) + 1;
uint32 nsig = 0;
- cover_data_t prev = 0;
+ cover_data_t prev_pc = 0;
+ bool prev_filter = true;
for (uint32 i = 0; i < cov->size; i++) {
cover_data_t pc = cover_data[i];
if (!cover_check(pc)) {
debug("got bad pc: 0x%llx\n", (uint64)pc);
doexit(0);
}
- cover_data_t sig = pc ^ prev;
- prev = hash(pc);
- if (!coverage_filter(pc))
- continue;
- if (dedup(sig))
+ cover_data_t sig = pc ^ hash(prev_pc);
+ bool filter = coverage_filter(pc);
+ // Ignore the edge only if both current and previous PCs are filtered out
+ // to capture all incoming and outcoming edges into the interesting code.
+ bool ignore = !filter && !prev_filter;
+ prev_pc = pc;
+ prev_filter = filter;
+ if (ignore || dedup(sig))
continue;
write_output(sig);
nsig++;