// 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.

// This library provides Symbolize() function that symbolizes program
// counters to their corresponding symbol names on linux platforms.
// This library has a minimal implementation of an ELF symbol table
// reader (i.e. it doesn't depend on libelf, etc.).
//
// The algorithm used in Symbolize() is as follows.
//
//   1. Go through a list of maps in /proc/self/maps and find the map
//   containing the program counter.
//
//   2. Open the mapped file and find a regular symbol table inside.
//   Iterate over symbols in the symbol table and look for the symbol
//   containing the program counter.  If such a symbol is found,
//   obtain the symbol name, and demangle the symbol if possible.
//   If the symbol isn't found in the regular symbol table (binary is
//   stripped), try the same thing with a dynamic symbol table.
//
// Note that Symbolize() is originally implemented to be used in
// signal handlers, hence it doesn't use malloc() and other unsafe
// operations.  It should be both thread-safe and async-signal-safe.
//
// Implementation note:
//
// We don't use heaps but only use stacks.  We want to reduce the
// stack consumption so that the symbolizer can run on small stacks.
//
// Here are some numbers collected with GCC 4.1.0 on x86:
// - sizeof(Elf32_Sym)  = 16
// - sizeof(Elf32_Shdr) = 40
// - sizeof(Elf64_Sym)  = 24
// - sizeof(Elf64_Shdr) = 64
//
// This implementation is intended to be async-signal-safe but uses some
// functions which are not guaranteed to be so, such as memchr() and
// memmove().  We assume they are async-signal-safe.

#include <dlfcn.h>
#include <elf.h>
#include <fcntl.h>
#include <link.h>  // For ElfW() macro.
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <array>
#include <atomic>
#include <cerrno>
#include <cinttypes>
#include <climits>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include "absl/base/casts.h"
#include "absl/base/dynamic_annotations.h"
#include "absl/base/internal/low_level_alloc.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/spinlock.h"
#include "absl/base/port.h"
#include "absl/debugging/internal/demangle.h"
#include "absl/debugging/internal/vdso_support.h"
#include "absl/strings/string_view.h"

#if defined(__FreeBSD__) && !defined(ElfW)
#define ElfW(x) __ElfN(x)
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN

// Value of argv[0]. Used by MaybeInitializeObjFile().
static char *argv0_value = nullptr;

void InitializeSymbolizer(const char *argv0) {
#ifdef ABSL_HAVE_VDSO_SUPPORT
  // We need to make sure VDSOSupport::Init() is called before any setuid or
  // chroot calls, so InitializeSymbolizer() should be called very early in the
  // life of a program.
  absl::debugging_internal::VDSOSupport::Init();
#endif
  if (argv0_value != nullptr) {
    free(argv0_value);
    argv0_value = nullptr;
  }
  if (argv0 != nullptr && argv0[0] != '\0') {
    argv0_value = strdup(argv0);
  }
}

namespace debugging_internal {
namespace {

// Re-runs fn until it doesn't cause EINTR.
#define NO_INTR(fn) \
  do {              \
  } while ((fn) < 0 && errno == EINTR)

// On Linux, ELF_ST_* are defined in <linux/elf.h>.  To make this portable
// we define our own ELF_ST_BIND and ELF_ST_TYPE if not available.
#ifndef ELF_ST_BIND
#define ELF_ST_BIND(info) (((unsigned char)(info)) >> 4)
#endif

#ifndef ELF_ST_TYPE
#define ELF_ST_TYPE(info) (((unsigned char)(info)) & 0xF)
#endif

// Some platforms use a special .opd section to store function pointers.
const char kOpdSectionName[] = ".opd";

#if (defined(__powerpc__) && !(_CALL_ELF > 1)) || defined(__ia64)
// Use opd section for function descriptors on these platforms, the function
// address is the first word of the descriptor.
enum { kPlatformUsesOPDSections = 1 };
#else  // not PPC or IA64
enum { kPlatformUsesOPDSections = 0 };
#endif

// This works for PowerPC & IA64 only.  A function descriptor consist of two
// pointers and the first one is the function's entry.
const size_t kFunctionDescriptorSize = sizeof(void *) * 2;

const int kMaxDecorators = 10;  // Seems like a reasonable upper limit.

struct InstalledSymbolDecorator {
  SymbolDecorator fn;
  void *arg;
  int ticket;
};

int g_num_decorators;
InstalledSymbolDecorator g_decorators[kMaxDecorators];

struct FileMappingHint {
  const void *start;
  const void *end;
  uint64_t offset;
  const char *filename;
};

// Protects g_decorators.
// We are using SpinLock and not a Mutex here, because we may be called
// from inside Mutex::Lock itself, and it prohibits recursive calls.
// This happens in e.g. base/stacktrace_syscall_unittest.
// Moreover, we are using only TryLock(), if the decorator list
// is being modified (is busy), we skip all decorators, and possibly
// loose some info. Sorry, that's the best we could do.
ABSL_CONST_INIT absl::base_internal::SpinLock g_decorators_mu(
    absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY);

const int kMaxFileMappingHints = 8;
int g_num_file_mapping_hints;
FileMappingHint g_file_mapping_hints[kMaxFileMappingHints];
// Protects g_file_mapping_hints.
ABSL_CONST_INIT absl::base_internal::SpinLock g_file_mapping_mu(
    absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY);

// Async-signal-safe function to zero a buffer.
// memset() is not guaranteed to be async-signal-safe.
static void SafeMemZero(void* p, size_t size) {
  unsigned char *c = static_cast<unsigned char *>(p);
  while (size--) {
    *c++ = 0;
  }
}

struct ObjFile {
  ObjFile()
      : filename(nullptr),
        start_addr(nullptr),
        end_addr(nullptr),
        offset(0),
        fd(-1),
        elf_type(-1) {
    SafeMemZero(&elf_header, sizeof(elf_header));
    SafeMemZero(&phdr[0], sizeof(phdr));
  }

  char *filename;
  const void *start_addr;
  const void *end_addr;
  uint64_t offset;

  // The following fields are initialized on the first access to the
  // object file.
  int fd;
  int elf_type;
  ElfW(Ehdr) elf_header;

  // PT_LOAD program header describing executable code.
  // Normally we expect just one, but SWIFT binaries have two.
  std::array<ElfW(Phdr), 2> phdr;
};

// Build 4-way associative cache for symbols. Within each cache line, symbols
// are replaced in LRU order.
enum {
  ASSOCIATIVITY = 4,
};
struct SymbolCacheLine {
  const void *pc[ASSOCIATIVITY];
  char *name[ASSOCIATIVITY];

