//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
//
// 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 "DWARFDebugInfoEntry.h"

#include <assert.h>

#include <algorithm>

#include "llvm/Support/LEB128.h"

#include "lldb/Core/Module.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/Stream.h"

#include "DWARFCompileUnit.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
#include "DWARFFormValue.h"
#include "DWARFUnit.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDwo.h"

using namespace lldb_private;
using namespace std;
extern int g_verbose;

// Extract a debug info entry for a given DWARFUnit from the data
// starting at the offset in offset_ptr
bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
                                  const DWARFUnit *cu,
                                  lldb::offset_t *offset_ptr) {
  m_offset = *offset_ptr;
  m_parent_idx = 0;
  m_sibling_idx = 0;
  const uint64_t abbr_idx = data.GetULEB128(offset_ptr);
  lldbassert(abbr_idx <= UINT16_MAX);
  m_abbr_idx = abbr_idx;

  // assert (fixed_form_sizes);  // For best performance this should be
  // specified!

  if (m_abbr_idx) {
    lldb::offset_t offset = *offset_ptr;
    const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
    if (abbrevDecl == nullptr) {
      cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
          "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
          "attach the file at the start of this error message",
          m_offset, (unsigned)abbr_idx);
      // WE can't parse anymore if the DWARF is borked...
      *offset_ptr = UINT32_MAX;
      return false;
    }
    m_tag = abbrevDecl->Tag();
    m_has_children = abbrevDecl->HasChildren();
    // Skip all data in the .debug_info or .debug_types for the attributes
    const uint32_t numAttributes = abbrevDecl->NumAttributes();
    uint32_t i;
    dw_form_t form;
    for (i = 0; i < numAttributes; ++i) {
      form = abbrevDecl->GetFormByIndexUnchecked(i);
      llvm::Optional<uint8_t> fixed_skip_size =
          DWARFFormValue::GetFixedSize(form, cu);
      if (fixed_skip_size)
        offset += *fixed_skip_size;
      else {
        bool form_is_indirect = false;
        do {
          form_is_indirect = false;
          uint32_t form_size = 0;
          switch (form) {
          // Blocks if inlined data that have a length field and the data bytes
          // inlined in the .debug_info/.debug_types
          case DW_FORM_exprloc:
          case DW_FORM_block:
            form_size = data.GetULEB128(&offset);
            break;
          case DW_FORM_block1:
            form_size = data.GetU8_unchecked(&offset);
            break;
          case DW_FORM_block2:
            form_size = data.GetU16_unchecked(&offset);
            break;
          case DW_FORM_block4:
            form_size = data.GetU32_unchecked(&offset);
            break;

          // Inlined NULL terminated C-strings
          case DW_FORM_string:
            data.GetCStr(&offset);
            break;

          // Compile unit address sized values
          case DW_FORM_addr:
            form_size = cu->GetAddressByteSize();
            break;
          case DW_FORM_ref_addr:
            if (cu->GetVersion() <= 2)
              form_size = cu->GetAddressByteSize();
            else
              form_size = 4;
            break;

          // 0 sized form
          case DW_FORM_flag_present:
            form_size = 0;
            break;

          // 1 byte values
          case DW_FORM_addrx1:
          case DW_FORM_data1:
          case DW_FORM_flag:
          case DW_FORM_ref1:
          case DW_FORM_strx1:
            form_size = 1;
            break;

          // 2 byte values
          case DW_FORM_addrx2:
          case DW_FORM_data2:
          case DW_FORM_ref2:
          case DW_FORM_strx2:
            form_size = 2;
            break;

          // 3 byte values
          case DW_FORM_addrx3:
          case DW_FORM_strx3:
            form_size = 3;
            break;

          // 4 byte values
          case DW_FORM_addrx4:
          case DW_FORM_data4:
          case DW_FORM_ref4:
          case DW_FORM_strx4:
            form_size = 4;
            break;

          // 8 byte values
          case DW_FORM_data8:
          case DW_FORM_ref8:
          case DW_FORM_ref_sig8:
            form_size = 8;
            break;

          // signed or unsigned LEB 128 values
          case DW_FORM_addrx:
          case DW_FORM_rnglistx:
          case DW_FORM_sdata:
          case DW_FORM_udata:
          case DW_FORM_ref_udata:
          case DW_FORM_GNU_addr_index:
          case DW_FORM_GNU_str_index:
          case DW_FORM_strx:
            data.Skip_LEB128(&offset);
            break;

          case DW_FORM_indirect:
            form_is_indirect = true;
            form = data.GetULEB128(&offset);
            break;

          case DW_FORM_strp:
          case DW_FORM_sec_offset:
            data.GetU32(&offset);
            break;

          case DW_FORM_implicit_const:
            form_size = 0;
            break;

          default:
            *offset_ptr = m_offset;
            return false;
          }
          offset += form_size;

        } while (form_is_indirect);
      }
    }
    *offset_ptr = offset;
    return true;
  } else {
    m_tag = 0;
    m_has_children = false;
    return true; // NULL debug tag entry
  }

  return false;
}

