2019-05-27 16:34:55 +03:00
|
|
|
// Copyright (c) 2019 Google LLC
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
#ifndef SOURCE_FUZZ_FUZZER_CONTEXT_H_
|
|
|
|
#define SOURCE_FUZZ_FUZZER_CONTEXT_H_
|
|
|
|
|
2019-06-18 20:41:08 +03:00
|
|
|
#include <functional>
|
2019-09-23 18:29:19 +03:00
|
|
|
#include <utility>
|
2019-06-18 20:41:08 +03:00
|
|
|
|
2019-05-27 16:34:55 +03:00
|
|
|
#include "source/fuzz/random_generator.h"
|
|
|
|
#include "source/opt/function.h"
|
|
|
|
|
|
|
|
namespace spvtools {
|
|
|
|
namespace fuzz {
|
|
|
|
|
|
|
|
// Encapsulates all parameters that control the fuzzing process, such as the
|
|
|
|
// source of randomness and the probabilities with which transformations are
|
|
|
|
// applied.
|
|
|
|
class FuzzerContext {
|
|
|
|
public:
|
|
|
|
// Constructs a fuzzer context with a given random generator and the minimum
|
|
|
|
// value that can be used for fresh ids.
|
|
|
|
FuzzerContext(RandomGenerator* random_generator, uint32_t min_fresh_id);
|
|
|
|
|
|
|
|
~FuzzerContext();
|
|
|
|
|
2019-09-10 17:02:25 +03:00
|
|
|
// Returns a random boolean.
|
|
|
|
bool ChooseEven();
|
|
|
|
|
|
|
|
// Returns true if and only if a randomly-chosen integer in the range [0, 100]
|
|
|
|
// is less than |percentage_chance|.
|
|
|
|
bool ChoosePercentage(uint32_t percentage_chance);
|
|
|
|
|
|
|
|
// Returns a random index into |sequence|, which is expected to have a 'size'
|
|
|
|
// method, and which must be non-empty. Typically 'HasSizeMethod' will be an
|
|
|
|
// std::vector.
|
|
|
|
template <typename HasSizeMethod>
|
2019-09-23 18:29:19 +03:00
|
|
|
uint32_t RandomIndex(const HasSizeMethod& sequence) {
|
2019-09-10 17:02:25 +03:00
|
|
|
assert(sequence.size() > 0);
|
|
|
|
return random_generator_->RandomUint32(
|
|
|
|
static_cast<uint32_t>(sequence.size()));
|
|
|
|
}
|
2019-05-27 16:34:55 +03:00
|
|
|
|
|
|
|
// Yields an id that is guaranteed not to be used in the module being fuzzed,
|
|
|
|
// or to have been issued before.
|
|
|
|
uint32_t GetFreshId();
|
|
|
|
|
2019-05-29 18:42:46 +03:00
|
|
|
// Probabilities associated with applying various transformations.
|
|
|
|
// Keep them in alphabetical order.
|
2019-06-05 10:02:16 +03:00
|
|
|
uint32_t GetChanceOfAddingDeadBreak() { return chance_of_adding_dead_break_; }
|
2019-07-25 15:50:33 +03:00
|
|
|
uint32_t GetChanceOfAddingDeadContinue() {
|
|
|
|
return chance_of_adding_dead_continue_;
|
|
|
|
}
|
2019-10-11 11:15:47 +03:00
|
|
|
uint32_t GetChanceOfAddingNoContractionDecoration() {
|
|
|
|
return chance_of_adding_no_contraction_decoration_;
|
|
|
|
}
|
2019-10-11 09:10:47 +03:00
|
|
|
uint32_t GetChanceOfAdjustingFunctionControl() {
|
|
|
|
return chance_of_adjusting_function_control_;
|
|
|
|
}
|
2019-10-10 15:34:38 +03:00
|
|
|
uint32_t GetChanceOfAdjustingLoopControl() {
|
|
|
|
return chance_of_adjusting_loop_control_;
|
|
|
|
}
|
2019-10-22 20:05:35 +03:00
|
|
|
uint32_t GetChanceOfAdjustingMemoryOperandsMask() {
|
|
|
|
return chance_of_adjusting_memory_operands_mask_;
|
|
|
|
}
|
2019-10-08 13:25:34 +03:00
|
|
|
uint32_t GetChanceOfAdjustingSelectionControl() {
|
|
|
|
return chance_of_adjusting_selection_control_;
|
|
|
|
}
|
2019-10-08 16:04:10 +03:00
|
|
|
uint32_t GetChanceOfConstructingComposite() {
|
|
|
|
return chance_of_constructing_composite_;
|
|
|
|
}
|
2019-09-12 01:45:20 +03:00
|
|
|
uint32_t GetChanceOfCopyingObject() { return chance_of_copying_object_; }
|
2019-05-31 11:59:06 +03:00
|
|
|
uint32_t GetChanceOfMovingBlockDown() { return chance_of_moving_block_down_; }
|
2019-06-18 20:41:08 +03:00
|
|
|
uint32_t GetChanceOfObfuscatingConstant() {
|
|
|
|
return chance_of_obfuscating_constant_;
|
|
|
|
}
|
2019-09-18 22:47:08 +03:00
|
|
|
uint32_t GetChanceOfReplacingIdWithSynonym() {
|
|
|
|
return chance_of_replacing_id_with_synonym_;
|
|
|
|
}
|
2019-06-07 00:22:35 +03:00
|
|
|
uint32_t GetChanceOfSplittingBlock() { return chance_of_splitting_block_; }
|
2019-10-10 15:34:38 +03:00
|
|
|
uint32_t GetRandomLoopControlPeelCount() {
|
|
|
|
return random_generator_->RandomUint32(max_loop_control_peel_count_);
|
|
|
|
}
|
|
|
|
uint32_t GetRandomLoopControlPartialCount() {
|
|
|
|
return random_generator_->RandomUint32(max_loop_control_partial_count_);
|
|
|
|
}
|
2019-05-29 18:42:46 +03:00
|
|
|
|
2019-09-10 17:02:25 +03:00
|
|
|
// Functions to control how deeply to recurse.
|
2019-06-18 20:41:08 +03:00
|
|
|
// Keep them in alphabetical order.
|
2019-09-10 17:02:25 +03:00
|
|
|
bool GoDeeperInConstantObfuscation(uint32_t depth) {
|
|
|
|
return go_deeper_in_constant_obfuscation_(depth, random_generator_);
|
2019-06-18 20:41:08 +03:00
|
|
|
}
|
|
|
|
|
2019-05-27 16:34:55 +03:00
|
|
|
private:
|
|
|
|
// The source of randomness.
|
|
|
|
RandomGenerator* random_generator_;
|
|
|
|
// The next fresh id to be issued.
|
|
|
|
uint32_t next_fresh_id_;
|
2019-05-29 18:42:46 +03:00
|
|
|
|
|
|
|
// Probabilities associated with applying various transformations.
|
|
|
|
// Keep them in alphabetical order.
|
2019-06-05 10:02:16 +03:00
|
|
|
uint32_t chance_of_adding_dead_break_;
|
2019-07-25 15:50:33 +03:00
|
|
|
uint32_t chance_of_adding_dead_continue_;
|
2019-10-11 11:15:47 +03:00
|
|
|
uint32_t chance_of_adding_no_contraction_decoration_;
|
2019-10-11 09:10:47 +03:00
|
|
|
uint32_t chance_of_adjusting_function_control_;
|
2019-10-10 15:34:38 +03:00
|
|
|
uint32_t chance_of_adjusting_loop_control_;
|
2019-10-22 20:05:35 +03:00
|
|
|
uint32_t chance_of_adjusting_memory_operands_mask_;
|
2019-10-08 13:25:34 +03:00
|
|
|
uint32_t chance_of_adjusting_selection_control_;
|
2019-10-08 16:04:10 +03:00
|
|
|
uint32_t chance_of_constructing_composite_;
|
2019-09-12 01:45:20 +03:00
|
|
|
uint32_t chance_of_copying_object_;
|
2019-05-31 11:59:06 +03:00
|
|
|
uint32_t chance_of_moving_block_down_;
|
2019-06-18 20:41:08 +03:00
|
|
|
uint32_t chance_of_obfuscating_constant_;
|
2019-09-18 22:47:08 +03:00
|
|
|
uint32_t chance_of_replacing_id_with_synonym_;
|
2019-05-29 18:42:46 +03:00
|
|
|
uint32_t chance_of_splitting_block_;
|
2019-06-18 20:41:08 +03:00
|
|
|
|
2019-10-10 15:34:38 +03:00
|
|
|
// Limits associated with various quantities for which random values are
|
|
|
|
// chosen during fuzzing.
|
|
|
|
// Keep them in alphabetical order.
|
|
|
|
uint32_t max_loop_control_partial_count_;
|
|
|
|
uint32_t max_loop_control_peel_count_;
|
|
|
|
|
2019-06-18 20:41:08 +03:00
|
|
|
// Functions to determine with what probability to go deeper when generating
|
|
|
|
// or mutating constructs recursively.
|
|
|
|
const std::function<bool(uint32_t, RandomGenerator*)>&
|
|
|
|
go_deeper_in_constant_obfuscation_;
|
2019-09-23 18:29:19 +03:00
|
|
|
|
|
|
|
// Requires |min_max.first| <= |min_max.second|, and returns a value in the
|
|
|
|
// range [ |min_max.first|, |min_max.second| ]
|
|
|
|
uint32_t ChooseBetweenMinAndMax(const std::pair<uint32_t, uint32_t>& min_max);
|
2019-05-27 16:34:55 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace fuzz
|
|
|
|
} // namespace spvtools
|
|
|
|
|
|
|
|
#endif // SOURCE_FUZZ_FUZZER_CONTEXT_H_
|