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;
|