static DWARFRangeList GetRangesOrReportError(const DWARFUnit &unit,
                                             const DWARFDebugInfoEntry &die,
                                             const DWARFFormValue &value) {
  llvm::Expected<DWARFRangeList> expected_ranges =
      (value.Form() == DW_FORM_rnglistx)
          ? unit.FindRnglistFromIndex(value.Unsigned())
          : unit.FindRnglistFromOffset(value.Unsigned());
  if (expected_ranges)
    return std::move(*expected_ranges);
  unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
      "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but "
      "range extraction failed (%s), please file a bug "
      "and attach the file at the start of this error message",
      die.GetOffset(), value.Unsigned(),
      toString(expected_ranges.takeError()).c_str());
  return DWARFRangeList();
}

// GetDIENamesAndRanges
//
// Gets the valid address ranges for a given DIE by looking for a
// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
    const DWARFUnit *cu, const char *&name, const char *&mangled,
    DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column,
    int &call_file, int &call_line, int &call_column,
    DWARFExpression *frame_base) const {
  dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
  dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
  std::vector<DWARFDIE> dies;
  bool set_frame_base_loclist_addr = false;

  const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);

  SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF();
  lldb::ModuleSP module = dwarf.GetObjectFile()->GetModule();

  if (abbrevDecl) {
    const DWARFDataExtractor &data = cu->GetData();
    lldb::offset_t offset = GetFirstAttributeOffset();

    if (!data.ValidOffset(offset))
      return false;

    const uint32_t numAttributes = abbrevDecl->NumAttributes();
    bool do_offset = false;

    for (uint32_t i = 0; i < numAttributes; ++i) {
      DWARFFormValue form_value(cu);
      dw_attr_t attr;
      abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);

      if (form_value.ExtractValue(data, &offset)) {
        switch (attr) {
        case DW_AT_low_pc:
          lo_pc = form_value.Address();

          if (do_offset)
            hi_pc += lo_pc;
          do_offset = false;
          break;

        case DW_AT_entry_pc:
          lo_pc = form_value.Address();
          break;

        case DW_AT_high_pc:
          if (form_value.Form() == DW_FORM_addr ||
              form_value.Form() == DW_FORM_addrx ||
              form_value.Form() == DW_FORM_GNU_addr_index) {
            hi_pc = form_value.Address();
          } else {
            hi_pc = form_value.Unsigned();
            if (lo_pc == LLDB_INVALID_ADDRESS)
              do_offset = hi_pc != LLDB_INVALID_ADDRESS;
            else
              hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save
                              // on relocations
          }
          break;

        case DW_AT_ranges:
          ranges = GetRangesOrReportError(*cu, *this, form_value);
          break;

        case DW_AT_name:
          if (name == nullptr)
            name = form_value.AsCString();
          break;

        case DW_AT_MIPS_linkage_name:
        case DW_AT_linkage_name:
          if (mangled == nullptr)
            mangled = form_value.AsCString();
          break;

        case DW_AT_abstract_origin:
          dies.push_back(form_value.Reference());
          break;

        case DW_AT_specification:
          dies.push_back(form_value.Reference());
          break;

        case DW_AT_decl_file:
          if (decl_file == 0)
            decl_file = form_value.Unsigned();
          break;

        case DW_AT_decl_line:
          if (decl_line == 0)
            decl_line = form_value.Unsigned();
          break;

        case DW_AT_decl_column:
          if (decl_column == 0)
            decl_column = form_value.Unsigned();
          break;

        case DW_AT_call_file:
          if (call_file == 0)
            call_file = form_value.Unsigned();
          break;

        case DW_AT_call_line:
          if (call_line == 0)
            call_line = form_value.Unsigned();
          break;

        case DW_AT_call_column:
          if (call_column == 0)
            call_column = form_value.Unsigned();
          break;

        case DW_AT_frame_base:
          if (frame_base) {
            if (form_value.BlockData()) {
              uint32_t block_offset =
                  form_value.BlockData() - data.GetDataStart();
              uint32_t block_length = form_value.Unsigned();
              *frame_base = DWARFExpression(module, data, cu,
                                            block_offset, block_length);
            } else {
              const DWARFDataExtractor &debug_loc_data = dwarf.DebugLocData();
              const dw_offset_t debug_loc_offset = form_value.Unsigned();

              size_t loc_list_length = DWARFExpression::LocationListSize(
                  cu, debug_loc_data, debug_loc_offset);
              if (loc_list_length > 0) {
                *frame_base =
                    DWARFExpression(module, debug_loc_data, cu,
                                    debug_loc_offset, loc_list_length);
                if (lo_pc != LLDB_INVALID_ADDRESS) {
                  assert(lo_pc >= cu->GetBaseAddress());
                  frame_base->SetLocationListSlide(lo_pc -
                                                   cu->GetBaseAddress());
                } else {
                  set_frame_base_loclist_addr = true;
                }
              }
            }
          }
          break;

        default:
          break;
        }
      }
    }
  }

  if (ranges.IsEmpty()) {
    if (lo_pc != LLDB_INVALID_ADDRESS) {
      if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
        ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
      else
        ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
    }
  }

  if (set_frame_base_loclist_addr) {
    dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
    assert(lowest_range_pc >= cu->GetBaseAddress());
    frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress());
  }

  if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
    for (const DWARFDIE &die : dies) {
      if (die) {
        die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
                                           decl_file, decl_line, decl_column,
                                           call_file, call_line, call_column);
      }
    }
  }
  return !ranges.IsEmpty();
}

