diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 3300 |
1 files changed, 1570 insertions, 1730 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index f48d8fc9eeb..ac088c460c6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -19,13 +19,13 @@ #include "lldb/Symbol/ObjectFile.h" #include "DWARFCompileUnit.h" +#include "DWARFDIECollection.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" +#include "DWARFDebugRanges.h" #include "DWARFDeclContext.h" -#include "DWARFDIECollection.h" #include "DWARFFormValue.h" -#include "DWARFDebugRanges.h" #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDwo.h" @@ -33,159 +33,157 @@ using namespace lldb_private; using namespace std; extern int g_verbose; -bool -DWARFDebugInfoEntry::FastExtract -( - const DWARFDataExtractor& debug_info_data, - const DWARFCompileUnit* cu, - const DWARFFormValue::FixedFormSizes& fixed_form_sizes, - lldb::offset_t *offset_ptr -) -{ - m_offset = *offset_ptr; - m_parent_idx = 0; - m_sibling_idx = 0; - m_empty_children = false; - const uint64_t abbr_idx = debug_info_data.GetULEB128 (offset_ptr); - assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); - 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 DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx); - - if (abbrevDecl == NULL) - { - 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 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); +bool DWARFDebugInfoEntry::FastExtract( + const DWARFDataExtractor &debug_info_data, const DWARFCompileUnit *cu, + const DWARFFormValue::FixedFormSizes &fixed_form_sizes, + lldb::offset_t *offset_ptr) { + m_offset = *offset_ptr; + m_parent_idx = 0; + m_sibling_idx = 0; + m_empty_children = false; + const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr); + assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); + 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 uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); - 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 - 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_unchecked (&offset); break; - case DW_FORM_block2 : form_size = debug_info_data.GetU16_unchecked (&offset);break; - case DW_FORM_block4 : form_size = debug_info_data.GetU32_unchecked (&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: - 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_is_indirect = true; - form = debug_info_data.GetULEB128 (&offset); - break; - - case DW_FORM_strp : - case DW_FORM_sec_offset : - if (cu->IsDWARF64 ()) - debug_info_data.GetU64 (offset_ptr); - else - debug_info_data.GetU32 (offset_ptr); - 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 + const DWARFAbbreviationDeclaration *abbrevDecl = + cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx); + + if (abbrevDecl == NULL) { + 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 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); + 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 + 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_unchecked(&offset); + break; + case DW_FORM_block2: + form_size = debug_info_data.GetU16_unchecked(&offset); + break; + case DW_FORM_block4: + form_size = debug_info_data.GetU32_unchecked(&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: + 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_is_indirect = true; + form = debug_info_data.GetULEB128(&offset); + break; + + case DW_FORM_strp: + case DW_FORM_sec_offset: + if (cu->IsDWARF64()) + debug_info_data.GetU64(offset_ptr); + else + debug_info_data.GetU32(offset_ptr); + break; - return false; + 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; } //---------------------------------------------------------------------- @@ -195,165 +193,164 @@ DWARFDebugInfoEntry::FastExtract // .debug_info and .debug_abbrev data within the SymbolFileDWARF class // starting at the given offset //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::Extract -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - lldb::offset_t *offset_ptr -) -{ - const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); -// 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::Error("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); - assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); - 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; - if (cu && isCompileUnitTag) - const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(0); - - // Skip all data in the .debug_info for the attributes - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - for (i=0; i<numAttributes; ++i) - { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); - - if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) - { - DWARFFormValue form_value(cu, form); - if (form_value.ExtractValue(debug_info_data, &offset)) - { - if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) - const_cast<DWARFCompileUnit*>(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: - 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_ptr); - else - debug_info_data.GetU32 (offset_ptr); - break; - - default: - *offset_ptr = offset; - return false; - } - - offset += form_size; - } while (form_is_indirect); - } - } - *offset_ptr = offset; - return true; +bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + lldb::offset_t *offset_ptr) { + const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data(); + // 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::Error("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); + assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); + 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; + if (cu && isCompileUnitTag) + const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(0); + + // Skip all data in the .debug_info for the attributes + const uint32_t numAttributes = abbrevDecl->NumAttributes(); + uint32_t i; + dw_attr_t attr; + dw_form_t form; + for (i = 0; i < numAttributes; ++i) { + abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); + + if (isCompileUnitTag && + ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { + DWARFFormValue form_value(cu, form); + if (form_value.ExtractValue(debug_info_data, &offset)) { + if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) + const_cast<DWARFCompileUnit *>(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: + 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_ptr); + else + debug_info_data.GetU32(offset_ptr); + break; + + default: + *offset_ptr = offset; + return false; + } + + offset += form_size; + } while (form_is_indirect); + } } - else - { - m_tag = 0; - m_has_children = false; - *offset_ptr = offset; - return true; // NULL debug tag entry - } + *offset_ptr = offset; + return true; + } + } else { + m_tag = 0; + m_has_children = false; + *offset_ptr = offset; + return true; // NULL debug tag entry } + } - return false; + return false; } //---------------------------------------------------------------------- @@ -362,20 +359,15 @@ DWARFDebugInfoEntry::Extract // 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 DWARFCompileUnit* 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); +void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *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); } //---------------------------------------------------------------------- @@ -385,238 +377,206 @@ DWARFDebugInfoEntry::DumpAncestry // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges // attributes. //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::GetDIENamesAndRanges -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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); - - dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; - dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; - std::vector<DIERef> die_refs; - bool set_frame_base_loclist_addr = false; - - lldb::offset_t offset; - const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); - - lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule(); - - if (abbrevDecl) - { - const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); - - if (!debug_info_data.ValidOffset(offset)) - return false; - - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - bool do_offset = false; +bool DWARFDebugInfoEntry::GetDIENamesAndRanges( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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; - for (i=0; i<numAttributes; ++i) - { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); - DWARFFormValue form_value(cu, form); - if (form_value.ExtractValue(debug_info_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_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: - { - const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); - if (debug_ranges) - { - debug_ranges->FindRanges(form_value.Unsigned(), ranges); - // All DW_AT_ranges are relative to the base address of the - // compile unit. We add the compile unit base address to make - // sure all the addresses are properly fixed up. - ranges.Slide(cu->GetBaseAddress()); - } - 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_name: - if (name == NULL) - name = form_value.AsCString(); - break; - - case DW_AT_MIPS_linkage_name: - case DW_AT_linkage_name: - if (mangled == NULL) - mangled = form_value.AsCString(); - break; - - case DW_AT_abstract_origin: - die_refs.emplace_back(form_value); - break; - - case DW_AT_specification: - die_refs.emplace_back(form_value); - 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() - debug_info_data.GetDataStart(); - uint32_t block_length = form_value.Unsigned(); - frame_base->SetOpcodeData(module, debug_info_data, block_offset, block_length); - } - else - { - const DWARFDataExtractor &debug_loc_data = dwarf2Data->get_debug_loc_data(); - 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); - 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; + 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); + + dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; + dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; + std::vector<DIERef> die_refs; + bool set_frame_base_loclist_addr = false; + + lldb::offset_t offset; + const DWARFAbbreviationDeclaration *abbrevDecl = + GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); + + lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule(); + + if (abbrevDecl) { + const DWARFDataExtractor &debug_info_data = + dwarf2Data->get_debug_info_data(); + + if (!debug_info_data.ValidOffset(offset)) + return false; + + const uint32_t numAttributes = abbrevDecl->NumAttributes(); + uint32_t i; + dw_attr_t attr; + dw_form_t form; + bool do_offset = false; + + for (i = 0; i < numAttributes; ++i) { + abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); + DWARFFormValue form_value(cu, form); + if (form_value.ExtractValue(debug_info_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_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: { + const DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); + if (debug_ranges) { + debug_ranges->FindRanges(form_value.Unsigned(), ranges); + // All DW_AT_ranges are relative to the base address of the + // compile unit. We add the compile unit base address to make + // sure all the addresses are properly fixed up. + ranges.Slide(cu->GetBaseAddress()); + } 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_name: + if (name == NULL) + name = form_value.AsCString(); + break; + + case DW_AT_MIPS_linkage_name: + case DW_AT_linkage_name: + if (mangled == NULL) + mangled = form_value.AsCString(); + break; + + case DW_AT_abstract_origin: + die_refs.emplace_back(form_value); + break; + + case DW_AT_specification: + die_refs.emplace_back(form_value); + 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() - debug_info_data.GetDataStart(); + uint32_t block_length = form_value.Unsigned(); + frame_base->SetOpcodeData(module, debug_info_data, block_offset, + block_length); + } else { + const DWARFDataExtractor &debug_loc_data = + dwarf2Data->get_debug_loc_data(); + 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); + 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; - 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)); + default: + break; } + } } - - 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()) { + 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 (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 (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 == 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); + } } - return !ranges.IsEmpty(); + } + return !ranges.IsEmpty(); } //---------------------------------------------------------------------- @@ -625,95 +585,74 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges // Dumps a debug information entry and all of it's attributes to the // specified stream. //---------------------------------------------------------------------- -void -DWARFDebugInfoEntry::Dump -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - Stream &s, - uint32_t recurse_depth -) const -{ - const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); - lldb::offset_t offset = m_offset; - - if (debug_info_data.ValidOffset(offset)) - { - dw_uleb128_t abbrCode = debug_info_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); - - 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 - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - for (i=0; i<numAttributes; ++i) - { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); - - DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, form); - } +void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, Stream &s, + uint32_t recurse_depth) const { + const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data(); + lldb::offset_t offset = m_offset; + + if (debug_info_data.ValidOffset(offset)) { + dw_uleb128_t abbrCode = debug_info_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); + + 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 + const uint32_t numAttributes = abbrevDecl->NumAttributes(); + uint32_t i; + dw_attr_t attr; + dw_form_t form; + for (i = 0; i < numAttributes; ++i) { + abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); - const DWARFDebugInfoEntry* child = GetFirstChild(); - if (recurse_depth > 0 && child) - { - s.IndentMore(); - - while (child) - { - child->Dump(dwarf2Data, 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); + DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, + form); } - else - { - s.Printf( "NULL\n"); + + const DWARFDebugInfoEntry *child = GetFirstChild(); + if (recurse_depth > 0 && child) { + s.IndentMore(); + + while (child) { + child->Dump(dwarf2Data, 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"); } + } } -void -DWARFDebugInfoEntry::DumpLocation -( - SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - Stream &s -) const -{ - const DWARFDIE cu_die = cu->GetCompileUnitDIEOnly(); - 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>"); +void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu, Stream &s) const { + const DWARFDIE cu_die = cu->GetCompileUnitDIEOnly(); + 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>"); } //---------------------------------------------------------------------- @@ -723,162 +662,142 @@ DWARFDebugInfoEntry::DumpLocation // special display of attributes is done (disassemble location lists, // show enumeration values for attributes, etc). //---------------------------------------------------------------------- -void -DWARFDebugInfoEntry::DumpAttribute -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const DWARFDataExtractor& debug_info_data, - lldb::offset_t *offset_ptr, - Stream &s, - dw_attr_t attr, - dw_form_t form -) -{ - bool verbose = s.GetVerbose(); - bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); - - if (verbose) - s.Offset (*offset_ptr); - else - s.Printf (" "); - s.Indent(DW_AT_value_to_name(attr)); - - if (show_form) - { - s.Printf( "[%s", DW_FORM_value_to_name(form)); +void DWARFDebugInfoEntry::DumpAttribute( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr, + Stream &s, dw_attr_t attr, dw_form_t form) { + bool verbose = s.GetVerbose(); + bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); + + if (verbose) + s.Offset(*offset_ptr); + else + s.Printf(" "); + s.Indent(DW_AT_value_to_name(attr)); + + if (show_form) { + s.Printf("[%s", DW_FORM_value_to_name(form)); + } + + DWARFFormValue form_value(cu, form); + + if (!form_value.ExtractValue(debug_info_data, offset_ptr)) + return; + + if (show_form) { + if (form == DW_FORM_indirect) { + s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form())); } - DWARFFormValue form_value(cu, form); + s.PutCString("] "); + } - if (!form_value.ExtractValue(debug_info_data, offset_ptr)) - return; + s.PutCString("( "); - if (show_form) - { - if (form == DW_FORM_indirect) - { - s.Printf( " [%s]", DW_FORM_value_to_name(form_value.Form())); - } + // Always dump form value if verbose is enabled + if (verbose) { + form_value.Dump(s); + } - s.PutCString("] "); - } + // Check to see if we have any special attribute formatters + switch (attr) { + case DW_AT_stmt_list: + if (verbose) + s.PutCString(" ( "); + s.Printf("0x%8.8" PRIx64, form_value.Unsigned()); + if (verbose) + s.PutCString(" )"); + break; - s.PutCString("( "); + case DW_AT_language: + if (verbose) + s.PutCString(" ( "); + s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); + if (verbose) + s.PutCString(" )"); + break; - // Always dump form value if verbose is enabled + case DW_AT_encoding: + if (verbose) + s.PutCString(" ( "); + s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); if (verbose) - { + s.PutCString(" )"); + 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) { + if (!verbose) form_value.Dump(s); - } - - - // Check to see if we have any special attribute formatters - switch (attr) - { - case DW_AT_stmt_list: - if ( verbose ) s.PutCString(" ( "); - s.Printf( "0x%8.8" PRIx64, form_value.Unsigned()); - if ( verbose ) s.PutCString(" )"); - break; - - case DW_AT_language: - if ( verbose ) s.PutCString(" ( "); - s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); - if ( verbose ) s.PutCString(" )"); - break; - - case DW_AT_encoding: - if ( verbose ) s.PutCString(" ( "); - s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); - if ( verbose ) s.PutCString(" )"); - 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) - { - if (!verbose) - form_value.Dump(s); - - // Location description is inlined in data in the form value - DWARFDataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned()); - if ( verbose ) s.PutCString(" ( "); - DWARFExpression::PrintDWARFExpression(s, - locationData, - DWARFCompileUnit::GetAddressByteSize(cu), - 4, - false); - if ( verbose ) s.PutCString(" )"); - } - 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(); - if (dwarf2Data) - { - if ( !verbose ) - form_value.Dump(s); - DWARFExpression::PrintDWARFLocationList(s, - cu, - dwarf2Data->get_debug_loc_data(), - debug_loc_offset); - } - else - { - if ( !verbose ) - form_value.Dump(s); - } - } - } - break; - - case DW_AT_abstract_origin: - case DW_AT_specification: - { - uint64_t abstract_die_offset = form_value.Reference(); - form_value.Dump(s); - // *ostrm_ptr << HEX32 << abstract_die_offset << " ( "; - if ( verbose ) s.PutCString(" ( "); - GetName(dwarf2Data, cu, abstract_die_offset, s); - if ( verbose ) s.PutCString(" )"); - } - break; - case DW_AT_type: - { - uint64_t type_die_offset = form_value.Reference(); - if (!verbose) - form_value.Dump(s); - s.PutCString(" ( "); - AppendTypeName(dwarf2Data, cu, type_die_offset, s); - s.PutCString(" )"); - } - break; + // Location description is inlined in data in the form value + DWARFDataExtractor locationData(debug_info_data, + (*offset_ptr) - form_value.Unsigned(), + form_value.Unsigned()); + if (verbose) + s.PutCString(" ( "); + DWARFExpression::PrintDWARFExpression( + s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false); + if (verbose) + s.PutCString(" )"); + } 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(); + if (dwarf2Data) { + if (!verbose) + form_value.Dump(s); + DWARFExpression::PrintDWARFLocationList( + s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset); + } else { + if (!verbose) + form_value.Dump(s); + } + } + } break; - case DW_AT_ranges: - { - if ( !verbose ) - form_value.Dump(s); - lldb::offset_t ranges_offset = form_value.Unsigned(); - dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; - if (dwarf2Data) - DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr); - } - break; + case DW_AT_abstract_origin: + case DW_AT_specification: { + uint64_t abstract_die_offset = form_value.Reference(); + form_value.Dump(s); + // *ostrm_ptr << HEX32 << abstract_die_offset << " ( "; + if (verbose) + s.PutCString(" ( "); + GetName(dwarf2Data, cu, abstract_die_offset, s); + if (verbose) + s.PutCString(" )"); + } break; + + case DW_AT_type: { + uint64_t type_die_offset = form_value.Reference(); + if (!verbose) + form_value.Dump(s); + s.PutCString(" ( "); + AppendTypeName(dwarf2Data, cu, type_die_offset, s); + s.PutCString(" )"); + } break; + + case DW_AT_ranges: { + if (!verbose) + form_value.Dump(s); + lldb::offset_t ranges_offset = form_value.Unsigned(); + dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; + if (dwarf2Data) + DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), + &ranges_offset, base_addr); + } break; - default: - if ( !verbose ) - form_value.Dump(s); - break; - } + default: + if (!verbose) + form_value.Dump(s); + break; + } - s.PutCString(" )\n"); + s.PutCString(" )\n"); } //---------------------------------------------------------------------- @@ -887,94 +806,78 @@ DWARFDebugInfoEntry::DumpAttribute // the results. Any duplicate attributes will have the first instance // take precedence (this can happen for declaration attributes). //---------------------------------------------------------------------- -size_t -DWARFDebugInfoEntry::GetAttributes (const DWARFCompileUnit* 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) - { - 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); +size_t DWARFDebugInfoEntry::GetAttributes( + const DWARFCompileUnit *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) { + SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + return GetAttributes(dwo_symbol_file->GetCompileUnit(), + fixed_form_sizes, attributes, curr_depth); } - if (abbrevDecl) - { - const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); - - if (fixed_form_sizes.Empty()) - fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize( - cu->GetAddressByteSize(), cu->IsDWARF64()); - - const uint32_t num_attributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - for (i=0; i<num_attributes; ++i) - { - abbrevDecl->GetAttrAndFormByIndexUnchecked (i, attr, 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)) - { - DWARFFormValue form_value (cu, form); - if (form_value.ExtractValue(debug_info_data, &offset)) - { - dw_offset_t die_offset = form_value.Reference(); - DWARFDIE spec_die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(die_offset); - if (spec_die) - spec_die.GetAttributes(attributes, curr_depth + 1); - } - } - else - { - const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); - if (fixed_skip_size) - offset += fixed_skip_size; - else - DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu); - } + dwarf2Data = cu->GetSymbolFileDWARF(); + abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); + } + + if (abbrevDecl) { + const DWARFDataExtractor &debug_info_data = + dwarf2Data->get_debug_info_data(); + + if (fixed_form_sizes.Empty()) + fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize( + cu->GetAddressByteSize(), cu->IsDWARF64()); + + const uint32_t num_attributes = abbrevDecl->NumAttributes(); + uint32_t i; + dw_attr_t attr; + dw_form_t form; + for (i = 0; i < num_attributes; ++i) { + abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, 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)) { + DWARFFormValue form_value(cu, form); + if (form_value.ExtractValue(debug_info_data, &offset)) { + dw_offset_t die_offset = form_value.Reference(); + DWARFDIE spec_die = + const_cast<DWARFCompileUnit *>(cu)->GetDIE(die_offset); + if (spec_die) + spec_die.GetAttributes(attributes, curr_depth + 1); + } + } else { + const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); + if (fixed_skip_size) + offset += fixed_skip_size; + else + DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu); + } } - else - { - attributes.Clear(); - } - return attributes.Size(); - + } else { + attributes.Clear(); + } + return attributes.Size(); } //---------------------------------------------------------------------- @@ -985,105 +888,84 @@ DWARFDebugInfoEntry::GetAttributes (const DWARFCompileUnit* cu, // 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 DWARFCompileUnit* 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) - 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) - { - uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); - - if (attr_idx != DW_INVALID_INDEX) - { - const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); - - uint32_t idx=0; - while (idx<attr_idx) - DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu); - - const dw_offset_t attr_offset = offset; - form_value.SetCompileUnit(cu); - form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); - if (form_value.ExtractValue(debug_info_data, &offset)) - { - if (end_attr_offset_ptr) - *end_attr_offset_ptr = offset; - return attr_offset; - } - } +dw_offset_t DWARFDebugInfoEntry::GetAttributeValue( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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) + 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) { + uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); + + if (attr_idx != DW_INVALID_INDEX) { + const DWARFDataExtractor &debug_info_data = + dwarf2Data->get_debug_info_data(); + + uint32_t idx = 0; + while (idx < attr_idx) + DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), + debug_info_data, &offset, cu); + + const dw_offset_t attr_offset = offset; + form_value.SetCompileUnit(cu); + form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); + if (form_value.ExtractValue(debug_info_data, &offset)) { + if (end_attr_offset_ptr) + *end_attr_offset_ptr = offset; + return attr_offset; + } + } + } + + if (check_specification_or_abstract_origin) { + if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) { + DWARFDIE die = + const_cast<DWARFCompileUnit *>(cu)->GetDIE(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); + if (die_offset) + return die_offset; + } } - if (check_specification_or_abstract_origin) - { - if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) - { - DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(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); - if (die_offset) - return die_offset; - } - } - - if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) - { - DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(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); - if (die_offset) - return die_offset; - } - } + if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) { + DWARFDIE die = + const_cast<DWARFCompileUnit *>(cu)->GetDIE(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); + if (die_offset) + return die_offset; + } } + } - if (!dwo_symbol_file) - return 0; + if (!dwo_symbol_file) + return 0; - DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit(); - if (!dwo_cu) - return 0; + DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); + if (!dwo_cu) + return 0; - DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly(); - if (!dwo_cu_die.IsValid()) - return 0; + DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly(); + if (!dwo_cu_die.IsValid()) + return 0; - return dwo_cu_die.GetDIE()->GetAttributeValue(dwo_symbol_file, - dwo_cu, - attr, - form_value, - end_attr_offset_ptr, - check_specification_or_abstract_origin); + return dwo_cu_die.GetDIE()->GetAttributeValue( + dwo_symbol_file, dwo_cu, attr, form_value, end_attr_offset_ptr, + check_specification_or_abstract_origin); } //---------------------------------------------------------------------- @@ -1094,19 +976,15 @@ DWARFDebugInfoEntry::GetAttributeValue // 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 DWARFCompileUnit* 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, check_specification_or_abstract_origin)) - return form_value.AsCString(); - return fail_value; +const char *DWARFDebugInfoEntry::GetAttributeValueAsString( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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, + check_specification_or_abstract_origin)) + return form_value.AsCString(); + return fail_value; } //---------------------------------------------------------------------- @@ -1114,20 +992,15 @@ DWARFDebugInfoEntry::GetAttributeValueAsString // // Get the value of an attribute as unsigned and return it. //---------------------------------------------------------------------- -uint64_t -DWARFDebugInfoEntry::GetAttributeValueAsUnsigned -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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, check_specification_or_abstract_origin)) - return form_value.Unsigned(); - return fail_value; +uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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, + check_specification_or_abstract_origin)) + return form_value.Unsigned(); + return fail_value; } //---------------------------------------------------------------------- @@ -1135,20 +1008,15 @@ DWARFDebugInfoEntry::GetAttributeValueAsUnsigned // // Get the value of an attribute a signed value and return it. //---------------------------------------------------------------------- -int64_t -DWARFDebugInfoEntry::GetAttributeValueAsSigned -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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; +int64_t DWARFDebugInfoEntry::GetAttributeValueAsSigned( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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; } //---------------------------------------------------------------------- @@ -1157,36 +1025,26 @@ DWARFDebugInfoEntry::GetAttributeValueAsSigned // 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 DWARFCompileUnit* 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, check_specification_or_abstract_origin)) - return form_value.Reference(); - return fail_value; +uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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, + check_specification_or_abstract_origin)) + return form_value.Reference(); + return fail_value; } -uint64_t -DWARFDebugInfoEntry::GetAttributeValueAsAddress -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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, check_specification_or_abstract_origin)) - return form_value.Address(); - return fail_value; +uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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, + check_specification_or_abstract_origin)) + return form_value.Address(); + return fail_value; } //---------------------------------------------------------------------- @@ -1197,27 +1055,20 @@ DWARFDebugInfoEntry::GetAttributeValueAsAddress // // Returns the hi_pc or fail_value. //---------------------------------------------------------------------- -dw_addr_t -DWARFDebugInfoEntry::GetAttributeHighPC -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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, check_specification_or_abstract_origin)) - { - dw_form_t form = form_value.Form(); - if (form == DW_FORM_addr || 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; +dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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, + check_specification_or_abstract_origin)) { + dw_form_t form = form_value.Form(); + if (form == DW_FORM_addr || 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; } //---------------------------------------------------------------------- @@ -1228,61 +1079,48 @@ DWARFDebugInfoEntry::GetAttributeHighPC // // Returns true or sets lo_pc and hi_pc to fail_value. //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::GetAttributeAddressRange -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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, check_specification_or_abstract_origin); - if (lo_pc != fail_value) - { - hi_pc = GetAttributeHighPC(dwarf2Data, 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; +bool DWARFDebugInfoEntry::GetAttributeAddressRange( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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, + check_specification_or_abstract_origin); + if (lo_pc != fail_value) { + hi_pc = GetAttributeHighPC(dwarf2Data, 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 (SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - DWARFRangeList &ranges, - bool check_hi_lo_pc, - bool check_specification_or_abstract_origin) const -{ - ranges.Clear(); - - dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, - cu, - DW_AT_ranges, - DW_INVALID_OFFSET, - check_specification_or_abstract_origin); - if (debug_ranges_offset != DW_INVALID_OFFSET) - { - DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); - - debug_ranges->FindRanges(debug_ranges_offset, ranges); - ranges.Slide (cu->GetBaseAddress()); - } - 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, check_specification_or_abstract_origin)) - { - if (lo_pc < hi_pc) - ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc)); - } +size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + DWARFRangeList &ranges, bool check_hi_lo_pc, + bool check_specification_or_abstract_origin) const { + ranges.Clear(); + + dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned( + dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET, + check_specification_or_abstract_origin); + if (debug_ranges_offset != DW_INVALID_OFFSET) { + DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); + + debug_ranges->FindRanges(debug_ranges_offset, ranges); + ranges.Slide(cu->GetBaseAddress()); + } 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, + check_specification_or_abstract_origin)) { + if (lo_pc < hi_pc) + ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc)); } - return ranges.GetSize(); + } + return ranges.GetSize(); } //---------------------------------------------------------------------- @@ -1291,14 +1129,9 @@ DWARFDebugInfoEntry::GetAttributeAddressRanges (SymbolFileDWARF* dwarf2Data, // Get value of the DW_AT_name attribute and return it if one exists, // else return NULL. //---------------------------------------------------------------------- -const char* -DWARFDebugInfoEntry::GetName -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu -) const -{ - return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); +const char *DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu) const { + return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); } //---------------------------------------------------------------------- @@ -1307,31 +1140,28 @@ DWARFDebugInfoEntry::GetName // 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 DWARFCompileUnit* cu, - bool substitute_name_allowed -) const -{ - const char* name = nullptr; - - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr, true); - if (name) - return name; - - name = GetAttributeValueAsString(dwarf2Data, 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); +const char * +DWARFDebugInfoEntry::GetMangledName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + bool substitute_name_allowed) const { + const char *name = nullptr; + + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, + nullptr, true); + if (name) return name; -} + name = GetAttributeValueAsString(dwarf2Data, 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); + return name; +} //---------------------------------------------------------------------- // GetPubname @@ -1339,29 +1169,25 @@ DWARFDebugInfoEntry::GetMangledName // 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 DWARFCompileUnit* cu -) const -{ - const char* name = nullptr; - if (!dwarf2Data) - return name; - - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr, true); - if (name) - return name; - - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, true); - if (name) - return name; - - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); +const char *DWARFDebugInfoEntry::GetPubname(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu) const { + const char *name = nullptr; + if (!dwarf2Data) return name; -} + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, + nullptr, true); + if (name) + return name; + + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, + true); + if (name) + return name; + + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); + return name; +} //---------------------------------------------------------------------- // GetName @@ -1372,41 +1198,30 @@ DWARFDebugInfoEntry::GetPubname // into the stream, and if no DW_AT_name attribute exists for the DIE // then nothing is printed. //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::GetName -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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; - } - } - } +bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *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; } //---------------------------------------------------------------------- @@ -1417,144 +1232,168 @@ DWARFDebugInfoEntry::GetName // the supplied stream. This is used to show the name of types given // a type identifier. //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::AppendTypeName -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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; +bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *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; } - 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); - } + // 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; - } + 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; + } + return false; } -bool -DWARFDebugInfoEntry::Contains (const DWARFDebugInfoEntry *die) const -{ - if (die) - { - const dw_offset_t die_offset = die->GetOffset(); - if (die_offset > GetOffset()) - { - const DWARFDebugInfoEntry *sibling = GetSibling(); - assert (sibling); // TODO: take this out - if (sibling) - return die_offset < sibling->GetOffset(); - } +bool DWARFDebugInfoEntry::Contains(const DWARFDebugInfoEntry *die) const { + if (die) { + const dw_offset_t die_offset = die->GetOffset(); + if (die_offset > GetOffset()) { + const DWARFDebugInfoEntry *sibling = GetSibling(); + assert(sibling); // TODO: take this out + if (sibling) + return die_offset < sibling->GetOffset(); } - return false; + } + return false; } //---------------------------------------------------------------------- // BuildAddressRangeTable //---------------------------------------------------------------------- -void -DWARFDebugInfoEntry::BuildAddressRangeTable -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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)) - { - /// 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); - } - } - +void DWARFDebugInfoEntry::BuildAddressRangeTable( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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)) { + /// 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(dwarf2Data, cu, debug_aranges); - child = child->GetSibling(); - } + const DWARFDebugInfoEntry *child = GetFirstChild(); + while (child) { + child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges); + child = child->GetSibling(); } + } } //---------------------------------------------------------------------- @@ -1565,477 +1404,478 @@ DWARFDebugInfoEntry::BuildAddressRangeTable // table instead of the compile unit offset (which is the way the // standard .debug_aranges section does it). //---------------------------------------------------------------------- -void -DWARFDebugInfoEntry::BuildFunctionAddressRangeTable -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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)) - { - // 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); - } - } +void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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)) { + // 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(dwarf2Data, cu, debug_aranges); - child = child->GetSibling(); - } + const DWARFDebugInfoEntry *child = GetFirstChild(); + while (child) { + child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges); + child = child->GetSibling(); } + } } -void -DWARFDebugInfoEntry::GetDeclContextDIEs (DWARFCompileUnit* cu, - DWARFDIECollection &decl_context_dies) const -{ +void DWARFDebugInfoEntry::GetDeclContextDIEs( + DWARFCompileUnit *cu, DWARFDIECollection &decl_context_dies) const { - DWARFDIE die (cu, const_cast<DWARFDebugInfoEntry *>(this)); - die.GetDeclContextDIEs(decl_context_dies); + DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this)); + die.GetDeclContextDIEs(decl_context_dies); } -void -DWARFDebugInfoEntry::GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - DWARFDeclContext &dwarf_decl_ctx) const -{ - const dw_tag_t tag = Tag(); - if (tag != DW_TAG_compile_unit) - { - dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu)); - DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, 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.GetDIE()->GetDWARFDeclContext (parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(), dwarf_decl_ctx); - } +void DWARFDebugInfoEntry::GetDWARFDeclContext( + SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu, + DWARFDeclContext &dwarf_decl_ctx) const { + const dw_tag_t tag = Tag(); + if (tag != DW_TAG_compile_unit) { + dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu)); + DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, 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.GetDIE()->GetDWARFDeclContext( + parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(), + dwarf_decl_ctx); } + } } +bool DWARFDebugInfoEntry::MatchesDWARFDeclContext( + SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu, + const DWARFDeclContext &dwarf_decl_ctx) const { -bool -DWARFDebugInfoEntry::MatchesDWARFDeclContext (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* 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; + 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, - DWARFCompileUnit* cu) const -{ - DWARFAttributes attributes; - GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes); - return GetParentDeclContextDIE (dwarf2Data, cu, attributes); +DWARFDebugInfoEntry::GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu) const { + DWARFAttributes attributes; + GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes); + return GetParentDeclContextDIE(dwarf2Data, cu, attributes); } DWARFDIE -DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* 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_namespace: - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: - return die; - - default: - break; - } - } - - 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; - } - } - - 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; - } - } - - die = die.GetParent(); - } - return DWARFDIE(); -} +DWARFDebugInfoEntry::GetParentDeclContextDIE( + SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *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_namespace: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: + return die; + + default: + break; + } + } + + 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; + } + } + 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; + } + } -const char * -DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - std::string &storage) const -{ - DWARFAttributes attributes; - GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes); - return GetQualifiedName (dwarf2Data, cu, attributes, storage); + die = die.GetParent(); + } + return DWARFDIE(); } -const char* -DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - const DWARFAttributes& attributes, - std::string &storage) const -{ - - const char *name = GetName (dwarf2Data, cu); - - if (name) - { - DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, 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 NULL; - return storage.c_str(); +const char *DWARFDebugInfoEntry::GetQualifiedName(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu, + std::string &storage) const { + DWARFAttributes attributes; + GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes); + return GetQualifiedName(dwarf2Data, cu, attributes, storage); } +const char *DWARFDebugInfoEntry::GetQualifiedName( + SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu, + const DWARFAttributes &attributes, std::string &storage) const { + + const char *name = GetName(dwarf2Data, cu); + + if (name) { + DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, 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 NULL; + return storage.c_str(); +} //---------------------------------------------------------------------- // LookupAddress //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::LookupAddress -( - const dw_addr_t address, - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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 : 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 : check_children = true; 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 : 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 : 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 : check_children = true; match_addr_range = true; break; - case DW_TAG_module : 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_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 : 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); - if (lo_pc != LLDB_INVALID_ADDRESS) - { - dw_addr_t hi_pc = GetAttributeHighPC(dwarf2Data, 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 - check_children = ((function_die != NULL) || (block_die != NULL)); - 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; - - 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) && ((function_die != NULL) || (block_die != NULL)); - } - } - else - { - dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); - if (debug_ranges_offset != DW_INVALID_OFFSET) - { - DWARFRangeList ranges; - DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); - debug_ranges->FindRanges(debug_ranges_offset, ranges); - // All DW_AT_ranges are relative to the base address of the - // compile unit. We add the compile unit base address to make - // sure all the addresses are properly fixed up. - ranges.Slide (cu->GetBaseAddress()); - if (ranges.FindEntryThatContains(address)) - { - found_address = true; - // puts("***MATCH***"); - switch (m_tag) - { - case DW_TAG_compile_unit: // File - check_children = ((function_die != NULL) || (block_die != NULL)); - 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; - - default: - check_children = true; - break; - } - } - else - { - check_children = false; - } - } - } - } +bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, + SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *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: + 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: + check_children = true; + 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: + 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: + 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: + check_children = true; + match_addr_range = true; + break; + case DW_TAG_module: + 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_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: + 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); + if (lo_pc != LLDB_INVALID_ADDRESS) { + dw_addr_t hi_pc = + GetAttributeHighPC(dwarf2Data, 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 + check_children = ((function_die != NULL) || (block_die != NULL)); + 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; - if (check_children) - { - // printf("checking children\n"); - DWARFDebugInfoEntry* child = GetFirstChild(); - while (child) - { - if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die)) - return true; - child = child->GetSibling(); + 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) && + ((function_die != NULL) || (block_die != NULL)); } - } - return found_address; -} + } else { + dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned( + dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); + if (debug_ranges_offset != DW_INVALID_OFFSET) { + DWARFRangeList ranges; + DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); + debug_ranges->FindRanges(debug_ranges_offset, ranges); + // All DW_AT_ranges are relative to the base address of the + // compile unit. We add the compile unit base address to make + // sure all the addresses are properly fixed up. + ranges.Slide(cu->GetBaseAddress()); + if (ranges.FindEntryThatContains(address)) { + found_address = true; + // puts("***MATCH***"); + switch (m_tag) { + case DW_TAG_compile_unit: // File + check_children = ((function_die != NULL) || (block_die != NULL)); + 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; -const DWARFAbbreviationDeclaration* -DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit *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 = dwarf2Data->get_debug_info_data().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); + default: + check_children = true; + break; } + } else { + check_children = false; + } } + } } - offset = DW_INVALID_OFFSET; - return NULL; -} - -bool -DWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b) -{ - return a.GetOffset() < b.GetOffset(); + if (check_children) { + // printf("checking children\n"); + DWARFDebugInfoEntry *child = GetFirstChild(); + while (child) { + if (child->LookupAddress(address, dwarf2Data, cu, function_die, + block_die)) + return true; + child = child->GetSibling(); + } + } + } + return found_address; } -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( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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 = + dwarf2Data->get_debug_info_data().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(); +} +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() ? " *" : ""); + } +} |