//===------------------------- 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",
                         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
