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

#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"

#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cstddef>
#include <cstdint>

using namespace llvm;
using namespace dwarf;

void DWARFAbbreviationDeclaration::clear() {
  Code = 0;
  Tag = DW_TAG_null;
  CodeByteSize = 0;
  HasChildren = false;
  AttributeSpecs.clear();
  FixedAttributeSize.reset();
}

DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
  clear();
}

bool
DWARFAbbreviationDeclaration::extract(DataExtractor Data, 
                                      uint32_t* OffsetPtr) {
  clear();
  const uint32_t Offset = *OffsetPtr;
  Code = Data.getULEB128(OffsetPtr);
  if (Code == 0) {
    return false;
  }
  CodeByteSize = *OffsetPtr - Offset;
  Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
  if (Tag == DW_TAG_null) {
    clear();
    return false;
  }
  uint8_t ChildrenByte = Data.getU8(OffsetPtr);
  HasChildren = (ChildrenByte == DW_CHILDREN_yes);
  // Assign a value to our optional FixedAttributeSize member variable. If
  // this member variable still has a value after the while loop below, then
  // all attribute data in this abbreviation declaration has a fixed byte size.
  FixedAttributeSize = FixedSizeInfo();

  // Read all of the abbreviation attributes and forms.
  while (true) {
    auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
    auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
    if (A && F) {
      bool IsImplicitConst = (F == DW_FORM_implicit_const);
      if (IsImplicitConst) {
        int64_t V = Data.getSLEB128(OffsetPtr);
        AttributeSpecs.push_back(AttributeSpec(A, F, V));
        continue;
      }
      Optional<uint8_t> ByteSize;
      // If this abbrevation still has a fixed byte size, then update the
      // FixedAttributeSize as needed.
      switch (F) {
      case DW_FORM_addr:
        if (FixedAttributeSize)
          ++FixedAttributeSize->NumAddrs;
        break;

      case DW_FORM_ref_addr:
        if (FixedAttributeSize)
          ++FixedAttributeSize->NumRefAddrs;
        break;

      case DW_FORM_strp:
      case DW_FORM_GNU_ref_alt:
      case DW_FORM_GNU_strp_alt:
      case DW_FORM_line_strp:
      case DW_FORM_sec_offset:
      case DW_FORM_strp_sup:
        if (FixedAttributeSize)
          ++FixedAttributeSize->NumDwarfOffsets;
        break;

      default:
        // The form has a byte size that doesn't depend on Params.
        // If it's a fixed size, keep track of it.
        if ((ByteSize =
                 DWARFFormValue::getFixedByteSize(F, DWARFFormParams()))) {
          if (FixedAttributeSize)
            FixedAttributeSize->NumBytes += *ByteSize;
          break;
        }
        // Indicate we no longer have a fixed byte size for this
        // abbreviation by clearing the FixedAttributeSize optional value
        // so it doesn't have a value.
        FixedAttributeSize.reset();
        break;
      }
      // Record this attribute and its fixed size if it has one.
      AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
    } else if (A == 0 && F == 0) {
      // We successfully reached the end of this abbreviation declaration
      // since both attribute and form are zero.
      break;
    } else {
      // Attribute and form pairs must either both be non-zero, in which case
      // they are added to the abbreviation declaration, or both be zero to
      // terminate the abbrevation declaration. In this case only one was
      // zero which is an error.
      clear();
      return false;
    }
  }
  return true;
}

void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
  auto tagString = TagString(getTag());
  OS << '[' << getCode() << "] ";
  if (!tagString.empty())
    OS << tagString;
  else
    OS << format("DW_TAG_Unknown_%x", getTag());
  OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
  for (const AttributeSpec &Spec : AttributeSpecs) {
    OS << '\t';
    auto attrString = AttributeString(Spec.Attr);
    if (!attrString.empty())
      OS << attrString;
    else
      OS << format("DW_AT_Unknown_%x", Spec.Attr);
    OS << '\t';
    auto formString = FormEncodingString(Spec.Form);
    if (!formString.empty())
      OS << formString;
    else
      OS << format("DW_FORM_Unknown_%x", Spec.Form);
    if (Spec.isImplicitConst())
      OS << '\t' << Spec.getImplicitConstValue();
    OS << '\n';
  }
  OS << '\n';
}

Optional<uint32_t>
DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
  for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
    if (AttributeSpecs[i].Attr == Attr)
      return i;
  }
  return None;
}

Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
    const uint32_t DIEOffset, const dwarf::Attribute Attr,
    const DWARFUnit &U) const {
  Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
  if (!MatchAttrIndex)
    return None;

  auto DebugInfoData = U.getDebugInfoExtractor();

  // Add the byte size of ULEB that for the abbrev Code so we can start
  // skipping the attribute data.
  uint32_t Offset = DIEOffset + CodeByteSize;
  uint32_t AttrIndex = 0;
  for (const auto &Spec : AttributeSpecs) {
    if (*MatchAttrIndex == AttrIndex) {
      // We have arrived at the attribute to extract, extract if from Offset.
      DWARFFormValue FormValue(Spec.Form);
      if (Spec.isImplicitConst()) {
        FormValue.setSValue(Spec.getImplicitConstValue());
        return FormValue;
      }
      if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
        return FormValue;
    }
    // March Offset along until we get to the attribute we want.
    if (auto FixedSize = Spec.getByteSize(U))
      Offset += *FixedSize;
    else
      DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset,
                                U.getFormParams());
    ++AttrIndex;
  }
  return None;
}

size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
    const DWARFUnit &U) const {
  size_t ByteSize = NumBytes;
  if (NumAddrs)
    ByteSize += NumAddrs * U.getAddressByteSize();
  if (NumRefAddrs)
    ByteSize += NumRefAddrs * U.getRefAddrByteSize();
  if (NumDwarfOffsets)
    ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
  return ByteSize;
}

Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
    const DWARFUnit &U) const {
  if (isImplicitConst())
    return 0;
  if (ByteSize.HasByteSize)
    return ByteSize.ByteSize;
  Optional<int64_t> S;
  auto FixedByteSize =
      DWARFFormValue::getFixedByteSize(Form, U.getFormParams());
  if (FixedByteSize)
    S = *FixedByteSize;
  return S;
}

Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
    const DWARFUnit &U) const {
  if (FixedAttributeSize)
    return FixedAttributeSize->getByteSize(U);
  return None;
}