// Dump
//
// Dumps a debug information entry and all of it's attributes to the specified
// stream.
void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s,
                               uint32_t recurse_depth) const {
  const DWARFDataExtractor &data = cu->GetData();
  lldb::offset_t offset = m_offset;

  if (data.ValidOffset(offset)) {
    dw_uleb128_t abbrCode = data.GetULEB128(&offset);

    s.Printf("\n0x%8.8x: ", m_offset);
    s.Indent();
    if (abbrCode != m_abbr_idx) {
      s.Printf("error: DWARF has been modified\n");
    } else if (abbrCode) {
      const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
      if (abbrevDecl) {
        s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
        s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' ');

        // Dump all data in the .debug_info/.debug_types for the attributes
        const uint32_t numAttributes = abbrevDecl->NumAttributes();
        for (uint32_t i = 0; i < numAttributes; ++i) {
          DWARFFormValue form_value(cu);
          dw_attr_t attr;
          abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);

          DumpAttribute(cu, data, &offset, s, attr, form_value);
        }

        const DWARFDebugInfoEntry *child = GetFirstChild();
        if (recurse_depth > 0 && child) {
          s.IndentMore();

          while (child) {
            child->Dump(cu, s, recurse_depth - 1);
            child = child->GetSibling();
          }
          s.IndentLess();
        }
      } else
        s.Printf("Abbreviation code note found in 'debug_abbrev' class for "
                 "code: %u\n",
                 abbrCode);
    } else {
      s.Printf("NULL\n");
    }
  }
}

