/*
 * 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 <lib/syslog/cpp/macros.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 "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
