//===-- ELFHeader.cpp ----------------------------------------- -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <cstring>

#include "lldb/Core/Section.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Stream.h"

#include "ELFHeader.h"

using namespace elf;
using namespace lldb;
using namespace llvm::ELF;

//------------------------------------------------------------------------------
// Static utility functions.
//
// GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor
// with error handling code and provide for parsing a sequence of values.
static bool GetMaxU64(const lldb_private::DataExtractor &data,
                      lldb::offset_t *offset, uint64_t *value,
                      uint32_t byte_size) {
  const lldb::offset_t saved_offset = *offset;
  *value = data.GetMaxU64(offset, byte_size);
  return *offset != saved_offset;
}

static bool GetMaxU64(const lldb_private::DataExtractor &data,
                      lldb::offset_t *offset, uint64_t *value,
                      uint32_t byte_size, uint32_t count) {
  lldb::offset_t saved_offset = *offset;

  for (uint32_t i = 0; i < count; ++i, ++value) {
    if (GetMaxU64(data, offset, value, byte_size) == false) {
      *offset = saved_offset;
      return false;
    }
  }
  return true;
}

static bool GetMaxS64(const lldb_private::DataExtractor &data,
                      lldb::offset_t *offset, int64_t *value,
                      uint32_t byte_size) {
  const lldb::offset_t saved_offset = *offset;
  *value = data.GetMaxS64(offset, byte_size);
  return *offset != saved_offset;
}

static bool GetMaxS64(const lldb_private::DataExtractor &data,
                      lldb::offset_t *offset, int64_t *value,
                      uint32_t byte_size, uint32_t count) {
  lldb::offset_t saved_offset = *offset;

  for (uint32_t i = 0; i < count; ++i, ++value) {
    if (GetMaxS64(data, offset, value, byte_size) == false) {
      *offset = saved_offset;
      return false;
    }
  }
  return true;
}

//------------------------------------------------------------------------------
// ELFHeader

ELFHeader::ELFHeader() { memset(this, 0, sizeof(ELFHeader)); }

ByteOrder ELFHeader::GetByteOrder() const {
  if (e_ident[EI_DATA] == ELFDATA2MSB)
    return eByteOrderBig;
  if (e_ident[EI_DATA] == ELFDATA2LSB)
    return eByteOrderLittle;
  return eByteOrderInvalid;
}

bool ELFHeader::HasHeaderExtension() const {
  bool result = false;

  // Check if any of these values looks like sentinel.
  result |= e_phnum_hdr == 0xFFFF; // PN_XNUM
  result |= e_shnum_hdr == SHN_UNDEF;
  result |= e_shstrndx_hdr == SHN_XINDEX;

  // If header extension is present, the section offset cannot be null.
  result &= e_shoff != 0;

  // Done.
  return result;
}

void ELFHeader::ParseHeaderExtension(lldb_private::DataExtractor &data) {
  // Extract section #0 header.
  ELFSectionHeader section_zero;
  lldb::offset_t offset = 0;
  lldb_private::DataExtractor sh_data(data, e_shoff, e_shentsize);
  bool ok = section_zero.Parse(sh_data, &offset);

  // If we succeeded, fix the header.
  if (ok) {
    if (e_phnum_hdr == 0xFFFF) // PN_XNUM
      e_phnum = section_zero.sh_info;
    if (e_shnum_hdr == SHN_UNDEF)
      e_shnum = section_zero.sh_size;
    if (e_shstrndx_hdr == SHN_XINDEX)
      e_shstrndx = section_zero.sh_link;
  }
}

bool ELFHeader::Parse(lldb_private::DataExtractor &data,
                      lldb::offset_t *offset) {
  // Read e_ident.  This provides byte order and address size info.
  if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL)
    return false;

  const unsigned byte_size = Is32Bit() ? 4 : 8;
  data.SetByteOrder(GetByteOrder());
  data.SetAddressByteSize(byte_size);

  // Read e_type and e_machine.
  if (data.GetU16(offset, &e_type, 2) == NULL)
    return false;

  // Read e_version.
  if (data.GetU32(offset, &e_version, 1) == NULL)
    return false;

  // Read e_entry, e_phoff and e_shoff.
  if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false)
    return false;

  // Read e_flags.
  if (data.GetU32(offset, &e_flags, 1) == NULL)
    return false;

  // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and e_shstrndx.
  if (data.GetU16(offset, &e_ehsize, 6) == NULL)
    return false;

  // Initialize e_phnum, e_shnum, and e_shstrndx with the values read from the
  // header.
  e_phnum = e_phnum_hdr;
  e_shnum = e_shnum_hdr;
  e_shstrndx = e_shstrndx_hdr;

  // See if we have extended header in section #0.
  if (HasHeaderExtension())
    ParseHeaderExtension(data);

  return true;
}

