/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 <stdint.h>
#include <stdlib.h>
#include <time.h>

#include <gtest/gtest.h>

#if defined(__BIONIC__)

#include <vector>

#include <procinfo/process_map.h>

#include "utils.h"

extern "C" void malloc_disable();
extern "C" void malloc_enable();
extern "C" int malloc_iterate(uintptr_t base, size_t size, void (*callback)(uintptr_t base,
                              size_t size, void* arg), void* arg);

struct AllocDataType {
  void* ptr;
  size_t size;
  size_t size_reported;
  size_t count;
};

struct TestDataType {
  size_t total_allocated_bytes;
  std::vector<AllocDataType> allocs;
};

static void AllocPtr(TestDataType* test_data, size_t size) {
  test_data->allocs.resize(test_data->allocs.size() + 1);
  AllocDataType* alloc = &test_data->allocs.back();
  void* ptr = malloc(size);
  ASSERT_TRUE(ptr != nullptr);
  alloc->ptr = ptr;
  alloc->size = malloc_usable_size(ptr);
  alloc->size_reported = 0;
  alloc->count = 0;
}

static void FreePtrs(TestDataType* test_data) {
  for (size_t i = 0; i < test_data->allocs.size(); i++) {
    free(test_data->allocs[i].ptr);
  }
}

static void SavePointers(uintptr_t base, size_t size, void* data) {
  TestDataType* test_data = reinterpret_cast<TestDataType*>(data);

  test_data->total_allocated_bytes += size;

  uintptr_t end;
  if (__builtin_add_overflow(base, size, &end)) {
    // Skip this entry.
    return;
  }

  for (size_t i = 0; i < test_data->allocs.size(); i++) {
    uintptr_t ptr = reinterpret_cast<uintptr_t>(test_data->allocs[i].ptr);
    if (ptr >= base && ptr < end) {
      test_data->allocs[i].count++;

      uintptr_t max_size = end - ptr;
      if (max_size > test_data->allocs[i].size) {
        test_data->allocs[i].size_reported = test_data->allocs[i].size;
      } else {
        test_data->allocs[i].size_reported = max_size;
      }
    }
  }
}

static void VerifyPtrs(TestDataType* test_data) {
  test_data->total_allocated_bytes = 0;

  // Find all of the maps that are [anon:libc_malloc].
  ASSERT_TRUE(android::procinfo::ReadMapFile(
      "/proc/self/maps",
      [&](uint64_t start, uint64_t end, uint16_t, uint64_t, ino_t, const char* name) {
        if (std::string(name) == "[anon:libc_malloc]") {
          malloc_disable();
          malloc_iterate(start, end - start, SavePointers, test_data);
          malloc_enable();
        }
      }));

  for (size_t i = 0; i < test_data->allocs.size(); i++) {
    EXPECT_EQ(1UL, test_data->allocs[i].count) << "Failed on size " << test_data->allocs[i].size;
    if (test_data->allocs[i].count == 1) {
      EXPECT_EQ(test_data->allocs[i].size, test_data->allocs[i].size_reported);
    }
  }
}

static void AllocateSizes(TestDataType* test_data, const std::vector<size_t>& sizes) {
  static constexpr size_t kInitialAllocations = 40;
  static constexpr size_t kNumAllocs = 50;
  for (size_t size : sizes) {
    // Verify that if the tcache is enabled, that tcache pointers
    // are found by allocating and freeing 20 pointers (should be larger
    // than the total number of cache entries).
    for (size_t i = 0; i < kInitialAllocations; i++) {
      void* ptr = malloc(size);
      ASSERT_TRUE(ptr != nullptr);
      memset(ptr, 0, size);
      free(ptr);
    }
    for (size_t i = 0; i < kNumAllocs; i++) {
      AllocPtr(test_data, size);
    }
  }
}
#endif

// Verify that small allocs can be found properly.
TEST(malloc_iterate, small_allocs) {
#if defined(__BIONIC__)
  SKIP_WITH_HWASAN;
  TestDataType test_data;

  // Try to cycle through all of the different small bins.
  // This is specific to the implementation of jemalloc and should be
  // adjusted if a different native memory allocator is used.
  std::vector<size_t> sizes{8,    16,   32,   48,    64,    80,    96,    112,   128,  160,
                            192,  224,  256,  320,   384,   448,   512,   640,   768,  896,
                            1024, 1280, 1536, 1792,  2048,  2560,  3072,  3584,  4096, 5120,
                            6144, 7168, 8192, 10240, 12288, 14336, 16384, 32768, 65536};
  AllocateSizes(&test_data, sizes);

  SCOPED_TRACE("");
  VerifyPtrs(&test_data);

  FreePtrs(&test_data);
#else
  GTEST_SKIP() << "bionic-only test";
#endif
}

// Verify that large allocs can be found properly.
TEST(malloc_iterate, large_allocs) {
#if defined(__BIONIC__)
  SKIP_WITH_HWASAN;
  TestDataType test_data;

  // Try some larger sizes.
  std::vector<size_t> sizes{131072, 262144, 524288, 1048576, 2097152};
  AllocateSizes(&test_data, sizes);

  SCOPED_TRACE("");
  VerifyPtrs(&test_data);

  FreePtrs(&test_data);
#else
  GTEST_SKIP() << "bionic-only test";
#endif
}

// Verify that there are no crashes attempting to get pointers from
// non-allocated pointers.
TEST(malloc_iterate, invalid_pointers) {
#if defined(__BIONIC__)
  SKIP_WITH_HWASAN;
  TestDataType test_data = {};

  // Find all of the maps that are not [anon:libc_malloc].
  ASSERT_TRUE(android::procinfo::ReadMapFile(
      "/proc/self/maps",
      [&](uint64_t start, uint64_t end, uint16_t, uint64_t, ino_t, const char* name) {
        if (std::string(name) != "[anon:libc_malloc]") {
          malloc_disable();
          malloc_iterate(start, end - start, SavePointers, &test_data);
          malloc_enable();
        }
      }));

  ASSERT_EQ(0UL, test_data.total_allocated_bytes);
#else
  GTEST_SKIP() << "bionic-only test";
#endif
}

TEST(malloc_iterate, malloc_disable_prevents_allocs) {
#if defined(__BIONIC__)
  SKIP_WITH_HWASAN;
  pid_t pid;
  if ((pid = fork()) == 0) {
    malloc_disable();
    void* ptr = malloc(1024);
    if (ptr == nullptr) {
      exit(1);
    }
    memset(ptr, 0, 1024);
    exit(0);
  }
  ASSERT_NE(-1, pid);

  // Expect that the malloc will hang forever, and that if the process
  // does not return for two seconds, it is hung.
  sleep(2);
  pid_t wait_pid = TEMP_FAILURE_RETRY(waitpid(pid, nullptr, WNOHANG));
  if (wait_pid <= 0) {
    kill(pid, SIGKILL);
  }
  ASSERT_NE(-1, wait_pid) << "Unknown failure in waitpid.";
  ASSERT_EQ(0, wait_pid) << "malloc_disable did not prevent allocation calls.";
#else
  GTEST_SKIP() << "bionic-only test";
#endif
}
