// Copyright 2018 The Abseil Authors.
//
// 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
//
//      https://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 "absl/debugging/symbolize.h"

#ifndef _WIN32
#include <fcntl.h>
#include <sys/mman.h>
#endif

#include <cstring>
#include <iostream>
#include <memory>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
#include "absl/base/casts.h"
#include "absl/base/internal/per_thread_tls.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/optimization.h"
#include "absl/debugging/internal/stack_consumption.h"
#include "absl/memory/memory.h"

using testing::Contains;

// Functions to symbolize. Use C linkage to avoid mangled names.
extern "C" {
void nonstatic_func() { ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); }
static void static_func() { ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); }
}  // extern "C"

struct Foo {
  static void func(int x);
};

// A C++ method that should have a mangled name.
void ABSL_ATTRIBUTE_NOINLINE Foo::func(int) {
  ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
}

// Create functions that will remain in different text sections in the
// final binary when linker option "-z,keep-text-section-prefix" is used.
int ABSL_ATTRIBUTE_SECTION_VARIABLE(.text.unlikely) unlikely_func() {
  return 0;
}

int ABSL_ATTRIBUTE_SECTION_VARIABLE(.text.hot) hot_func() {
  return 0;
}

int ABSL_ATTRIBUTE_SECTION_VARIABLE(.text.startup) startup_func() {
  return 0;
}

int ABSL_ATTRIBUTE_SECTION_VARIABLE(.text.exit) exit_func() {
  return 0;
}

int /*ABSL_ATTRIBUTE_SECTION_VARIABLE(.text)*/ regular_func() {
  return 0;
}

// Thread-local data may confuse the symbolizer, ensure that it does not.
// Variable sizes and order are important.
#if ABSL_PER_THREAD_TLS
static ABSL_PER_THREAD_TLS_KEYWORD char symbolize_test_thread_small[1];
static ABSL_PER_THREAD_TLS_KEYWORD char
    symbolize_test_thread_big[2 * 1024 * 1024];
#endif

// Used below to hopefully inhibit some compiler/linker optimizations
// that may remove kHpageTextPadding, kPadding0, and kPadding1 from
// the binary.
static volatile bool volatile_bool = false;

// Force the binary to be large enough that a THP .text remap will succeed.
static constexpr size_t kHpageSize = 1 << 21;
const char kHpageTextPadding[kHpageSize * 4] ABSL_ATTRIBUTE_SECTION_VARIABLE(
    .text) = "";

static char try_symbolize_buffer[4096];

// A wrapper function for absl::Symbolize() to make the unit test simple.  The
// limit must be < sizeof(try_symbolize_buffer).  Returns null if
// absl::Symbolize() returns false, otherwise returns try_symbolize_buffer with
// the result of absl::Symbolize().
static const char *TrySymbolizeWithLimit(void *pc, int limit) {
  ABSL_RAW_CHECK(limit <= sizeof(try_symbolize_buffer),
                 "try_symbolize_buffer is too small");

  // Use the heap to facilitate heap and buffer sanitizer tools.
  auto heap_buffer = absl::make_unique<char[]>(sizeof(try_symbolize_buffer));
  bool found = absl::Symbolize(pc, heap_buffer.get(), limit);
  if (found) {
    ABSL_RAW_CHECK(strnlen(heap_buffer.get(), limit) < limit,
                   "absl::Symbolize() did not properly terminate the string");
    strncpy(try_symbolize_buffer, heap_buffer.get(),
            sizeof(try_symbolize_buffer) - 1);
    try_symbolize_buffer[sizeof(try_symbolize_buffer) - 1] = '\0';
  }

  return found ? try_symbolize_buffer : nullptr;
}

// A wrapper for TrySymbolizeWithLimit(), with a large limit.
static const char *TrySymbolize(void *pc) {
  return TrySymbolizeWithLimit(pc, sizeof(try_symbolize_buffer));
}

#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE

TEST(Symbolize, Cached) {
  // Compilers should give us pointers to them.
  EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func)));

  // The name of an internal linkage symbol is not specified; allow either a
  // mangled or an unmangled name here.
  const char *static_func_symbol = TrySymbolize((void *)(&static_func));
  EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 ||
              strcmp("static_func()", static_func_symbol) == 0);

  EXPECT_TRUE(nullptr == TrySymbolize(nullptr));
}

