diff --git a/fuzzcheck/src/builder.rs b/fuzzcheck/src/builder.rs index da480c2..8cd8be4 100644 --- a/fuzzcheck/src/builder.rs +++ b/fuzzcheck/src/builder.rs @@ -289,7 +289,7 @@ where F::NormalizedFunction, ::Mutator, T::Owned, - DiverseAndMaxHitsSensor, + impl Sensor::Observations, (usize, u64))>, BasicAndDiverseAndMaxHitsPool, > { self.mutator(::default_mutator()) @@ -460,7 +460,13 @@ where pub fn default_sensor_and_pool_with_custom_filter( self, keep: impl Fn(&Path, &str) -> bool, - ) -> FuzzerBuilder4 { + ) -> FuzzerBuilder4< + F, + M, + V, + impl Sensor::Observations, (usize, u64))>, + BasicAndDiverseAndMaxHitsPool, + > { let (sensor, pool) = default_sensor_and_pool_with_custom_filter(keep).finish(); FuzzerBuilder4 { test_function: self.test_function, @@ -480,7 +486,13 @@ where /// to execute - this slows down the fuzzer. pub fn default_sensor_and_pool( self, - ) -> FuzzerBuilder4 { + ) -> FuzzerBuilder4< + F, + M, + V, + impl Sensor::Observations, (usize, u64))>, + BasicAndDiverseAndMaxHitsPool, + > { let (sensor, pool) = default_sensor_and_pool().finish(); FuzzerBuilder4 { test_function: self.test_function, @@ -694,9 +706,6 @@ pub type BasicAndMaxHitsSensor = impl WrapperSensor< Observations = (::Observations, u64), >; -pub type DiverseAndMaxHitsSensor = - impl Sensor::Observations, (usize, u64))>; - pub type BasicPool = SimplestToActivateCounterPool; pub type DiversePool = AndPool, DifferentObservations>; pub type MaxHitsPool = AndPool, DifferentObservations>; @@ -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 { +pub fn default_sensor_and_pool() -> SensorAndPoolBuilder< + impl Sensor::Observations, (usize, u64))>, + BasicAndDiverseAndMaxHitsPool, +> { basic_sensor_and_pool() .find_most_diverse_set_of_test_cases(20) .find_test_cases_repeatedly_hitting_coverage_counters() @@ -791,7 +803,10 @@ pub fn default_sensor_and_pool() -> SensorAndPoolBuilder bool, -) -> SensorAndPoolBuilder { +) -> SensorAndPoolBuilder< + impl 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() @@ -897,12 +912,22 @@ impl SensorAndPoolBuilder { SensorAndPoolBuilder { sensor, pool } } } -impl SensorAndPoolBuilder { + +impl SensorAndPoolBuilder +where + T: WrapperSensor< + Wrapped = CodeCoverageSensor, + Observations = (::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 { + ) -> SensorAndPoolBuilder< + impl Sensor::Observations, (usize, u64))>, + BasicAndDiverseAndMaxHitsPool, + > { let nbr_counters = self.sensor.wrapped().count_instrumented; let sensor = self.sensor.map( diff --git a/fuzzcheck/src/code_coverage_sensor/llvm_coverage.rs b/fuzzcheck/src/code_coverage_sensor/llvm_coverage.rs index 2d91832..b4450eb 100644 --- a/fuzzcheck/src/code_coverage_sensor/llvm_coverage.rs +++ b/fuzzcheck/src/code_coverage_sensor/llvm_coverage.rs @@ -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, 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; @@ -364,20 +363,28 @@ pub fn read_prf_data(prf_data: &[u8]) -> Result, 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: @@ -707,7 +714,7 @@ pub fn read_covmap(covmap: &[u8], idx: &mut usize) -> Result StringMutator { |value, _cplx| (value.as_bytes().len() * 8) as f64, ) } + impl DefaultMutator for String { - type Mutator = StringMutator; + type Mutator = impl Mutator; #[coverage(off)] fn default_mutator() -> Self::Mutator { diff --git a/usage_tests/basic_example.sh b/usage_tests/basic_example.sh old mode 100644 new mode 100755