// Copyright (c) 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: Alfred Peng

#include <demangle.h>
#include <fcntl.h>
#include <gelf.h>
#include <link.h>
#include <sys/mman.h>
#include <stab.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <functional>
#include <map>
#include <vector>

#include "common/scoped_ptr.h"
#include "common/solaris/dump_symbols.h"
#include "common/solaris/file_id.h"
#include "common/solaris/guid_creator.h"

// This namespace contains helper functions.
namespace {

using std::make_pair;

#if defined(_LP64)
typedef Elf64_Sym   Elf_Sym;
#else
typedef Elf32_Sym   Elf_Sym;
#endif

// Symbol table entry from stabs. Sun CC specific.
struct slist {
  // String table index.
  unsigned int n_strx;
  // Stab type. 
  unsigned char n_type;
  char n_other;
  short n_desc;
  unsigned long n_value;
};

// Symbol table entry
struct SymbolEntry {
  // Offset from the start of the file.
  GElf_Addr offset;
  // Function size.
  GElf_Word size;
};

// Infomation of a line.
struct LineInfo {
  // Offset from start of the function.
  // Load from stab symbol.
  GElf_Off rva_to_func;
  // Offset from base of the loading binary.
  GElf_Off rva_to_base;
  // Size of the line.
  // The first line: equals to rva_to_func.
  // The other lines: the difference of rva_to_func of the line and
  // rva_to_func of the previous N_SLINE.
  uint32_t size;
  // Line number.
  uint32_t line_num;
};

// Information of a function.
struct FuncInfo {
  // Name of the function.
  const char *name;
  // Offset from the base of the loading address.
  GElf_Off rva_to_base;
  // Virtual address of the function.
  // Load from stab symbol.
  GElf_Addr addr;
  // Size of the function.
  // Equal to rva_to_func of the last function line.
  uint32_t size;
  // Total size of stack parameters.
  uint32_t stack_param_size;
  // Line information array.
  std::vector<struct LineInfo> line_info;
};

// Information of a source file.
struct SourceFileInfo {
  // Name of the source file.
  const char *name;
  // Starting address of the source file.
  GElf_Addr addr;
  // Id of the source file.
  int source_id;
  // Functions information.
  std::vector<struct FuncInfo> func_info;
};

struct CompareString {
  bool operator()(const char *s1, const char *s2) const {
    return strcmp(s1, s2) < 0;
  }
};

typedef std::map<const char *, struct SymbolEntry *, CompareString> SymbolMap;

// Information of a symbol table.
// This is the root of all types of symbol.
struct SymbolInfo {
  std::vector<struct SourceFileInfo> source_file_info;
  // Symbols information.
  SymbolMap symbol_entries;
};

// Stab section name.
const char *kStabName = ".stab";

// Stab str section name.
const char *kStabStrName = ".stabstr";

// Symtab section name.
const char *kSymtabName = ".symtab";

// Strtab section name.
const char *kStrtabName = ".strtab";

// Default buffer lenght for demangle.
const int demangleLen = 20000;

// Offset to the string table.
uint64_t stringOffset = 0;

// Update the offset to the start of the string index of the next
// object module for every N_ENDM stabs.
inline void RecalculateOffset(struct slist* cur_list, char *stabstr) {
  while ((--cur_list)->n_strx == 0) ;
  stringOffset += cur_list->n_strx;

  char *temp = stabstr + stringOffset;
  while (*temp != '\0') {
    ++stringOffset;
    ++temp;
  }
  // Skip the extra '\0'
  ++stringOffset;
}

// Demangle using demangle library on Solaris.
std::string Demangle(const char *mangled) {
  int status = 0;
  std::string str(mangled);
  char *demangled = (char *)malloc(demangleLen);

  if (!demangled) {
    fprintf(stderr, "no enough memory.\n");
    goto out;
  }

  if ((status = cplus_demangle(mangled, demangled, demangleLen)) ==
      DEMANGLE_ESPACE) {
    fprintf(stderr, "incorrect demangle.\n");
    goto out;
  }

  str = demangled;
  free(demangled);

out:
  return str; 
}

bool WriteFormat(int fd, const char *fmt, ...) {
  va_list list;
  char buffer[4096];
  ssize_t expected, written;
  va_start(list, fmt);
  vsnprintf(buffer, sizeof(buffer), fmt, list);
  expected = strlen(buffer);
  written = write(fd, buffer, strlen(buffer));
  va_end(list);
  return expected == written;
}

bool IsValidElf(const GElf_Ehdr *elf_header) {
  return memcmp(elf_header, ELFMAG, SELFMAG) == 0;
}

static bool FindSectionByName(Elf *elf, const char *name,
                              int shstrndx,
                              GElf_Shdr *shdr) {
  assert(name != NULL);

  if (strlen(name) == 0)
    return false;

  Elf_Scn *scn = NULL;

  while ((scn = elf_nextscn(elf, scn)) != NULL) {
    if (gelf_getshdr(scn, shdr) == (GElf_Shdr *)0) {
      fprintf(stderr, "failed to read section header: %s\n", elf_errmsg(0));
      return false;
    }

    const char *section_name = elf_strptr(elf, shstrndx, shdr->sh_name);
    if (!section_name) {
      fprintf(stderr, "Section name error: %s\n", elf_errmsg(-1));
      continue;
    }

    if (strcmp(section_name, name) == 0)
      return true;
  }

  return false;
}

// The parameter size is used for FPO-optimized code, and
// this is all tied up with the debugging data for Windows x86.
// Set it to 0 on Solaris.
int LoadStackParamSize(struct slist *list,
                       struct slist *list_end,
                       struct FuncInfo *func_info) {
  struct slist *cur_list = list;
  int step = 1;
  while (cur_list < list_end && cur_list->n_type == N_PSYM) {
    ++cur_list;
    ++step;
  }

