Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -11,10 +11,12 @@ #include "SymbolFileDWARF.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Error.h" #include "DWARFAbbreviationDeclaration.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugRanges.h" +#include "DWARFDefines.h" #include #include #include @@ -74,8 +76,9 @@ const DWARFFormValue::FixedFormSizes &fixed_form_sizes, lldb::offset_t *offset_ptr); - bool Extract(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - lldb::offset_t *offset_ptr); + llvm::Expected + extract(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, + lldb::offset_t *offset_ptr); bool LookupAddress(const dw_addr_t address, SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -27,6 +27,8 @@ #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDwo.h" +#include "llvm/Object/Error.h" + using namespace lldb_private; using namespace std; extern int g_verbose; @@ -206,162 +208,165 @@ // .debug_abbrev data within the SymbolFileDWARF class starting at the given // offset //---------------------------------------------------------------------- -bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, - const DWARFUnit *cu, - lldb::offset_t *offset_ptr) { +llvm::Expected +DWARFDebugInfoEntry::extract(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, + lldb::offset_t *offset_ptr) { const DWARFDataExtractor &debug_info_data = cu->GetData(); - // const DWARFDataExtractor& debug_str_data = - // dwarf2Data->get_debug_str_data(); - const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset(); lldb::offset_t offset = *offset_ptr; - // if (offset >= cu_end_offset) - // Log::Status("DIE at offset 0x%8.8x is beyond the end of the current - // compile unit (0x%8.8x)", m_offset, cu_end_offset); - if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) { - m_offset = offset; - - const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset); - lldbassert(abbr_idx <= UINT16_MAX); - m_abbr_idx = abbr_idx; - if (abbr_idx) { - const DWARFAbbreviationDeclaration *abbrevDecl = - cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx); - if (abbrevDecl) { - m_tag = abbrevDecl->Tag(); - m_has_children = abbrevDecl->HasChildren(); + assert(offset < cu->GetNextCompileUnitOffset() && + debug_info_data.ValidOffset(offset)); - bool isCompileUnitTag = (m_tag == DW_TAG_compile_unit || - m_tag == DW_TAG_partial_unit); - if (cu && isCompileUnitTag) - const_cast(cu)->SetBaseAddress(0); + m_offset = offset; - // Skip all data in the .debug_info for the attributes - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - for (uint32_t i = 0; i < numAttributes; ++i) { - DWARFFormValue form_value(cu); - dw_attr_t attr; - abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); - dw_form_t form = form_value.Form(); - - if (isCompileUnitTag && - ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { - if (form_value.ExtractValue(debug_info_data, &offset)) { - if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) - const_cast(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 = 4; - break; - - // 0 sized form - case DW_FORM_flag_present: - case DW_FORM_implicit_const: - form_size = 0; - break; - - // 1 byte values - case DW_FORM_data1: - case DW_FORM_flag: - case DW_FORM_ref1: - form_size = 1; - break; - - // 2 byte values - case DW_FORM_data2: - case DW_FORM_ref2: - form_size = 2; - break; - - // 4 byte values - case DW_FORM_data4: - case DW_FORM_ref4: - form_size = 4; - break; - - // 8 byte values - case DW_FORM_data8: - case DW_FORM_ref8: - case DW_FORM_ref_sig8: - form_size = 8; - break; - - // signed or unsigned LEB 128 values - case DW_FORM_addrx: - 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: - debug_info_data.GetU32(&offset); - break; - - default: - *offset_ptr = offset; - return false; - } + const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset); + if (abbr_idx > UINT16_MAX) + return llvm::make_error( + "Invalid abbreviation index"); - offset += form_size; - } while (form_is_indirect); - } - } - *offset_ptr = offset; - return true; + m_abbr_idx = abbr_idx; + + // NULL debug tag entry + if (abbr_idx == 0) { + m_tag = 0; + m_has_children = false; + *offset_ptr = offset; + return DWARFEnumState::Complete; + } + + const DWARFAbbreviationDeclaration *abbrevDecl = + cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx); + + if (!abbrevDecl) + return llvm::make_error( + "Invalid abbrev index for DIE"); + + m_tag = abbrevDecl->Tag(); + m_has_children = abbrevDecl->HasChildren(); + + bool isCompileUnitTag = + (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit); + + if (cu && isCompileUnitTag) + const_cast(cu)->SetBaseAddress(0); + + // Skip all data in the .debug_info for the attributes + const uint32_t numAttributes = abbrevDecl->NumAttributes(); + for (uint32_t i = 0; i < numAttributes; ++i) { + DWARFFormValue form_value(cu); + dw_attr_t attr; + abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); + dw_form_t form = form_value.Form(); + + if (isCompileUnitTag && + ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { + if (form_value.ExtractValue(debug_info_data, &offset)) { + if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) + const_cast(cu)->SetBaseAddress(form_value.Address()); } - } else { - m_tag = 0; - m_has_children = false; - *offset_ptr = offset; - return true; // NULL debug tag entry + continue; } - } - return false; + 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 = 4; + break; + + // 0 sized form + case DW_FORM_flag_present: + case DW_FORM_implicit_const: + form_size = 0; + break; + + // 1 byte values + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + form_size = 1; + break; + + // 2 byte values + case DW_FORM_data2: + case DW_FORM_ref2: + form_size = 2; + break; + + // 4 byte values + case DW_FORM_data4: + case DW_FORM_ref4: + form_size = 4; + break; + + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + form_size = 8; + break; + + // signed or unsigned LEB 128 values + case DW_FORM_addrx: + 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: + debug_info_data.GetU32(&offset); + break; + + default: + *offset_ptr = offset; + return llvm::make_error( + "Invalid attribute form"); + } + + offset += form_size; + } while (form_is_indirect); + } + *offset_ptr = offset; + return DWARFEnumState::MoreItems; } //---------------------------------------------------------------------- @@ -1162,27 +1167,30 @@ bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_offset_t die_offset, Stream &s) { - if (dwarf2Data == NULL) { - s.PutCString("NULL"); - return false; - } + assert(dwarf2Data); 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; - } - } + auto state = die.extract(dwarf2Data, cu, &offset); + if (!state) { + llvm::consumeError(state.takeError()); + return false; + } else if (*state == DWARFEnumState::Complete) { + return false; } - return false; + + if (die.IsNULL()) { + s.PutCString("NULL"); + return true; + } + + const char *name = + die.GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); + if (!name) + return false; + + s.PutCString(name); + return true; } //---------------------------------------------------------------------- @@ -1196,125 +1204,127 @@ const DWARFUnit *cu, const dw_offset_t die_offset, Stream &s) { - if (dwarf2Data == NULL) { - s.PutCString("NULL"); - return false; - } + assert(dwarf2Data); 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; - } + llvm::Expected state = die.extract(dwarf2Data, cu, &offset); + if (!state) { + llvm::consumeError(state.takeError()); + return false; + } + if (*state == DWARFEnumState::Complete) + 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); - } + if (die.IsNULL()) { + s.PutCString("NULL"); + return true; + } + const char *name = die.GetPubname(dwarf2Data, cu); + if (name) { + s.PutCString(name); + return true; + } - 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; - } - } + const DWARFAbbreviationDeclaration *abbrevDecl = + die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); + + if (!abbrevDecl) + 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; } - return false; + + // Follow the DW_AT_type if possible + DWARFFormValue form_value; + bool result = true; + 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; } //---------------------------------------------------------------------- Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -12,13 +12,15 @@ #include "DWARFDIE.h" #include "SymbolFileDWARF.h" +#include "llvm/Support/Error.h" + #include class DWARFDebugRangesBase { public: virtual ~DWARFDebugRangesBase(){}; - virtual void Extract(SymbolFileDWARF *dwarf2Data) = 0; + virtual llvm::Error extract(SymbolFileDWARF *dwarf2Data) = 0; virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const = 0; virtual uint64_t GetOffset(size_t Index) const = 0; @@ -28,7 +30,7 @@ public: DWARFDebugRanges(); - void Extract(SymbolFileDWARF *dwarf2Data) override; + llvm::Error extract(SymbolFileDWARF *dwarf2Data) override; bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const override; uint64_t GetOffset(size_t Index) const override; @@ -38,8 +40,9 @@ lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr); protected: - bool Extract(SymbolFileDWARF *dwarf2Data, lldb::offset_t *offset_ptr, - DWARFRangeList &range_list); + llvm::Error extractOne(SymbolFileDWARF *dwarf2Data, + lldb::offset_t *offset_ptr, + DWARFRangeList &range_list); typedef std::map range_map; typedef range_map::iterator range_map_iterator; @@ -56,7 +59,7 @@ }; public: - void Extract(SymbolFileDWARF *dwarf2Data) override; + llvm::Error extract(SymbolFileDWARF *dwarf2Data) override; bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const override; uint64_t GetOffset(size_t Index) const override; Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -10,6 +10,7 @@ #include "DWARFUnit.h" #include "SymbolFileDWARF.h" #include "lldb/Utility/Stream.h" +#include "llvm/Object/Error.h" #include using namespace lldb_private; @@ -29,23 +30,33 @@ DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {} -void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) { +llvm::Error DWARFDebugRanges::extract(SymbolFileDWARF *dwarf2Data) { DWARFRangeList range_list; lldb::offset_t offset = 0; dw_offset_t debug_ranges_offset = offset; - while (Extract(dwarf2Data, &offset, range_list)) { + + const DWARFDataExtractor &debug_ranges_data = + dwarf2Data->get_debug_ranges_data(); + + // Consume the entire debug_ranges section. + while (debug_ranges_data.ValidOffset(offset)) { + llvm::Error error = extractOne(dwarf2Data, &offset, range_list); + if (error) + return error; + range_list.Sort(); m_range_map[debug_ranges_offset] = range_list; debug_ranges_offset = offset; } + + return llvm::ErrorSuccess(); } -bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data, - lldb::offset_t *offset_ptr, - DWARFRangeList &range_list) { +llvm::Error DWARFDebugRanges::extractOne(SymbolFileDWARF *dwarf2Data, + lldb::offset_t *offset_ptr, + DWARFRangeList &range_list) { range_list.Clear(); - lldb::offset_t range_offset = *offset_ptr; const DWARFDataExtractor &debug_ranges_data = dwarf2Data->get_debug_ranges_data(); uint32_t addr_size = debug_ranges_data.GetAddressByteSize(); @@ -57,10 +68,8 @@ dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); - if (!begin && !end) { - // End of range list - break; - } + if (!begin && !end) + return llvm::ErrorSuccess(); if (begin == base_addr_marker) { base_addr = end; @@ -72,8 +81,8 @@ range_list.Append(DWARFRangeList::Entry(begin + base_addr, end - begin)); } - // Make sure we consumed at least something - return range_offset != *offset_ptr; + return llvm::make_error( + "range list not terminated by null entry"); } void DWARFDebugRanges::Dump(Stream &s, @@ -255,7 +264,7 @@ return false; } -void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) { +llvm::Error DWARFDebugRngLists::extract(SymbolFileDWARF *dwarf2Data) { const DWARFDataExtractor &data = dwarf2Data->get_debug_rnglists_data(); lldb::offset_t offset = 0; @@ -265,15 +274,15 @@ // Check version. if (data.GetU16(&offset) < 5) - return; + return llvm::make_error( + "Unsupported range list version"); uint8_t addrSize = data.GetU8(&offset); // We do not support non-zero segment selector size. - if (data.GetU8(&offset) != 0) { - lldbassert(0 && "not implemented"); - return; - } + if (data.GetU8(&offset) != 0) + return llvm::make_error( + "Non-zero segment selector size unsupported"); uint32_t offsetsAmount = data.GetU32(&offset); for (uint32_t i = 0; i < offsetsAmount; ++i) @@ -285,6 +294,7 @@ m_range_map[listOffset] = rangeList; listOffset = offset; } + return llvm::ErrorSuccess(); } uint64_t DWARFDebugRngLists::GetOffset(size_t Index) const { Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -723,18 +723,25 @@ } DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() { - if (m_ranges == NULL) { - static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); - Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, - static_cast(this)); + if (m_ranges) + return m_ranges.get(); + + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, + static_cast(this)); - if (get_debug_ranges_data().GetByteSize() > 0) - m_ranges.reset(new DWARFDebugRanges()); - else if (get_debug_rnglists_data().GetByteSize() > 0) - m_ranges.reset(new DWARFDebugRngLists()); + if (get_debug_ranges_data().GetByteSize() > 0) + m_ranges = llvm::make_unique(); + else if (get_debug_rnglists_data().GetByteSize() > 0) + m_ranges = llvm::make_unique(); + else + return nullptr; - if (m_ranges) - m_ranges->Extract(this); + auto error = m_ranges->extract(this); + if (error) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + LLDB_LOG_ERROR(log, std::move(error), + "Unable to get debug range information: {0}"); } return m_ranges.get(); }