//===-- allocator_fuzzer.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#define SCUDO_FUZZ
#include "allocator_config.h"
#include "combined.h"
#include <format>
#include <fuzzer/FuzzedDataProvider.h>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  FuzzedDataProvider FDP(Data, Size);
  if (FDP.remaining_bytes() == 0)
    return 0;

  // TODO: Make this configurable.
  static bool ZeroFill = true;

  // After a number of operation, reset the the allocator with different
  // parameters.
  using AllocatorT = scudo::Allocator<scudo::Config>;
  static std::unique_ptr<AllocatorT> Allocator;
  if (Allocator == nullptr) {
    Allocator.reset(new AllocatorT());
    Allocator->init();
    // The way we are using the allocator doesn't work properly with MTE
    // enabled.
    if (scudo::systemSupportsMemoryTagging())
      Allocator->disableMemoryTagging();
    Allocator->setOption(scudo::Option::ReleaseInterval, 1000);

    // Set the fill type once for the allocator, changing the fill type during
    // the run can lead to some data not being zeroed if zero on deallocate
    // is enabled.
    std::cout << std::format("Allocator Created with ZeroFill {}\n", ZeroFill);
    Allocator->setFillContents(ZeroFill ? scudo::ZeroFill : scudo::NoFill);
  }

  constexpr size_t kMaxAllocatedBytes = 50 * 1024 * 1024;
  size_t TotalAllocatedBytes = 0;
  std::vector<void *> Allocations;
  while (FDP.remaining_bytes() > 0) {
    uint8_t Op = FDP.ConsumeIntegralInRange<uint8_t>(0, 4);
    if (Op == 0 || Op == 1) {
      if (TotalAllocatedBytes >= kMaxAllocatedBytes)
        continue;

      bool ZeroContents = FDP.ConsumeBool();
      size_t ReqSize =
          FDP.ConsumeIntegralInRange<size_t>(1, 1 << 20); // Up to 1MB
      void *Ptr;
      if (Op == 0) {
        // Allocate default alignment
        Ptr = Allocator->allocate(ReqSize, scudo::Chunk::Origin::Malloc, 2,
                                  ZeroContents);
      } else {
        // Allocate with alignment
        size_t Alignment =
            1 << FDP.ConsumeIntegralInRange<size_t>(4, 12); // 16 to 4096
        Ptr = Allocator->allocate(ReqSize, scudo::Chunk::Origin::Memalign,
                                  Alignment, ZeroContents);
        CHECK_EQ(0, reinterpret_cast<uintptr_t>(Ptr) & (Alignment - 1));
      }
      CHECK(Ptr != nullptr);
      size_t Size = Allocator->getUsableSize(Ptr);
      TotalAllocatedBytes += Size;
      Allocations.push_back(Ptr);
      if (ZeroContents || ZeroFill) {
        bool Mismatch = false;
        uint8_t *Data = reinterpret_cast<uint8_t *>(Ptr);
        for (size_t i = 0; i < Size; i++) {
          if (Data[i] != 0) {
            if (!Mismatch) {
              std::cerr << std::format(
                  "Failed Ptr {} Size {} ZeroContents {} ZeroFill {}\n", Ptr,
                  Size, ZeroContents, ZeroFill);
              Mismatch = true;
            }
            std::cerr << std::format("  Index {} Ptr {} Value {}\n", i,
                                     (void *)&Data[i], Data[i]);
          }
        }
        if (Mismatch)
          abort();
      }
      memset(Ptr, 0xff, Size);
    } else if (Op == 2) {
      if (Allocations.empty())
        continue;

      // Deallocate
      size_t Index =
          FDP.ConsumeIntegralInRange<size_t>(0, Allocations.size() - 1);
      TotalAllocatedBytes -= Allocator->getUsableSize(Allocations[Index]);
      Allocator->deallocate(Allocations[Index], scudo::Chunk::Origin::Malloc);
      Allocations.erase(Allocations.begin() + Index);
    } else if (Op == 3 && !Allocations.empty()) {
      // Reallocate (Assumes reallocate of a memalign does not crash).
      size_t Index =
          FDP.ConsumeIntegralInRange<size_t>(0, Allocations.size() - 1);
      size_t OldSize = Allocator->getUsableSize(Allocations[Index]);
      TotalAllocatedBytes -= OldSize;
      size_t NewSize = FDP.ConsumeIntegralInRange<size_t>(1, 1 << 20);
      void *NewPtr = Allocator->reallocate(Allocations[Index], NewSize);
      if (NewSize == 0) {
        CHECK(NewPtr == nullptr);
        Allocations.erase(Allocations.begin() + Index);
      } else {
        CHECK(NewPtr != nullptr);
        NewSize = Allocator->getUsableSize(NewPtr);
        memset(NewPtr, 0xff, NewSize);
        Allocations[Index] = NewPtr;
        TotalAllocatedBytes += NewSize;
      }
    } else if (Op == 4) {
      // ReleaseToOS
      scudo::ReleaseToOS ReleaseType =
          static_cast<scudo::ReleaseToOS>(FDP.ConsumeIntegralInRange<size_t>(
              0, static_cast<size_t>(scudo::ReleaseToOS::Last)));
      Allocator->releaseToOS(ReleaseType);
    }
  }

  for (void *Ptr : Allocations) {
    Allocator->deallocate(Ptr, scudo::Chunk::Origin::Malloc);
  }

  return 0;
}