  func_info->stack_param_size = 0;
  return step;
}

int LoadLineInfo(struct slist *list,
                 struct slist *list_end,
                 struct FuncInfo *func_info) {
  struct slist *cur_list = list;
  do {
    // Skip non line information.
    while (cur_list < list_end && cur_list->n_type != N_SLINE) {
      // Only exit when got another function, or source file, or end stab.
      if (cur_list->n_type == N_FUN || cur_list->n_type == N_SO ||
          cur_list->n_type == N_ENDM) {
        return cur_list - list;
      }
      ++cur_list;
    }
    struct LineInfo line;
    while (cur_list < list_end && cur_list->n_type == N_SLINE) {
      line.rva_to_func = cur_list->n_value;
      // n_desc is a signed short
      line.line_num = (unsigned short)cur_list->n_desc;
      func_info->line_info.push_back(line);
      ++cur_list;
    }
    if (cur_list == list_end && cur_list->n_type == N_ENDM)
      break;
  } while (list < list_end);

  return cur_list - list;
}

int LoadFuncSymbols(struct slist *list,
                    struct slist *list_end,
                    char *stabstr,
                    GElf_Word base,
                    struct SourceFileInfo *source_file_info) {
  struct slist *cur_list = list;
  assert(cur_list->n_type == N_SO);
  ++cur_list;