// DumpAttribute
//
// Dumps a debug information entry attribute along with it's form. Any special
// display of attributes is done (disassemble location lists, show enumeration
// values for attributes, etc).
void DWARFDebugInfoEntry::DumpAttribute(
    const DWARFUnit *cu, const DWARFDataExtractor &data,
    lldb::offset_t *offset_ptr, Stream &s, dw_attr_t attr,
    DWARFFormValue &form_value) {
  bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);

  s.Printf("            ");
  s.Indent(DW_AT_value_to_name(attr));

  if (show_form) {
    s.Printf("[%s", DW_FORM_value_to_name(form_value.Form()));
  }

  if (!form_value.ExtractValue(data, offset_ptr))
    return;

  if (show_form) {
    if (form_value.Form() == DW_FORM_indirect) {
      s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form()));
    }

    s.PutCString("] ");
  }

  s.PutCString("( ");

  SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF();

  // Check to see if we have any special attribute formatters
  switch (attr) {
  case DW_AT_stmt_list:
    s.Printf("0x%8.8" PRIx64, form_value.Unsigned());
    break;

  case DW_AT_language:
    s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
    break;

  case DW_AT_encoding:
    s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
    break;

  case DW_AT_frame_base:
  case DW_AT_location:
  case DW_AT_data_member_location: {
    const uint8_t *blockData = form_value.BlockData();
    if (blockData) {
      // Location description is inlined in data in the form value
      DWARFDataExtractor locationData(data,
                                      (*offset_ptr) - form_value.Unsigned(),
                                      form_value.Unsigned());
      DWARFExpression::PrintDWARFExpression(
          s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false);
    } else {
      // We have a location list offset as the value that is the offset into
      // the .debug_loc section that describes the value over it's lifetime
      uint64_t debug_loc_offset = form_value.Unsigned();
      DWARFExpression::PrintDWARFLocationList(s, cu, dwarf.DebugLocData(),
                                              debug_loc_offset);
    }
  } break;

  case DW_AT_abstract_origin:
  case DW_AT_specification: {
    DWARFDIE abstract_die = form_value.Reference();
    form_value.Dump(s);
    //  *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( ";
    abstract_die.GetName(s);
  } break;

  case DW_AT_type: {
    DWARFDIE type_die = form_value.Reference();
    s.PutCString(" ( ");
    type_die.AppendTypeName(s);
    s.PutCString(" )");
  } break;

  default:
    break;
  }

  s.PutCString(" )\n");
}

// Get all attribute values for a given DIE, including following any
// specification or abstract origin attributes and including those in the
// results. Any duplicate attributes will have the first instance take
// precedence (this can happen for declaration attributes).
size_t DWARFDebugInfoEntry::GetAttributes(
    const DWARFUnit *cu, DWARFAttributes &attributes,
    uint32_t curr_depth) const {
  const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
  if (abbrevDecl) {
    const DWARFDataExtractor &data = cu->GetData();
    lldb::offset_t offset = GetFirstAttributeOffset();

    const uint32_t num_attributes = abbrevDecl->NumAttributes();
    for (uint32_t i = 0; i < num_attributes; ++i) {
      DWARFFormValue form_value(cu);
      dw_attr_t attr;
      abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
      const dw_form_t form = form_value.Form();

      // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
      // attributes, the depth will be non-zero. We need to omit certain
      // attributes that don't make sense.
      switch (attr) {
      case DW_AT_sibling:
      case DW_AT_declaration:
        if (curr_depth > 0) {
          // This attribute doesn't make sense when combined with the DIE that
          // references this DIE. We know a DIE is referencing this DIE because
          // curr_depth is not zero
          break;
        }
        LLVM_FALLTHROUGH;
      default:
        attributes.Append(cu, offset, attr, form);
        break;
      }

      if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
        if (form_value.ExtractValue(data, &offset)) {
          DWARFDIE spec_die = form_value.Reference();
          if (spec_die)
            spec_die.GetAttributes(attributes, curr_depth + 1);
        }
      } else {
        llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
        if (fixed_skip_size)
          offset += *fixed_skip_size;
        else
          DWARFFormValue::SkipValue(form, data, &offset, cu);
      }
    }
  } else {
    attributes.Clear();
  }
  return attributes.Size();
}