TEST(Symbolize, Truncation) {
  constexpr char kNonStaticFunc[] = "nonstatic_func";
  EXPECT_STREQ("nonstatic_func",
               TrySymbolizeWithLimit((void *)(&nonstatic_func),
                                     strlen(kNonStaticFunc) + 1));
  EXPECT_STREQ("nonstatic_...",
               TrySymbolizeWithLimit((void *)(&nonstatic_func),
                                     strlen(kNonStaticFunc) + 0));
  EXPECT_STREQ("nonstatic...",
               TrySymbolizeWithLimit((void *)(&nonstatic_func),
                                     strlen(kNonStaticFunc) - 1));
  EXPECT_STREQ("n...", TrySymbolizeWithLimit((void *)(&nonstatic_func), 5));
  EXPECT_STREQ("...", TrySymbolizeWithLimit((void *)(&nonstatic_func), 4));
  EXPECT_STREQ("..", TrySymbolizeWithLimit((void *)(&nonstatic_func), 3));
  EXPECT_STREQ(".", TrySymbolizeWithLimit((void *)(&nonstatic_func), 2));
  EXPECT_STREQ("", TrySymbolizeWithLimit((void *)(&nonstatic_func), 1));
  EXPECT_EQ(nullptr, TrySymbolizeWithLimit((void *)(&nonstatic_func), 0));
}

TEST(Symbolize, SymbolizeWithDemangling) {
  Foo::func(100);
  EXPECT_STREQ("Foo::func()", TrySymbolize((void *)(&Foo::func)));
}

TEST(Symbolize, SymbolizeSplitTextSections) {
  EXPECT_STREQ("unlikely_func()", TrySymbolize((void *)(&unlikely_func)));
  EXPECT_STREQ("hot_func()", TrySymbolize((void *)(&hot_func)));
  EXPECT_STREQ("startup_func()", TrySymbolize((void *)(&startup_func)));
  EXPECT_STREQ("exit_func()", TrySymbolize((void *)(&exit_func)));
  EXPECT_STREQ("regular_func()", TrySymbolize((void *)(&regular_func)));
}

// Tests that verify that Symbolize stack footprint is within some limit.
#ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION

static void *g_pc_to_symbolize;
static char g_symbolize_buffer[4096];
static char *g_symbolize_result;

static void SymbolizeSignalHandler(int signo) {
  if (absl::Symbolize(g_pc_to_symbolize, g_symbolize_buffer,
                      sizeof(g_symbolize_buffer))) {
    g_symbolize_result = g_symbolize_buffer;
  } else {
    g_symbolize_result = nullptr;
  }
}

// Call Symbolize and figure out the stack footprint of this call.
static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
  g_pc_to_symbolize = pc;
  *stack_consumed = absl::debugging_internal::GetSignalHandlerStackConsumption(
      SymbolizeSignalHandler);
  return g_symbolize_result;
}

static int GetStackConsumptionUpperLimit() {
  // Symbolize stack consumption should be within 2kB.
  int stack_consumption_upper_limit = 2048;
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
    defined(THREAD_SANITIZER)
  // Account for sanitizer instrumentation requiring additional stack space.
  stack_consumption_upper_limit *= 5;
#endif
  return stack_consumption_upper_limit;
}

TEST(Symbolize, SymbolizeStackConsumption) {
  int stack_consumed = 0;

  const char *symbol =
      SymbolizeStackConsumption((void *)(&nonstatic_func), &stack_consumed);
  EXPECT_STREQ("nonstatic_func", symbol);
  EXPECT_GT(stack_consumed, 0);
  EXPECT_LT(stack_consumed, GetStackConsumptionUpperLimit());

  // The name of an internal linkage symbol is not specified; allow either a
  // mangled or an unmangled name here.
  symbol = SymbolizeStackConsumption((void *)(&static_func), &stack_consumed);
  EXPECT_TRUE(strcmp("static_func", symbol) == 0 ||
              strcmp("static_func()", symbol) == 0);
  EXPECT_GT(stack_consumed, 0);
  EXPECT_LT(stack_consumed, GetStackConsumptionUpperLimit());
}

TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) {
  Foo::func(100);
  int stack_consumed = 0;

  const char *symbol =
      SymbolizeStackConsumption((void *)(&Foo::func), &stack_consumed);

  EXPECT_STREQ("Foo::func()", symbol);
  EXPECT_GT(stack_consumed, 0);
  EXPECT_LT(stack_consumed, GetStackConsumptionUpperLimit());
}

#endif  // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION

// Use a 64K page size for PPC.
const size_t kPageSize = 64 << 10;
// We place a read-only symbols into the .text section and verify that we can
// symbolize them and other symbols after remapping them.
const char kPadding0[kPageSize * 4] ABSL_ATTRIBUTE_SECTION_VARIABLE(.text) =
    "";
const char kPadding1[kPageSize * 4] ABSL_ATTRIBUTE_SECTION_VARIABLE(.text) =
    "";

static int FilterElfHeader(struct dl_phdr_info *info, size_t size, void *data) {
  for (int i = 0; i < info->dlpi_phnum; i++) {
    if (info->dlpi_phdr[i].p_type == PT_LOAD &&
        info->dlpi_phdr[i].p_flags == (PF_R | PF_X)) {
      const void *const vaddr =
          absl::bit_cast<void *>(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
      const auto segsize = info->dlpi_phdr[i].p_memsz;

      const char *self_exe;
      if (info->dlpi_name != nullptr && info->dlpi_name[0] != '\0') {
        self_exe = info->dlpi_name;
      } else {
        self_exe = "/proc/self/exe";
      }

      absl::debugging_internal::RegisterFileMappingHint(
          vaddr, reinterpret_cast<const char *>(vaddr) + segsize,
          info->dlpi_phdr[i].p_offset, self_exe);

      return 1;
    }
  }

  return 1;
}

TEST(Symbolize, SymbolizeWithMultipleMaps) {
  // Force kPadding0 and kPadding1 to be linked in.
  if (volatile_bool) {
    ABSL_RAW_LOG(INFO, "%s", kPadding0);
    ABSL_RAW_LOG(INFO, "%s", kPadding1);
  }

  // Verify we can symbolize everything.
  char buf[512];
  memset(buf, 0, sizeof(buf));
  absl::Symbolize(kPadding0, buf, sizeof(buf));
  EXPECT_STREQ("kPadding0", buf);

  memset(buf, 0, sizeof(buf));
  absl::Symbolize(kPadding1, buf, sizeof(buf));
  EXPECT_STREQ("kPadding1", buf);

  // Specify a hint for the executable segment.
  dl_iterate_phdr(FilterElfHeader, nullptr);

  // Reload at least one page out of kPadding0, kPadding1
  const char *ptrs[] = {kPadding0, kPadding1};

  for (const char *ptr : ptrs) {
    const int kMapFlags = MAP_ANONYMOUS | MAP_PRIVATE;
    void *addr = mmap(nullptr, kPageSize, PROT_READ, kMapFlags, 0, 0);
    ASSERT_NE(addr, MAP_FAILED);

    // kPadding[0-1] is full of zeroes, so we can remap anywhere within it, but
    // we ensure there is at least a full page of padding.
    void *remapped = reinterpret_cast<void *>(
        reinterpret_cast<uintptr_t>(ptr + kPageSize) & ~(kPageSize - 1ULL));

    const int kMremapFlags = (MREMAP_MAYMOVE | MREMAP_FIXED);
    void *ret = mremap(addr, kPageSize, kPageSize, kMremapFlags, remapped);
    ASSERT_NE(ret, MAP_FAILED);
  }

  // Invalidate the symbolization cache so we are forced to rely on the hint.
  absl::Symbolize(nullptr, buf, sizeof(buf));

  // Verify we can still symbolize.
  const char *expected[] = {"kPadding0", "kPadding1"};
  const size_t offsets[] = {0, kPageSize, 2 * kPageSize, 3 * kPageSize};

  for (int i = 0; i < 2; i++) {
    for (size_t offset : offsets) {
      memset(buf, 0, sizeof(buf));
      absl::Symbolize(ptrs[i] + offset, buf, sizeof(buf));
      EXPECT_STREQ(expected[i], buf);
    }
  }
}

// Appends string(*args->arg) to args->symbol_buf.
static void DummySymbolDecorator(
    const absl::debugging_internal::SymbolDecoratorArgs *args) {
  std::string *message = static_cast<std::string *>(args->arg);
  strncat(args->symbol_buf, message->c_str(),
          args->symbol_buf_size - strlen(args->symbol_buf) - 1);
}

TEST(Symbolize, InstallAndRemoveSymbolDecorators) {
  int ticket_a;
  std::string a_message("a");
  EXPECT_GE(ticket_a = absl::debugging_internal::InstallSymbolDecorator(
                DummySymbolDecorator, &a_message),
            0);

  int ticket_b;
  std::string b_message("b");
  EXPECT_GE(ticket_b = absl::debugging_internal::InstallSymbolDecorator(
                DummySymbolDecorator, &b_message),
            0);

  int ticket_c;
  std::string c_message("c");
  EXPECT_GE(ticket_c = absl::debugging_internal::InstallSymbolDecorator(
                DummySymbolDecorator, &c_message),
            0);

  char *address = reinterpret_cast<char *>(1);
  EXPECT_STREQ("abc", TrySymbolize(address++));

  EXPECT_TRUE(absl::debugging_internal::RemoveSymbolDecorator(ticket_b));

  EXPECT_STREQ("ac", TrySymbolize(address++));

  // Cleanup: remove all remaining decorators so other stack traces don't
  // get mystery "ac" decoration.
  EXPECT_TRUE(absl::debugging_internal::RemoveSymbolDecorator(ticket_a));
  EXPECT_TRUE(absl::debugging_internal::RemoveSymbolDecorator(ticket_c));
}

// Some versions of Clang with optimizations enabled seem to be able
// to optimize away the .data section if no variables live in the
// section. This variable should get placed in the .data section, and
// the test below checks for the existence of a .data section.
static int in_data_section = 1;

TEST(Symbolize, ForEachSection) {
  int fd = TEMP_FAILURE_RETRY(open("/proc/self/exe", O_RDONLY));
  ASSERT_NE(fd, -1);

  std::vector<std::string> sections;
  ASSERT_TRUE(absl::debugging_internal::ForEachSection(
      fd, [&sections](const std::string &name, const ElfW(Shdr) &) {
        sections.push_back(name);
        return true;
      }));

  // Check for the presence of common section names.
  EXPECT_THAT(sections, Contains(".text"));
  EXPECT_THAT(sections, Contains(".rodata"));
  EXPECT_THAT(sections, Contains(".bss"));
  ++in_data_section;
  EXPECT_THAT(sections, Contains(".data"));

  close(fd);
}

// x86 specific tests.  Uses some inline assembler.
extern "C" {
inline void *ABSL_ATTRIBUTE_ALWAYS_INLINE inline_func() {
  void *pc = nullptr;
#if defined(__i386__)
  __asm__ __volatile__("call 1f;\n 1: pop %[PC]" : [ PC ] "=r"(pc));
#elif defined(__x86_64__)
  __asm__ __volatile__("leaq 0(%%rip),%[PC];\n" : [ PC ] "=r"(pc));
#endif
  return pc;
}

void *ABSL_ATTRIBUTE_NOINLINE non_inline_func() {
  void *pc = nullptr;
#if defined(__i386__)
  __asm__ __volatile__("call 1f;\n 1: pop %[PC]" : [ PC ] "=r"(pc));
#elif defined(__x86_64__)
  __asm__ __volatile__("leaq 0(%%rip),%[PC];\n" : [ PC ] "=r"(pc));
#endif
  return pc;
}

void ABSL_ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() {
#if defined(ABSL_HAVE_ATTRIBUTE_NOINLINE) && \
    (defined(__i386__) || defined(__x86_64__))
  void *pc = non_inline_func();
  const char *symbol = TrySymbolize(pc);
  ABSL_RAW_CHECK(symbol != nullptr, "TestWithPCInsideNonInlineFunction failed");
  ABSL_RAW_CHECK(strcmp(symbol, "non_inline_func") == 0,
                 "TestWithPCInsideNonInlineFunction failed");
  std::cout << "TestWithPCInsideNonInlineFunction passed" << std::endl;
#endif
}

void ABSL_ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() {
#if defined(ABSL_HAVE_ATTRIBUTE_ALWAYS_INLINE) && \
    (defined(__i386__) || defined(__x86_64__))
  void *pc = inline_func();  // Must be inlined.
  const char *symbol = TrySymbolize(pc);
  ABSL_RAW_CHECK(symbol != nullptr, "TestWithPCInsideInlineFunction failed");
  ABSL_RAW_CHECK(strcmp(symbol, __FUNCTION__) == 0,
                 "TestWithPCInsideInlineFunction failed");
  std::cout << "TestWithPCInsideInlineFunction passed" << std::endl;
#endif
}
}

// Test with a return address.
void ABSL_ATTRIBUTE_NOINLINE TestWithReturnAddress() {
#if defined(ABSL_HAVE_ATTRIBUTE_NOINLINE)
  void *return_address = __builtin_return_address(0);
  const char *symbol = TrySymbolize(return_address);
  ABSL_RAW_CHECK(symbol != nullptr, "TestWithReturnAddress failed");
  ABSL_RAW_CHECK(strcmp(symbol, "main") == 0, "TestWithReturnAddress failed");
  std::cout << "TestWithReturnAddress passed" << std::endl;
#endif
}

#elif defined(_WIN32) && defined(_DEBUG)

TEST(Symbolize, Basics) {
  EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func)));

  // The name of an internal linkage symbol is not specified; allow either a
  // mangled or an unmangled name here.
  const char* static_func_symbol = TrySymbolize((void *)(&static_func));
  ASSERT_TRUE(static_func_symbol != nullptr);
  EXPECT_TRUE(strstr(static_func_symbol, "static_func") != nullptr);

  EXPECT_TRUE(nullptr == TrySymbolize(nullptr));
}