  // age[i] is incremented when a line is accessed. it's reset to zero if the
  // i'th entry is read.
  uint32_t age[ASSOCIATIVITY];
};

// ---------------------------------------------------------------
// An async-signal-safe arena for LowLevelAlloc
static std::atomic<base_internal::LowLevelAlloc::Arena *> g_sig_safe_arena;

static base_internal::LowLevelAlloc::Arena *SigSafeArena() {
  return g_sig_safe_arena.load(std::memory_order_acquire);
}

static void InitSigSafeArena() {
  if (SigSafeArena() == nullptr) {
    base_internal::LowLevelAlloc::Arena *new_arena =
        base_internal::LowLevelAlloc::NewArena(
            base_internal::LowLevelAlloc::kAsyncSignalSafe);
    base_internal::LowLevelAlloc::Arena *old_value = nullptr;
    if (!g_sig_safe_arena.compare_exchange_strong(old_value, new_arena,
                                                  std::memory_order_release,
                                                  std::memory_order_relaxed)) {
      // We lost a race to allocate an arena; deallocate.
      base_internal::LowLevelAlloc::DeleteArena(new_arena);
    }
  }
}

// ---------------------------------------------------------------
// An AddrMap is a vector of ObjFile, using SigSafeArena() for allocation.

class AddrMap {
 public:
  AddrMap() : size_(0), allocated_(0), obj_(nullptr) {}
  ~AddrMap() { base_internal::LowLevelAlloc::Free(obj_); }
  int Size() const { return size_; }
  ObjFile *At(int i) { return &obj_[i]; }
  ObjFile *Add();
  void Clear();

 private:
  int size_;       // count of valid elements (<= allocated_)
  int allocated_;  // count of allocated elements
  ObjFile *obj_;   // array of allocated_ elements
  AddrMap(const AddrMap &) = delete;
  AddrMap &operator=(const AddrMap &) = delete;
};

void AddrMap::Clear() {
  for (int i = 0; i != size_; i++) {
    At(i)->~ObjFile();
  }
  size_ = 0;
}

ObjFile *AddrMap::Add() {
  if (size_ == allocated_) {
    int new_allocated = allocated_ * 2 + 50;
    ObjFile *new_obj_ =
        static_cast<ObjFile *>(base_internal::LowLevelAlloc::AllocWithArena(
            new_allocated * sizeof(*new_obj_), SigSafeArena()));
    if (obj_) {
      memcpy(new_obj_, obj_, allocated_ * sizeof(*new_obj_));
      base_internal::LowLevelAlloc::Free(obj_);
    }
    obj_ = new_obj_;
    allocated_ = new_allocated;
  }
  return new (&obj_[size_++]) ObjFile;
}

// ---------------------------------------------------------------

enum FindSymbolResult { SYMBOL_NOT_FOUND = 1, SYMBOL_TRUNCATED, SYMBOL_FOUND };

class Symbolizer {
 public:
  Symbolizer();
  ~Symbolizer();
  const char *GetSymbol(const void *const pc);

 private:
  char *CopyString(const char *s) {
    int len = strlen(s);
    char *dst = static_cast<char *>(
        base_internal::LowLevelAlloc::AllocWithArena(len + 1, SigSafeArena()));
    ABSL_RAW_CHECK(dst != nullptr, "out of memory");
    memcpy(dst, s, len + 1);
    return dst;
  }
  ObjFile *FindObjFile(const void *const start,
                       size_t size) ABSL_ATTRIBUTE_NOINLINE;
  static bool RegisterObjFile(const char *filename,
                              const void *const start_addr,
                              const void *const end_addr, uint64_t offset,
                              void *arg);
  SymbolCacheLine *GetCacheLine(const void *const pc);
  const char *FindSymbolInCache(const void *const pc);
  const char *InsertSymbolInCache(const void *const pc, const char *name);
  void AgeSymbols(SymbolCacheLine *line);
  void ClearAddrMap();
  FindSymbolResult GetSymbolFromObjectFile(const ObjFile &obj,
                                           const void *const pc,
                                           const ptrdiff_t relocation,
                                           char *out, int out_size,
                                           char *tmp_buf, int tmp_buf_size);
  const char *GetUncachedSymbol(const void *pc);

  enum {
    SYMBOL_BUF_SIZE = 3072,
    TMP_BUF_SIZE = 1024,
    SYMBOL_CACHE_LINES = 128,
  };

  AddrMap addr_map_;

  bool ok_;
  bool addr_map_read_;

  char symbol_buf_[SYMBOL_BUF_SIZE];

  // tmp_buf_ will be used to store arrays of ElfW(Shdr) and ElfW(Sym)
  // so we ensure that tmp_buf_ is properly aligned to store either.
  alignas(16) char tmp_buf_[TMP_BUF_SIZE];
  static_assert(alignof(ElfW(Shdr)) <= 16,
                "alignment of tmp buf too small for Shdr");
  static_assert(alignof(ElfW(Sym)) <= 16,
                "alignment of tmp buf too small for Sym");

  SymbolCacheLine symbol_cache_[SYMBOL_CACHE_LINES];
};

static std::atomic<Symbolizer *> g_cached_symbolizer;

}  // namespace

static int SymbolizerSize() {
#if defined(__wasm__) || defined(__asmjs__)
  int pagesize = getpagesize();
#else
  int pagesize = sysconf(_SC_PAGESIZE);
#endif
  return ((sizeof(Symbolizer) - 1) / pagesize + 1) * pagesize;
}

// Return (and set null) g_cached_symbolized_state if it is not null.
// Otherwise return a new symbolizer.
static Symbolizer *AllocateSymbolizer() {
  InitSigSafeArena();
  Symbolizer *symbolizer =
      g_cached_symbolizer.exchange(nullptr, std::memory_order_acquire);
  if (symbolizer != nullptr) {
    return symbolizer;
  }
  return new (base_internal::LowLevelAlloc::AllocWithArena(
      SymbolizerSize(), SigSafeArena())) Symbolizer();
}

// Set g_cached_symbolize_state to s if it is null, otherwise
// delete s.
static void FreeSymbolizer(Symbolizer *s) {
  Symbolizer *old_cached_symbolizer = nullptr;
  if (!g_cached_symbolizer.compare_exchange_strong(old_cached_symbolizer, s,
                                                   std::memory_order_release,
                                                   std::memory_order_relaxed)) {
    s->~Symbolizer();
    base_internal::LowLevelAlloc::Free(s);
  }
}

Symbolizer::Symbolizer() : ok_(true), addr_map_read_(false) {
  for (SymbolCacheLine &symbol_cache_line : symbol_cache_) {
    for (size_t j = 0; j < ABSL_ARRAYSIZE(symbol_cache_line.name); ++j) {
      symbol_cache_line.pc[j] = nullptr;
      symbol_cache_line.name[j] = nullptr;
      symbol_cache_line.age[j] = 0;
    }
  }
}

Symbolizer::~Symbolizer() {
  for (SymbolCacheLine &symbol_cache_line : symbol_cache_) {
    for (char *s : symbol_cache_line.name) {
      base_internal::LowLevelAlloc::Free(s);
    }
  }
  ClearAddrMap();
}

// We don't use assert() since it's not guaranteed to be
// async-signal-safe.  Instead we define a minimal assertion
// macro. So far, we don't need pretty printing for __FILE__, etc.
#define SAFE_ASSERT(expr) ((expr) ? static_cast<void>(0) : abort())

// Read up to "count" bytes from file descriptor "fd" into the buffer
// starting at "buf" while handling short reads and EINTR.  On
// success, return the number of bytes read.  Otherwise, return -1.
static ssize_t ReadPersistent(int fd, void *buf, size_t count) {
  SAFE_ASSERT(fd >= 0);
  SAFE_ASSERT(count <= SSIZE_MAX);
  char *buf0 = reinterpret_cast<char *>(buf);
  size_t num_bytes = 0;
  while (num_bytes < count) {
    ssize_t len;
    NO_INTR(len = read(fd, buf0 + num_bytes, count - num_bytes));
    if (len < 0) {  // There was an error other than EINTR.
      ABSL_RAW_LOG(WARNING, "read failed: errno=%d", errno);
      return -1;
    }
    if (len == 0) {  // Reached EOF.
      break;
    }
    num_bytes += len;
  }
  SAFE_ASSERT(num_bytes <= count);
  return static_cast<ssize_t>(num_bytes);
}

// Read up to "count" bytes from "offset" in the file pointed by file
// descriptor "fd" into the buffer starting at "buf".  On success,
// return the number of bytes read.  Otherwise, return -1.
static ssize_t ReadFromOffset(const int fd, void *buf, const size_t count,
                              const off_t offset) {
  off_t off = lseek(fd, offset, SEEK_SET);
  if (off == (off_t)-1) {
    ABSL_RAW_LOG(WARNING, "lseek(%d, %ju, SEEK_SET) failed: errno=%d", fd,
                 static_cast<uintmax_t>(offset), errno);
    return -1;
  }
  return ReadPersistent(fd, buf, count);
}

// Try reading exactly "count" bytes from "offset" bytes in a file
// pointed by "fd" into the buffer starting at "buf" while handling
// short reads and EINTR.  On success, return true. Otherwise, return
// false.
static bool ReadFromOffsetExact(const int fd, void *buf, const size_t count,
                                const off_t offset) {
  ssize_t len = ReadFromOffset(fd, buf, count, offset);
  return len >= 0 && static_cast<size_t>(len) == count;
}

// Returns elf_header.e_type if the file pointed by fd is an ELF binary.
static int FileGetElfType(const int fd) {
  ElfW(Ehdr) elf_header;
  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
    return -1;
  }
  if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) {
    return -1;
  }
  return elf_header.e_type;
}