  source_file_info->func_info.clear();
  while (cur_list < list_end) {
    // Go until the function symbol.
    while (cur_list < list_end && cur_list->n_type != N_FUN) {
      if (cur_list->n_type == N_SO) {
        return cur_list - list;
      }
      ++cur_list;
      if (cur_list->n_type == N_ENDM)
        RecalculateOffset(cur_list, stabstr);
      continue;
    }
    while (cur_list->n_type == N_FUN) {
      struct FuncInfo func_info;
      memset(&func_info, 0, sizeof(func_info));
      func_info.name = stabstr + cur_list->n_strx + stringOffset;
      // The n_value field is always 0 from stab generated by Sun CC.
      // TODO(Alfred): Find the correct value.
      func_info.addr = cur_list->n_value;
      ++cur_list;
      if (cur_list->n_type == N_ENDM)
        RecalculateOffset(cur_list, stabstr);
      if (cur_list->n_type != N_ESYM && cur_list->n_type != N_ISYM &&
          cur_list->n_type != N_FUN) {
        // Stack parameter size.
        cur_list += LoadStackParamSize(cur_list, list_end, &func_info);
        // Line info.
        cur_list += LoadLineInfo(cur_list, list_end, &func_info);
      }
      if (cur_list < list_end && cur_list->n_type == N_ENDM)
        RecalculateOffset(cur_list, stabstr);
      // Functions in this module should have address bigger than the module
      // starting address.
      //
      // These two values are always 0 with Sun CC.
      // TODO(Alfred): Get the correct value or remove the condition statement.
      if (func_info.addr >= source_file_info->addr) {
        source_file_info->func_info.push_back(func_info);
      }
    }
  }
  return cur_list - list;
}

// Compute size and rva information based on symbols loaded from stab section.
bool ComputeSizeAndRVA(struct SymbolInfo *symbols) {
  std::vector<struct SourceFileInfo> *sorted_files =
    &(symbols->source_file_info);
  SymbolMap *symbol_entries = &(symbols->symbol_entries);
  for (size_t i = 0; i < sorted_files->size(); ++i) {
    struct SourceFileInfo &source_file = (*sorted_files)[i];
    std::vector<struct FuncInfo> *sorted_functions = &(source_file.func_info);
    int func_size = sorted_functions->size();

    for (size_t j = 0; j < func_size; ++j) {
      struct FuncInfo &func_info = (*sorted_functions)[j];
      int line_count = func_info.line_info.size();

      // Discard the ending part of the name.
      std::string func_name(func_info.name);
      std::string::size_type last_colon = func_name.find_first_of(':');
      if (last_colon != std::string::npos)
        func_name = func_name.substr(0, last_colon);

      // Fine the symbol offset from the loading address and size by name.
      SymbolMap::const_iterator it = symbol_entries->find(func_name.c_str());
      if (it->second) {
        func_info.rva_to_base = it->second->offset;
        func_info.size = (line_count == 0) ? 0 : it->second->size;
      } else {
        func_info.rva_to_base = 0;
        func_info.size = 0;
      }

      // Compute function and line size.
      for (size_t k = 0; k < line_count; ++k) {
        struct LineInfo &line_info = func_info.line_info[k];

        line_info.rva_to_base = line_info.rva_to_func + func_info.rva_to_base;
        if (k == line_count - 1) {
          line_info.size = func_info.size - line_info.rva_to_func;
        } else {
          struct LineInfo &next_line = func_info.line_info[k + 1];
          line_info.size = next_line.rva_to_func - line_info.rva_to_func;
        }
      }  // for each line.
    }  // for each function.
  }  // for each source file.
  for (SymbolMap::iterator it = symbol_entries->begin();
       it != symbol_entries->end(); ++it) {
    free(it->second);
  }
  return true;
}

bool LoadAllSymbols(const GElf_Shdr *stab_section,
                    const GElf_Shdr *stabstr_section,
                    GElf_Word base,
                    struct SymbolInfo *symbols) {
  if (stab_section == NULL || stabstr_section == NULL)
    return false;

  char *stabstr = 
    reinterpret_cast<char *>(stabstr_section->sh_offset + base);
  struct slist *lists =
    reinterpret_cast<struct slist *>(stab_section->sh_offset + base);
  int nstab = stab_section->sh_size / sizeof(struct slist);
  int source_id = 0;