TEST(Symbolize, Truncation) {
  constexpr char kNonStaticFunc[] = "nonstatic_func";
  EXPECT_STREQ("nonstatic_func",
               TrySymbolizeWithLimit((void *)(&nonstatic_func),
                                     strlen(kNonStaticFunc) + 1));
  EXPECT_STREQ("nonstatic_...",
               TrySymbolizeWithLimit((void *)(&nonstatic_func),
                                     strlen(kNonStaticFunc) + 0));
  EXPECT_STREQ("nonstatic...",
               TrySymbolizeWithLimit((void *)(&nonstatic_func),
                                     strlen(kNonStaticFunc) - 1));
  EXPECT_STREQ("n...", TrySymbolizeWithLimit((void *)(&nonstatic_func), 5));
  EXPECT_STREQ("...", TrySymbolizeWithLimit((void *)(&nonstatic_func), 4));
  EXPECT_STREQ("..", TrySymbolizeWithLimit((void *)(&nonstatic_func), 3));
  EXPECT_STREQ(".", TrySymbolizeWithLimit((void *)(&nonstatic_func), 2));
  EXPECT_STREQ("", TrySymbolizeWithLimit((void *)(&nonstatic_func), 1));
  EXPECT_EQ(nullptr, TrySymbolizeWithLimit((void *)(&nonstatic_func), 0));
}