// Read the section headers in the given ELF binary, and if a section
// of the specified type is found, set the output to this section header
// and return true.  Otherwise, return false.
// To keep stack consumption low, we would like this function to not get
// inlined.
static ABSL_ATTRIBUTE_NOINLINE bool GetSectionHeaderByType(
    const int fd, ElfW(Half) sh_num, const off_t sh_offset, ElfW(Word) type,
    ElfW(Shdr) * out, char *tmp_buf, int tmp_buf_size) {
  ElfW(Shdr) *buf = reinterpret_cast<ElfW(Shdr) *>(tmp_buf);
  const int buf_entries = tmp_buf_size / sizeof(buf[0]);
  const int buf_bytes = buf_entries * sizeof(buf[0]);

  for (int i = 0; i < sh_num;) {
    const ssize_t num_bytes_left = (sh_num - i) * sizeof(buf[0]);
    const ssize_t num_bytes_to_read =
        (buf_bytes > num_bytes_left) ? num_bytes_left : buf_bytes;
    const off_t offset = sh_offset + i * sizeof(buf[0]);
    const ssize_t len = ReadFromOffset(fd, buf, num_bytes_to_read, offset);
    if (len % sizeof(buf[0]) != 0) {
      ABSL_RAW_LOG(
          WARNING,
          "Reading %zd bytes from offset %ju returned %zd which is not a "
          "multiple of %zu.",
          num_bytes_to_read, static_cast<uintmax_t>(offset), len,
          sizeof(buf[0]));
      return false;
    }
    const ssize_t num_headers_in_buf = len / sizeof(buf[0]);
    SAFE_ASSERT(num_headers_in_buf <= buf_entries);
    for (int j = 0; j < num_headers_in_buf; ++j) {
      if (buf[j].sh_type == type) {
        *out = buf[j];
        return true;
      }
    }
    i += num_headers_in_buf;
  }
  return false;
}

// There is no particular reason to limit section name to 63 characters,
// but there has (as yet) been no need for anything longer either.
const int kMaxSectionNameLen = 64;

bool ForEachSection(int fd,
                    const std::function<bool(absl::string_view name,
                                             const ElfW(Shdr) &)> &callback) {
  ElfW(Ehdr) elf_header;
  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
    return false;
  }

  ElfW(Shdr) shstrtab;
  off_t shstrtab_offset =
      (elf_header.e_shoff + elf_header.e_shentsize * elf_header.e_shstrndx);
  if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) {
    return false;
  }

  for (int i = 0; i < elf_header.e_shnum; ++i) {
    ElfW(Shdr) out;
    off_t section_header_offset =
        (elf_header.e_shoff + elf_header.e_shentsize * i);
    if (!ReadFromOffsetExact(fd, &out, sizeof(out), section_header_offset)) {
      return false;
    }
    off_t name_offset = shstrtab.sh_offset + out.sh_name;
    char header_name[kMaxSectionNameLen];
    ssize_t n_read =
        ReadFromOffset(fd, &header_name, kMaxSectionNameLen, name_offset);
    if (n_read == -1) {
      return false;
    } else if (n_read > kMaxSectionNameLen) {
      // Long read?
      return false;
    }

    absl::string_view name(header_name, strnlen(header_name, n_read));
    if (!callback(name, out)) {
      break;
    }
  }
  return true;
}

// name_len should include terminating '\0'.
bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
                            ElfW(Shdr) * out) {
  char header_name[kMaxSectionNameLen];
  if (sizeof(header_name) < name_len) {
    ABSL_RAW_LOG(WARNING,
                 "Section name '%s' is too long (%zu); "
                 "section will not be found (even if present).",
                 name, name_len);
    // No point in even trying.
    return false;
  }

  ElfW(Ehdr) elf_header;
  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
    return false;
  }

  ElfW(Shdr) shstrtab;
  off_t shstrtab_offset =
      (elf_header.e_shoff + elf_header.e_shentsize * elf_header.e_shstrndx);
  if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) {
    return false;
  }

  for (int i = 0; i < elf_header.e_shnum; ++i) {
    off_t section_header_offset =
        (elf_header.e_shoff + elf_header.e_shentsize * i);
    if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) {
      return false;
    }
    off_t name_offset = shstrtab.sh_offset + out->sh_name;
    ssize_t n_read = ReadFromOffset(fd, &header_name, name_len, name_offset);
    if (n_read < 0) {
      return false;
    } else if (static_cast<size_t>(n_read) != name_len) {
      // Short read -- name could be at end of file.
      continue;
    }
    if (memcmp(header_name, name, name_len) == 0) {
      return true;
    }
  }
  return false;
}

// Compare symbols at in the same address.
// Return true if we should pick symbol1.
static bool ShouldPickFirstSymbol(const ElfW(Sym) & symbol1,
                                  const ElfW(Sym) & symbol2) {
  // If one of the symbols is weak and the other is not, pick the one
  // this is not a weak symbol.
  char bind1 = ELF_ST_BIND(symbol1.st_info);
  char bind2 = ELF_ST_BIND(symbol1.st_info);
  if (bind1 == STB_WEAK && bind2 != STB_WEAK) return false;
  if (bind2 == STB_WEAK && bind1 != STB_WEAK) return true;

  // If one of the symbols has zero size and the other is not, pick the
  // one that has non-zero size.
  if (symbol1.st_size != 0 && symbol2.st_size == 0) {
    return true;
  }
  if (symbol1.st_size == 0 && symbol2.st_size != 0) {
    return false;
  }

  // If one of the symbols has no type and the other is not, pick the
  // one that has a type.
  char type1 = ELF_ST_TYPE(symbol1.st_info);
  char type2 = ELF_ST_TYPE(symbol1.st_info);
  if (type1 != STT_NOTYPE && type2 == STT_NOTYPE) {
    return true;
  }
  if (type1 == STT_NOTYPE && type2 != STT_NOTYPE) {
    return false;
  }

  // Pick the first one, if we still cannot decide.
  return true;
}

