diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp')
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 1097 |
1 files changed, 247 insertions, 850 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 7531aeac709a..2f55b7d40ed9 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -1,9 +1,8 @@ //===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -13,19 +12,21 @@ #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 "DWARFUnit.h" -#include "DWARFDIECollection.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" @@ -33,14 +34,15 @@ using namespace lldb_private; using namespace std; extern int g_verbose; -bool DWARFDebugInfoEntry::FastExtract( - const DWARFDataExtractor &debug_info_data, const DWARFUnit *cu, - const DWARFFormValue::FixedFormSizes &fixed_form_sizes, - lldb::offset_t *offset_ptr) { +// 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 = debug_info_data.GetULEB128(offset_ptr); + const uint64_t abbr_idx = data.GetULEB128(offset_ptr); lldbassert(abbr_idx <= UINT16_MAX); m_abbr_idx = abbr_idx; @@ -49,12 +51,9 @@ bool DWARFDebugInfoEntry::FastExtract( if (m_abbr_idx) { lldb::offset_t offset = *offset_ptr; - - const DWARFAbbreviationDeclaration *abbrevDecl = - cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx); - - if (abbrevDecl == NULL) { - cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError( + 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); @@ -64,16 +63,16 @@ bool DWARFDebugInfoEntry::FastExtract( } m_tag = abbrevDecl->Tag(); m_has_children = abbrevDecl->HasChildren(); - // Skip all data in the .debug_info for the attributes + // 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); - - const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); + llvm::Optional<uint8_t> fixed_skip_size = + DWARFFormValue::GetFixedSize(form, cu); if (fixed_skip_size) - offset += fixed_skip_size; + offset += *fixed_skip_size; else { bool form_is_indirect = false; do { @@ -81,24 +80,24 @@ bool DWARFDebugInfoEntry::FastExtract( 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 + // inlined in the .debug_info/.debug_types case DW_FORM_exprloc: case DW_FORM_block: - form_size = debug_info_data.GetULEB128(&offset); + form_size = data.GetULEB128(&offset); break; case DW_FORM_block1: - form_size = debug_info_data.GetU8_unchecked(&offset); + form_size = data.GetU8_unchecked(&offset); break; case DW_FORM_block2: - form_size = debug_info_data.GetU16_unchecked(&offset); + form_size = data.GetU16_unchecked(&offset); break; case DW_FORM_block4: - form_size = debug_info_data.GetU32_unchecked(&offset); + form_size = data.GetU32_unchecked(&offset); break; // Inlined NULL terminated C-strings case DW_FORM_string: - debug_info_data.GetCStr(&offset); + data.GetCStr(&offset); break; // Compile unit address sized values @@ -109,7 +108,7 @@ bool DWARFDebugInfoEntry::FastExtract( if (cu->GetVersion() <= 2) form_size = cu->GetAddressByteSize(); else - form_size = cu->IsDWARF64() ? 8 : 4; + form_size = 4; break; // 0 sized form @@ -164,20 +163,17 @@ bool DWARFDebugInfoEntry::FastExtract( case DW_FORM_GNU_addr_index: case DW_FORM_GNU_str_index: case DW_FORM_strx: - debug_info_data.Skip_LEB128(&offset); + data.Skip_LEB128(&offset); break; case DW_FORM_indirect: form_is_indirect = true; - form = debug_info_data.GetULEB128(&offset); + form = data.GetULEB128(&offset); break; case DW_FORM_strp: case DW_FORM_sec_offset: - if (cu->IsDWARF64()) - debug_info_data.GetU64(&offset); - else - debug_info_data.GetU32(&offset); + data.GetU32(&offset); break; case DW_FORM_implicit_const: @@ -204,233 +200,48 @@ bool DWARFDebugInfoEntry::FastExtract( return false; } -//---------------------------------------------------------------------- -// Extract -// -// Extract a debug info entry for a given compile unit from the .debug_info and -// .debug_abbrev data within the SymbolFileDWARF class starting at the given -// offset -//---------------------------------------------------------------------- -bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, - const DWARFUnit *cu, - lldb::offset_t *offset_ptr) { - const DWARFDataExtractor &debug_info_data = cu->GetData(); - // const DWARFDataExtractor& debug_str_data = - // dwarf2Data->get_debug_str_data(); - const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset(); - lldb::offset_t offset = *offset_ptr; - // if (offset >= cu_end_offset) - // Log::Status("DIE at offset 0x%8.8x is beyond the end of the current - // compile unit (0x%8.8x)", m_offset, cu_end_offset); - if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) { - m_offset = offset; - - const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset); - lldbassert(abbr_idx <= UINT16_MAX); - m_abbr_idx = abbr_idx; - if (abbr_idx) { - const DWARFAbbreviationDeclaration *abbrevDecl = - cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx); - - if (abbrevDecl) { - m_tag = abbrevDecl->Tag(); - m_has_children = abbrevDecl->HasChildren(); - - bool isCompileUnitTag = (m_tag == DW_TAG_compile_unit || - m_tag == DW_TAG_partial_unit); - if (cu && isCompileUnitTag) - const_cast<DWARFUnit *>(cu)->SetBaseAddress(0); - - // Skip all data in the .debug_info 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); - dw_form_t form = form_value.Form(); - - if (isCompileUnitTag && - ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { - if (form_value.ExtractValue(debug_info_data, &offset)) { - if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) - const_cast<DWARFUnit *>(cu)->SetBaseAddress( - form_value.Address()); - } - } 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 - case DW_FORM_exprloc: - case DW_FORM_block: - form_size = debug_info_data.GetULEB128(&offset); - break; - case DW_FORM_block1: - form_size = debug_info_data.GetU8(&offset); - break; - case DW_FORM_block2: - form_size = debug_info_data.GetU16(&offset); - break; - case DW_FORM_block4: - form_size = debug_info_data.GetU32(&offset); - break; - - // Inlined NULL terminated C-strings - case DW_FORM_string: - debug_info_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 = cu->IsDWARF64() ? 8 : 4; - break; - - // 0 sized form - case DW_FORM_flag_present: - case DW_FORM_implicit_const: - form_size = 0; - break; - - // 1 byte values - case DW_FORM_data1: - case DW_FORM_flag: - case DW_FORM_ref1: - form_size = 1; - break; - - // 2 byte values - case DW_FORM_data2: - case DW_FORM_ref2: - form_size = 2; - break; - - // 4 byte values - case DW_FORM_data4: - case DW_FORM_ref4: - 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_sdata: - case DW_FORM_udata: - case DW_FORM_ref_udata: - case DW_FORM_GNU_addr_index: - case DW_FORM_GNU_str_index: - debug_info_data.Skip_LEB128(&offset); - break; - - case DW_FORM_indirect: - form = debug_info_data.GetULEB128(&offset); - form_is_indirect = true; - break; - - case DW_FORM_strp: - case DW_FORM_sec_offset: - if (cu->IsDWARF64()) - debug_info_data.GetU64(&offset); - else - debug_info_data.GetU32(&offset); - break; - - default: - *offset_ptr = offset; - return false; - } - - offset += form_size; - } while (form_is_indirect); - } - } - *offset_ptr = offset; - return true; - } - } else { - m_tag = 0; - m_has_children = false; - *offset_ptr = offset; - return true; // NULL debug tag entry - } - } - - return false; -} - -//---------------------------------------------------------------------- -// DumpAncestry -// -// Dumps all of a debug information entries parents up until oldest and all of -// it's attributes to the specified stream. -//---------------------------------------------------------------------- -void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data, - const DWARFUnit *cu, - const DWARFDebugInfoEntry *oldest, - Stream &s, - uint32_t recurse_depth) const { - const DWARFDebugInfoEntry *parent = GetParent(); - if (parent && parent != oldest) - parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0); - Dump(dwarf2Data, cu, s, recurse_depth); +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(); } -static dw_offset_t GetRangesOffset(const DWARFDebugRangesBase *debug_ranges, - DWARFFormValue &form_value) { - if (form_value.Form() == DW_FORM_rnglistx) - return debug_ranges->GetOffset(form_value.Unsigned()); - return form_value.Unsigned(); -} - -//---------------------------------------------------------------------- // 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( - SymbolFileDWARF *dwarf2Data, 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 { - if (dwarf2Data == nullptr) - return false; - - SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile(); - if (dwo_symbol_file) - return GetDIENamesAndRanges( - dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), name, mangled, - ranges, decl_file, decl_line, decl_column, call_file, call_line, - call_column, frame_base); - + 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<DIERef> die_refs; + std::vector<DWARFDIE> dies; bool set_frame_base_loclist_addr = false; - lldb::offset_t offset; - const DWARFAbbreviationDeclaration *abbrevDecl = - GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); + const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); - lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule(); + SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF(); + lldb::ModuleSP module = dwarf.GetObjectFile()->GetModule(); if (abbrevDecl) { - const DWARFDataExtractor &debug_info_data = cu->GetData(); + const DWARFDataExtractor &data = cu->GetData(); + lldb::offset_t offset = GetFirstAttributeOffset(); - if (!debug_info_data.ValidOffset(offset)) + if (!data.ValidOffset(offset)) return false; const uint32_t numAttributes = abbrevDecl->NumAttributes(); @@ -441,7 +252,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( dw_attr_t attr; abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); - if (form_value.ExtractValue(debug_info_data, &offset)) { + if (form_value.ExtractValue(data, &offset)) { switch (attr) { case DW_AT_low_pc: lo_pc = form_value.Address(); @@ -457,6 +268,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( 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 { @@ -469,35 +281,27 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( } break; - case DW_AT_ranges: { - const DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges(); - if (debug_ranges) - debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), ranges); - else - cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError( - "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 - ") attribute yet DWARF has no .debug_ranges, please file a bug " - "and attach the file at the start of this error message", - m_offset, form_value.Unsigned()); - } break; + case DW_AT_ranges: + ranges = GetRangesOrReportError(*cu, *this, form_value); + break; case DW_AT_name: - if (name == NULL) + if (name == nullptr) name = form_value.AsCString(); break; case DW_AT_MIPS_linkage_name: case DW_AT_linkage_name: - if (mangled == NULL) + if (mangled == nullptr) mangled = form_value.AsCString(); break; case DW_AT_abstract_origin: - die_refs.emplace_back(form_value); + dies.push_back(form_value.Reference()); break; case DW_AT_specification: - die_refs.emplace_back(form_value); + dies.push_back(form_value.Reference()); break; case DW_AT_decl_file: @@ -534,20 +338,20 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( if (frame_base) { if (form_value.BlockData()) { uint32_t block_offset = - form_value.BlockData() - debug_info_data.GetDataStart(); + form_value.BlockData() - data.GetDataStart(); uint32_t block_length = form_value.Unsigned(); - frame_base->SetOpcodeData(module, debug_info_data, block_offset, - block_length); + *frame_base = DWARFExpression(module, data, cu, + block_offset, block_length); } else { - const DWARFDataExtractor &debug_loc_data = - dwarf2Data->DebugLocData(); + 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->SetOpcodeData(module, debug_loc_data, - debug_loc_offset, loc_list_length); + *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 - @@ -582,56 +386,48 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress()); } - if (ranges.IsEmpty() || name == NULL || mangled == NULL) { - for (const DIERef &die_ref : die_refs) { - if (die_ref.die_offset != DW_INVALID_OFFSET) { - DWARFDIE die = dwarf2Data->GetDIE(die_ref); - if (die) - die.GetDIE()->GetDIENamesAndRanges( - die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file, - decl_line, decl_column, call_file, call_line, call_column); + 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(SymbolFileDWARF *dwarf2Data, - const DWARFUnit *cu, Stream &s, +void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s, uint32_t recurse_depth) const { - const DWARFDataExtractor &debug_info_data = cu->GetData(); + const DWARFDataExtractor &data = cu->GetData(); lldb::offset_t offset = m_offset; - if (debug_info_data.ValidOffset(offset)) { - dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&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 DWARFAbbreviationDeclaration *abbrevDecl = - cu->GetAbbreviations()->GetAbbreviationDeclaration(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 for the attributes + // 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(dwarf2Data, cu, debug_info_data, &offset, s, attr, - form_value); + DumpAttribute(cu, data, &offset, s, attr, form_value); } const DWARFDebugInfoEntry *child = GetFirstChild(); @@ -639,7 +435,7 @@ void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data, s.IndentMore(); while (child) { - child->Dump(dwarf2Data, cu, s, recurse_depth - 1); + child->Dump(cu, s, recurse_depth - 1); child = child->GetSibling(); } s.IndentLess(); @@ -654,34 +450,15 @@ void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data, } } -void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data, - DWARFUnit *cu, Stream &s) const { - const DWARFBaseDIE cu_die = cu->GetUnitDIEOnly(); - const char *cu_name = NULL; - if (cu_die) - cu_name = cu_die.GetName(); - const char *obj_file_name = NULL; - ObjectFile *obj_file = dwarf2Data->GetObjectFile(); - if (obj_file) - obj_file_name = - obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"); - const char *die_name = GetName(dwarf2Data, cu); - s.Printf("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", cu->GetOffset(), - GetOffset(), die_name ? die_name : "", cu_name ? cu_name : "<NULL>", - obj_file_name ? obj_file_name : "<NULL>"); -} - -//---------------------------------------------------------------------- // 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( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr, - Stream &s, dw_attr_t attr, DWARFFormValue &form_value) { + 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(" "); @@ -691,7 +468,7 @@ void DWARFDebugInfoEntry::DumpAttribute( s.Printf("[%s", DW_FORM_value_to_name(form_value.Form())); } - if (!form_value.ExtractValue(debug_info_data, offset_ptr)) + if (!form_value.ExtractValue(data, offset_ptr)) return; if (show_form) { @@ -704,6 +481,8 @@ void DWARFDebugInfoEntry::DumpAttribute( s.PutCString("( "); + SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF(); + // Check to see if we have any special attribute formatters switch (attr) { case DW_AT_stmt_list: @@ -724,7 +503,7 @@ void DWARFDebugInfoEntry::DumpAttribute( const uint8_t *blockData = form_value.BlockData(); if (blockData) { // Location description is inlined in data in the form value - DWARFDataExtractor locationData(debug_info_data, + DWARFDataExtractor locationData(data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned()); DWARFExpression::PrintDWARFExpression( @@ -733,38 +512,26 @@ void DWARFDebugInfoEntry::DumpAttribute( // 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(); - if (dwarf2Data) { - DWARFExpression::PrintDWARFLocationList( - s, cu, dwarf2Data->DebugLocData(), debug_loc_offset); - } + DWARFExpression::PrintDWARFLocationList(s, cu, dwarf.DebugLocData(), + debug_loc_offset); } } break; case DW_AT_abstract_origin: case DW_AT_specification: { - uint64_t abstract_die_offset = form_value.Reference(); + DWARFDIE abstract_die = form_value.Reference(); form_value.Dump(s); - // *ostrm_ptr << HEX32 << abstract_die_offset << " ( "; - GetName(dwarf2Data, cu, abstract_die_offset, s); + // *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( "; + abstract_die.GetName(s); } break; case DW_AT_type: { - uint64_t type_die_offset = form_value.Reference(); + DWARFDIE type_die = form_value.Reference(); s.PutCString(" ( "); - AppendTypeName(dwarf2Data, cu, type_die_offset, s); + type_die.AppendTypeName(s); s.PutCString(" )"); } break; - case DW_AT_ranges: { - if (!dwarf2Data) - break; - lldb::offset_t ranges_offset = - GetRangesOffset(dwarf2Data->DebugRanges(), form_value); - dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; - DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), - &ranges_offset, base_addr); - } break; - default: break; } @@ -772,36 +539,17 @@ void DWARFDebugInfoEntry::DumpAttribute( 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, DWARFFormValue::FixedFormSizes fixed_form_sizes, - DWARFAttributes &attributes, uint32_t curr_depth) const { - SymbolFileDWARF *dwarf2Data = nullptr; - const DWARFAbbreviationDeclaration *abbrevDecl = nullptr; - lldb::offset_t offset = 0; - if (cu) { - if (m_tag != DW_TAG_compile_unit && m_tag != DW_TAG_partial_unit) { - SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile(); - if (dwo_symbol_file) - return GetAttributes(dwo_symbol_file->GetCompileUnit(), - fixed_form_sizes, attributes, curr_depth); - } - - dwarf2Data = cu->GetSymbolFileDWARF(); - abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); - } - + const DWARFUnit *cu, DWARFAttributes &attributes, + uint32_t curr_depth) const { + const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); if (abbrevDecl) { - const DWARFDataExtractor &debug_info_data = cu->GetData(); - - if (fixed_form_sizes.Empty()) - fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize( - cu->GetAddressByteSize(), cu->IsDWARF64()); + 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) { @@ -829,19 +577,17 @@ size_t DWARFDebugInfoEntry::GetAttributes( } if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) { - if (form_value.ExtractValue(debug_info_data, &offset)) { - dw_offset_t die_offset = form_value.Reference(); - DWARFDIE spec_die = - const_cast<DWARFUnit *>(cu)->GetDIE(die_offset); + if (form_value.ExtractValue(data, &offset)) { + DWARFDIE spec_die = form_value.Reference(); if (spec_die) spec_die.GetAttributes(attributes, curr_depth + 1); } } else { - const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); + llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu); if (fixed_skip_size) - offset += fixed_skip_size; + offset += *fixed_skip_size; else - DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu); + DWARFFormValue::SkipValue(form, data, &offset, cu); } } } else { @@ -850,45 +596,32 @@ size_t DWARFDebugInfoEntry::GetAttributes( return attributes.Size(); } -//---------------------------------------------------------------------- // GetAttributeValue // -// Get the value of an attribute and return the .debug_info 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). -//---------------------------------------------------------------------- +// 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( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - const dw_attr_t attr, DWARFFormValue &form_value, + 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 { - SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile(); - if (dwo_symbol_file && m_tag != DW_TAG_compile_unit && - m_tag != DW_TAG_partial_unit) - return GetAttributeValue(dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), - attr, form_value, end_attr_offset_ptr, - check_specification_or_abstract_origin); - - lldb::offset_t offset; - const DWARFAbbreviationDeclaration *abbrevDecl = - GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); - - if (abbrevDecl) { + if (const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu)) { uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); if (attr_idx != DW_INVALID_INDEX) { - const DWARFDataExtractor &debug_info_data = cu->GetData(); + const DWARFDataExtractor &data = cu->GetData(); + lldb::offset_t offset = GetFirstAttributeOffset(); uint32_t idx = 0; while (idx < attr_idx) DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), - debug_info_data, &offset, cu); + data, &offset, cu); const dw_offset_t attr_offset = offset; - form_value.SetCompileUnit(cu); + form_value.SetUnit(cu); form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); - if (form_value.ExtractValue(debug_info_data, &offset)) { + if (form_value.ExtractValue(data, &offset)) { if (end_attr_offset_ptr) *end_attr_offset_ptr = offset; return attr_offset; @@ -897,35 +630,35 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue( } if (check_specification_or_abstract_origin) { - if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) { - DWARFDIE die = - const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference()); + if (GetAttributeValue(cu, DW_AT_specification, form_value)) { + DWARFDIE die = form_value.Reference(); if (die) { dw_offset_t die_offset = die.GetDIE()->GetAttributeValue( - die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr, - false); + die.GetCU(), attr, form_value, end_attr_offset_ptr, false); if (die_offset) return die_offset; } } - if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) { - DWARFDIE die = - const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference()); + 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.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr, - false); + 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; - DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); + DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); if (!dwo_cu) return 0; @@ -934,105 +667,78 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue( return 0; return dwo_cu_die.GetDIE()->GetAttributeValue( - dwo_symbol_file, dwo_cu, attr, form_value, end_attr_offset_ptr, + 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( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - const dw_attr_t attr, const char *fail_value, + const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value, bool check_specification_or_abstract_origin) const { DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, + 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( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - const dw_attr_t attr, uint64_t fail_value, + const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin) const { DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, + if (GetAttributeValue(cu, attr, form_value, nullptr, check_specification_or_abstract_origin)) return form_value.Unsigned(); return fail_value; } -//---------------------------------------------------------------------- -// GetAttributeValueAsSigned -// -// Get the value of an attribute a signed value and return it. -//---------------------------------------------------------------------- -int64_t DWARFDebugInfoEntry::GetAttributeValueAsSigned( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - const dw_attr_t attr, int64_t fail_value, - bool check_specification_or_abstract_origin) const { - DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, - check_specification_or_abstract_origin)) - return form_value.Signed(); - return fail_value; -} - -//---------------------------------------------------------------------- // GetAttributeValueAsReference // // Get the value of an attribute as reference and fix up and compile unit // relative offsets as needed. -//---------------------------------------------------------------------- -uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - const dw_attr_t attr, uint64_t fail_value, +DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference( + const DWARFUnit *cu, const dw_attr_t attr, bool check_specification_or_abstract_origin) const { DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, + if (GetAttributeValue(cu, attr, form_value, nullptr, check_specification_or_abstract_origin)) return form_value.Reference(); - return fail_value; + return {}; } uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - const dw_attr_t attr, uint64_t fail_value, + const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin) const { DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, + 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( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t lo_pc, - uint64_t fail_value, bool check_specification_or_abstract_origin) const { + const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value, + bool check_specification_or_abstract_origin) const { DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr, + 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_GNU_addr_index) + 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> @@ -1041,22 +747,19 @@ dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC( 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( - SymbolFileDWARF *dwarf2Data, 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(dwarf2Data, cu, DW_AT_low_pc, fail_value, + 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(dwarf2Data, cu, lo_pc, fail_value, + hi_pc = GetAttributeHighPC(cu, lo_pc, fail_value, check_specification_or_abstract_origin); if (hi_pc != fail_value) return true; @@ -1067,21 +770,17 @@ bool DWARFDebugInfoEntry::GetAttributeAddressRange( } size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - DWARFRangeList &ranges, bool check_hi_lo_pc, + const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc, bool check_specification_or_abstract_origin) const { ranges.Clear(); DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) { - if (DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges()) - debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), - ranges); + 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(dwarf2Data, cu, lo_pc, 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)); @@ -1090,250 +789,67 @@ size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( 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(SymbolFileDWARF *dwarf2Data, - const DWARFUnit *cu) const { - return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); +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(SymbolFileDWARF *dwarf2Data, - const DWARFUnit *cu, +DWARFDebugInfoEntry::GetMangledName(const DWARFUnit *cu, bool substitute_name_allowed) const { const char *name = nullptr; - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, - nullptr, true); + name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true); if (name) return name; - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, - true); + name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true); if (name) return name; if (!substitute_name_allowed) return nullptr; - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); + 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(SymbolFileDWARF *dwarf2Data, - const DWARFUnit *cu) const { +const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const { const char *name = nullptr; - if (!dwarf2Data) + if (!cu) return name; - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, - nullptr, true); + name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true); if (name) return name; - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, - true); + name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true); if (name) return name; - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); + name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true); return name; } -//---------------------------------------------------------------------- -// GetName -// -// Get value of the DW_AT_name attribute for a debug information entry that -// exists at offset "die_offset" and place that value into the supplied stream -// object. If the DIE is a NULL object "NULL" is placed into the stream, and if -// no DW_AT_name attribute exists for the DIE then nothing is printed. -//---------------------------------------------------------------------- -bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data, - const DWARFUnit *cu, - const dw_offset_t die_offset, Stream &s) { - if (dwarf2Data == NULL) { - s.PutCString("NULL"); - return false; - } - - DWARFDebugInfoEntry die; - lldb::offset_t offset = die_offset; - if (die.Extract(dwarf2Data, cu, &offset)) { - if (die.IsNULL()) { - s.PutCString("NULL"); - return true; - } else { - const char *name = die.GetAttributeValueAsString( - dwarf2Data, cu, DW_AT_name, nullptr, true); - if (name) { - s.PutCString(name); - return true; - } - } - } - return false; -} - -//---------------------------------------------------------------------- -// AppendTypeName -// -// Follows the type name definition down through all needed tags to end up with -// a fully qualified type name and dump the results to the supplied stream. -// This is used to show the name of types given a type identifier. -//---------------------------------------------------------------------- -bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data, - const DWARFUnit *cu, - const dw_offset_t die_offset, - Stream &s) { - if (dwarf2Data == NULL) { - s.PutCString("NULL"); - return false; - } - - DWARFDebugInfoEntry die; - lldb::offset_t offset = die_offset; - if (die.Extract(dwarf2Data, cu, &offset)) { - if (die.IsNULL()) { - s.PutCString("NULL"); - return true; - } else { - const char *name = die.GetPubname(dwarf2Data, cu); - if (name) - s.PutCString(name); - else { - bool result = true; - const DWARFAbbreviationDeclaration *abbrevDecl = - die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); - - if (abbrevDecl == NULL) - return false; - - switch (abbrevDecl->Tag()) { - case DW_TAG_array_type: - break; // print out a "[]" after printing the full type of the element - // below - case DW_TAG_base_type: - s.PutCString("base "); - break; - case DW_TAG_class_type: - s.PutCString("class "); - break; - case DW_TAG_const_type: - s.PutCString("const "); - break; - case DW_TAG_enumeration_type: - s.PutCString("enum "); - break; - case DW_TAG_file_type: - s.PutCString("file "); - break; - case DW_TAG_interface_type: - s.PutCString("interface "); - break; - case DW_TAG_packed_type: - s.PutCString("packed "); - break; - case DW_TAG_pointer_type: - break; // print out a '*' after printing the full type below - case DW_TAG_ptr_to_member_type: - break; // print out a '*' after printing the full type below - case DW_TAG_reference_type: - break; // print out a '&' after printing the full type below - case DW_TAG_restrict_type: - s.PutCString("restrict "); - break; - case DW_TAG_set_type: - s.PutCString("set "); - break; - case DW_TAG_shared_type: - s.PutCString("shared "); - break; - case DW_TAG_string_type: - s.PutCString("string "); - break; - case DW_TAG_structure_type: - s.PutCString("struct "); - break; - case DW_TAG_subrange_type: - s.PutCString("subrange "); - break; - case DW_TAG_subroutine_type: - s.PutCString("function "); - break; - case DW_TAG_thrown_type: - s.PutCString("thrown "); - break; - case DW_TAG_union_type: - s.PutCString("union "); - break; - case DW_TAG_unspecified_type: - s.PutCString("unspecified "); - break; - case DW_TAG_volatile_type: - s.PutCString("volatile "); - break; - default: - return false; - } - - // Follow the DW_AT_type if possible - DWARFFormValue form_value; - if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) { - uint64_t next_die_offset = form_value.Reference(); - result = AppendTypeName(dwarf2Data, cu, next_die_offset, s); - } - - switch (abbrevDecl->Tag()) { - case DW_TAG_array_type: - s.PutCString("[]"); - break; - case DW_TAG_pointer_type: - s.PutChar('*'); - break; - case DW_TAG_ptr_to_member_type: - s.PutChar('*'); - break; - case DW_TAG_reference_type: - s.PutChar('&'); - break; - default: - break; - } - return result; - } - } - } - return false; -} - -//---------------------------------------------------------------------- // BuildAddressRangeTable -//---------------------------------------------------------------------- void DWARFDebugInfoEntry::BuildAddressRangeTable( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - DWARFDebugAranges *debug_aranges) const { + 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(dwarf2Data, cu, lo_pc, 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); @@ -1342,29 +858,25 @@ void DWARFDebugInfoEntry::BuildAddressRangeTable( const DWARFDebugInfoEntry *child = GetFirstChild(); while (child) { - child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges); + 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( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - DWARFDebugAranges *debug_aranges) const { + 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(dwarf2Data, cu, lo_pc, 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); @@ -1373,57 +885,37 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( const DWARFDebugInfoEntry *child = GetFirstChild(); while (child) { - child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges); + child->BuildFunctionAddressRangeTable(cu, debug_aranges); child = child->GetSibling(); } } } -void DWARFDebugInfoEntry::GetDeclContextDIEs( - DWARFUnit *cu, DWARFDIECollection &decl_context_dies) const { - - DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this)); - die.GetDeclContextDIEs(decl_context_dies); -} - void DWARFDebugInfoEntry::GetDWARFDeclContext( - SymbolFileDWARF *dwarf2Data, DWARFUnit *cu, - DWARFDeclContext &dwarf_decl_ctx) const { + 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(dwarf2Data, cu)); - DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu); + 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.GetDWARF(), parent_decl_ctx_die.GetCU(), - dwarf_decl_ctx); + parent_decl_ctx_die.GetCU(), dwarf_decl_ctx); } } } -bool DWARFDebugInfoEntry::MatchesDWARFDeclContext( - SymbolFileDWARF *dwarf2Data, DWARFUnit *cu, - const DWARFDeclContext &dwarf_decl_ctx) const { - - DWARFDeclContext this_dwarf_decl_ctx; - GetDWARFDeclContext(dwarf2Data, cu, this_dwarf_decl_ctx); - return this_dwarf_decl_ctx == dwarf_decl_ctx; -} - DWARFDIE -DWARFDebugInfoEntry::GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data, - DWARFUnit *cu) const { +DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const { DWARFAttributes attributes; - GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes); - return GetParentDeclContextDIE(dwarf2Data, cu, attributes); + GetAttributes(cu, attributes); + return GetParentDeclContextDIE(cu, attributes); } DWARFDIE DWARFDebugInfoEntry::GetParentDeclContextDIE( - SymbolFileDWARF *dwarf2Data, DWARFUnit *cu, - const DWARFAttributes &attributes) const { + DWARFUnit *cu, const DWARFAttributes &attributes) const { DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this)); while (die) { @@ -1445,28 +937,18 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE( } } - dw_offset_t die_offset; - - die_offset = - attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET); - if (die_offset != DW_INVALID_OFFSET) { - DWARFDIE spec_die = cu->GetDIE(die_offset); - if (spec_die) { - DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE(); - if (decl_ctx_die) - return decl_ctx_die; - } + 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; } - die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin, - DW_INVALID_OFFSET); - if (die_offset != DW_INVALID_OFFSET) { - DWARFDIE abs_die = cu->GetDIE(die_offset); - if (abs_die) { - DWARFDIE decl_ctx_die = abs_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(); @@ -1474,22 +956,22 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE( return DWARFDIE(); } -const char *DWARFDebugInfoEntry::GetQualifiedName(SymbolFileDWARF *dwarf2Data, - DWARFUnit *cu, +const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, std::string &storage) const { DWARFAttributes attributes; - GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes); - return GetQualifiedName(dwarf2Data, cu, attributes, storage); + GetAttributes(cu, attributes); + return GetQualifiedName(cu, attributes, storage); } -const char *DWARFDebugInfoEntry::GetQualifiedName( - SymbolFileDWARF *dwarf2Data, DWARFUnit *cu, - const DWARFAttributes &attributes, std::string &storage) const { +const char * +DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, + const DWARFAttributes &attributes, + std::string &storage) const { - const char *name = GetName(dwarf2Data, cu); + const char *name = GetName(cu); if (name) { - DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu); + DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu); storage.clear(); // TODO: change this to get the correct decl context parent.... while (parent_decl_ctx_die) { @@ -1530,15 +1012,11 @@ const char *DWARFDebugInfoEntry::GetQualifiedName( storage.append(name); } if (storage.empty()) - return NULL; + return nullptr; return storage.c_str(); } -//---------------------------------------------------------------------- -// LookupAddress -//---------------------------------------------------------------------- bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, DWARFDebugInfoEntry **function_die, DWARFDebugInfoEntry **block_die) { @@ -1555,13 +1033,9 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, check_children = true; break; case DW_TAG_entry_point: - break; case DW_TAG_enumeration_type: - break; case DW_TAG_formal_parameter: - break; case DW_TAG_imported_declaration: - break; case DW_TAG_label: break; case DW_TAG_lexical_block: @@ -1569,9 +1043,7 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, match_addr_range = true; break; case DW_TAG_member: - break; case DW_TAG_pointer_type: - break; case DW_TAG_reference_type: break; case DW_TAG_compile_unit: @@ -1583,20 +1055,15 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, check_children = true; break; case DW_TAG_subroutine_type: - break; case DW_TAG_typedef: - break; case DW_TAG_union_type: - break; case DW_TAG_unspecified_parameters: - break; case DW_TAG_variant: break; case DW_TAG_common_block: check_children = true; break; case DW_TAG_common_inclusion: - break; case DW_TAG_inheritance: break; case DW_TAG_inlined_subroutine: @@ -1607,86 +1074,62 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, match_addr_range = true; break; case DW_TAG_ptr_to_member_type: - break; case DW_TAG_set_type: - break; case DW_TAG_subrange_type: - break; case DW_TAG_with_stmt: - break; case DW_TAG_access_declaration: - break; case DW_TAG_base_type: break; case DW_TAG_catch_block: match_addr_range = true; break; case DW_TAG_const_type: - break; case DW_TAG_constant: - break; case DW_TAG_enumerator: - break; case DW_TAG_file_type: - break; case DW_TAG_friend: - break; case DW_TAG_namelist: - break; case DW_TAG_namelist_item: - break; case DW_TAG_packed_type: break; case DW_TAG_subprogram: match_addr_range = true; break; case DW_TAG_template_type_parameter: - break; case DW_TAG_template_value_parameter: - break; case DW_TAG_GNU_template_parameter_pack: - break; case DW_TAG_thrown_type: break; case DW_TAG_try_block: match_addr_range = true; break; case DW_TAG_variant_part: - break; case DW_TAG_variable: - break; case DW_TAG_volatile_type: - break; case DW_TAG_dwarf_procedure: - break; case DW_TAG_restrict_type: - break; case DW_TAG_interface_type: break; case DW_TAG_namespace: check_children = true; break; case DW_TAG_imported_module: - break; case DW_TAG_unspecified_type: break; case DW_TAG_partial_unit: match_addr_range = true; break; case DW_TAG_imported_unit: - break; case DW_TAG_shared_type: - break; default: break; } if (match_addr_range) { - dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, - LLDB_INVALID_ADDRESS); + 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(dwarf2Data, cu, 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); @@ -1696,13 +1139,14 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, switch (m_tag) { case DW_TAG_compile_unit: // File case DW_TAG_partial_unit: // File - check_children = ((function_die != NULL) || (block_die != NULL)); + check_children = + ((function_die != nullptr) || (block_die != nullptr)); break; case DW_TAG_subprogram: // Function if (function_die) *function_die = this; - check_children = (block_die != NULL); + check_children = (block_die != nullptr); break; case DW_TAG_inlined_subroutine: // Inlined Function @@ -1722,48 +1166,43 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, // 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 != NULL) || (block_die != NULL)); + check_children = + (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) && + ((function_die != nullptr) || (block_die != nullptr)); } } else { - DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) { - DWARFRangeList ranges; - DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges(); - debug_ranges->FindRanges( - cu, GetRangesOffset(debug_ranges, form_value), ranges); - - if (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 != NULL) || (block_die != NULL)); + 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 != NULL); - 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; + case DW_TAG_subprogram: // Function + if (function_die) + *function_die = this; + check_children = (block_die != nullptr); + break; - default: + 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; } - } else { - check_children = false; + break; + + default: + check_children = true; + break; } + } else { + check_children = false; } } } @@ -1772,8 +1211,7 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, // printf("checking children\n"); DWARFDebugInfoEntry *child = GetFirstChild(); while (child) { - if (child->LookupAddress(address, dwarf2Data, cu, function_die, - block_die)) + if (child->LookupAddress(address, cu, function_die, block_die)) return true; child = child->GetSibling(); } @@ -1782,59 +1220,18 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, return found_address; } -const DWARFAbbreviationDeclaration * -DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - lldb::offset_t &offset) const { - if (dwarf2Data) { - offset = GetOffset(); - - const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations(); - if (abbrev_set) { - const DWARFAbbreviationDeclaration *abbrev_decl = - abbrev_set->GetAbbreviationDeclaration(m_abbr_idx); - if (abbrev_decl) { - // Make sure the abbreviation code still matches. If it doesn't and the - // DWARF data was mmap'ed, the backing file might have been modified - // which is bad news. - const uint64_t abbrev_code = cu->GetData().GetULEB128(&offset); - - if (abbrev_decl->Code() == abbrev_code) - return abbrev_decl; - - dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( - "0x%8.8x: the DWARF debug information has been modified (abbrev " - "code was %u, and is now %u)", - GetOffset(), (uint32_t)abbrev_decl->Code(), (uint32_t)abbrev_code); - } - } - } - offset = DW_INVALID_OFFSET; - return NULL; -} - -bool DWARFDebugInfoEntry::OffsetLessThan(const DWARFDebugInfoEntry &a, - const DWARFDebugInfoEntry &b) { - return a.GetOffset() < b.GetOffset(); +lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const { + return GetOffset() + llvm::getULEB128Size(m_abbr_idx); } -void DWARFDebugInfoEntry::DumpDIECollection( - Stream &strm, DWARFDebugInfoEntry::collection &die_collection) { - DWARFDebugInfoEntry::const_iterator pos; - DWARFDebugInfoEntry::const_iterator end = die_collection.end(); - strm.PutCString("\noffset parent sibling child\n"); - strm.PutCString("-------- -------- -------- --------\n"); - for (pos = die_collection.begin(); pos != end; ++pos) { - const DWARFDebugInfoEntry &die_ref = *pos; - const DWARFDebugInfoEntry *p = die_ref.GetParent(); - const DWARFDebugInfoEntry *s = die_ref.GetSibling(); - const DWARFDebugInfoEntry *c = die_ref.GetFirstChild(); - strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n", die_ref.GetOffset(), - p ? p->GetOffset() : 0, s ? s->GetOffset() : 0, - c ? c->GetOffset() : 0, die_ref.Tag(), - DW_TAG_value_to_name(die_ref.Tag()), - die_ref.HasChildren() ? " *" : ""); +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 { |