//===-- sanitizer_symbolizer_libbacktrace.cc ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is shared between AddressSanitizer and ThreadSanitizer
// run-time libraries.
// Libbacktrace implementation of symbolizer parts.
//===----------------------------------------------------------------------===//

#include "sanitizer_platform.h"

#include "sanitizer_internal_defs.h"
#include "sanitizer_symbolizer.h"
#include "sanitizer_symbolizer_libbacktrace.h"

#if SANITIZER_LIBBACKTRACE
# include "backtrace-supported.h"
# if SANITIZER_POSIX && BACKTRACE_SUPPORTED && !BACKTRACE_USES_MALLOC
#  include "backtrace.h"
#  if SANITIZER_CP_DEMANGLE
#   undef ARRAY_SIZE
#   include "demangle.h"
#  endif
# else
#  define SANITIZER_LIBBACKTRACE 0
# endif
#endif

namespace __sanitizer {

static char *DemangleAlloc(const char *name, bool always_alloc);

#if SANITIZER_LIBBACKTRACE

namespace {

# if SANITIZER_CP_DEMANGLE
struct CplusV3DemangleData {
  char *buf;
  uptr size, allocated;
};

extern "C" {
static void CplusV3DemangleCallback(const char *s, size_t l, void *vdata) {
  CplusV3DemangleData *data = (CplusV3DemangleData *)vdata;
  uptr needed = data->size + l + 1;
  if (needed > data->allocated) {
    data->allocated *= 2;
    if (needed > data->allocated)
      data->allocated = needed;
    char *buf = (char *)InternalAlloc(data->allocated);
    if (data->buf) {
      internal_memcpy(buf, data->buf, data->size);
      InternalFree(data->buf);
    }
    data->buf = buf;
  }
  internal_memcpy(data->buf + data->size, s, l);
  data->buf[data->size + l] = '\0';
  data->size += l;
}
}  // extern "C"

char *CplusV3Demangle(const char *name) {
  CplusV3DemangleData data;
  data.buf = 0;
  data.size = 0;
  data.allocated = 0;
  if (cplus_demangle_v3_callback(name, DMGL_PARAMS | DMGL_ANSI,
                                 CplusV3DemangleCallback, &data)) {
    if (data.size + 64 > data.allocated)
      return data.buf;
    char *buf = internal_strdup(data.buf);
    InternalFree(data.buf);
    return buf;
  }
  if (data.buf)
    InternalFree(data.buf);
  return 0;
}
# endif  // SANITIZER_CP_DEMANGLE

struct SymbolizeCodeCallbackArg {
  SymbolizedStack *first;
  SymbolizedStack *last;
  uptr frames_symbolized;

  AddressInfo *get_new_frame(uintptr_t addr) {
    CHECK(last);
    if (frames_symbolized > 0) {
      SymbolizedStack *cur = SymbolizedStack::New(addr);
      AddressInfo *info = &cur->info;
      info->FillModuleInfo(first->info.module, first->info.module_offset);
      last->next = cur;
      last = cur;
    }
    CHECK_EQ(addr, first->info.address);
    CHECK_EQ(addr, last->info.address);
    return &last->info;
  }
};

extern "C" {
static int SymbolizeCodePCInfoCallback(void *vdata, uintptr_t addr,
                                       const char *filename, int lineno,
                                       const char *function) {
  SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;
  if (function) {
    AddressInfo *info = cdata->get_new_frame(addr);
    info->function = DemangleAlloc(function, /*always_alloc*/ true);
    if (filename)
      info->file = internal_strdup(filename);
    info->line = lineno;
    cdata->frames_symbolized++;
  }
  return 0;
}

static void SymbolizeCodeCallback(void *vdata, uintptr_t addr,
                                  const char *symname, uintptr_t, uintptr_t) {
  SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;
  if (symname) {
    AddressInfo *info = cdata->get_new_frame(addr);
    info->function = DemangleAlloc(symname, /*always_alloc*/ true);
    cdata->frames_symbolized++;
  }
}

static void SymbolizeDataCallback(void *vdata, uintptr_t, const char *symname,
                                  uintptr_t symval, uintptr_t symsize) {
  DataInfo *info = (DataInfo *)vdata;
  if (symname && symval) {
    info->name = DemangleAlloc(symname, /*always_alloc*/ true);
    info->start = symval;
    info->size = symsize;
  }
}

static void ErrorCallback(void *, const char *, int) {}
}  // extern "C"

}  // namespace

LibbacktraceSymbolizer *LibbacktraceSymbolizer::get(LowLevelAllocator *alloc) {
  // State created in backtrace_create_state is leaked.
  void *state = (void *)(backtrace_create_state("/proc/self/exe", 0,
                                                ErrorCallback, NULL));
  if (!state)
    return 0;
  return new(*alloc) LibbacktraceSymbolizer(state);
}

bool LibbacktraceSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
  SymbolizeCodeCallbackArg data;
  data.first = stack;
  data.last = stack;
  data.frames_symbolized = 0;
  backtrace_pcinfo((backtrace_state *)state_, addr, SymbolizeCodePCInfoCallback,
                   ErrorCallback, &data);
  if (data.frames_symbolized > 0)
    return true;
  backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeCodeCallback,
                    ErrorCallback, &data);
  return (data.frames_symbolized > 0);
}

bool LibbacktraceSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
  backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeDataCallback,
                    ErrorCallback, info);
  return true;
}

#else  // SANITIZER_LIBBACKTRACE

LibbacktraceSymbolizer *LibbacktraceSymbolizer::get(LowLevelAllocator *alloc) {
  return 0;
}

bool LibbacktraceSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
  (void)state_;
  return false;
}

bool LibbacktraceSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
  return false;
}

#endif  // SANITIZER_LIBBACKTRACE

static char *DemangleAlloc(const char *name, bool always_alloc) {
#if SANITIZER_LIBBACKTRACE && SANITIZER_CP_DEMANGLE
  if (char *demangled = CplusV3Demangle(name))
    return demangled;
#endif
  if (always_alloc)
    return internal_strdup(name);
  return 0;
}

const char *LibbacktraceSymbolizer::Demangle(const char *name) {
  return DemangleAlloc(name, /*always_alloc*/ false);
}

}  // namespace __sanitizer
