// 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.

#include "source/fuzz/fuzzer.h"

#include <cassert>
#include <memory>
#include <numeric>

#include "source/fuzz/fact_manager/fact_manager.h"
#include "source/fuzz/fuzzer_context.h"
#include "source/fuzz/fuzzer_pass_add_access_chains.h"
#include "source/fuzz/fuzzer_pass_add_bit_instruction_synonyms.h"
#include "source/fuzz/fuzzer_pass_add_composite_inserts.h"
#include "source/fuzz/fuzzer_pass_add_composite_types.h"
#include "source/fuzz/fuzzer_pass_add_copy_memory.h"
#include "source/fuzz/fuzzer_pass_add_dead_blocks.h"
#include "source/fuzz/fuzzer_pass_add_dead_breaks.h"
#include "source/fuzz/fuzzer_pass_add_dead_continues.h"
#include "source/fuzz/fuzzer_pass_add_equation_instructions.h"
#include "source/fuzz/fuzzer_pass_add_function_calls.h"
#include "source/fuzz/fuzzer_pass_add_global_variables.h"
#include "source/fuzz/fuzzer_pass_add_image_sample_unused_components.h"
#include "source/fuzz/fuzzer_pass_add_loads.h"
#include "source/fuzz/fuzzer_pass_add_local_variables.h"
#include "source/fuzz/fuzzer_pass_add_loop_preheaders.h"
#include "source/fuzz/fuzzer_pass_add_loops_to_create_int_constant_synonyms.h"
#include "source/fuzz/fuzzer_pass_add_no_contraction_decorations.h"
#include "source/fuzz/fuzzer_pass_add_opphi_synonyms.h"
#include "source/fuzz/fuzzer_pass_add_parameters.h"
#include "source/fuzz/fuzzer_pass_add_relaxed_decorations.h"
#include "source/fuzz/fuzzer_pass_add_stores.h"
#include "source/fuzz/fuzzer_pass_add_synonyms.h"
#include "source/fuzz/fuzzer_pass_add_vector_shuffle_instructions.h"
#include "source/fuzz/fuzzer_pass_adjust_branch_weights.h"
#include "source/fuzz/fuzzer_pass_adjust_function_controls.h"
#include "source/fuzz/fuzzer_pass_adjust_loop_controls.h"
#include "source/fuzz/fuzzer_pass_adjust_memory_operands_masks.h"
#include "source/fuzz/fuzzer_pass_adjust_selection_controls.h"
#include "source/fuzz/fuzzer_pass_apply_id_synonyms.h"
#include "source/fuzz/fuzzer_pass_construct_composites.h"
#include "source/fuzz/fuzzer_pass_copy_objects.h"
#include "source/fuzz/fuzzer_pass_donate_modules.h"
#include "source/fuzz/fuzzer_pass_duplicate_regions_with_selections.h"
#include "source/fuzz/fuzzer_pass_flatten_conditional_branches.h"
#include "source/fuzz/fuzzer_pass_inline_functions.h"
#include "source/fuzz/fuzzer_pass_interchange_signedness_of_integer_operands.h"
#include "source/fuzz/fuzzer_pass_interchange_zero_like_constants.h"
#include "source/fuzz/fuzzer_pass_invert_comparison_operators.h"
#include "source/fuzz/fuzzer_pass_make_vector_operations_dynamic.h"
#include "source/fuzz/fuzzer_pass_merge_blocks.h"
#include "source/fuzz/fuzzer_pass_merge_function_returns.h"
#include "source/fuzz/fuzzer_pass_mutate_pointers.h"
#include "source/fuzz/fuzzer_pass_obfuscate_constants.h"
#include "source/fuzz/fuzzer_pass_outline_functions.h"
#include "source/fuzz/fuzzer_pass_permute_blocks.h"
#include "source/fuzz/fuzzer_pass_permute_function_parameters.h"
#include "source/fuzz/fuzzer_pass_permute_instructions.h"
#include "source/fuzz/fuzzer_pass_permute_phi_operands.h"
#include "source/fuzz/fuzzer_pass_propagate_instructions_down.h"
#include "source/fuzz/fuzzer_pass_propagate_instructions_up.h"
#include "source/fuzz/fuzzer_pass_push_ids_through_variables.h"
#include "source/fuzz/fuzzer_pass_replace_adds_subs_muls_with_carrying_extended.h"
#include "source/fuzz/fuzzer_pass_replace_branches_from_dead_blocks_with_exits.h"
#include "source/fuzz/fuzzer_pass_replace_copy_memories_with_loads_stores.h"
#include "source/fuzz/fuzzer_pass_replace_copy_objects_with_stores_loads.h"
#include "source/fuzz/fuzzer_pass_replace_irrelevant_ids.h"
#include "source/fuzz/fuzzer_pass_replace_linear_algebra_instructions.h"
#include "source/fuzz/fuzzer_pass_replace_loads_stores_with_copy_memories.h"
#include "source/fuzz/fuzzer_pass_replace_opphi_ids_from_dead_predecessors.h"
#include "source/fuzz/fuzzer_pass_replace_opselects_with_conditional_branches.h"
#include "source/fuzz/fuzzer_pass_replace_parameter_with_global.h"
#include "source/fuzz/fuzzer_pass_replace_params_with_struct.h"
#include "source/fuzz/fuzzer_pass_split_blocks.h"
#include "source/fuzz/fuzzer_pass_swap_commutable_operands.h"
#include "source/fuzz/fuzzer_pass_swap_conditional_branch_operands.h"
#include "source/fuzz/fuzzer_pass_toggle_access_chain_instruction.h"
#include "source/fuzz/fuzzer_pass_wrap_regions_in_selections.h"
#include "source/fuzz/pass_management/repeated_pass_manager.h"
#include "source/fuzz/pass_management/repeated_pass_manager_looped_with_recommendations.h"
#include "source/fuzz/pass_management/repeated_pass_manager_random_with_recommendations.h"
#include "source/fuzz/pass_management/repeated_pass_manager_simple.h"
#include "source/fuzz/pass_management/repeated_pass_recommender_standard.h"
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
#include "source/fuzz/transformation_context.h"
#include "source/opt/build_module.h"
#include "source/spirv_fuzzer_options.h"
#include "source/util/make_unique.h"