  // First pass, load all symbols from the object file.
  for (int i = 0; i < nstab; ) {
    int step = 1;
    struct slist *cur_list = lists + i;
    if (cur_list->n_type == N_SO) {
      // FUNC <address> <size> <param_stack_size> <function>
      struct SourceFileInfo source_file_info;
      source_file_info.name = stabstr + cur_list->n_strx + stringOffset;
      // The n_value field is always 0 from stab generated by Sun CC.
      // TODO(Alfred): Find the correct value.
      source_file_info.addr = cur_list->n_value;
      if (strchr(source_file_info.name, '.'))
        source_file_info.source_id = source_id++;
      else
        source_file_info.source_id = -1;
      step = LoadFuncSymbols(cur_list, lists + nstab - 1, stabstr,
                             base, &source_file_info);
      symbols->source_file_info.push_back(source_file_info);
    }
    i += step;
  }
  // Second pass, compute the size of functions and lines.
  return ComputeSizeAndRVA(symbols);
}

bool LoadSymbols(Elf *elf, GElf_Ehdr *elf_header, struct SymbolInfo *symbols,
                 void *obj_base) {
  GElf_Word base = reinterpret_cast<GElf_Word>(obj_base);

  const GElf_Shdr *sections =
    reinterpret_cast<GElf_Shdr *>(elf_header->e_shoff + base);
  GElf_Shdr stab_section;
  if (!FindSectionByName(elf, kStabName, elf_header->e_shstrndx,
                         &stab_section)) {
    fprintf(stderr, "Stab section not found.\n");
    return false;
  }
  GElf_Shdr stabstr_section;
  if (!FindSectionByName(elf, kStabStrName, elf_header->e_shstrndx,
                         &stabstr_section)) {
    fprintf(stderr, "Stabstr section not found.\n");
    return false;
  }
  GElf_Shdr symtab_section;
  if (!FindSectionByName(elf, kSymtabName, elf_header->e_shstrndx,
                         &symtab_section)) {
    fprintf(stderr, "Symtab section not found.\n");
    return false;
  }
  GElf_Shdr strtab_section;
  if (!FindSectionByName(elf, kStrtabName, elf_header->e_shstrndx,
                         &strtab_section)) {
    fprintf(stderr, "Strtab section not found.\n");
    return false;
  }

  Elf_Sym *symbol = (Elf_Sym *)((char *)base + symtab_section.sh_offset);
  for (int i = 0; i < symtab_section.sh_size/symtab_section.sh_entsize; ++i) {
    struct SymbolEntry *symbol_entry =
        (struct SymbolEntry *)malloc(sizeof(struct SymbolEntry));
    const char *name = reinterpret_cast<char *>(
        strtab_section.sh_offset + (GElf_Word)base + symbol->st_name);
    symbol_entry->offset = symbol->st_value;
    symbol_entry->size = symbol->st_size;
    symbols->symbol_entries.insert(make_pair(name, symbol_entry));
    ++symbol;
  }


  // Load symbols.
  return LoadAllSymbols(&stab_section, &stabstr_section, base, symbols);
}

bool WriteModuleInfo(int fd, GElf_Half arch, const std::string &obj_file) {
  const char *arch_name = NULL;
  if (arch == EM_386)
    arch_name = "x86";
  else if (arch == EM_X86_64)
    arch_name = "x86_64";
  else if (arch == EM_SPARC32PLUS)
    arch_name = "SPARC_32+";
  else {
    printf("Please add more ARCH support\n");
    return false;
  }

  unsigned char identifier[16];
  google_breakpad::FileID file_id(obj_file.c_str());
  if (file_id.ElfFileIdentifier(identifier)) {
    char identifier_str[40];
    file_id.ConvertIdentifierToString(identifier,
                                      identifier_str, sizeof(identifier_str));
    std::string filename = obj_file;
    size_t slash_pos = obj_file.find_last_of("/");
    if (slash_pos != std::string::npos)
      filename = obj_file.substr(slash_pos + 1);
    return WriteFormat(fd, "MODULE solaris %s %s %s\n", arch_name,
                       identifier_str, filename.c_str());
  }
  return false;
}

bool WriteSourceFileInfo(int fd, const struct SymbolInfo &symbols) {
  for (size_t i = 0; i < symbols.source_file_info.size(); ++i) {
    if (symbols.source_file_info[i].source_id != -1) {
      const char *name = symbols.source_file_info[i].name;
      if (!WriteFormat(fd, "FILE %d %s\n",
                       symbols.source_file_info[i].source_id, name))
        return false;
    }
  }
  return true;
}

bool WriteOneFunction(int fd, int source_id,
                      const struct FuncInfo &func_info){
  // Discard the ending part of the name.
  std::string func_name(func_info.name);
  std::string::size_type last_colon = func_name.find_last_of(':');
  if (last_colon != std::string::npos)
    func_name = func_name.substr(0, last_colon);
  func_name = Demangle(func_name.c_str());

  if (func_info.size <= 0)
    return true;

  // rva_to_base could be unsigned long(32 bit) or unsigned long long(64 bit).
  if (WriteFormat(fd, "FUNC %llx %x %d %s\n",
                  (long long)func_info.rva_to_base,
                  func_info.size,
                  func_info.stack_param_size,
                  func_name.c_str())) {
    for (size_t i = 0; i < func_info.line_info.size(); ++i) {
      const struct LineInfo &line_info = func_info.line_info[i];
      if (line_info.line_num == 0)
        return true;
      if (!WriteFormat(fd, "%llx %x %d %d\n",
                       (long long)line_info.rva_to_base,
                       line_info.size,
                       line_info.line_num,
                       source_id))
        return false;
    }
    return true;
  }
  return false;
}

bool WriteFunctionInfo(int fd, const struct SymbolInfo &symbols) {
  for (size_t i = 0; i < symbols.source_file_info.size(); ++i) {
    const struct SourceFileInfo &file_info = symbols.source_file_info[i];
    for (size_t j = 0; j < file_info.func_info.size(); ++j) {
      const struct FuncInfo &func_info = file_info.func_info[j];
      if (!WriteOneFunction(fd, file_info.source_id, func_info))
        return false;
    }
  }
  return true;
}

bool DumpStabSymbols(int fd, const struct SymbolInfo &symbols) {
  return WriteSourceFileInfo(fd, symbols) &&
    WriteFunctionInfo(fd, symbols);
}

//
// FDWrapper
//
// Wrapper class to make sure opened file is closed.
//
class FDWrapper {
 public:
  explicit FDWrapper(int fd) :
    fd_(fd) {
    }
  ~FDWrapper() {
    if (fd_ != -1)
      close(fd_);
  }
  int get() {
    return fd_;
  }
  int release() {
    int fd = fd_;
    fd_ = -1;
    return fd;
  }
 private:
  int fd_;
};

//
// MmapWrapper
//
// Wrapper class to make sure mapped regions are unmapped.
//
class MmapWrapper {
 public:
  MmapWrapper(void *mapped_address, size_t mapped_size) :
    base_(mapped_address), size_(mapped_size) {
  }
  ~MmapWrapper() {
    if (base_ != NULL) {
      assert(size_ > 0);
      munmap((char *)base_, size_);
    }
  }
  void release() {
    base_ = NULL;
    size_ = 0;
  }

