// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "elf_symtab.h"

#include "lib/fxl/logging.h"

namespace debugger_utils {

ElfSymbolTable::ElfSymbolTable(const std::string& file_name,
                               const std::string& contents)
    : file_name_(file_name), contents_(contents) {}

ElfSymbolTable::~ElfSymbolTable() {
  if (symbols_)
    delete[] symbols_;
}

bool ElfSymbolTable::Populate(ElfReader* elf, unsigned symtab_type) {
  FXL_DCHECK(symtab_type == SHT_SYMTAB || symtab_type == SHT_DYNSYM);

  // TODO(dje): Add support for loading both SHT_SYMTAB and SHT_DYNSYM.
  if (symbols_) {
    FXL_LOG(ERROR) << "Already populated";
    return false;
  }

  ElfError rc = elf->ReadSectionHeaders();
  if (rc != ElfError::OK) {
    FXL_LOG(ERROR) << "Error reading ELF section headers: " << ElfErrorName(rc);
    return false;
  }

  const ElfSectionHeader* shdr = elf->GetSectionHeaderByType(symtab_type);
  if (!shdr)
    return true;  // empty symbol table

  size_t num_sections = elf->GetNumSections();
  size_t string_section = shdr->sh_link;
  if (string_section >= num_sections) {
    FXL_LOG(ERROR) << "Bad string section: " << string_section;
    return false;
  }
  const ElfSectionHeader& str_shdr = elf->GetSectionHeader(string_section);

  std::unique_ptr<ElfSectionContents> contents;
  rc = elf->GetSectionContents(*shdr, &contents);
  if (rc != ElfError::OK) {
    FXL_LOG(ERROR) << "Error reading ELF section: " << ElfErrorName(rc);
    return false;
  }

  rc = elf->GetSectionContents(str_shdr, &string_section_);
  if (rc != ElfError::OK) {
    FXL_LOG(ERROR) << "Error reading ELF string section: " << ElfErrorName(rc);
    return false;
  }

  auto strings = reinterpret_cast<const char*>(string_section_->contents());
  size_t max_string_offset = string_section_->GetSize();

  size_t num_raw_symbols = contents->GetNumEntries();
  symbols_ = new ElfSymbol[num_raw_symbols];

  size_t num_symbols = 0;
  for (size_t i = 0; i < num_raw_symbols; ++i) {
    const ElfRawSymbol& sym = contents->GetSymbolEntry(i);
    if (sym.st_name >= max_string_offset) {
      FXL_LOG(ERROR) << "Bad symbol string name offset: " << sym.st_name;
      continue;
    }
    ElfSymbol* s = &symbols_[num_symbols++];
    // TODO(dje): IWBN to have a convenience function for getting symbol
    // names, not sure what it will look like yet.
    s->name = strings + sym.st_name;
    s->addr = sym.st_value;
    s->size = sym.st_size;
  }

  num_symbols_ = num_symbols;
  Finalize();
  return true;
}

static int CompareSymbol(const void* ap, const void* bp) {
  auto a = reinterpret_cast<const ElfSymbol*>(ap);
  auto b = reinterpret_cast<const ElfSymbol*>(bp);
  if (a->addr >= b->addr && a->addr < b->addr + b->size)
    return 0;
  if (b->addr >= a->addr && b->addr < a->addr + a->size)
    return 0;
  return a->addr - b->addr;
}

void ElfSymbolTable::Finalize() {
  qsort(symbols_, num_symbols_, sizeof(ElfSymbol), CompareSymbol);
}

const ElfSymbol* ElfSymbolTable::FindSymbol(uint64_t addr) const {
  ElfSymbol search = {.addr = addr};

  /* add last hit cache here */

  auto s = reinterpret_cast<const ElfSymbol*>(bsearch(
      &search, symbols_, num_symbols_, sizeof(ElfSymbol), CompareSymbol));
  return s;
}

void ElfSymbolTable::Dump(FILE* f) const {
  fprintf(f, "file: %s\n", file_name_.c_str());
  fprintf(f, "contents: %s\n", contents_.c_str());
  for (size_t i = 0; i < num_symbols_; i++) {
    ElfSymbol* s = &symbols_[i];
    if (s->addr && s->name[0])
      fprintf(f, "%p %s\n", (void*)s->addr, s->name);
  }
}

}  // namespace debugger_utils