TEST(Symbolize, SymbolizeWithDemangling) {
  const char* result = TrySymbolize((void *)(&Foo::func));
  ASSERT_TRUE(result != nullptr);
  EXPECT_TRUE(strstr(result, "Foo::func") != nullptr) << result;
}

#else  // Symbolizer unimplemented

TEST(Symbolize, Unimplemented) {
  char buf[64];
  EXPECT_FALSE(absl::Symbolize((void *)(&nonstatic_func), buf, sizeof(buf)));
  EXPECT_FALSE(absl::Symbolize((void *)(&static_func), buf, sizeof(buf)));
  EXPECT_FALSE(absl::Symbolize((void *)(&Foo::func), buf, sizeof(buf)));
}

#endif

int main(int argc, char **argv) {
  // Make sure kHpageTextPadding is linked into the binary.
  if (volatile_bool) {
    ABSL_RAW_LOG(INFO, "%s", kHpageTextPadding);
  }

#if ABSL_PER_THREAD_TLS
  // Touch the per-thread variables.
  symbolize_test_thread_small[0] = 0;
  symbolize_test_thread_big[0] = 0;
#endif

  absl::InitializeSymbolizer(argv[0]);
  testing::InitGoogleTest(&argc, argv);

#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE
  TestWithPCInsideInlineFunction();
  TestWithPCInsideNonInlineFunction();
  TestWithReturnAddress();
#endif

  return RUN_ALL_TESTS();
}
