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

#include "sanitizer_allocator_internal.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_symbolizer_internal.h"

namespace __sanitizer {

const char *ExtractToken(const char *str, const char *delims, char **result) {
  uptr prefix_len = internal_strcspn(str, delims);
  *result = (char*)InternalAlloc(prefix_len + 1);
  internal_memcpy(*result, str, prefix_len);
  (*result)[prefix_len] = '\0';
  const char *prefix_end = str + prefix_len;
  if (*prefix_end != '\0') prefix_end++;
  return prefix_end;
}

const char *ExtractInt(const char *str, const char *delims, int *result) {
  char *buff;
  const char *ret = ExtractToken(str, delims, &buff);
  if (buff != 0) {
    *result = (int)internal_atoll(buff);
  }
  InternalFree(buff);
  return ret;
}

const char *ExtractUptr(const char *str, const char *delims, uptr *result) {
  char *buff;
  const char *ret = ExtractToken(str, delims, &buff);
  if (buff != 0) {
    *result = (uptr)internal_atoll(buff);
  }
  InternalFree(buff);
  return ret;
}

const char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter,
                                      char **result) {
  const char *found_delimiter = internal_strstr(str, delimiter);
  uptr prefix_len =
      found_delimiter ? found_delimiter - str : internal_strlen(str);
  *result = (char *)InternalAlloc(prefix_len + 1);
  internal_memcpy(*result, str, prefix_len);
  (*result)[prefix_len] = '\0';
  const char *prefix_end = str + prefix_len;
  if (*prefix_end != '\0') prefix_end += internal_strlen(delimiter);
  return prefix_end;
}

SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) {
  BlockingMutexLock l(&mu_);
  const char *module_name;
  uptr module_offset;
  SymbolizedStack *res = SymbolizedStack::New(addr);
  if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset))
    return res;
  // Always fill data about module name and offset.
  res->info.FillModuleInfo(module_name, module_offset);
  for (auto iter = Iterator(&tools_); iter.hasNext();) {
    auto *tool = iter.next();
    SymbolizerScope sym_scope(this);
    if (tool->SymbolizePC(addr, res)) {
      return res;
    }
  }
  return res;
}

bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) {
  BlockingMutexLock l(&mu_);
  const char *module_name;
  uptr module_offset;
  if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset))
    return false;
  info->Clear();
  info->module = internal_strdup(module_name);
  info->module_offset = module_offset;
  for (auto iter = Iterator(&tools_); iter.hasNext();) {
    auto *tool = iter.next();
    SymbolizerScope sym_scope(this);
    if (tool->SymbolizeData(addr, info)) {
      return true;
    }
  }
  return true;
}

bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name,
                                             uptr *module_address) {
  BlockingMutexLock l(&mu_);
  const char *internal_module_name = nullptr;
  if (!FindModuleNameAndOffsetForAddress(pc, &internal_module_name,
                                         module_address))
    return false;

  if (module_name)
    *module_name = module_names_.GetOwnedCopy(internal_module_name);
  return true;
}

void Symbolizer::Flush() {
  BlockingMutexLock l(&mu_);
  for (auto iter = Iterator(&tools_); iter.hasNext();) {
    auto *tool = iter.next();
    SymbolizerScope sym_scope(this);
    tool->Flush();
  }
}

const char *Symbolizer::Demangle(const char *name) {
  BlockingMutexLock l(&mu_);
  for (auto iter = Iterator(&tools_); iter.hasNext();) {
    auto *tool = iter.next();
    SymbolizerScope sym_scope(this);
    if (const char *demangled = tool->Demangle(name))
      return demangled;
  }
  return PlatformDemangle(name);
}

void Symbolizer::PrepareForSandboxing() {
  BlockingMutexLock l(&mu_);
  PlatformPrepareForSandboxing();
}

bool Symbolizer::FindModuleNameAndOffsetForAddress(uptr address,
                                                   const char **module_name,
                                                   uptr *module_offset) {
  LoadedModule *module = FindModuleForAddress(address);
  if (module == 0)
    return false;
  *module_name = module->full_name();
  *module_offset = address - module->base_address();
  return true;
}