// Return true if an address is inside a section.
static bool InSection(const void *address, const ElfW(Shdr) * section) {
  const char *start = reinterpret_cast<const char *>(section->sh_addr);
  size_t size = static_cast<size_t>(section->sh_size);
  return start <= address && address < (start + size);
}

static const char *ComputeOffset(const char *base, ptrdiff_t offset) {
  // Note: cast to uintptr_t to avoid undefined behavior when base evaluates to
  // zero and offset is non-zero.
  return reinterpret_cast<const char *>(
      reinterpret_cast<uintptr_t>(base) + offset);
}

// Read a symbol table and look for the symbol containing the
// pc. Iterate over symbols in a symbol table and look for the symbol
// containing "pc".  If the symbol is found, and its name fits in
// out_size, the name is written into out and SYMBOL_FOUND is returned.
// If the name does not fit, truncated name is written into out,
// and SYMBOL_TRUNCATED is returned. Out is NUL-terminated.
// If the symbol is not found, SYMBOL_NOT_FOUND is returned;
// To keep stack consumption low, we would like this function to not get
// inlined.
static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol(
    const void *const pc, const int fd, char *out, int out_size,
    ptrdiff_t relocation, const ElfW(Shdr) * strtab, const ElfW(Shdr) * symtab,
    const ElfW(Shdr) * opd, char *tmp_buf, int tmp_buf_size) {
  if (symtab == nullptr) {
    return SYMBOL_NOT_FOUND;
  }

  // Read multiple symbols at once to save read() calls.
  ElfW(Sym) *buf = reinterpret_cast<ElfW(Sym) *>(tmp_buf);
  const int buf_entries = tmp_buf_size / sizeof(buf[0]);

  const int num_symbols = symtab->sh_size / symtab->sh_entsize;

  // On platforms using an .opd section (PowerPC & IA64), a function symbol
  // has the address of a function descriptor, which contains the real
  // starting address.  However, we do not always want to use the real
  // starting address because we sometimes want to symbolize a function
  // pointer into the .opd section, e.g. FindSymbol(&foo,...).
  const bool pc_in_opd =
      kPlatformUsesOPDSections && opd != nullptr && InSection(pc, opd);
  const bool deref_function_descriptor_pointer =
      kPlatformUsesOPDSections && opd != nullptr && !pc_in_opd;

  ElfW(Sym) best_match;
  SafeMemZero(&best_match, sizeof(best_match));
  bool found_match = false;
  for (int i = 0; i < num_symbols;) {
    off_t offset = symtab->sh_offset + i * symtab->sh_entsize;
    const int num_remaining_symbols = num_symbols - i;
    const int entries_in_chunk = std::min(num_remaining_symbols, buf_entries);
    const int bytes_in_chunk = entries_in_chunk * sizeof(buf[0]);
    const ssize_t len = ReadFromOffset(fd, buf, bytes_in_chunk, offset);
    SAFE_ASSERT(len % sizeof(buf[0]) == 0);
    const ssize_t num_symbols_in_buf = len / sizeof(buf[0]);
    SAFE_ASSERT(num_symbols_in_buf <= entries_in_chunk);
    for (int j = 0; j < num_symbols_in_buf; ++j) {
      const ElfW(Sym) &symbol = buf[j];

      // For a DSO, a symbol address is relocated by the loading address.
      // We keep the original address for opd redirection below.
      const char *const original_start_address =
          reinterpret_cast<const char *>(symbol.st_value);
      const char *start_address =
          ComputeOffset(original_start_address, relocation);

#ifdef __arm__
      // ARM functions are always aligned to multiples of two bytes; the
      // lowest-order bit in start_address is ignored by the CPU and indicates
      // whether the function contains ARM (0) or Thumb (1) code. We don't care
      // about what encoding is being used; we just want the real start address
      // of the function.
      start_address = reinterpret_cast<const char *>(
          reinterpret_cast<uintptr_t>(start_address) & ~1);
#endif

      if (deref_function_descriptor_pointer &&
          InSection(original_start_address, opd)) {
        // The opd section is mapped into memory.  Just dereference
        // start_address to get the first double word, which points to the
        // function entry.
        start_address = *reinterpret_cast<const char *const *>(start_address);
      }

      // If pc is inside the .opd section, it points to a function descriptor.
      const size_t size = pc_in_opd ? kFunctionDescriptorSize : symbol.st_size;
      const void *const end_address = ComputeOffset(start_address, size);
      if (symbol.st_value != 0 &&  // Skip null value symbols.
          symbol.st_shndx != 0 &&  // Skip undefined symbols.
#ifdef STT_TLS
          ELF_ST_TYPE(symbol.st_info) != STT_TLS &&  // Skip thread-local data.
#endif                                               // STT_TLS
          ((start_address <= pc && pc < end_address) ||
           (start_address == pc && pc == end_address))) {
        if (!found_match || ShouldPickFirstSymbol(symbol, best_match)) {
          found_match = true;
          best_match = symbol;
        }
      }
    }
    i += num_symbols_in_buf;
  }

  if (found_match) {
    const size_t off = strtab->sh_offset + best_match.st_name;
    const ssize_t n_read = ReadFromOffset(fd, out, out_size, off);
    if (n_read <= 0) {
      // This should never happen.
      ABSL_RAW_LOG(WARNING,
                   "Unable to read from fd %d at offset %zu: n_read = %zd", fd,
                   off, n_read);
      return SYMBOL_NOT_FOUND;
    }
    ABSL_RAW_CHECK(n_read <= out_size, "ReadFromOffset read too much data.");

    // strtab->sh_offset points into .strtab-like section that contains
    // NUL-terminated strings: '\0foo\0barbaz\0...".
    //
    // sh_offset+st_name points to the start of symbol name, but we don't know
    // how long the symbol is, so we try to read as much as we have space for,
    // and usually over-read (i.e. there is a NUL somewhere before n_read).
    if (memchr(out, '\0', n_read) == nullptr) {
      // Either out_size was too small (n_read == out_size and no NUL), or
      // we tried to read past the EOF (n_read < out_size) and .strtab is
      // corrupt (missing terminating NUL; should never happen for valid ELF).
      out[n_read - 1] = '\0';
      return SYMBOL_TRUNCATED;
    }
    return SYMBOL_FOUND;
  }

  return SYMBOL_NOT_FOUND;
}