// GetAttributeValue
//
// Get the value of an attribute and return the .debug_info or .debug_types
// offset of the attribute if it was properly extracted into form_value,
// or zero if we fail since an offset of zero is invalid for an attribute (it
// would be a compile unit header).
dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
    const DWARFUnit *cu, const dw_attr_t attr, DWARFFormValue &form_value,
    dw_offset_t *end_attr_offset_ptr,
    bool check_specification_or_abstract_origin) const {
  if (const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu)) {
    uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);

    if (attr_idx != DW_INVALID_INDEX) {
      const DWARFDataExtractor &data = cu->GetData();
      lldb::offset_t offset = GetFirstAttributeOffset();

      uint32_t idx = 0;
      while (idx < attr_idx)
        DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
                                  data, &offset, cu);

      const dw_offset_t attr_offset = offset;
      form_value.SetUnit(cu);
      form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
      if (form_value.ExtractValue(data, &offset)) {
        if (end_attr_offset_ptr)
          *end_attr_offset_ptr = offset;
        return attr_offset;
      }
    }
  }

  if (check_specification_or_abstract_origin) {
    if (GetAttributeValue(cu, DW_AT_specification, form_value)) {
      DWARFDIE die = form_value.Reference();
      if (die) {
        dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
            die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
        if (die_offset)
          return die_offset;
      }
    }

    if (GetAttributeValue(cu, DW_AT_abstract_origin, form_value)) {
      DWARFDIE die = form_value.Reference();
      if (die) {
        dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
            die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
        if (die_offset)
          return die_offset;
      }
    }
  }

  // If we're a unit DIE, also check the attributes of the dwo unit (if any).
  if (GetParent())
    return 0;
  SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
  if (!dwo_symbol_file)
    return 0;

  DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
  if (!dwo_cu)
    return 0;

  DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
  if (!dwo_cu_die.IsValid())
    return 0;

  return dwo_cu_die.GetDIE()->GetAttributeValue(
      dwo_cu, attr, form_value, end_attr_offset_ptr,
      check_specification_or_abstract_origin);
}

// GetAttributeValueAsString
//
// Get the value of an attribute as a string return it. The resulting pointer
// to the string data exists within the supplied SymbolFileDWARF and will only
// be available as long as the SymbolFileDWARF is still around and it's content
// doesn't change.
const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
    const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value,
    bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(cu, attr, form_value, nullptr,
                        check_specification_or_abstract_origin))
    return form_value.AsCString();
  return fail_value;
}

// GetAttributeValueAsUnsigned
//
// Get the value of an attribute as unsigned and return it.
uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
    const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
    bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(cu, attr, form_value, nullptr,
                        check_specification_or_abstract_origin))
    return form_value.Unsigned();
  return fail_value;
}

// GetAttributeValueAsReference
//
// Get the value of an attribute as reference and fix up and compile unit
// relative offsets as needed.
DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference(
    const DWARFUnit *cu, const dw_attr_t attr,
    bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(cu, attr, form_value, nullptr,
                        check_specification_or_abstract_origin))
    return form_value.Reference();
  return {};
}

uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
    const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
    bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(cu, attr, form_value, nullptr,
                        check_specification_or_abstract_origin))
    return form_value.Address();
  return fail_value;
}

// GetAttributeHighPC
//
// Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low-
// pc>.
//
// Returns the hi_pc or fail_value.
dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
    const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value,
    bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(cu, DW_AT_high_pc, form_value, nullptr,
                        check_specification_or_abstract_origin)) {
    dw_form_t form = form_value.Form();
    if (form == DW_FORM_addr || form == DW_FORM_addrx ||
        form == DW_FORM_GNU_addr_index)
      return form_value.Address();

    // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
    return lo_pc + form_value.Unsigned();
  }
  return fail_value;
}