LoadedModule *Symbolizer::FindModuleForAddress(uptr address) {
  bool modules_were_reloaded = false;
  if (!modules_fresh_) {
    for (uptr i = 0; i < n_modules_; i++)
      modules_[i].clear();
    n_modules_ =
        GetListOfModules(modules_, kMaxNumberOfModules, /* filter */ nullptr);
    CHECK_GT(n_modules_, 0);
    CHECK_LT(n_modules_, kMaxNumberOfModules);
    modules_fresh_ = true;
    modules_were_reloaded = true;
  }
  for (uptr i = 0; i < n_modules_; i++) {
    if (modules_[i].containsAddress(address)) {
      return &modules_[i];
    }
  }
  // Reload the modules and look up again, if we haven't tried it yet.
  if (!modules_were_reloaded) {
    // FIXME: set modules_fresh_ from dlopen()/dlclose() interceptors.
    // It's too aggressive to reload the list of modules each time we fail
    // to find a module for a given address.
    modules_fresh_ = false;
    return FindModuleForAddress(address);
  }
  return 0;
}

Symbolizer *Symbolizer::GetOrInit() {
  SpinMutexLock l(&init_mu_);
  if (symbolizer_)
    return symbolizer_;
  symbolizer_ = PlatformInit();
  CHECK(symbolizer_);
  return symbolizer_;
}

// For now we assume the following protocol:
// For each request of the form
//   <module_name> <module_offset>
// passed to STDIN, external symbolizer prints to STDOUT response:
//   <function_name>
//   <file_name>:<line_number>:<column_number>
//   <function_name>
//   <file_name>:<line_number>:<column_number>
//   ...
//   <empty line>
class LLVMSymbolizerProcess : public SymbolizerProcess {
 public:
  explicit LLVMSymbolizerProcess(const char *path) : SymbolizerProcess(path) {}

 private:
  bool ReachedEndOfOutput(const char *buffer, uptr length) const override {
    // Empty line marks the end of llvm-symbolizer output.
    return length >= 2 && buffer[length - 1] == '\n' &&
           buffer[length - 2] == '\n';
  }

  void GetArgV(const char *path_to_binary,
               const char *(&argv)[kArgVMax]) const override {
#if defined(__x86_64h__)
    const char* const kSymbolizerArch = "--default-arch=x86_64h";
#elif defined(__x86_64__)
    const char* const kSymbolizerArch = "--default-arch=x86_64";
#elif defined(__i386__)
    const char* const kSymbolizerArch = "--default-arch=i386";
#elif defined(__powerpc64__) && defined(__BIG_ENDIAN__)
    const char* const kSymbolizerArch = "--default-arch=powerpc64";
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)
    const char* const kSymbolizerArch = "--default-arch=powerpc64le";
#else
    const char* const kSymbolizerArch = "--default-arch=unknown";
#endif

    const char *const inline_flag = common_flags()->symbolize_inline_frames
                                        ? "--inlining=true"
                                        : "--inlining=false";
    int i = 0;
    argv[i++] = path_to_binary;
    argv[i++] = inline_flag;
    argv[i++] = kSymbolizerArch;
    argv[i++] = nullptr;
  }
};

LLVMSymbolizer::LLVMSymbolizer(const char *path, LowLevelAllocator *allocator)
    : symbolizer_process_(new(*allocator) LLVMSymbolizerProcess(path)) {}

// Parse a <file>:<line>[:<column>] buffer. The file path may contain colons on
// Windows, so extract tokens from the right hand side first. The column info is
// also optional.
static const char *ParseFileLineInfo(AddressInfo *info, const char *str) {
  char *file_line_info = 0;
  str = ExtractToken(str, "\n", &file_line_info);
  CHECK(file_line_info);
  // Parse the last :<int>, which must be there.
  char *last_colon = internal_strrchr(file_line_info, ':');
  CHECK(last_colon);
  int line_or_column = internal_atoll(last_colon + 1);
  // Truncate the string at the last colon and find the next-to-last colon.
  *last_colon = '\0';
  last_colon = internal_strrchr(file_line_info, ':');
  if (last_colon && IsDigit(last_colon[1])) {
    // If the second-to-last colon is followed by a digit, it must be the line
    // number, and the previous parsed number was a column.
    info->line = internal_atoll(last_colon + 1);
    info->column = line_or_column;
    *last_colon = '\0';
  } else {
    // Otherwise, we have line info but no column info.
    info->line = line_or_column;
    info->column = 0;
  }
  ExtractToken(file_line_info, "", &info->file);
  InternalFree(file_line_info);
  return str;
}