// Get the symbol name of "pc" from the file pointed by "fd".  Process
// both regular and dynamic symbol tables if necessary.
// See FindSymbol() comment for description of return value.
FindSymbolResult Symbolizer::GetSymbolFromObjectFile(
    const ObjFile &obj, const void *const pc, const ptrdiff_t relocation,
    char *out, int out_size, char *tmp_buf, int tmp_buf_size) {
  ElfW(Shdr) symtab;
  ElfW(Shdr) strtab;
  ElfW(Shdr) opd;
  ElfW(Shdr) *opd_ptr = nullptr;

  // On platforms using an .opd sections for function descriptor, read
  // the section header.  The .opd section is in data segment and should be
  // loaded but we check that it is mapped just to be extra careful.
  if (kPlatformUsesOPDSections) {
    if (GetSectionHeaderByName(obj.fd, kOpdSectionName,
                               sizeof(kOpdSectionName) - 1, &opd) &&
        FindObjFile(reinterpret_cast<const char *>(opd.sh_addr) + relocation,
                    opd.sh_size) != nullptr) {
      opd_ptr = &opd;
    } else {
      return SYMBOL_NOT_FOUND;
    }
  }

  // Consult a regular symbol table, then fall back to the dynamic symbol table.
  for (const auto symbol_table_type : {SHT_SYMTAB, SHT_DYNSYM}) {
    if (!GetSectionHeaderByType(obj.fd, obj.elf_header.e_shnum,
                                obj.elf_header.e_shoff, symbol_table_type,
                                &symtab, tmp_buf, tmp_buf_size)) {
      continue;
    }
    if (!ReadFromOffsetExact(
            obj.fd, &strtab, sizeof(strtab),
            obj.elf_header.e_shoff + symtab.sh_link * sizeof(symtab))) {
      continue;
    }
    const FindSymbolResult rc =
        FindSymbol(pc, obj.fd, out, out_size, relocation, &strtab, &symtab,
                   opd_ptr, tmp_buf, tmp_buf_size);
    if (rc != SYMBOL_NOT_FOUND) {
      return rc;
    }
  }

  return SYMBOL_NOT_FOUND;
}

namespace {
// Thin wrapper around a file descriptor so that the file descriptor
// gets closed for sure.
class FileDescriptor {
 public:
  explicit FileDescriptor(int fd) : fd_(fd) {}
  FileDescriptor(const FileDescriptor &) = delete;
  FileDescriptor &operator=(const FileDescriptor &) = delete;

  ~FileDescriptor() {
    if (fd_ >= 0) {
      NO_INTR(close(fd_));
    }
  }

  int get() const { return fd_; }

 private:
  const int fd_;
};

// Helper class for reading lines from file.
//
// Note: we don't use ProcMapsIterator since the object is big (it has
// a 5k array member) and uses async-unsafe functions such as sscanf()
// and snprintf().
class LineReader {
 public:
  explicit LineReader(int fd, char *buf, int buf_len)
      : fd_(fd),
        buf_len_(buf_len),
        buf_(buf),
        bol_(buf),
        eol_(buf),
        eod_(buf) {}

  LineReader(const LineReader &) = delete;
  LineReader &operator=(const LineReader &) = delete;

  // Read '\n'-terminated line from file.  On success, modify "bol"
  // and "eol", then return true.  Otherwise, return false.
  //
  // Note: if the last line doesn't end with '\n', the line will be
  // dropped.  It's an intentional behavior to make the code simple.
  bool ReadLine(const char **bol, const char **eol) {
    if (BufferIsEmpty()) {  // First time.
      const ssize_t num_bytes = ReadPersistent(fd_, buf_, buf_len_);
      if (num_bytes <= 0) {  // EOF or error.
        return false;
      }
      eod_ = buf_ + num_bytes;
      bol_ = buf_;
    } else {
      bol_ = eol_ + 1;            // Advance to the next line in the buffer.
      SAFE_ASSERT(bol_ <= eod_);  // "bol_" can point to "eod_".
      if (!HasCompleteLine()) {
        const int incomplete_line_length = eod_ - bol_;
        // Move the trailing incomplete line to the beginning.
        memmove(buf_, bol_, incomplete_line_length);
        // Read text from file and append it.
        char *const append_pos = buf_ + incomplete_line_length;
        const int capacity_left = buf_len_ - incomplete_line_length;
        const ssize_t num_bytes =
            ReadPersistent(fd_, append_pos, capacity_left);
        if (num_bytes <= 0) {  // EOF or error.
          return false;
        }
        eod_ = append_pos + num_bytes;
        bol_ = buf_;
      }
    }
    eol_ = FindLineFeed();
    if (eol_ == nullptr) {  // '\n' not found.  Malformed line.
      return false;
    }
    *eol_ = '\0';  // Replace '\n' with '\0'.

    *bol = bol_;
    *eol = eol_;
    return true;
  }

 private:
  char *FindLineFeed() const {
    return reinterpret_cast<char *>(memchr(bol_, '\n', eod_ - bol_));
  }

  bool BufferIsEmpty() const { return buf_ == eod_; }

  bool HasCompleteLine() const {
    return !BufferIsEmpty() && FindLineFeed() != nullptr;
  }

  const int fd_;
  const int buf_len_;
  char *const buf_;
  char *bol_;
  char *eol_;
  const char *eod_;  // End of data in "buf_".
};
}  // namespace

// Place the hex number read from "start" into "*hex".  The pointer to
// the first non-hex character or "end" is returned.
static const char *GetHex(const char *start, const char *end,
                          uint64_t *const value) {
  uint64_t hex = 0;
  const char *p;
  for (p = start; p < end; ++p) {
    int ch = *p;
    if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') ||
        (ch >= 'a' && ch <= 'f')) {
      hex = (hex << 4) | (ch < 'A' ? ch - '0' : (ch & 0xF) + 9);
    } else {  // Encountered the first non-hex character.
      break;
    }
  }
  SAFE_ASSERT(p <= end);
  *value = hex;
  return p;
}

static const char *GetHex(const char *start, const char *end,
                          const void **const addr) {
  uint64_t hex = 0;
  const char *p = GetHex(start, end, &hex);
  *addr = reinterpret_cast<void *>(hex);
  return p;
}

// Normally we are only interested in "r?x" maps.
// On the PowerPC, function pointers point to descriptors in the .opd
// section.  The descriptors themselves are not executable code, so
// we need to relax the check below to "r??".
static bool ShouldUseMapping(const char *const flags) {
  return flags[0] == 'r' && (kPlatformUsesOPDSections || flags[2] == 'x');
}