bool ELFHeader::MagicBytesMatch(const uint8_t *magic) {
  return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0;
}

unsigned ELFHeader::AddressSizeInBytes(const uint8_t *magic) {
  unsigned address_size = 0;

  switch (magic[EI_CLASS]) {
  case ELFCLASS32:
    address_size = 4;
    break;

  case ELFCLASS64:
    address_size = 8;
    break;
  }
  return address_size;
}

unsigned ELFHeader::GetRelocationJumpSlotType() const {
  unsigned slot = 0;

  switch (e_machine) {
  default:
    assert(false && "architecture not supported");
    break;
  case EM_PPC:
    slot = R_PPC_JMP_SLOT;
    break;
  case EM_PPC64:
    slot = R_PPC64_JMP_SLOT;
    break;
  case EM_386:
  case EM_IAMCU: // FIXME: is this correct?
    slot = R_386_JUMP_SLOT;
    break;
  case EM_X86_64:
    slot = R_X86_64_JUMP_SLOT;
    break;
  case EM_ARM:
    slot = R_ARM_JUMP_SLOT;
    break;
  case EM_HEXAGON:
    slot = R_HEX_JMP_SLOT;
    break;
  case EM_AARCH64:
    slot = R_AARCH64_JUMP_SLOT;
    break;
  case EM_MIPS:
    slot = R_MIPS_JUMP_SLOT;
    break;
  case EM_S390:
    slot = R_390_JMP_SLOT;
    break;
  }

  return slot;
}

//------------------------------------------------------------------------------
// ELFSectionHeader

ELFSectionHeader::ELFSectionHeader() {
  memset(this, 0, sizeof(ELFSectionHeader));
}

bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
                             lldb::offset_t *offset) {
  const unsigned byte_size = data.GetAddressByteSize();

  // Read sh_name and sh_type.
  if (data.GetU32(offset, &sh_name, 2) == NULL)
    return false;

  // Read sh_flags.
  if (GetMaxU64(data, offset, &sh_flags, byte_size) == false)
    return false;

  // Read sh_addr, sh_off and sh_size.
  if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false)
    return false;

  // Read sh_link and sh_info.
  if (data.GetU32(offset, &sh_link, 2) == NULL)
    return false;

  // Read sh_addralign and sh_entsize.
  if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false)
    return false;

  return true;
}

//------------------------------------------------------------------------------
// ELFSymbol

ELFSymbol::ELFSymbol() { memset(this, 0, sizeof(ELFSymbol)); }

#define ENUM_TO_CSTR(e)                                                        \
  case e:                                                                      \
    return #e

const char *ELFSymbol::bindingToCString(unsigned char binding) {
  switch (binding) {
    ENUM_TO_CSTR(STB_LOCAL);
    ENUM_TO_CSTR(STB_GLOBAL);
    ENUM_TO_CSTR(STB_WEAK);
    ENUM_TO_CSTR(STB_LOOS);
    ENUM_TO_CSTR(STB_HIOS);
    ENUM_TO_CSTR(STB_LOPROC);
    ENUM_TO_CSTR(STB_HIPROC);
  }
  return "";
}

const char *ELFSymbol::typeToCString(unsigned char type) {
  switch (type) {
    ENUM_TO_CSTR(STT_NOTYPE);
    ENUM_TO_CSTR(STT_OBJECT);
    ENUM_TO_CSTR(STT_FUNC);
    ENUM_TO_CSTR(STT_SECTION);
    ENUM_TO_CSTR(STT_FILE);
    ENUM_TO_CSTR(STT_COMMON);
    ENUM_TO_CSTR(STT_TLS);
    ENUM_TO_CSTR(STT_GNU_IFUNC);
    ENUM_TO_CSTR(STT_HIOS);
    ENUM_TO_CSTR(STT_LOPROC);
    ENUM_TO_CSTR(STT_HIPROC);
  }
  return "";
}