// Parses one or more two-line strings in the following format:
//   <function_name>
//   <file_name>:<line_number>[:<column_number>]
// Used by LLVMSymbolizer, Addr2LinePool and InternalSymbolizer, since all of
// them use the same output format.
void ParseSymbolizePCOutput(const char *str, SymbolizedStack *res) {
  bool top_frame = true;
  SymbolizedStack *last = res;
  while (true) {
    char *function_name = 0;
    str = ExtractToken(str, "\n", &function_name);
    CHECK(function_name);
    if (function_name[0] == '\0') {
      // There are no more frames.
      InternalFree(function_name);
      break;
    }
    SymbolizedStack *cur;
    if (top_frame) {
      cur = res;
      top_frame = false;
    } else {
      cur = SymbolizedStack::New(res->info.address);
      cur->info.FillModuleInfo(res->info.module, res->info.module_offset);
      last->next = cur;
      last = cur;
    }

    AddressInfo *info = &cur->info;
    info->function = function_name;
    str = ParseFileLineInfo(info, str);

    // Functions and filenames can be "??", in which case we write 0
    // to address info to mark that names are unknown.
    if (0 == internal_strcmp(info->function, "??")) {
      InternalFree(info->function);
      info->function = 0;
    }
    if (0 == internal_strcmp(info->file, "??")) {
      InternalFree(info->file);
      info->file = 0;
    }
  }
}

// Parses a two-line string in the following format:
//   <symbol_name>
//   <start_address> <size>
// Used by LLVMSymbolizer and InternalSymbolizer.
void ParseSymbolizeDataOutput(const char *str, DataInfo *info) {
  str = ExtractToken(str, "\n", &info->name);
  str = ExtractUptr(str, " ", &info->start);
  str = ExtractUptr(str, "\n", &info->size);
}

bool LLVMSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
  if (const char *buf = SendCommand(/*is_data*/ false, stack->info.module,
                                    stack->info.module_offset)) {
    ParseSymbolizePCOutput(buf, stack);
    return true;
  }
  return false;
}

bool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
  if (const char *buf =
          SendCommand(/*is_data*/ true, info->module, info->module_offset)) {
    ParseSymbolizeDataOutput(buf, info);
    info->start += (addr - info->module_offset); // Add the base address.
    return true;
  }
  return false;
}

const char *LLVMSymbolizer::SendCommand(bool is_data, const char *module_name,
                                        uptr module_offset) {
  CHECK(module_name);
  internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n",
                    is_data ? "DATA " : "", module_name, module_offset);
  return symbolizer_process_->SendCommand(buffer_);
}

SymbolizerProcess::SymbolizerProcess(const char *path, bool use_forkpty)
    : path_(path),
      input_fd_(kInvalidFd),
      output_fd_(kInvalidFd),
      times_restarted_(0),
      failed_to_start_(false),
      reported_invalid_path_(false),
      use_forkpty_(use_forkpty) {
  CHECK(path_);
  CHECK_NE(path_[0], '\0');
}

const char *SymbolizerProcess::SendCommand(const char *command) {
  for (; times_restarted_ < kMaxTimesRestarted; times_restarted_++) {
    // Start or restart symbolizer if we failed to send command to it.
    if (const char *res = SendCommandImpl(command))
      return res;
    Restart();
  }
  if (!failed_to_start_) {
    Report("WARNING: Failed to use and restart external symbolizer!\n");
    failed_to_start_ = true;
  }
  return 0;
}

const char *SymbolizerProcess::SendCommandImpl(const char *command) {
  if (input_fd_ == kInvalidFd || output_fd_ == kInvalidFd)
      return 0;
  if (!WriteToSymbolizer(command, internal_strlen(command)))
      return 0;
  if (!ReadFromSymbolizer(buffer_, kBufferSize))
      return 0;
  return buffer_;
}

bool SymbolizerProcess::Restart() {
  if (input_fd_ != kInvalidFd)
    CloseFile(input_fd_);
  if (output_fd_ != kInvalidFd)
    CloseFile(output_fd_);
  return StartSymbolizerSubprocess();
}

bool SymbolizerProcess::ReadFromSymbolizer(char *buffer, uptr max_length) {
  if (max_length == 0)
    return true;
  uptr read_len = 0;
  while (true) {
    uptr just_read = 0;
    bool success = ReadFromFile(input_fd_, buffer + read_len,
                                max_length - read_len - 1, &just_read);
    // We can't read 0 bytes, as we don't expect external symbolizer to close
    // its stdout.
    if (!success || just_read == 0) {
      Report("WARNING: Can't read from symbolizer at fd %d\n", input_fd_);
      return false;
    }
    read_len += just_read;
    if (ReachedEndOfOutput(buffer, read_len))
      break;
  }
  buffer[read_len] = '\0';
  return true;
}

bool SymbolizerProcess::WriteToSymbolizer(const char *buffer, uptr length) {
  if (length == 0)
    return true;
  uptr write_len = 0;
  bool success = WriteToFile(output_fd_, buffer, length, &write_len);
  if (!success || write_len != length) {
    Report("WARNING: Can't write to symbolizer at fd %d\n", output_fd_);
    return false;
  }
  return true;
}

}  // namespace __sanitizer