// Read /proc/self/maps and run "callback" for each mmapped file found.  If
// "callback" returns false, stop scanning and return true. Else continue
// scanning /proc/self/maps. Return true if no parse error is found.
static ABSL_ATTRIBUTE_NOINLINE bool ReadAddrMap(
    bool (*callback)(const char *filename, const void *const start_addr,
                     const void *const end_addr, uint64_t offset, void *arg),
    void *arg, void *tmp_buf, int tmp_buf_size) {
  // Use /proc/self/task/<pid>/maps instead of /proc/self/maps. The latter
  // requires kernel to stop all threads, and is significantly slower when there
  // are 1000s of threads.
  char maps_path[80];
  snprintf(maps_path, sizeof(maps_path), "/proc/self/task/%d/maps", getpid());

  int maps_fd;
  NO_INTR(maps_fd = open(maps_path, O_RDONLY));
  FileDescriptor wrapped_maps_fd(maps_fd);
  if (wrapped_maps_fd.get() < 0) {
    ABSL_RAW_LOG(WARNING, "%s: errno=%d", maps_path, errno);
    return false;
  }

  // Iterate over maps and look for the map containing the pc.  Then
  // look into the symbol tables inside.
  LineReader reader(wrapped_maps_fd.get(), static_cast<char *>(tmp_buf),
                    tmp_buf_size);
  while (true) {
    const char *cursor;
    const char *eol;
    if (!reader.ReadLine(&cursor, &eol)) {  // EOF or malformed line.
      break;
    }

    const char *line = cursor;
    const void *start_address;
    // Start parsing line in /proc/self/maps.  Here is an example:
    //
    // 08048000-0804c000 r-xp 00000000 08:01 2142121    /bin/cat
    //
    // We want start address (08048000), end address (0804c000), flags
    // (r-xp) and file name (/bin/cat).

    // Read start address.
    cursor = GetHex(cursor, eol, &start_address);
    if (cursor == eol || *cursor != '-') {
      ABSL_RAW_LOG(WARNING, "Corrupt /proc/self/maps line: %s", line);
      return false;
    }
    ++cursor;  // Skip '-'.

    // Read end address.
    const void *end_address;
    cursor = GetHex(cursor, eol, &end_address);
    if (cursor == eol || *cursor != ' ') {
      ABSL_RAW_LOG(WARNING, "Corrupt /proc/self/maps line: %s", line);
      return false;
    }
    ++cursor;  // Skip ' '.

    // Read flags.  Skip flags until we encounter a space or eol.
    const char *const flags_start = cursor;
    while (cursor < eol && *cursor != ' ') {
      ++cursor;
    }
    // We expect at least four letters for flags (ex. "r-xp").
    if (cursor == eol || cursor < flags_start + 4) {
      ABSL_RAW_LOG(WARNING, "Corrupt /proc/self/maps: %s", line);
      return false;
    }

    // Check flags.
    if (!ShouldUseMapping(flags_start)) {
      continue;  // We skip this map.
    }
    ++cursor;  // Skip ' '.

    // Read file offset.
    uint64_t offset;
    cursor = GetHex(cursor, eol, &offset);
    ++cursor;  // Skip ' '.

    // Skip to file name.  "cursor" now points to dev.  We need to skip at least
    // two spaces for dev and inode.
    int num_spaces = 0;
    while (cursor < eol) {
      if (*cursor == ' ') {
        ++num_spaces;
      } else if (num_spaces >= 2) {
        // The first non-space character after  skipping two spaces
        // is the beginning of the file name.
        break;
      }
      ++cursor;
    }

    // Check whether this entry corresponds to our hint table for the true
    // filename.
    bool hinted =
        GetFileMappingHint(&start_address, &end_address, &offset, &cursor);
    if (!hinted && (cursor == eol || cursor[0] == '[')) {
      // not an object file, typically [vdso] or [vsyscall]
      continue;
    }
    if (!callback(cursor, start_address, end_address, offset, arg)) break;
  }
  return true;
}

// Find the objfile mapped in address region containing [addr, addr + len).
ObjFile *Symbolizer::FindObjFile(const void *const addr, size_t len) {
  for (int i = 0; i < 2; ++i) {
    if (!ok_) return nullptr;

    // Read /proc/self/maps if necessary
    if (!addr_map_read_) {
      addr_map_read_ = true;
      if (!ReadAddrMap(RegisterObjFile, this, tmp_buf_, TMP_BUF_SIZE)) {
        ok_ = false;
        return nullptr;
      }
    }

    int lo = 0;
    int hi = addr_map_.Size();
    while (lo < hi) {
      int mid = (lo + hi) / 2;
      if (addr < addr_map_.At(mid)->end_addr) {
        hi = mid;
      } else {
        lo = mid + 1;
      }
    }
    if (lo != addr_map_.Size()) {
      ObjFile *obj = addr_map_.At(lo);
      SAFE_ASSERT(obj->end_addr > addr);
      if (addr >= obj->start_addr &&
          reinterpret_cast<const char *>(addr) + len <= obj->end_addr)
        return obj;
    }

    // The address mapping may have changed since it was last read.  Retry.
    ClearAddrMap();
  }
  return nullptr;
}

void Symbolizer::ClearAddrMap() {
  for (int i = 0; i != addr_map_.Size(); i++) {
    ObjFile *o = addr_map_.At(i);
    base_internal::LowLevelAlloc::Free(o->filename);
    if (o->fd >= 0) {
      NO_INTR(close(o->fd));
    }
  }
  addr_map_.Clear();
  addr_map_read_ = false;
}

// Callback for ReadAddrMap to register objfiles in an in-memory table.
bool Symbolizer::RegisterObjFile(const char *filename,
                                 const void *const start_addr,
                                 const void *const end_addr, uint64_t offset,
                                 void *arg) {
  Symbolizer *impl = static_cast<Symbolizer *>(arg);

  // Files are supposed to be added in the increasing address order.  Make
  // sure that's the case.
  int addr_map_size = impl->addr_map_.Size();
  if (addr_map_size != 0) {
    ObjFile *old = impl->addr_map_.At(addr_map_size - 1);
    if (old->end_addr > end_addr) {
      ABSL_RAW_LOG(ERROR,
                   "Unsorted addr map entry: 0x%" PRIxPTR ": %s <-> 0x%" PRIxPTR
                   ": %s",
                   reinterpret_cast<uintptr_t>(end_addr), filename,
                   reinterpret_cast<uintptr_t>(old->end_addr), old->filename);
      return true;
    } else if (old->end_addr == end_addr) {
      // The same entry appears twice. This sometimes happens for [vdso].
      if (old->start_addr != start_addr ||
          strcmp(old->filename, filename) != 0) {
        ABSL_RAW_LOG(ERROR,
                     "Duplicate addr 0x%" PRIxPTR ": %s <-> 0x%" PRIxPTR ": %s",
                     reinterpret_cast<uintptr_t>(end_addr), filename,
                     reinterpret_cast<uintptr_t>(old->end_addr), old->filename);
      }
      return true;
    }
  }
  ObjFile *obj = impl->addr_map_.Add();
  obj->filename = impl->CopyString(filename);
  obj->start_addr = start_addr;
  obj->end_addr = end_addr;
  obj->offset = offset;
  obj->elf_type = -1;  // filled on demand
  obj->fd = -1;        // opened on demand
  return true;
}

// This function wraps the Demangle function to provide an interface
// where the input symbol is demangled in-place.
// To keep stack consumption low, we would like this function to not
// get inlined.
static ABSL_ATTRIBUTE_NOINLINE void DemangleInplace(char *out, int out_size,
                                                    char *tmp_buf,
                                                    int tmp_buf_size) {
  if (Demangle(out, tmp_buf, tmp_buf_size)) {
    // Demangling succeeded. Copy to out if the space allows.
    int len = strlen(tmp_buf);
    if (len + 1 <= out_size) {  // +1 for '\0'.
      SAFE_ASSERT(len < tmp_buf_size);
      memmove(out, tmp_buf, len + 1);
    }
  }
}

SymbolCacheLine *Symbolizer::GetCacheLine(const void *const pc) {
  uintptr_t pc0 = reinterpret_cast<uintptr_t>(pc);
  pc0 >>= 3;  // drop the low 3 bits

  // Shuffle bits.
  pc0 ^= (pc0 >> 6) ^ (pc0 >> 12) ^ (pc0 >> 18);
  return &symbol_cache_[pc0 % SYMBOL_CACHE_LINES];
}

void Symbolizer::AgeSymbols(SymbolCacheLine *line) {
  for (uint32_t &age : line->age) {
    ++age;
  }
}

const char *Symbolizer::FindSymbolInCache(const void *const pc) {
  if (pc == nullptr) return nullptr;

  SymbolCacheLine *line = GetCacheLine(pc);
  for (size_t i = 0; i < ABSL_ARRAYSIZE(line->pc); ++i) {
    if (line->pc[i] == pc) {
      AgeSymbols(line);
      line->age[i] = 0;
      return line->name[i];
    }
  }
  return nullptr;
}

