//===-- 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_MAC) {
    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)