const char *ELFSymbol::sectionIndexToCString(
    elf_half shndx, const lldb_private::SectionList *section_list) {
  switch (shndx) {
    ENUM_TO_CSTR(SHN_UNDEF);
    ENUM_TO_CSTR(SHN_LOPROC);
    ENUM_TO_CSTR(SHN_HIPROC);
    ENUM_TO_CSTR(SHN_LOOS);
    ENUM_TO_CSTR(SHN_HIOS);
    ENUM_TO_CSTR(SHN_ABS);
    ENUM_TO_CSTR(SHN_COMMON);
    ENUM_TO_CSTR(SHN_XINDEX);
  default: {
    const lldb_private::Section *section =
        section_list->GetSectionAtIndex(shndx).get();
    if (section)
      return section->GetName().AsCString("");
  } break;
  }
  return "";
}

void ELFSymbol::Dump(lldb_private::Stream *s, uint32_t idx,
                     const lldb_private::DataExtractor *strtab_data,
                     const lldb_private::SectionList *section_list) {
  s->Printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64
            " 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n",
            idx, st_value, st_size, st_name, st_info,
            bindingToCString(getBinding()), typeToCString(getType()), st_other,
            st_shndx, sectionIndexToCString(st_shndx, section_list),
            strtab_data ? strtab_data->PeekCStr(st_name) : "");
}

bool ELFSymbol::Parse(const lldb_private::DataExtractor &data,
                      lldb::offset_t *offset) {
  const unsigned byte_size = data.GetAddressByteSize();
  const bool parsing_32 = byte_size == 4;

  // Read st_name.
  if (data.GetU32(offset, &st_name, 1) == NULL)
    return false;

  if (parsing_32) {
    // Read st_value and st_size.
    if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false)
      return false;

    // Read st_info and st_other.
    if (data.GetU8(offset, &st_info, 2) == NULL)
      return false;

    // Read st_shndx.
    if (data.GetU16(offset, &st_shndx, 1) == NULL)
      return false;
  } else {
    // Read st_info and st_other.
    if (data.GetU8(offset, &st_info, 2) == NULL)
      return false;

    // Read st_shndx.
    if (data.GetU16(offset, &st_shndx, 1) == NULL)
      return false;

    // Read st_value and st_size.
    if (data.GetU64(offset, &st_value, 2) == NULL)
      return false;
  }
  return true;
}

//------------------------------------------------------------------------------
// ELFProgramHeader

ELFProgramHeader::ELFProgramHeader() {
  memset(this, 0, sizeof(ELFProgramHeader));
}

bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
                             lldb::offset_t *offset) {
  const uint32_t byte_size = data.GetAddressByteSize();
  const bool parsing_32 = byte_size == 4;

  // Read p_type;
  if (data.GetU32(offset, &p_type, 1) == NULL)
    return false;

  if (parsing_32) {
    // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz.
    if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false)
      return false;

    // Read p_flags.
    if (data.GetU32(offset, &p_flags, 1) == NULL)
      return false;

    // Read p_align.
    if (GetMaxU64(data, offset, &p_align, byte_size) == false)
      return false;
  } else {
    // Read p_flags.
    if (data.GetU32(offset, &p_flags, 1) == NULL)
      return false;

    // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align.
    if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false)
      return false;
  }

  return true;
}

//------------------------------------------------------------------------------
// ELFDynamic

ELFDynamic::ELFDynamic() { memset(this, 0, sizeof(ELFDynamic)); }

bool ELFDynamic::Parse(const lldb_private::DataExtractor &data,
                       lldb::offset_t *offset) {
  const unsigned byte_size = data.GetAddressByteSize();
  return GetMaxS64(data, offset, &d_tag, byte_size, 2);
}

//------------------------------------------------------------------------------
// ELFRel

ELFRel::ELFRel() { memset(this, 0, sizeof(ELFRel)); }

bool ELFRel::Parse(const lldb_private::DataExtractor &data,
                   lldb::offset_t *offset) {
  const unsigned byte_size = data.GetAddressByteSize();

  // Read r_offset and r_info.
  if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
    return false;

  return true;
}

//------------------------------------------------------------------------------
// ELFRela

ELFRela::ELFRela() { memset(this, 0, sizeof(ELFRela)); }

bool ELFRela::Parse(const lldb_private::DataExtractor &data,
                    lldb::offset_t *offset) {
  const unsigned byte_size = data.GetAddressByteSize();

  // Read r_offset and r_info.
  if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
    return false;

  // Read r_addend;
  if (GetMaxS64(data, offset, &r_addend, byte_size) == false)
    return false;

  return true;
}