const char *Symbolizer::InsertSymbolInCache(const void *const pc,
                                            const char *name) {
  SAFE_ASSERT(pc != nullptr);

  SymbolCacheLine *line = GetCacheLine(pc);
  uint32_t max_age = 0;
  int oldest_index = -1;
  for (size_t i = 0; i < ABSL_ARRAYSIZE(line->pc); ++i) {
    if (line->pc[i] == nullptr) {
      AgeSymbols(line);
      line->pc[i] = pc;
      line->name[i] = CopyString(name);
      line->age[i] = 0;
      return line->name[i];
    }
    if (line->age[i] >= max_age) {
      max_age = line->age[i];
      oldest_index = i;
    }
  }

  AgeSymbols(line);
  ABSL_RAW_CHECK(oldest_index >= 0, "Corrupt cache");
  base_internal::LowLevelAlloc::Free(line->name[oldest_index]);
  line->pc[oldest_index] = pc;
  line->name[oldest_index] = CopyString(name);
  line->age[oldest_index] = 0;
  return line->name[oldest_index];
}

static void MaybeOpenFdFromSelfExe(ObjFile *obj) {
  if (memcmp(obj->start_addr, ELFMAG, SELFMAG) != 0) {
    return;
  }
  int fd = open("/proc/self/exe", O_RDONLY);
  if (fd == -1) {
    return;
  }
  // Verify that contents of /proc/self/exe matches in-memory image of
  // the binary. This can fail if the "deleted" binary is in fact not
  // the main executable, or for binaries that have the first PT_LOAD
  // segment smaller than 4K. We do it in four steps so that the
  // buffer is smaller and we don't consume too much stack space.
  const char *mem = reinterpret_cast<const char *>(obj->start_addr);
  for (int i = 0; i < 4; ++i) {
    char buf[1024];
    ssize_t n = read(fd, buf, sizeof(buf));
    if (n != sizeof(buf) || memcmp(buf, mem, sizeof(buf)) != 0) {
      close(fd);
      return;
    }
    mem += sizeof(buf);
  }
  obj->fd = fd;
}

static bool MaybeInitializeObjFile(ObjFile *obj) {
  if (obj->fd < 0) {
    obj->fd = open(obj->filename, O_RDONLY);

    if (obj->fd < 0) {
      // Getting /proc/self/exe here means that we were hinted.
      if (strcmp(obj->filename, "/proc/self/exe") == 0) {
        // /proc/self/exe may be inaccessible (due to setuid, etc.), so try
        // accessing the binary via argv0.
        if (argv0_value != nullptr) {
          obj->fd = open(argv0_value, O_RDONLY);
        }
      } else {
        MaybeOpenFdFromSelfExe(obj);
      }
    }

    if (obj->fd < 0) {
      ABSL_RAW_LOG(WARNING, "%s: open failed: errno=%d", obj->filename, errno);
      return false;
    }
    obj->elf_type = FileGetElfType(obj->fd);
    if (obj->elf_type < 0) {
      ABSL_RAW_LOG(WARNING, "%s: wrong elf type: %d", obj->filename,
                   obj->elf_type);
      return false;
    }

    if (!ReadFromOffsetExact(obj->fd, &obj->elf_header, sizeof(obj->elf_header),
                             0)) {
      ABSL_RAW_LOG(WARNING, "%s: failed to read elf header", obj->filename);
      return false;
    }
    const int phnum = obj->elf_header.e_phnum;
    const int phentsize = obj->elf_header.e_phentsize;
    size_t phoff = obj->elf_header.e_phoff;
    size_t num_executable_load_segments = 0;
    for (int j = 0; j < phnum; j++) {
      ElfW(Phdr) phdr;
      if (!ReadFromOffsetExact(obj->fd, &phdr, sizeof(phdr), phoff)) {
        ABSL_RAW_LOG(WARNING, "%s: failed to read program header %d",
                     obj->filename, j);
        return false;
      }
      phoff += phentsize;
      constexpr int rx = PF_X | PF_R;
      if (phdr.p_type != PT_LOAD || (phdr.p_flags & rx) != rx) {
        // Not a LOAD segment, or not executable code.
        continue;
      }
      if (num_executable_load_segments < obj->phdr.size()) {
        memcpy(&obj->phdr[num_executable_load_segments++], &phdr, sizeof(phdr));
      } else {
        ABSL_RAW_LOG(WARNING, "%s: too many executable LOAD segments",
                     obj->filename);
        break;
      }
    }
    if (num_executable_load_segments == 0) {
      // This object has no "r-x" LOAD segments. That's unexpected.
      ABSL_RAW_LOG(WARNING, "%s: no executable LOAD segments", obj->filename);
      return false;
    }
  }
  return true;
}

// The implementation of our symbolization routine.  If it
// successfully finds the symbol containing "pc" and obtains the
// symbol name, returns pointer to that symbol. Otherwise, returns nullptr.
// If any symbol decorators have been installed via InstallSymbolDecorator(),
// they are called here as well.
// To keep stack consumption low, we would like this function to not
// get inlined.
const char *Symbolizer::GetUncachedSymbol(const void *pc) {
  ObjFile *const obj = FindObjFile(pc, 1);
  ptrdiff_t relocation = 0;
  int fd = -1;
  if (obj != nullptr) {
    if (MaybeInitializeObjFile(obj)) {
      const size_t start_addr = reinterpret_cast<size_t>(obj->start_addr);
      if (obj->elf_type == ET_DYN && start_addr >= obj->offset) {
        // This object was relocated.
        //
        // For obj->offset > 0, adjust the relocation since a mapping at offset
        // X in the file will have a start address of [true relocation]+X.
        relocation = start_addr - obj->offset;

        // Note: some binaries have multiple "rx" LOAD segments. We must
        // find the right one.
        ElfW(Phdr) *phdr = nullptr;
        for (size_t j = 0; j < obj->phdr.size(); j++) {
          ElfW(Phdr) &p = obj->phdr[j];
          if (p.p_type != PT_LOAD) {
            // We only expect PT_LOADs. This must be PT_NULL that we didn't
            // write over (i.e. we exhausted all interesting PT_LOADs).
            ABSL_RAW_CHECK(p.p_type == PT_NULL, "unexpected p_type");
            break;
          }
          if (pc < reinterpret_cast<void *>(start_addr + p.p_memsz)) {
            phdr = &p;
            break;
          }
        }
        if (phdr == nullptr) {
          // That's unexpected. Hope for the best.
          ABSL_RAW_LOG(
              WARNING,
              "%s: unable to find LOAD segment for pc: %p, start_addr: %zx",
              obj->filename, pc, start_addr);
        } else {
          // Adjust relocation in case phdr.p_vaddr != 0.
          // This happens for binaries linked with `lld --rosegment`, and for
          // binaries linked with BFD `ld -z separate-code`.
          relocation -= phdr->p_vaddr - phdr->p_offset;
        }
      }

      fd = obj->fd;
      if (GetSymbolFromObjectFile(*obj, pc, relocation, symbol_buf_,
                                  sizeof(symbol_buf_), tmp_buf_,
                                  sizeof(tmp_buf_)) == SYMBOL_FOUND) {
        // Only try to demangle the symbol name if it fit into symbol_buf_.
        DemangleInplace(symbol_buf_, sizeof(symbol_buf_), tmp_buf_,
                        sizeof(tmp_buf_));
      }
    }
  } else {
#if ABSL_HAVE_VDSO_SUPPORT
    VDSOSupport vdso;
    if (vdso.IsPresent()) {
      VDSOSupport::SymbolInfo symbol_info;
      if (vdso.LookupSymbolByAddress(pc, &symbol_info)) {
        // All VDSO symbols are known to be short.
        size_t len = strlen(symbol_info.name);
        ABSL_RAW_CHECK(len + 1 < sizeof(symbol_buf_),
                       "VDSO symbol unexpectedly long");
        memcpy(symbol_buf_, symbol_info.name, len + 1);
      }
    }
#endif
  }

  if (g_decorators_mu.TryLock()) {
    if (g_num_decorators > 0) {
      SymbolDecoratorArgs decorator_args = {
          pc,       relocation,       fd,     symbol_buf_, sizeof(symbol_buf_),
          tmp_buf_, sizeof(tmp_buf_), nullptr};
      for (int i = 0; i < g_num_decorators; ++i) {
        decorator_args.arg = g_decorators[i].arg;
        g_decorators[i].fn(&decorator_args);
      }
    }
    g_decorators_mu.Unlock();
  }
  if (symbol_buf_[0] == '\0') {
    return nullptr;
  }
  symbol_buf_[sizeof(symbol_buf_) - 1] = '\0';  // Paranoia.
  return InsertSymbolInCache(pc, symbol_buf_);
}

