/*
 * Copyright (c) 2015, Intel Corporation
 * Author: Andi Kleen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 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 HOLDER 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.
 */

#include "elf.h"

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "garnet/lib/debugger_utils/byte_block_file.h"
#include "garnet/lib/debugger_utils/elf_reader.h"
#include "garnet/lib/debugger_utils/util.h"
#include "src/lib/fxl/logging.h"
#include "third_party/processor-trace/libipt/include/intel-pt.h"

namespace simple_pt {

// Read in the symbol table(s) of |elf|.
// |base| is the address at which the file was loaded, and |len|
// is the length of the text segment.
// |offset| is the different between where the file was actually
// loaded (|base|) and address recorded in the file.

static bool ReadSymtabs(debugger_utils::ElfReader* elf, uint64_t cr3, uint64_t base, uint64_t len,
                        uint64_t offset, bool is_kernel, std::unique_ptr<SymbolTable>* out_symtab,
                        std::unique_ptr<SymbolTable>* out_dynsym) {
  size_t num_sections = elf->GetNumSections();

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

  std::unique_ptr<SymbolTable> symtab;
  std::unique_ptr<SymbolTable> dynsym;

  for (size_t i = 0; i < num_sections; ++i) {
    const debugger_utils::ElfSectionHeader& shdr = elf->GetSectionHeader(i);
    SymbolTable* st;
    switch (shdr.sh_type) {
      case SHT_SYMTAB:
        symtab.reset(new SymbolTable(elf, "symtab", cr3, base, offset, is_kernel));
        st = symtab.get();
        break;
      case SHT_DYNSYM:
        dynsym.reset(new SymbolTable(elf, "dynsym", cr3, base, offset, is_kernel));
        st = dynsym.get();
        break;
      default:
        continue;
    }

    if (!st->Populate(elf, shdr.sh_type))
      return false;

    // Compute the last address used by symbols in the table.
    size_t num_symbols = st->num_symbols();
    uint64_t end = 0;
    for (size_t j = 0; j < num_symbols; j++) {
      const debugger_utils::ElfSymbol& sym = st->GetSymbol(j);
      if (end < sym.addr + sym.size)
        end = sym.addr + sym.size;
    }

    // Assign the full range of symbols to the symtab so that even if a symbol
    // isn't found, we still know the pc came from this file.
    // Other segments technically needn't be contiguous, which one would have
    // to deal with to handle more than just the (assumed) one text segment.
    if (len > end)
      st->set_end(offset + len);
    else
      st->set_end(offset + end);
  }

  if (!symtab && !dynsym)
    FX_LOGS(WARNING) << elf->file_name() << " has no symbols";
  *out_symtab = std::move(symtab);
  *out_dynsym = std::move(dynsym);

  return true;
}

// Find the base address, length, and file offset of the text segment
// of a non-PIC ELF.

static void FindBaseLenFileoff(debugger_utils::ElfReader* elf, uint64_t* base, uint64_t* len,
                               uint64_t* fileoff) {
  size_t num_segments = elf->GetNumSegments();
  for (size_t i = 0; i < num_segments; ++i) {
    const debugger_utils::ElfSegmentHeader& phdr = elf->GetSegmentHeader(i);
    if (phdr.p_type == PT_LOAD && (phdr.p_flags & PF_X) != 0) {
      *base = phdr.p_vaddr;
      *len = phdr.p_memsz;
      *fileoff = phdr.p_offset;
      return;
    }
  }
}

// Given a potential PIC ELF loaded at |base|, compute the offset from where
// the file says segments are loaded to where they were actually loaded.

static void FindOffset(debugger_utils::ElfReader* elf, uint64_t base, uint64_t* offset) {
  uint64_t minaddr = UINT64_MAX;

  if (!base) {
    *offset = 0;
    return;
  }

  size_t num_segments = elf->GetNumSegments();
  for (size_t i = 0; i < num_segments; ++i) {
    const debugger_utils::ElfSegmentHeader& phdr = elf->GetSegmentHeader(i);
    if (phdr.p_type == PT_LOAD && phdr.p_vaddr < minaddr) {
      minaddr = phdr.p_vaddr;
    }
  }

  // Punt if no loadable segments found.
  if (minaddr == UINT64_MAX) {
    *offset = 0;
    return;
  }

  *offset = base - minaddr;
}

static void AddProgbits(debugger_utils::ElfReader* elf, struct pt_image* image,
                        const char* file_name, uint64_t base, uint64_t cr3, uint64_t offset,
                        uint64_t file_off, uint64_t map_len) {
  size_t num_segments = elf->GetNumSegments();
  for (size_t i = 0; i < num_segments; ++i) {
    const debugger_utils::ElfSegmentHeader& phdr = elf->GetSegmentHeader(i);

    if ((phdr.p_type == PT_LOAD) && (phdr.p_flags & PF_X) && phdr.p_offset >= file_off &&
        (!map_len || phdr.p_offset + phdr.p_filesz <= file_off + map_len)) {
      struct pt_asid asid;
      int err;

      /* The first loadable section in zircon.elf is
         unusable to us. Plus we want to ignore it here.
         This test is an attempt to not be too zircon specific. */
      if (phdr.p_vaddr < phdr.p_paddr)
        continue;

      pt_asid_init(&asid);
      asid.cr3 = cr3;
      errno = 0;

      err = pt_image_add_file(image, file_name, phdr.p_offset, phdr.p_filesz, &asid,
                              phdr.p_vaddr + offset);
      /* Duplicate. Just ignore. */
      if (err == -pte_bad_image)
        continue;
      if (err < 0) {
        fprintf(stderr, "reading prog code at %" PRIx64 ":%" PRIx64 " from %s: %s (%s): %d\n",
                phdr.p_vaddr, phdr.p_filesz, file_name, pt_errstr(pt_errcode(err)),
                errno ? strerror(errno) : "", err);
        return;
      }
    }
  }
}

static bool ElfOpen(const char* file_name, std::unique_ptr<debugger_utils::ElfReader>* out_elf) {
  int fd = open(file_name, O_RDONLY);
  if (fd < 0) {
    FX_LOGS(ERROR) << file_name << ", " << debugger_utils::ErrnoString(errno);
    return false;
  }

  auto bb = std::shared_ptr<debugger_utils::FileByteBlock>(new debugger_utils::FileByteBlock(fd));

  std::unique_ptr<debugger_utils::ElfReader> elf;
  debugger_utils::ElfError rc = debugger_utils::ElfReader::Create(file_name, bb, 0, 0, &elf);
  if (rc != debugger_utils::ElfError::OK) {
    FX_LOGS(ERROR) << "Error creating ELF reader: " << debugger_utils::ElfErrorName(rc);
    return false;
  }

  rc = elf->ReadSegmentHeaders();
  if (rc != debugger_utils::ElfError::OK) {
    FX_LOGS(ERROR) << "Error reading ELF segment headers: " << ElfErrorName(rc);
    return false;
  }

  *out_elf = std::move(elf);
  return true;
}

bool ReadElf(const char* file_name, struct pt_image* image, uint64_t base, uint64_t cr3,
             uint64_t file_off, uint64_t map_len, std::unique_ptr<SymbolTable>* out_symtab,
             std::unique_ptr<SymbolTable>* out_dynsym) {
  std::unique_ptr<debugger_utils::ElfReader> elf;
  if (!ElfOpen(file_name, &elf))
    return false;

  bool pic = false;
  const debugger_utils::ElfHeader& hdr = elf->header();
  pic = hdr.e_type == ET_DYN;
  if (pic && base == 0) {
    FX_LOGS(ERROR) << "PIC/PIE ELF with base 0 is not supported";
    return false;
  }

  uint64_t offset = 0;
  if (pic)
    FindOffset(elf.get(), base, &offset);

  if (!ReadSymtabs(elf.get(), cr3, base, map_len, offset, false, out_symtab, out_dynsym))
    return false;

  AddProgbits(elf.get(), image, file_name, base, cr3, offset, file_off, map_len);

  return true;
}

bool ReadNonPicElf(const char* file_name, pt_image* image, uint64_t cr3, bool is_kernel,
                   std::unique_ptr<SymbolTable>* out_symtab,
                   std::unique_ptr<SymbolTable>* out_dynsym) {
  std::unique_ptr<debugger_utils::ElfReader> elf;
  if (!ElfOpen(file_name, &elf))
    return false;

  // TODO(dje): kernel pc values can appear in traces with userspace cr3
  // values, e.g., when performing a syscall. For now, ignore cr3 for
  // kernel pcs. The original value of zero was odd anyway.
  uint64_t kernel_cr3_for_symtab = pt_asid_no_cr3;

  // TODO(dje): Need to handle PIE kernels.
  uint64_t base = 0, len = 0;
  uint64_t offset = 0, file_off = 0;
  FindBaseLenFileoff(elf.get(), &base, &len, &file_off);

  if (!ReadSymtabs(elf.get(), kernel_cr3_for_symtab, base, len, offset, is_kernel, out_symtab,
                   out_dynsym))
    return false;

  AddProgbits(elf.get(), image, file_name, base, cr3 ? cr3 : pt_asid_no_cr3, offset, file_off, len);

  return true;
}

}  // namespace simple_pt