 private:
  void *base_;
  size_t size_;
};

}  // namespace

namespace google_breakpad {

class AutoElfEnder {
 public:
  AutoElfEnder(Elf *elf) : elf_(elf) {}
  ~AutoElfEnder() { if (elf_) elf_end(elf_); }
 private:
  Elf *elf_;
};


bool DumpSymbols::WriteSymbolFile(const std::string &obj_file, int sym_fd) {
  if (elf_version(EV_CURRENT) == EV_NONE) {
    fprintf(stderr, "elf_version() failed: %s\n", elf_errmsg(0));
    return false;
  }

  int obj_fd = open(obj_file.c_str(), O_RDONLY);
  if (obj_fd < 0)
    return false;
  FDWrapper obj_fd_wrapper(obj_fd);
  struct stat st;
  if (fstat(obj_fd, &st) != 0 && st.st_size <= 0)
    return false;
  void *obj_base = mmap(NULL, st.st_size,
                        PROT_READ, MAP_PRIVATE, obj_fd, 0);
  if (obj_base == MAP_FAILED)
    return false;
  MmapWrapper map_wrapper(obj_base, st.st_size);
  GElf_Ehdr elf_header;
  Elf *elf = elf_begin(obj_fd, ELF_C_READ, NULL);
  AutoElfEnder elfEnder(elf);

  if (gelf_getehdr(elf, &elf_header) == (GElf_Ehdr *)NULL) {
    fprintf(stderr, "failed to read elf header: %s\n", elf_errmsg(-1));
    return false;
  }

  if (!IsValidElf(&elf_header)) {
    fprintf(stderr, "header magic doesn't match\n");
    return false;
  }
  struct SymbolInfo symbols;
  if (!LoadSymbols(elf, &elf_header, &symbols, obj_base))
    return false;
  // Write to symbol file.
  if (WriteModuleInfo(sym_fd, elf_header.e_machine, obj_file) &&
      DumpStabSymbols(sym_fd, symbols))
    return true;

  return false;
}

}  // namespace google_breakpad