const char *Symbolizer::GetSymbol(const void *pc) {
  const char *entry = FindSymbolInCache(pc);
  if (entry != nullptr) {
    return entry;
  }
  symbol_buf_[0] = '\0';

#ifdef __hppa__
  {
    // In some contexts (e.g., return addresses), PA-RISC uses the lowest two
    // bits of the address to indicate the privilege level. Clear those bits
    // before trying to symbolize.
    const auto pc_bits = reinterpret_cast<uintptr_t>(pc);
    const auto address = pc_bits & ~0x3;
    entry = GetUncachedSymbol(reinterpret_cast<const void *>(address));
    if (entry != nullptr) {
      return entry;
    }

    // In some contexts, PA-RISC also uses bit 1 of the address to indicate that
    // this is a cross-DSO function pointer. Such function pointers actually
    // point to a procedure label, a struct whose first 32-bit (pointer) element
    // actually points to the function text. With no symbol found for this
    // address so far, try interpreting it as a cross-DSO function pointer and
    // see how that goes.
    if (pc_bits & 0x2) {
      return GetUncachedSymbol(*reinterpret_cast<const void *const *>(address));
    }

    return nullptr;
  }
#else
  return GetUncachedSymbol(pc);
#endif
}

bool RemoveAllSymbolDecorators(void) {
  if (!g_decorators_mu.TryLock()) {
    // Someone else is using decorators. Get out.
    return false;
  }
  g_num_decorators = 0;
  g_decorators_mu.Unlock();
  return true;
}

bool RemoveSymbolDecorator(int ticket) {
  if (!g_decorators_mu.TryLock()) {
    // Someone else is using decorators. Get out.
    return false;
  }
  for (int i = 0; i < g_num_decorators; ++i) {
    if (g_decorators[i].ticket == ticket) {
      while (i < g_num_decorators - 1) {
        g_decorators[i] = g_decorators[i + 1];
        ++i;
      }
      g_num_decorators = i;
      break;
    }
  }
  g_decorators_mu.Unlock();
  return true;  // Decorator is known to be removed.
}

int InstallSymbolDecorator(SymbolDecorator decorator, void *arg) {
  static int ticket = 0;

  if (!g_decorators_mu.TryLock()) {
    // Someone else is using decorators. Get out.
    return -2;
  }
  int ret = ticket;
  if (g_num_decorators >= kMaxDecorators) {
    ret = -1;
  } else {
    g_decorators[g_num_decorators] = {decorator, arg, ticket++};
    ++g_num_decorators;
  }
  g_decorators_mu.Unlock();
  return ret;
}

bool RegisterFileMappingHint(const void *start, const void *end, uint64_t offset,
                             const char *filename) {
  SAFE_ASSERT(start <= end);
  SAFE_ASSERT(filename != nullptr);

  InitSigSafeArena();

  if (!g_file_mapping_mu.TryLock()) {
    return false;
  }

  bool ret = true;
  if (g_num_file_mapping_hints >= kMaxFileMappingHints) {
    ret = false;
  } else {
    // TODO(ckennelly): Move this into a string copy routine.
    int len = strlen(filename);
    char *dst = static_cast<char *>(
        base_internal::LowLevelAlloc::AllocWithArena(len + 1, SigSafeArena()));
    ABSL_RAW_CHECK(dst != nullptr, "out of memory");
    memcpy(dst, filename, len + 1);

    auto &hint = g_file_mapping_hints[g_num_file_mapping_hints++];
    hint.start = start;
    hint.end = end;
    hint.offset = offset;
    hint.filename = dst;
  }

  g_file_mapping_mu.Unlock();
  return ret;
}

bool GetFileMappingHint(const void **start, const void **end, uint64_t *offset,
                        const char **filename) {
  if (!g_file_mapping_mu.TryLock()) {
    return false;
  }
  bool found = false;
  for (int i = 0; i < g_num_file_mapping_hints; i++) {
    if (g_file_mapping_hints[i].start <= *start &&
        *end <= g_file_mapping_hints[i].end) {
      // We assume that the start_address for the mapping is the base
      // address of the ELF section, but when [start_address,end_address) is
      // not strictly equal to [hint.start, hint.end), that assumption is
      // invalid.
      //
      // This uses the hint's start address (even though hint.start is not
      // necessarily equal to start_address) to ensure the correct
      // relocation is computed later.
      *start = g_file_mapping_hints[i].start;
      *end = g_file_mapping_hints[i].end;
      *offset = g_file_mapping_hints[i].offset;
      *filename = g_file_mapping_hints[i].filename;
      found = true;
      break;
    }
  }
  g_file_mapping_mu.Unlock();
  return found;
}

}  // namespace debugging_internal

bool Symbolize(const void *pc, char *out, int out_size) {
  // Symbolization is very slow under tsan.
  ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
  SAFE_ASSERT(out_size >= 0);
  debugging_internal::Symbolizer *s = debugging_internal::AllocateSymbolizer();
  const char *name = s->GetSymbol(pc);
  bool ok = false;
  if (name != nullptr && out_size > 0) {
    strncpy(out, name, out_size);
    ok = true;
    if (out[out_size - 1] != '\0') {
      // strncpy() does not '\0' terminate when it truncates.  Do so, with
      // trailing ellipsis.
      static constexpr char kEllipsis[] = "...";
      int ellipsis_size =
          std::min(implicit_cast<int>(strlen(kEllipsis)), out_size - 1);
      memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size);
      out[out_size - 1] = '\0';
    }
  }
  debugging_internal::FreeSymbolizer(s);
  ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END();
  return ok;
}

ABSL_NAMESPACE_END
}  // namespace absl

extern "C" bool AbslInternalGetFileMappingHint(const void **start,
                                               const void **end, uint64_t *offset,
                                               const char **filename) {
  return absl::debugging_internal::GetFileMappingHint(start, end, offset,
                                                      filename);
}
