//===------------------------- EHHeaderParser.hpp -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//
//  Parses ELF .eh_frame_hdr sections.
//
//===----------------------------------------------------------------------===//

#ifndef __EHHEADERPARSER_HPP__
#define __EHHEADERPARSER_HPP__

#include "libunwind.h"

#include "AddressSpace.hpp"
#include "DwarfParser.hpp"

namespace libunwind {

/// \brief EHHeaderParser does basic parsing of an ELF .eh_frame_hdr section.
///
/// See DWARF spec for details:
///    http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
///
template <typename A> class EHHeaderParser {
public:
  typedef typename A::pint_t pint_t;

  /// Information encoded in the EH frame header.
  struct EHHeaderInfo {
    pint_t eh_frame_ptr;
    size_t fde_count;
    pint_t table;
    uint8_t table_enc;
  };

  static void decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd,
                          EHHeaderInfo &ehHdrInfo);
  static bool findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
                      uint32_t sectionLength,
                      typename CFI_Parser<A>::FDE_Info *fdeInfo,
                      typename CFI_Parser<A>::CIE_Info *cieInfo);

private:
  static bool decodeTableEntry(A &addressSpace, pint_t &tableEntry,
                               pint_t ehHdrStart, pint_t ehHdrEnd,
                               uint8_t tableEnc,
                               typename CFI_Parser<A>::FDE_Info *fdeInfo,
                               typename CFI_Parser<A>::CIE_Info *cieInfo);
  static size_t getTableEntrySize(uint8_t tableEnc);
};

template <typename A>
void EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart,
                                    pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo) {
  pint_t p = ehHdrStart;
  uint8_t version = addressSpace.get8(p++);
  if (version != 1)
    _LIBUNWIND_ABORT("Unsupported .eh_frame_hdr version");

  uint8_t eh_frame_ptr_enc = addressSpace.get8(p++);
  uint8_t fde_count_enc = addressSpace.get8(p++);
  ehHdrInfo.table_enc = addressSpace.get8(p++);

  ehHdrInfo.eh_frame_ptr =
      addressSpace.getEncodedP(p, ehHdrEnd, eh_frame_ptr_enc, ehHdrStart);
  ehHdrInfo.fde_count =
      addressSpace.getEncodedP(p, ehHdrEnd, fde_count_enc, ehHdrStart);
  ehHdrInfo.table = p;
}

template <typename A>
bool EHHeaderParser<A>::decodeTableEntry(
    A &addressSpace, pint_t &tableEntry, pint_t ehHdrStart, pint_t ehHdrEnd,
    uint8_t tableEnc, typename CFI_Parser<A>::FDE_Info *fdeInfo,
    typename CFI_Parser<A>::CIE_Info *cieInfo) {
  // Have to decode the whole FDE for the PC range anyway, so just throw away
  // the PC start.
  addressSpace.getEncodedP(tableEntry, ehHdrEnd, tableEnc, ehHdrStart);
  pint_t fde =
      addressSpace.getEncodedP(tableEntry, ehHdrEnd, tableEnc, ehHdrStart);
  const char *message =
      CFI_Parser<A>::decodeFDE(addressSpace, fde, fdeInfo, cieInfo);
  if (message != NULL) {
    _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s\n",
                         message);
    return false;
  }

  return true;
}

template <typename A>
bool EHHeaderParser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
                                uint32_t sectionLength,
                                typename CFI_Parser<A>::FDE_Info *fdeInfo,
                                typename CFI_Parser<A>::CIE_Info *cieInfo) {
  pint_t ehHdrEnd = ehHdrStart + sectionLength;

  EHHeaderParser<A>::EHHeaderInfo hdrInfo;
  EHHeaderParser<A>::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd, hdrInfo);

  size_t tableEntrySize = getTableEntrySize(hdrInfo.table_enc);
  pint_t tableEntry;

  size_t low = 0;
  for (size_t len = hdrInfo.fde_count; len > 1;) {
    size_t mid = low + (len / 2);
    tableEntry = hdrInfo.table + mid * tableEntrySize;
    pint_t start = addressSpace.getEncodedP(tableEntry, ehHdrEnd,
                                            hdrInfo.table_enc, ehHdrStart);

    if (start == pc) {
      low = mid;
      break;
    } else if (start < pc) {
      low = mid;
      len -= (len / 2);
    } else {
      len /= 2;
    }
  }

  tableEntry = hdrInfo.table + low * tableEntrySize;
  if (decodeTableEntry(addressSpace, tableEntry, ehHdrStart, ehHdrEnd,
                       hdrInfo.table_enc, fdeInfo, cieInfo)) {
    if (pc >= fdeInfo->pcStart && pc < fdeInfo->pcEnd)
      return true;
  }

  return false;
}

template <typename A>
size_t EHHeaderParser<A>::getTableEntrySize(uint8_t tableEnc) {
  switch (tableEnc & 0x0f) {
  case DW_EH_PE_sdata2:
  case DW_EH_PE_udata2:
    return 4;
  case DW_EH_PE_sdata4:
  case DW_EH_PE_udata4:
    return 8;
  case DW_EH_PE_sdata8:
  case DW_EH_PE_udata8:
    return 16;
  case DW_EH_PE_sleb128:
  case DW_EH_PE_uleb128:
    _LIBUNWIND_ABORT("Can't binary search on variable length encoded data.");
  case DW_EH_PE_omit:
    return 0;
  default:
    _LIBUNWIND_ABORT("Unknown DWARF encoding for search table.");
  }
}

}

#endif
