//===-- sanitizer_procmaps_test.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
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
//
//===----------------------------------------------------------------------===//
#if !defined(_WIN32)  // There are no /proc/maps on Windows.

#  include "sanitizer_common/sanitizer_procmaps.h"

#  include <stdlib.h>
#  include <string.h>

#  include <vector>

#  include "gtest/gtest.h"

static void noop() {}
extern const char *argv0;

namespace __sanitizer {

#if SANITIZER_LINUX && !SANITIZER_ANDROID
TEST(MemoryMappingLayout, CodeRange) {
  uptr start, end;
  bool res = GetCodeRangeForFile("[vdso]", &start, &end);
  EXPECT_EQ(res, true);
  EXPECT_GT(start, 0U);
  EXPECT_LT(start, end);
}
#endif

TEST(MemoryMappingLayout, DumpListOfModules) {
  const char *last_slash = strrchr(argv0, '/');
  const char *binary_name = last_slash ? last_slash + 1 : argv0;
  MemoryMappingLayout memory_mapping(false);
  const uptr kMaxModules = 100;
  InternalMmapVector<LoadedModule> modules;
  modules.reserve(kMaxModules);
  memory_mapping.DumpListOfModules(&modules);
  EXPECT_GT(modules.size(), 0U);
  bool found = false;
  for (uptr i = 0; i < modules.size(); ++i) {
    if (modules[i].containsAddress((uptr)&noop)) {
      // Verify that the module name is sane.
      if (strstr(modules[i].full_name(), binary_name) != 0)
        found = true;
    }
    modules[i].clear();
  }
  EXPECT_TRUE(found);
}

TEST(MemoryMapping, LoadedModuleArchAndUUID) {
  if (SANITIZER_APPLE) {
    MemoryMappingLayout memory_mapping(false);
    const uptr kMaxModules = 100;
    InternalMmapVector<LoadedModule> modules;
    modules.reserve(kMaxModules);
    memory_mapping.DumpListOfModules(&modules);
    for (uptr i = 0; i < modules.size(); ++i) {
      ModuleArch arch = modules[i].arch();
      // Darwin unit tests are only run on i386/x86_64/x86_64h.
      if (SANITIZER_WORDSIZE == 32) {
        EXPECT_EQ(arch, kModuleArchI386);
      } else if (SANITIZER_WORDSIZE == 64) {
        EXPECT_TRUE(arch == kModuleArchX86_64 || arch == kModuleArchX86_64H);
      }
      const u8 *uuid = modules[i].uuid();
      u8 null_uuid[kModuleUUIDSize] = {0};
      EXPECT_NE(memcmp(null_uuid, uuid, kModuleUUIDSize), 0);
    }
  }
}

#  if (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
       SANITIZER_SOLARIS) &&                                       \
      defined(_LP64)
const char *const parse_unix_input = R"(
7fb9862f1000-7fb9862f3000 rw-p 00000000 00:00 0 
Size:                  8 kB
Rss:                   4 kB
7fb9864ae000-7fb9864b1000 r--p 001ba000 fd:01 22413919                   /lib/x86_64-linux-gnu/libc-2.32.so
Size:                 12 kB
Rss:                  12 kB
)";

TEST(MemoryMapping, ParseUnixMemoryProfile) {
  struct entry {
    uptr p;
    uptr rss;
    bool file;
  };
  typedef std::vector<entry> entries_t;
  entries_t entries;
  std::vector<char> input(parse_unix_input,
                          parse_unix_input + strlen(parse_unix_input));
  ParseUnixMemoryProfile(
      [](uptr p, uptr rss, bool file, uptr *mem) {
        reinterpret_cast<entries_t *>(mem)->push_back({p, rss, file});
      },
      reinterpret_cast<uptr *>(&entries), &input[0], input.size());
  EXPECT_EQ(entries.size(), 2ul);
  EXPECT_EQ(entries[0].p, 0x7fb9862f1000ul);
  EXPECT_EQ(entries[0].rss, 4ul << 10);
  EXPECT_EQ(entries[0].file, false);
  EXPECT_EQ(entries[1].p, 0x7fb9864ae000ul);
  EXPECT_EQ(entries[1].rss, 12ul << 10);
  EXPECT_EQ(entries[1].file, true);
}

TEST(MemoryMapping, ParseUnixMemoryProfileTruncated) {
  // ParseUnixMemoryProfile used to crash on truncated inputs.
  // This test allocates 2 pages, protects the second one
  // and places the input at the very end of the first page
  // to test for over-reads.
  uptr page = GetPageSizeCached();
  char *mem = static_cast<char *>(
      MmapOrDie(2 * page, "ParseUnixMemoryProfileTruncated"));
  EXPECT_TRUE(MprotectNoAccess(reinterpret_cast<uptr>(mem + page), page));
  const uptr len = strlen(parse_unix_input);
  for (uptr i = 0; i < len; i++) {
    char *smaps = mem + page - len + i;
    memcpy(smaps, parse_unix_input, len - i);
    ParseUnixMemoryProfile([](uptr p, uptr rss, bool file, uptr *mem) {},
                           nullptr, smaps, len - i);
  }
  UnmapOrDie(mem, 2 * page);
}
#  endif

}  // namespace __sanitizer
#endif  // !defined(_WIN32)
