/*
 * 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/elf_reader.h"
#include "garnet/lib/debugger_utils/byte_block_file.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) {
    FXL_LOG(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)
    FXL_LOG(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) {
    FXL_LOG(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) {
    FXL_LOG(ERROR) << "Error creating ELF reader: " << debugger_utils::ElfErrorName(rc);
    return false;
  }

  rc = elf->ReadSegmentHeaders();
  if (rc != debugger_utils::ElfError::OK) {
    FXL_LOG(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) {
    FXL_LOG(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
