fuzzer_context.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright (c) 2019 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "source/fuzz/fuzzer_context.h"
  15. #include <cmath>
  16. namespace spvtools {
  17. namespace fuzz {
  18. namespace {
  19. // Default <minimum, maximum> pairs of probabilities for applying various
  20. // transformations. All values are percentages. Keep them in alphabetical order.
  21. const std::pair<uint32_t, uint32_t> kChanceOfAddingDeadBreak = {5, 80};
  22. const std::pair<uint32_t, uint32_t> kChanceOfAddingDeadContinue = {5, 80};
  23. const std::pair<uint32_t, uint32_t> kChanceOfAddingNoContractionDecoration = {
  24. 5, 70};
  25. const std::pair<uint32_t, uint32_t> kChanceOfAdjustingFunctionControl = {20,
  26. 70};
  27. const std::pair<uint32_t, uint32_t> kChanceOfAdjustingLoopControl = {20, 90};
  28. const std::pair<uint32_t, uint32_t> kChanceOfAdjustingMemoryOperandsMask = {20,
  29. 90};
  30. const std::pair<uint32_t, uint32_t> kChanceOfAdjustingSelectionControl = {20,
  31. 90};
  32. const std::pair<uint32_t, uint32_t> kChanceOfCopyingObject = {20, 50};
  33. const std::pair<uint32_t, uint32_t> kChanceOfConstructingComposite = {20, 50};
  34. const std::pair<uint32_t, uint32_t> kChanceOfMovingBlockDown = {20, 50};
  35. const std::pair<uint32_t, uint32_t> kChanceOfObfuscatingConstant = {10, 90};
  36. const std::pair<uint32_t, uint32_t> kChanceOfReplacingIdWithSynonym = {10, 90};
  37. const std::pair<uint32_t, uint32_t> kChanceOfSplittingBlock = {40, 95};
  38. // Default limits for various quantities that are chosen during fuzzing.
  39. // Keep them in alphabetical order.
  40. const uint32_t kDefaultMaxLoopControlPartialCount = 100;
  41. const uint32_t kDefaultMaxLoopControlPeelCount = 100;
  42. // Default functions for controlling how deep to go during recursive
  43. // generation/transformation. Keep them in alphabetical order.
  44. const std::function<bool(uint32_t, RandomGenerator*)>
  45. kDefaultGoDeeperInConstantObfuscation =
  46. [](uint32_t current_depth, RandomGenerator* random_generator) -> bool {
  47. double chance = 1.0 / std::pow(3.0, static_cast<float>(current_depth + 1));
  48. return random_generator->RandomDouble() < chance;
  49. };
  50. } // namespace
  51. FuzzerContext::FuzzerContext(RandomGenerator* random_generator,
  52. uint32_t min_fresh_id)
  53. : random_generator_(random_generator),
  54. next_fresh_id_(min_fresh_id),
  55. go_deeper_in_constant_obfuscation_(
  56. kDefaultGoDeeperInConstantObfuscation) {
  57. chance_of_adding_dead_break_ =
  58. ChooseBetweenMinAndMax(kChanceOfAddingDeadBreak);
  59. chance_of_adding_dead_continue_ =
  60. ChooseBetweenMinAndMax(kChanceOfAddingDeadContinue);
  61. chance_of_adding_no_contraction_decoration_ =
  62. ChooseBetweenMinAndMax(kChanceOfAddingNoContractionDecoration);
  63. chance_of_adjusting_function_control_ =
  64. ChooseBetweenMinAndMax(kChanceOfAdjustingFunctionControl);
  65. chance_of_adjusting_loop_control_ =
  66. ChooseBetweenMinAndMax(kChanceOfAdjustingLoopControl);
  67. chance_of_adjusting_memory_operands_mask_ =
  68. ChooseBetweenMinAndMax(kChanceOfAdjustingMemoryOperandsMask);
  69. chance_of_adjusting_selection_control_ =
  70. ChooseBetweenMinAndMax(kChanceOfAdjustingSelectionControl);
  71. chance_of_constructing_composite_ =
  72. ChooseBetweenMinAndMax(kChanceOfConstructingComposite);
  73. chance_of_copying_object_ = ChooseBetweenMinAndMax(kChanceOfCopyingObject);
  74. chance_of_moving_block_down_ =
  75. ChooseBetweenMinAndMax(kChanceOfMovingBlockDown);
  76. chance_of_obfuscating_constant_ =
  77. ChooseBetweenMinAndMax(kChanceOfObfuscatingConstant);
  78. chance_of_replacing_id_with_synonym_ =
  79. ChooseBetweenMinAndMax(kChanceOfReplacingIdWithSynonym);
  80. chance_of_splitting_block_ = ChooseBetweenMinAndMax(kChanceOfSplittingBlock);
  81. max_loop_control_partial_count_ = kDefaultMaxLoopControlPartialCount;
  82. max_loop_control_peel_count_ = kDefaultMaxLoopControlPeelCount;
  83. }
  84. FuzzerContext::~FuzzerContext() = default;
  85. uint32_t FuzzerContext::GetFreshId() { return next_fresh_id_++; }
  86. bool FuzzerContext::ChooseEven() { return random_generator_->RandomBool(); }
  87. bool FuzzerContext::ChoosePercentage(uint32_t percentage_chance) {
  88. assert(percentage_chance <= 100);
  89. return random_generator_->RandomPercentage() < percentage_chance;
  90. }
  91. uint32_t FuzzerContext::ChooseBetweenMinAndMax(
  92. const std::pair<uint32_t, uint32_t>& min_max) {
  93. assert(min_max.first <= min_max.second);
  94. return min_max.first +
  95. random_generator_->RandomUint32(min_max.second - min_max.first + 1);
  96. }
  97. } // namespace fuzz
  98. } // namespace spvtools