Skip to content

Commit

Permalink
Merge pull request #45 from teymour-aldridge/tait-problems
Browse files Browse the repository at this point in the history
Upgrade to newest LLVM/Rust versions
  • Loading branch information
teymour-aldridge authored Aug 16, 2024
2 parents 9077693 + 7632452 commit 2acc737
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 25 deletions.
45 changes: 35 additions & 10 deletions fuzzcheck/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ where
F::NormalizedFunction,
<T::Owned as DefaultMutator>::Mutator,
T::Owned,
DiverseAndMaxHitsSensor,
impl Sensor<Observations = (<CodeCoverageSensor as Sensor>::Observations, (usize, u64))>,
BasicAndDiverseAndMaxHitsPool,
> {
self.mutator(<T::Owned as DefaultMutator>::default_mutator())
Expand Down Expand Up @@ -460,7 +460,13 @@ where
pub fn default_sensor_and_pool_with_custom_filter(
self,
keep: impl Fn(&Path, &str) -> bool,
) -> FuzzerBuilder4<F, M, V, DiverseAndMaxHitsSensor, BasicAndDiverseAndMaxHitsPool> {
) -> FuzzerBuilder4<
F,
M,
V,
impl Sensor<Observations = (<CodeCoverageSensor as Sensor>::Observations, (usize, u64))>,
BasicAndDiverseAndMaxHitsPool,
> {
let (sensor, pool) = default_sensor_and_pool_with_custom_filter(keep).finish();
FuzzerBuilder4 {
test_function: self.test_function,
Expand All @@ -480,7 +486,13 @@ where
/// to execute - this slows down the fuzzer.
pub fn default_sensor_and_pool(
self,
) -> FuzzerBuilder4<F, M, V, DiverseAndMaxHitsSensor, BasicAndDiverseAndMaxHitsPool> {
) -> FuzzerBuilder4<
F,
M,
V,
impl Sensor<Observations = (<CodeCoverageSensor as Sensor>::Observations, (usize, u64))>,
BasicAndDiverseAndMaxHitsPool,
> {
let (sensor, pool) = default_sensor_and_pool().finish();
FuzzerBuilder4 {
test_function: self.test_function,
Expand Down Expand Up @@ -694,9 +706,6 @@ pub type BasicAndMaxHitsSensor = impl WrapperSensor<
Observations = (<CodeCoverageSensor as Sensor>::Observations, u64),
>;

pub type DiverseAndMaxHitsSensor =
impl Sensor<Observations = (<CodeCoverageSensor as Sensor>::Observations, (usize, u64))>;

pub type BasicPool = SimplestToActivateCounterPool;
pub type DiversePool = AndPool<MostNDiversePool, MaximiseObservationPool<u64>, DifferentObservations>;
pub type MaxHitsPool = AndPool<MaximiseEachCounterPool, MaximiseObservationPool<u64>, DifferentObservations>;
Expand Down Expand Up @@ -780,7 +789,10 @@ pub fn basic_sensor_and_pool_with_custom_filter(
/// Currently, the result cannot be augmented any further. Thus, the only action you can take on the result is to
/// use [`.finish()`](SensorAndPoolBuilder::finish) to obtain the concrete sensor and pool.
#[coverage(off)]
pub fn default_sensor_and_pool() -> SensorAndPoolBuilder<DiverseAndMaxHitsSensor, BasicAndDiverseAndMaxHitsPool> {
pub fn default_sensor_and_pool() -> SensorAndPoolBuilder<
impl Sensor<Observations = (<CodeCoverageSensor as Sensor>::Observations, (usize, u64))>,
BasicAndDiverseAndMaxHitsPool,
> {
basic_sensor_and_pool()
.find_most_diverse_set_of_test_cases(20)
.find_test_cases_repeatedly_hitting_coverage_counters()
Expand All @@ -791,7 +803,10 @@ pub fn default_sensor_and_pool() -> SensorAndPoolBuilder<DiverseAndMaxHitsSensor
#[coverage(off)]
pub fn default_sensor_and_pool_with_custom_filter(
keep: impl Fn(&Path, &str) -> bool,
) -> SensorAndPoolBuilder<DiverseAndMaxHitsSensor, BasicAndDiverseAndMaxHitsPool> {
) -> SensorAndPoolBuilder<
impl Sensor<Observations = (<CodeCoverageSensor as Sensor>::Observations, (usize, u64))>,
BasicAndDiverseAndMaxHitsPool,
> {
basic_sensor_and_pool_with_custom_filter(keep)
.find_most_diverse_set_of_test_cases(20)
.find_test_cases_repeatedly_hitting_coverage_counters()
Expand Down Expand Up @@ -897,12 +912,22 @@ impl SensorAndPoolBuilder<BasicSensor, BasicPool> {
SensorAndPoolBuilder { sensor, pool }
}
}
impl SensorAndPoolBuilder<DiverseSensor, BasicAndDiversePool> {

impl<T> SensorAndPoolBuilder<T, BasicAndDiversePool>
where
T: WrapperSensor<
Wrapped = CodeCoverageSensor,
Observations = (<CodeCoverageSensor as Sensor>::Observations, usize),
>,
{
/// Augment the current pool such that it also tries to find test cases repeatedly hitting the same regions of code.
#[coverage(off)]
pub fn find_test_cases_repeatedly_hitting_coverage_counters(
self,
) -> SensorAndPoolBuilder<DiverseAndMaxHitsSensor, BasicAndDiverseAndMaxHitsPool> {
) -> SensorAndPoolBuilder<
impl Sensor<Observations = (<CodeCoverageSensor as Sensor>::Observations, (usize, u64))>,
BasicAndDiverseAndMaxHitsPool,
> {
let nbr_counters = self.sensor.wrapped().count_instrumented;

let sensor = self.sensor.map(
Expand Down
35 changes: 21 additions & 14 deletions fuzzcheck/src/code_coverage_sensor/llvm_coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,17 +342,16 @@ pub struct PrfData {
}

#[coverage(off)]
/// This function reads the __llvm_prf_data section.
///
/// ### Implementation notes
/// The `__llvm_prf_data`/profile data section is a list of structs which
/// contain data about the functions which are being instrumented.
///
/// The struct definition can be found here (this is fixed to a given commit, so
/// you may need to look at more recent ones):
/// https://github.com/llvm/llvm-project/blob/7c3b67d2038cfb48a80299089f6a1308eee1df7f/compiler-rt/include/profile/InstrProfData.inc#L65-L95
pub fn read_prf_data(prf_data: &[u8]) -> Result<Vec<PrfData>, ReadCovMapError> {
// Read the prf_data section.
//
// The problem is that there is no clear reference for it, and its format can be updated by newer LLVM versions
//
// Look at this commit: https://github.com/llvm/llvm-project/commit/24c615fa6b6b7910c8743f9044226499adfac4e6
// (as well as the commit it references) for a few of the files involved in generating the prf_data section, which
// can then be used to implement this function
//
// In particular, look at InstrProfData.inc

let mut counts = Vec::new();
let mut idx = 0;

Expand All @@ -364,20 +363,28 @@ pub fn read_prf_data(prf_data: &[u8]) -> Result<Vec<PrfData>, ReadCovMapError> {
structural_hash,
};
let _relative_counter_ptr = read_u64(prf_data, &mut idx);
let _relative_bitmap_ptr = read_u64(prf_data, &mut idx);
let _function_ptr = read_u64(prf_data, &mut idx);
let _values = read_u64(prf_data, &mut idx); // values are only used for PGO, not coverage instrumentation

// u32 counters
let nbr_counters = read_u32(prf_data, &mut idx);

assert!(nbr_counters >= 1);

if structural_hash == 0 {
// it is a dummy function, so it doesn't have counters
// 1 counter seems to be the minimum for some reason
assert!(nbr_counters <= 1);
assert!(nbr_counters <= 1, "actual number = {nbr_counters}");
}

// u16 but aligned
let _num_value_site = read_i16(prf_data, &mut idx); // this is used for PGO only, I think
idx += 2; // alignment
let _num_value_site_1 = read_i16(prf_data, &mut idx); // this is used for PGO only, I think
let _num_value_site_2 = read_i16(prf_data, &mut idx);

let _num_bitmap_bytes = read_u32(prf_data, &mut idx);

idx += 4;

// This is no longer a valid check with LLVM 14.0, I think?
// Maybe due to:
Expand Down Expand Up @@ -707,7 +714,7 @@ pub fn read_covmap(covmap: &[u8], idx: &mut usize) -> Result<CovMap, ReadCovMapE
let length_encoded_data = read_i32(covmap, idx) as usize;
let _always_0 = read_i32(covmap, idx);
let version = read_i32(covmap, idx);
if (3..=5).contains(&version) == false {
if (3..=6).contains(&version) == false {
return Err(ReadCovMapError::InvalidVersion(version));
}

Expand Down
3 changes: 2 additions & 1 deletion fuzzcheck/src/mutators/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ pub fn string_mutator() -> StringMutator {
|value, _cplx| (value.as_bytes().len() * 8) as f64,
)
}

impl DefaultMutator for String {
type Mutator = StringMutator;
type Mutator = impl Mutator<String>;

#[coverage(off)]
fn default_mutator() -> Self::Mutator {
Expand Down
Empty file modified usage_tests/basic_example.sh
100644 → 100755
Empty file.

0 comments on commit 2acc737

Please sign in to comment.