/*
 * 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 "symtab.h"

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

#include "garnet/lib/debugger_utils/elf_reader.h"
#include "garnet/lib/debugger_utils/elf_symtab.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 {

SymbolTable::SymbolTable(debugger_utils::ElfReader* reader,
                         const std::string& contents,
                         uint64_t cr3,
                         uint64_t base,
                         uint64_t offset,
                         bool is_kernel)
    : debugger_utils::ElfSymbolTable(reader->file_name(), contents),
      cr3_(cr3),
      base_(base),
      end_(0),
      offset_(offset),
      is_kernel_(is_kernel) {}

const Symbol* SymbolTable::FindSymbol(uint64_t addr) const {
  if (addr < base_ || addr >= end_)
    return nullptr;
  return debugger_utils::ElfSymbolTable::FindSymbol(addr - offset_);
}

static bool Cr3Matches(uint64_t cr3_1, uint64_t cr3_2) {
  // TODO(dje): Zero was used early on to mean "match everything".
  // pt_asid_no_cr3 currently serves that purpose too. Both currently mean
  // the same thing for backwards compatibility, but it may be useful to
  // distinguish "match everything" vs "match nothing".
  if (cr3_1 == 0 || cr3_2 == 0)
    return true;
  if (cr3_1 == pt_asid_no_cr3 || cr3_2 == pt_asid_no_cr3)
    return true;
  return cr3_1 == cr3_2;
}

const SymbolTable* FindSymbolTable(const SymbolTableTable& symtabs,
                                   uint64_t cr3, uint64_t pc) {
  for (auto& st : symtabs) {
    if (!Cr3Matches(st->cr3(), cr3))
      continue;
    if (pc < st->base() || pc >= st->end())
      continue;
    return st.get();
  }

  return nullptr;
}

const Symbol* FindSymbol(const SymbolTableTable& symtabs,
                         uint64_t cr3, uint64_t pc,
                         const SymbolTable** out_symtab) {
  const SymbolTable* symtab = FindSymbolTable(symtabs, cr3, pc);
  if (!symtab) {
    *out_symtab = nullptr;
    return nullptr;
  }
  *out_symtab = symtab;
  return symtab->FindSymbol(pc);
}

const char* FindPcFileName(const SymbolTableTable& symtabs,
                           uint64_t cr3, uint64_t pc) {
  for (const auto& st : symtabs) {
    if (!Cr3Matches(st->cr3(), cr3))
      continue;
    if (pc < st->base() || pc >= st->end())
      continue;
    return st->file_name().c_str();
  }
  return nullptr;
}

bool SeenCr3(const SymbolTableTable& symtabs, uint64_t cr3) {
  for (const auto& st : symtabs) {
    if (st->cr3() == cr3)
      return true;
  }
  return false;
}

}  // simple_pt
