//===- DWARFAbbreviationDeclaration.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#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/FormatVariadic.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,
                                      uint64_t* OffsetPtr) {
  clear();
  const uint64_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 = dwarf::getFixedFormByteSize(F, dwarf::FormParams()))) {
          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 {
  OS << '[' << getCode() << "] ";
  OS << formatv("{0}", getTag());
  OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
  for (const AttributeSpec &Spec : AttributeSpecs) {
    OS << formatv("\t{0}\t{1}", Spec.Attr, 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 uint64_t DIEOffset, const dwarf::Attribute Attr,
    const DWARFUnit &U) const {
  // Check if this abbreviation has this attribute without needing to skip
  // any data so we can return quickly if it doesn't.
  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.
  uint64_t Offset = DIEOffset + CodeByteSize;
  for (uint32_t CurAttrIdx = 0; CurAttrIdx != *MatchAttrIndex; ++CurAttrIdx)
    // Match Offset along until we get to the attribute we want.
    if (auto FixedSize = AttributeSpecs[CurAttrIdx].getByteSize(U))
      Offset += *FixedSize;
    else
      DWARFFormValue::skipValue(AttributeSpecs[CurAttrIdx].Form, DebugInfoData,
                                &Offset, U.getFormParams());

  // We have arrived at the attribute to extract, extract if from Offset.
  const AttributeSpec &Spec = AttributeSpecs[*MatchAttrIndex];
  if (Spec.isImplicitConst())
    return DWARFFormValue::createFromSValue(Spec.Form,
                                            Spec.getImplicitConstValue());

  DWARFFormValue FormValue(Spec.Form);
  if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
    return FormValue;

  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 = dwarf::getFixedFormByteSize(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;
}
