diff options
-rw-r--r-- | src/aflrun.cpp | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/src/aflrun.cpp b/src/aflrun.cpp index 60d8fab0..cc697d60 100644 --- a/src/aflrun.cpp +++ b/src/aflrun.cpp @@ -1,8 +1,5 @@ #include "aflrun.h" -#include <boost/dynamic_bitset.hpp> -namespace bo = boost; - #include <algorithm> #include <cassert> #include <cmath> @@ -1998,6 +1995,27 @@ public: } }; +class Bitset +{ + std::vector<uint_fast64_t> masks; +public: + Bitset(size_t bit_length) : masks {bit_length + 63ull >> 8ull} + {} + + /// Return if the bit at the given index is set + /// and do it in case it is not. + bool operator()(size_t index) + { + // Undefined behavior if index is out of bound + auto& mask = this->masks[index >> 8ull]; + const auto bit = 1 << (index & 63ull); + if (mask & bit) + return true; + mask |= bit; + return false; + } +}; + template<typename F> class Clusters { @@ -2191,15 +2209,14 @@ public: abort(); } size_t idx = 0; - bo::dynamic_bitset<> visited_clusters(size()); + Bitset visited_clusters {size()}; for (const auto& b : *blocks) { auto it = target_to_idx.find(b.first); - if (it == target_to_idx.end() || visited_clusters[it->second] || - cluster_tops[it->second] == nullptr) + if (it == target_to_idx.end() || + cluster_tops[it->second] == nullptr || + visited_clusters(it->second)) continue; - - visited_clusters[it->second] = true; ret_tops[idx++] = cluster_tops[it->second].get(); } return idx; @@ -3886,8 +3903,8 @@ size_t aflrun_get_virgins( // The maximum potential number of clusters is current number of cluster // plus number of new context-sensitive targets, because each target // can only increase the number of clusters by one. - bo::dynamic_bitset<> visited_clusters(clusters.size() + num); - visited_clusters[0] = true; // always skip primary cluster + Bitset visited_clusters {clusters.size() + num}; + visited_clusters(0); // always skip primary cluster size_t idx = 0; for (const ctx_t* t = targets; t < t_end; ++t) @@ -3895,10 +3912,8 @@ size_t aflrun_get_virgins( // Note that even if binary is compiled with AFLRUN_CTX_DIV, // but fuzzer is not, it can still work correctly size_t cluster = clusters.get_cluster(to_cluster_target(t)); - if (visited_clusters[cluster]) + if (visited_clusters(cluster)) continue; - visited_clusters[cluster] = true; - ret_clusters[idx] = cluster; ret_maps[idx++] = clusters.get_virgin_map(cluster); } @@ -3923,17 +3938,15 @@ size_t aflrun_get_seed_virgins(u32 seed, u8** ret_maps, size_t* ret_clusters) auto it = div_blocks->seed_blocks.find(seed); if (it == div_blocks->seed_blocks.end()) return 0; - bo::dynamic_bitset<> visited_clusters(clusters.size() + it->second.size()); - visited_clusters[0] = true; // always skip primary cluster + Bitset visited_clusters {clusters.size() + it->second.size()}; + visited_clusters(0); // always skip primary cluster size_t idx = 0; for (auto t : it->second) { size_t cluster = clusters.get_cluster(t); - if (visited_clusters[cluster]) + if (visited_clusters(cluster)) continue; - visited_clusters[cluster] = true; - ret_clusters[idx] = cluster; ret_maps[idx++] = clusters.get_virgin_map(cluster); } @@ -3947,17 +3960,15 @@ size_t aflrun_get_seed_tops(u32 seed, void*** ret_tops) auto it = div_blocks->seed_blocks.find(seed); if (it == div_blocks->seed_blocks.end()) return 0; - bo::dynamic_bitset<> visited_clusters(clusters.size() + it->second.size()); - visited_clusters[0] = true; // always skip primary cluster + Bitset visited_clusters {clusters.size() + it->second.size()}; + visited_clusters(0); // always skip primary cluster size_t idx = 0; for (auto t : it->second) { size_t cluster = clusters.get_cluster(t); - if (visited_clusters[cluster]) + if (visited_clusters(cluster)) continue; - visited_clusters[cluster] = true; - ret_tops[idx++] = clusters.get_top_rated(cluster); } return idx; |