//===- EhFrameHdr.cpp -----------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/LD/EhFrameHdr.h>

#include <mcld/Support/MemoryArea.h>
#include <mcld/Support/MemoryRegion.h>
#include <mcld/LD/EhFrame.h>
#include <mcld/LD/LDSection.h>

#include <llvm/Support/Dwarf.h>
#include <llvm/Support/DataTypes.h>

#include <algorithm>
#include <cstring>

using namespace mcld;
using namespace llvm::dwarf;

//===----------------------------------------------------------------------===//
// Helper Function
//===----------------------------------------------------------------------===//
namespace bit32 {

typedef std::pair<SizeTraits<32>::Address, SizeTraits<32>::Address> Entry;

bool EntryCompare(const Entry& pX, const Entry& pY)
{ return (pX.first < pY.first); }

} // bit32 namespace

//===----------------------------------------------------------------------===//
// Template Specification Functions
//===----------------------------------------------------------------------===//
/// emitOutput<32> - write out eh_frame_hdr
template<>
void EhFrameHdr::emitOutput<32>(MemoryArea& pOutput)
{
  MemoryRegion* ehframehdr_region =
    pOutput.request(m_EhFrameHdr.offset(), m_EhFrameHdr.size());

  MemoryRegion* ehframe_region =
    pOutput.request(m_EhFrame.offset(),
                    m_EhFrame.size());

  uint8_t* data = (uint8_t*)ehframehdr_region->start();
  // version
  data[0] = 1;
  // eh_frame_ptr_enc
  data[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;

  // eh_frame_ptr
  uint32_t* eh_frame_ptr = (uint32_t*)(data + 4);
  *eh_frame_ptr = m_EhFrame.addr() - (m_EhFrameHdr.addr() + 4);

  // fde_count
  uint32_t* fde_count = (uint32_t*)(data + 8);
  if (m_EhFrame.hasEhFrame())
    *fde_count = 0;
  else
    *fde_count = m_EhFrame.getEhFrame()->numOfFDEs();

  if (0 != *fde_count) {
    // fde_count_enc
    data[2] = DW_EH_PE_udata4;
    // table_enc
    data[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;

  }
  else {
    // fde_count_enc
    data[2] = DW_EH_PE_omit;
    // table_enc
    data[3] = DW_EH_PE_omit;
  }

  if (0 != *fde_count) {

    // prepare the binary search table
    typedef std::vector<bit32::Entry> SearchTableType;
    SearchTableType search_table;
    MemoryRegion* ehframe_region =
      pOutput.request(m_EhFrame.offset(), m_EhFrame.size());
    EhFrame::const_fde_iterator fde, fde_end = m_EhFrame.getEhFrame()->fde_end();
    for(fde = m_EhFrame.getEhFrame()->fde_begin(); fde != fde_end; ++fde) {
      assert(*fde != NULL);
      SizeTraits<32>::Offset offset;
      SizeTraits<32>::Address fde_pc;
      SizeTraits<32>::Address fde_addr;
      offset = (*fde)->getOffset();
      fde_pc = computePCBegin(**fde, *ehframe_region);
      fde_addr = m_EhFrame.addr() + offset;
      search_table.push_back(std::make_pair(fde_pc, fde_addr));
    }
    pOutput.release(ehframe_region);

    std::sort(search_table.begin(), search_table.end(), bit32::EntryCompare);

    // write out the binary search table
    uint32_t* bst = (uint32_t*)(data + 12);
    SearchTableType::const_iterator entry, entry_end = search_table.end();
    size_t id = 0;
    for (entry = search_table.begin(); entry != entry_end; ++entry) {
      bst[id++] = (*entry).first - m_EhFrameHdr.addr();
      bst[id++] = (*entry).second - m_EhFrameHdr.addr();
    }
  }
  pOutput.release(ehframehdr_region);
  pOutput.release(ehframe_region);
}

//===----------------------------------------------------------------------===//
// EhFrameHdr
//===----------------------------------------------------------------------===//

EhFrameHdr::EhFrameHdr(LDSection& pEhFrameHdr, const LDSection& pEhFrame)
  : m_EhFrameHdr(pEhFrameHdr), m_EhFrame(pEhFrame) {
}

EhFrameHdr::~EhFrameHdr()
{
}

/// @ref lsb core generic 4.1
/// .eh_frame_hdr section format
/// uint8_t : version
/// uint8_t : eh_frame_ptr_enc
/// uint8_t : fde_count_enc
/// uint8_t : table_enc
/// uint32_t : eh_frame_ptr
/// uint32_t : fde_count
/// __________________________ when fde_count > 0
/// <uint32_t, uint32_t>+ : binary search table
/// sizeOutput - base on the fde count to size output
void EhFrameHdr::sizeOutput()
{
  size_t size = 12;
  if (m_EhFrame.hasEhFrame())
    size += 8 * m_EhFrame.getEhFrame()->numOfFDEs();
  m_EhFrameHdr.setSize(size);
}

/// computePCBegin - return the address of FDE's pc
/// @ref binutils gold: ehframe.cc:222
uint32_t EhFrameHdr::computePCBegin(const EhFrame::FDE& pFDE,
                                    const MemoryRegion& pEhFrameRegion)
{
  uint8_t fde_encoding = pFDE.getCIE().getFDEEncode();
  unsigned int eh_value = fde_encoding & 0x7;

  // check the size to read in
  if (eh_value == llvm::dwarf::DW_EH_PE_absptr) {
    eh_value = DW_EH_PE_udata4;
  }

  size_t pc_size = 0x0;
  switch (eh_value) {
    case DW_EH_PE_udata2:
      pc_size = 2;
      break;
    case DW_EH_PE_udata4:
      pc_size = 4;
      break;
    case DW_EH_PE_udata8:
      pc_size = 8;
      break;
    default:
      // TODO
      break;
  }

  SizeTraits<32>::Address pc = 0x0;
  const uint8_t* offset = (const uint8_t*) pEhFrameRegion.start() +
                          pFDE.getOffset() +
                          pFDE.getDataStart();
  std::memcpy(&pc, offset, pc_size);

  // adjust the signed value
  bool is_signed = (fde_encoding & llvm::dwarf::DW_EH_PE_signed) != 0x0;
  if (DW_EH_PE_udata2 == eh_value && is_signed)
    pc = (pc ^ 0x8000) - 0x8000;

  // handle eh application
  switch (fde_encoding & 0x70)
  {
    case DW_EH_PE_absptr:
      break;
    case DW_EH_PE_pcrel:
      pc += m_EhFrame.addr() + pFDE.getOffset() + pFDE.getDataStart();
      break;
    case DW_EH_PE_datarel:
      // TODO
      break;
    default:
      // TODO
      break;
  }
  return pc;
}