// GetAttributeAddressRange
//
// Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset-
// from-low-pc>.
//
// Returns true or sets lo_pc and hi_pc to fail_value.
bool DWARFDebugInfoEntry::GetAttributeAddressRange(
    const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc,
    uint64_t fail_value, bool check_specification_or_abstract_origin) const {
  lo_pc = GetAttributeValueAsAddress(cu, DW_AT_low_pc, fail_value,
                                     check_specification_or_abstract_origin);
  if (lo_pc != fail_value) {
    hi_pc = GetAttributeHighPC(cu, lo_pc, fail_value,
                               check_specification_or_abstract_origin);
    if (hi_pc != fail_value)
      return true;
  }
  lo_pc = fail_value;
  hi_pc = fail_value;
  return false;
}

size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
    const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
    bool check_specification_or_abstract_origin) const {
  ranges.Clear();

  DWARFFormValue form_value;
  if (GetAttributeValue(cu, DW_AT_ranges, form_value)) {
    ranges = GetRangesOrReportError(*cu, *this, form_value);
  } else if (check_hi_lo_pc) {
    dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
    dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
    if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS,
                                 check_specification_or_abstract_origin)) {
      if (lo_pc < hi_pc)
        ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
    }
  }
  return ranges.GetSize();
}

// GetName
//
// Get value of the DW_AT_name attribute and return it if one exists, else
// return NULL.
const char *DWARFDebugInfoEntry::GetName(const DWARFUnit *cu) const {
  return GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
}

// GetMangledName
//
// Get value of the DW_AT_MIPS_linkage_name attribute and return it if one
// exists, else return the value of the DW_AT_name attribute
const char *
DWARFDebugInfoEntry::GetMangledName(const DWARFUnit *cu,
                                    bool substitute_name_allowed) const {
  const char *name = nullptr;

  name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
  if (name)
    return name;

  name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
  if (name)
    return name;

  if (!substitute_name_allowed)
    return nullptr;

  name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
  return name;
}

// GetPubname
//
// Get value the name for a DIE as it should appear for a .debug_pubnames or
// .debug_pubtypes section.
const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
  const char *name = nullptr;
  if (!cu)
    return name;

  name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
  if (name)
    return name;

  name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
  if (name)
    return name;

  name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
  return name;
}

// BuildAddressRangeTable
void DWARFDebugInfoEntry::BuildAddressRangeTable(
    const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
  if (m_tag) {
    if (m_tag == DW_TAG_subprogram) {
      dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
      dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
      if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
        /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x -
        /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
        debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc);
      }
    }

    const DWARFDebugInfoEntry *child = GetFirstChild();
    while (child) {
      child->BuildAddressRangeTable(cu, debug_aranges);
      child = child->GetSibling();
    }
  }
}

// BuildFunctionAddressRangeTable
//
// This function is very similar to the BuildAddressRangeTable function except
// that the actual DIE offset for the function is placed in the table instead
// of the compile unit offset (which is the way the standard .debug_aranges
// section does it).
void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
    const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
  if (m_tag) {
    if (m_tag == DW_TAG_subprogram) {
      dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
      dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
      if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
        //  printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " -
        //  0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
        debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
      }
    }

    const DWARFDebugInfoEntry *child = GetFirstChild();
    while (child) {
      child->BuildFunctionAddressRangeTable(cu, debug_aranges);
      child = child->GetSibling();
    }
  }
}

void DWARFDebugInfoEntry::GetDWARFDeclContext(
    DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const {
  const dw_tag_t tag = Tag();
  if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) {
    dwarf_decl_ctx.AppendDeclContext(tag, GetName(cu));
    DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu);
    if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
      if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit &&
          parent_decl_ctx_die.Tag() != DW_TAG_partial_unit)
        parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
            parent_decl_ctx_die.GetCU(), dwarf_decl_ctx);
    }
  }
}

DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
  DWARFAttributes attributes;
  GetAttributes(cu, attributes);
  return GetParentDeclContextDIE(cu, attributes);
}

DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(
    DWARFUnit *cu, const DWARFAttributes &attributes) const {
  DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));

  while (die) {
    // If this is the original DIE that we are searching for a declaration for,
    // then don't look in the cache as we don't want our own decl context to be
    // our decl context...
    if (die.GetDIE() != this) {
      switch (die.Tag()) {
      case DW_TAG_compile_unit:
      case DW_TAG_partial_unit:
      case DW_TAG_namespace:
      case DW_TAG_structure_type:
      case DW_TAG_union_type:
      case DW_TAG_class_type:
        return die;

      default:
        break;
      }
    }

    DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification);
    if (spec_die) {
      DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
      if (decl_ctx_die)
        return decl_ctx_die;
    }

    DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin);
    if (abs_die) {
      DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
      if (decl_ctx_die)
        return decl_ctx_die;
    }

    die = die.GetParent();
  }
  return DWARFDIE();
}

const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
                                                  std::string &storage) const {
  DWARFAttributes attributes;
  GetAttributes(cu, attributes);
  return GetQualifiedName(cu, attributes, storage);
}

const char *
DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
                                      const DWARFAttributes &attributes,
                                      std::string &storage) const {

  const char *name = GetName(cu);

  if (name) {
    DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu);
    storage.clear();
    // TODO: change this to get the correct decl context parent....
    while (parent_decl_ctx_die) {
      const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
      switch (parent_tag) {
      case DW_TAG_namespace: {
        const char *namespace_name = parent_decl_ctx_die.GetName();
        if (namespace_name) {
          storage.insert(0, "::");
          storage.insert(0, namespace_name);
        } else {
          storage.insert(0, "(anonymous namespace)::");
        }
        parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
      } break;

      case DW_TAG_class_type:
      case DW_TAG_structure_type:
      case DW_TAG_union_type: {
        const char *class_union_struct_name = parent_decl_ctx_die.GetName();

        if (class_union_struct_name) {
          storage.insert(0, "::");
          storage.insert(0, class_union_struct_name);
        }
        parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
      } break;

      default:
        parent_decl_ctx_die.Clear();
        break;
      }
    }

    if (storage.empty())
      storage.append("::");

    storage.append(name);
  }
  if (storage.empty())
    return nullptr;
  return storage.c_str();
}

bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
                                        const DWARFUnit *cu,
                                        DWARFDebugInfoEntry **function_die,
                                        DWARFDebugInfoEntry **block_die) {
  bool found_address = false;
  if (m_tag) {
    bool check_children = false;
    bool match_addr_range = false;
    //  printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset,
    //  DW_TAG_value_to_name(tag), address);
    switch (m_tag) {
    case DW_TAG_array_type:
      break;
    case DW_TAG_class_type:
      check_children = true;
      break;
    case DW_TAG_entry_point:
    case DW_TAG_enumeration_type:
    case DW_TAG_formal_parameter:
    case DW_TAG_imported_declaration:
    case DW_TAG_label:
      break;
    case DW_TAG_lexical_block:
      check_children = true;
      match_addr_range = true;
      break;
    case DW_TAG_member:
    case DW_TAG_pointer_type:
    case DW_TAG_reference_type:
      break;
    case DW_TAG_compile_unit:
      match_addr_range = true;
      break;
    case DW_TAG_string_type:
      break;
    case DW_TAG_structure_type:
      check_children = true;
      break;
    case DW_TAG_subroutine_type:
    case DW_TAG_typedef:
    case DW_TAG_union_type:
    case DW_TAG_unspecified_parameters:
    case DW_TAG_variant:
      break;
    case DW_TAG_common_block:
      check_children = true;
      break;
    case DW_TAG_common_inclusion:
    case DW_TAG_inheritance:
      break;
    case DW_TAG_inlined_subroutine:
      check_children = true;
      match_addr_range = true;
      break;
    case DW_TAG_module:
      match_addr_range = true;
      break;
    case DW_TAG_ptr_to_member_type:
    case DW_TAG_set_type:
    case DW_TAG_subrange_type:
    case DW_TAG_with_stmt:
    case DW_TAG_access_declaration:
    case DW_TAG_base_type:
      break;
    case DW_TAG_catch_block:
      match_addr_range = true;
      break;
    case DW_TAG_const_type:
    case DW_TAG_constant:
    case DW_TAG_enumerator:
    case DW_TAG_file_type:
    case DW_TAG_friend:
    case DW_TAG_namelist:
    case DW_TAG_namelist_item:
    case DW_TAG_packed_type:
      break;
    case DW_TAG_subprogram:
      match_addr_range = true;
      break;
    case DW_TAG_template_type_parameter:
    case DW_TAG_template_value_parameter:
    case DW_TAG_GNU_template_parameter_pack:
    case DW_TAG_thrown_type:
      break;
    case DW_TAG_try_block:
      match_addr_range = true;
      break;
    case DW_TAG_variant_part:
    case DW_TAG_variable:
    case DW_TAG_volatile_type:
    case DW_TAG_dwarf_procedure:
    case DW_TAG_restrict_type:
    case DW_TAG_interface_type:
      break;
    case DW_TAG_namespace:
      check_children = true;
      break;
    case DW_TAG_imported_module:
    case DW_TAG_unspecified_type:
      break;
    case DW_TAG_partial_unit:
      match_addr_range = true;
      break;
    case DW_TAG_imported_unit:
    case DW_TAG_shared_type:
    default:
      break;
    }

    if (match_addr_range) {
      dw_addr_t lo_pc =
          GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
      if (lo_pc != LLDB_INVALID_ADDRESS) {
        dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS);
        if (hi_pc != LLDB_INVALID_ADDRESS) {
          //  printf("\n0x%8.8x: %30s: address = 0x%8.8x  [0x%8.8x - 0x%8.8x) ",
          //  m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
          if ((lo_pc <= address) && (address < hi_pc)) {
            found_address = true;
            //  puts("***MATCH***");
            switch (m_tag) {
            case DW_TAG_compile_unit: // File
            case DW_TAG_partial_unit: // File
              check_children =
                  ((function_die != nullptr) || (block_die != nullptr));
              break;

            case DW_TAG_subprogram: // Function
              if (function_die)
                *function_die = this;
              check_children = (block_die != nullptr);
              break;

            case DW_TAG_inlined_subroutine: // Inlined Function
            case DW_TAG_lexical_block:      // Block { } in code
              if (block_die) {
                *block_die = this;
                check_children = true;
              }
              break;

            default:
              check_children = true;
              break;
            }
          }
        } else {
          // Compile units may not have a valid high/low pc when there
          // are address gaps in subroutines so we must always search
          // if there is no valid high and low PC.
          check_children =
              (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) &&
              ((function_die != nullptr) || (block_die != nullptr));
        }
      } else {
        DWARFRangeList ranges;
        if (GetAttributeAddressRanges(cu, ranges, /*check_hi_lo_pc*/ false) &&
            ranges.FindEntryThatContains(address)) {
          found_address = true;
          //  puts("***MATCH***");
          switch (m_tag) {
          case DW_TAG_compile_unit: // File
          case DW_TAG_partial_unit: // File
              check_children =
                  ((function_die != nullptr) || (block_die != nullptr));
              break;

          case DW_TAG_subprogram: // Function
            if (function_die)
              *function_die = this;
            check_children = (block_die != nullptr);
            break;

          case DW_TAG_inlined_subroutine: // Inlined Function
          case DW_TAG_lexical_block:      // Block { } in code
            if (block_die) {
              *block_die = this;
              check_children = true;
            }
            break;

          default:
            check_children = true;
            break;
          }
        } else {
          check_children = false;
        }
      }
    }

    if (check_children) {
      //  printf("checking children\n");
      DWARFDebugInfoEntry *child = GetFirstChild();
      while (child) {
        if (child->LookupAddress(address, cu, function_die, block_die))
          return true;
        child = child->GetSibling();
      }
    }
  }
  return found_address;
}

lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const {
  return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
}

const DWARFAbbreviationDeclaration *
DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const {
  if (cu) {
    const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
    if (abbrev_set)
      return abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
  }
  return nullptr;
}

bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const {
  return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx &&
         m_sibling_idx == rhs.m_sibling_idx &&
         m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children &&
         m_tag == rhs.m_tag;
}

bool DWARFDebugInfoEntry::operator!=(const DWARFDebugInfoEntry &rhs) const {
  return !(*this == rhs);
}