namespace spvtools {
namespace fuzz {

namespace {
const uint32_t kIdBoundGap = 100;

const uint32_t kTransformationLimit = 2000;

}  // namespace

Fuzzer::Fuzzer(spv_target_env target_env, MessageConsumer consumer,
               const std::vector<uint32_t>& binary_in,
               const protobufs::FactSequence& initial_facts,
               const std::vector<fuzzerutil::ModuleSupplier>& donor_suppliers,
               std::unique_ptr<RandomGenerator> random_generator,
               bool enable_all_passes,
               RepeatedPassStrategy repeated_pass_strategy,
               bool validate_after_each_fuzzer_pass,
               spv_validator_options validator_options)
    : target_env_(target_env),
      consumer_(std::move(consumer)),
      binary_in_(binary_in),
      initial_facts_(initial_facts),
      donor_suppliers_(donor_suppliers),
      random_generator_(std::move(random_generator)),
      enable_all_passes_(enable_all_passes),
      repeated_pass_strategy_(repeated_pass_strategy),
      validate_after_each_fuzzer_pass_(validate_after_each_fuzzer_pass),
      validator_options_(validator_options),
      num_repeated_passes_applied_(0),
      ir_context_(nullptr),
      fuzzer_context_(nullptr),
      transformation_context_(nullptr),
      transformation_sequence_out_() {}

Fuzzer::~Fuzzer() = default;

template <typename FuzzerPassT, typename... Args>
void Fuzzer::MaybeAddRepeatedPass(uint32_t percentage_chance_of_adding_pass,
                                  RepeatedPassInstances* pass_instances,
                                  Args&&... extra_args) {
  if (enable_all_passes_ ||
      fuzzer_context_->ChoosePercentage(percentage_chance_of_adding_pass)) {
    pass_instances->SetPass(MakeUnique<FuzzerPassT>(
        ir_context_.get(), transformation_context_.get(), fuzzer_context_.get(),
        &transformation_sequence_out_, std::forward<Args>(extra_args)...));
  }
}

template <typename FuzzerPassT, typename... Args>
void Fuzzer::MaybeAddFinalPass(std::vector<std::unique_ptr<FuzzerPass>>* passes,
                               Args&&... extra_args) {
  if (enable_all_passes_ || fuzzer_context_->ChooseEven()) {
    passes->push_back(MakeUnique<FuzzerPassT>(
        ir_context_.get(), transformation_context_.get(), fuzzer_context_.get(),
        &transformation_sequence_out_, std::forward<Args>(extra_args)...));
  }
}

bool Fuzzer::ApplyPassAndCheckValidity(
    FuzzerPass* pass, const spvtools::SpirvTools& tools) const {
  pass->Apply();
  if (validate_after_each_fuzzer_pass_) {
    std::vector<uint32_t> binary_to_validate;
    ir_context_->module()->ToBinary(&binary_to_validate, false);
    if (!tools.Validate(&binary_to_validate[0], binary_to_validate.size(),
                        validator_options_)) {
      consumer_(SPV_MSG_INFO, nullptr, {},
                "Binary became invalid during fuzzing (set a breakpoint to "
                "inspect); stopping.");
      return false;
    }
  }
  return true;
}

Fuzzer::FuzzerResult Fuzzer::Run() {
  // Check compatibility between the library version being linked with and the
  // header files being used.
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  assert(ir_context_ == nullptr && fuzzer_context_ == nullptr &&
         transformation_context_ == nullptr &&
         transformation_sequence_out_.transformation_size() == 0 &&
         "'Run' must not be invoked more than once.");

  spvtools::SpirvTools tools(target_env_);
  tools.SetMessageConsumer(consumer_);
  if (!tools.IsValid()) {
    consumer_(SPV_MSG_ERROR, nullptr, {},
              "Failed to create SPIRV-Tools interface; stopping.");
    return {Fuzzer::FuzzerResultStatus::kFailedToCreateSpirvToolsInterface,
            std::vector<uint32_t>(), protobufs::TransformationSequence()};
  }

  // Initial binary should be valid.
  if (!tools.Validate(&binary_in_[0], binary_in_.size(), validator_options_)) {
    consumer_(SPV_MSG_ERROR, nullptr, {},
              "Initial binary is invalid; stopping.");
    return {Fuzzer::FuzzerResultStatus::kInitialBinaryInvalid,
            std::vector<uint32_t>(), protobufs::TransformationSequence()};
  }

  // Build the module from the input binary.
  ir_context_ =
      BuildModule(target_env_, consumer_, binary_in_.data(), binary_in_.size());
  assert(ir_context_);

  // The fuzzer will introduce new ids into the module.  The module's id bound
  // gives the smallest id that can be used for this purpose.  We add an offset
  // to this so that there is a sizeable gap between the ids used in the
  // original module and the ids used for fuzzing, as a readability aid.
  //
  // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/2541) consider the
  //  case where the maximum id bound is reached.
  auto minimum_fresh_id = ir_context_->module()->id_bound() + kIdBoundGap;
  fuzzer_context_ =
      MakeUnique<FuzzerContext>(random_generator_.get(), minimum_fresh_id);

  transformation_context_ = MakeUnique<TransformationContext>(
      MakeUnique<FactManager>(ir_context_.get()), validator_options_);
  transformation_context_->GetFactManager()->AddInitialFacts(consumer_,
                                                             initial_facts_);

  RepeatedPassInstances pass_instances{};

  // The following passes are likely to be very useful: many other passes
  // introduce synonyms, irrelevant ids and constants that these passes can work
  // with.  We thus enable them with high probability.
  MaybeAddRepeatedPass<FuzzerPassObfuscateConstants>(90, &pass_instances);
  MaybeAddRepeatedPass<FuzzerPassApplyIdSynonyms>(90, &pass_instances);
  MaybeAddRepeatedPass<FuzzerPassReplaceIrrelevantIds>(90, &pass_instances);

  do {
    // Each call to MaybeAddRepeatedPass randomly decides whether the given pass
    // should be enabled, and adds an instance of the pass to |pass_instances|
    // if it is enabled.
    MaybeAddRepeatedPass<FuzzerPassAddAccessChains>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddBitInstructionSynonyms>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddCompositeInserts>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddCompositeTypes>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddCopyMemory>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddDeadBlocks>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddDeadBreaks>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddDeadContinues>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddEquationInstructions>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddFunctionCalls>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddGlobalVariables>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddImageSampleUnusedComponents>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddLoads>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddLocalVariables>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddLoopPreheaders>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddLoopsToCreateIntConstantSynonyms>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddOpPhiSynonyms>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddParameters>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddRelaxedDecorations>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddStores>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddSynonyms>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassAddVectorShuffleInstructions>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassConstructComposites>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassCopyObjects>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassDonateModules>(&pass_instances,
                                                  donor_suppliers_);
    MaybeAddRepeatedPass<FuzzerPassDuplicateRegionsWithSelections>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassFlattenConditionalBranches>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassInlineFunctions>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassInvertComparisonOperators>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassMakeVectorOperationsDynamic>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassMergeBlocks>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassMergeFunctionReturns>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassMutatePointers>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassOutlineFunctions>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassPermuteBlocks>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassPermuteFunctionParameters>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassPermuteInstructions>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassPropagateInstructionsDown>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassPropagateInstructionsUp>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassPushIdsThroughVariables>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassReplaceAddsSubsMulsWithCarryingExtended>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassReplaceBranchesFromDeadBlocksWithExits>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassReplaceCopyMemoriesWithLoadsStores>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassReplaceCopyObjectsWithStoresLoads>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassReplaceLoadsStoresWithCopyMemories>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassReplaceParameterWithGlobal>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassReplaceLinearAlgebraInstructions>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassReplaceOpPhiIdsFromDeadPredecessors>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassReplaceOpSelectsWithConditionalBranches>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassReplaceParamsWithStruct>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassSplitBlocks>(&pass_instances);
    MaybeAddRepeatedPass<FuzzerPassSwapBranchConditionalOperands>(
        &pass_instances);
    MaybeAddRepeatedPass<FuzzerPassWrapRegionsInSelections>(&pass_instances);
    // There is a theoretical possibility that no pass instances were created
    // until now; loop again if so.
  } while (pass_instances.GetPasses().empty());

  RepeatedPassRecommenderStandard pass_recommender(&pass_instances,
                                                   fuzzer_context_.get());

  std::unique_ptr<RepeatedPassManager> repeated_pass_manager = nullptr;
  switch (repeated_pass_strategy_) {
    case RepeatedPassStrategy::kSimple:
      repeated_pass_manager = MakeUnique<RepeatedPassManagerSimple>(
          fuzzer_context_.get(), &pass_instances);
      break;
    case RepeatedPassStrategy::kLoopedWithRecommendations:
      repeated_pass_manager =
          MakeUnique<RepeatedPassManagerLoopedWithRecommendations>(
              fuzzer_context_.get(), &pass_instances, &pass_recommender);
      break;
    case RepeatedPassStrategy::kRandomWithRecommendations:
      repeated_pass_manager =
          MakeUnique<RepeatedPassManagerRandomWithRecommendations>(
              fuzzer_context_.get(), &pass_instances, &pass_recommender);
      break;
  }

  do {
    if (!ApplyPassAndCheckValidity(
            repeated_pass_manager->ChoosePass(transformation_sequence_out_),
            tools)) {
      return {Fuzzer::FuzzerResultStatus::kFuzzerPassLedToInvalidModule,
              std::vector<uint32_t>(), protobufs::TransformationSequence()};
    }
  } while (ShouldContinueFuzzing());

  // Now apply some passes that it does not make sense to apply repeatedly,
  // as they do not unlock other passes.
  std::vector<std::unique_ptr<FuzzerPass>> final_passes;
  MaybeAddFinalPass<FuzzerPassAdjustBranchWeights>(&final_passes);
  MaybeAddFinalPass<FuzzerPassAdjustFunctionControls>(&final_passes);
  MaybeAddFinalPass<FuzzerPassAdjustLoopControls>(&final_passes);
  MaybeAddFinalPass<FuzzerPassAdjustMemoryOperandsMasks>(&final_passes);
  MaybeAddFinalPass<FuzzerPassAdjustSelectionControls>(&final_passes);
  MaybeAddFinalPass<FuzzerPassAddNoContractionDecorations>(&final_passes);
  MaybeAddFinalPass<FuzzerPassInterchangeSignednessOfIntegerOperands>(
      &final_passes);
  MaybeAddFinalPass<FuzzerPassInterchangeZeroLikeConstants>(&final_passes);
  MaybeAddFinalPass<FuzzerPassPermutePhiOperands>(&final_passes);
  MaybeAddFinalPass<FuzzerPassSwapCommutableOperands>(&final_passes);
  MaybeAddFinalPass<FuzzerPassToggleAccessChainInstruction>(&final_passes);
  for (auto& pass : final_passes) {
    if (!ApplyPassAndCheckValidity(pass.get(), tools)) {
      return {Fuzzer::FuzzerResultStatus::kFuzzerPassLedToInvalidModule,
              std::vector<uint32_t>(), protobufs::TransformationSequence()};
    }
  }
  // Encode the module as a binary.
  std::vector<uint32_t> binary_out;
  ir_context_->module()->ToBinary(&binary_out, false);

  return {Fuzzer::FuzzerResultStatus::kComplete, std::move(binary_out),
          std::move(transformation_sequence_out_)};
}

bool Fuzzer::ShouldContinueFuzzing() {
  // There's a risk that fuzzing could get stuck, if none of the enabled fuzzer
  // passes are able to apply any transformations.  To guard against this we
  // count the number of times some repeated pass has been applied and ensure
  // that fuzzing stops if the number of repeated passes hits the limit on the
  // number of transformations that can be applied.
  assert(
      num_repeated_passes_applied_ <= kTransformationLimit &&
      "The number of repeated passes applied must not exceed its upper limit.");
  if (num_repeated_passes_applied_ == kTransformationLimit) {
    // Stop because fuzzing has got stuck.
    return false;
  }
  auto transformations_applied_so_far =
      static_cast<uint32_t>(transformation_sequence_out_.transformation_size());
  if (transformations_applied_so_far >= kTransformationLimit) {
    // Stop because we have reached the transformation limit.
    return false;
  }
  auto chance_of_continuing = static_cast<uint32_t>(
      100.0 * (1.0 - (static_cast<double>(transformations_applied_so_far) /
                      static_cast<double>(kTransformationLimit))));
  if (!fuzzer_context_->ChoosePercentage(chance_of_continuing)) {
    // We have probabilistically decided to stop.
    return false;
  }
  // Continue fuzzing!
  num_repeated_passes_applied_++;
  return true;
}

}  // namespace fuzz
}  // namespace spvtools
