Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -10,12 +10,14 @@ #define SymbolFileDWARF_DWARFCompileUnit_h_ #include "DWARFUnit.h" +#include "llvm/Support/Error.h" class DWARFCompileUnit : public DWARFUnit { public: - static DWARFUnitSP Extract(SymbolFileDWARF *dwarf2Data, - const lldb_private::DWARFDataExtractor &debug_info, - lldb::offset_t *offset_ptr); + static llvm::Expected + extract(SymbolFileDWARF *dwarf2Data, + const lldb_private::DWARFDataExtractor &debug_info, + lldb::offset_t *offset_ptr); void Dump(lldb_private::Stream *s) const override; //------------------------------------------------------------------ Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -10,6 +10,7 @@ #include "SymbolFileDWARF.h" #include "lldb/Utility/Stream.h" +#include "llvm/Object/Error.h" using namespace lldb; using namespace lldb_private; @@ -17,50 +18,64 @@ DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data) : DWARFUnit(dwarf2Data) {} -DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data, - const DWARFDataExtractor &debug_info, - lldb::offset_t *offset_ptr) { +llvm::Expected +DWARFCompileUnit::extract(SymbolFileDWARF *dwarf2Data, + const DWARFDataExtractor &debug_info, + lldb::offset_t *offset_ptr) { + assert(debug_info.ValidOffset(*offset_ptr)); + // std::make_shared would require the ctor to be public. std::shared_ptr cu_sp(new DWARFCompileUnit(dwarf2Data)); cu_sp->m_offset = *offset_ptr; - if (debug_info.ValidOffset(*offset_ptr)) { - dw_offset_t abbr_offset; - const DWARFDebugAbbrev *abbr = dwarf2Data->DebugAbbrev(); - cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr); - cu_sp->m_version = debug_info.GetU16(offset_ptr); - - if (cu_sp->m_version == 5) { - cu_sp->m_unit_type = debug_info.GetU8(offset_ptr); - cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); - abbr_offset = debug_info.GetDWARFOffset(offset_ptr); - - if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton) - cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr); - } else { - abbr_offset = debug_info.GetDWARFOffset(offset_ptr); - cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); - } - - bool length_OK = - debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1); - bool version_OK = SymbolFileDWARF::SupportedVersion(cu_sp->m_version); - bool abbr_offset_OK = - dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset); - bool addr_size_OK = (cu_sp->m_addr_size == 4) || (cu_sp->m_addr_size == 8); - - if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && - abbr != NULL) { - cu_sp->m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset); - return cu_sp; - } - - // reset the offset to where we tried to parse from if anything went wrong - *offset_ptr = cu_sp->m_offset; + dw_offset_t abbr_offset; + const DWARFDebugAbbrev *abbr = dwarf2Data->DebugAbbrev(); + if (!abbr) + return llvm::make_error( + "No debug_abbrev data"); + + cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr); + cu_sp->m_version = debug_info.GetU16(offset_ptr); + + if (cu_sp->m_version == 5) { + cu_sp->m_unit_type = debug_info.GetU8(offset_ptr); + cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); + abbr_offset = debug_info.GetDWARFOffset(offset_ptr); + + if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton) + cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr); + } else { + abbr_offset = debug_info.GetDWARFOffset(offset_ptr); + cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); } - return nullptr; + bool length_OK = + debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1); + bool version_OK = SymbolFileDWARF::SupportedVersion(cu_sp->m_version); + bool abbr_offset_OK = + dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset); + bool addr_size_OK = (cu_sp->m_addr_size == 4) || (cu_sp->m_addr_size == 8); + + if (!length_OK) + return llvm::make_error( + "Invalid compile unit length"); + if (!version_OK) + return llvm::make_error( + "Unsupported compile unit version"); + if (!abbr_offset_OK) + return llvm::make_error( + "Abbreviation offset for compile unit is not valid"); + if (!addr_size_OK) + return llvm::make_error( + "Invalid compile unit address size"); + + cu_sp->m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset); + if (!cu_sp->m_abbrevs) + return llvm::make_error( + "No abbrev exists at the specified offset."); + + return cu_sp; } void DWARFCompileUnit::Dump(Stream *s) const { Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h @@ -44,8 +44,8 @@ uint8_t seg_size); void AddDescriptor(const DWARFDebugArangeSet::Descriptor &range); void Compact(); - bool Extract(const lldb_private::DWARFDataExtractor &data, - lldb::offset_t *offset_ptr); + llvm::Error extract(const lldb_private::DWARFDataExtractor &data, + lldb::offset_t *offset_ptr); void Dump(lldb_private::Stream *s) const; dw_offset_t GetCompileUnitDIEOffset() const { return m_header.cu_offset; } dw_offset_t GetOffsetOfNextEntry() const; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp @@ -10,6 +10,7 @@ #include "SymbolFileDWARF.h" #include "lldb/Utility/Stream.h" +#include "llvm/Object/Error.h" #include using namespace lldb_private; @@ -130,98 +131,88 @@ } } -bool DWARFDebugArangeSet::Extract(const DWARFDataExtractor &data, - lldb::offset_t *offset_ptr) { - if (data.ValidOffset(*offset_ptr)) { - m_arange_descriptors.clear(); - m_offset = *offset_ptr; - - // 7.20 Address Range Table - // - // Each set of entries in the table of address ranges contained in the - // .debug_aranges section begins with a header consisting of: a 4-byte - // length containing the length of the set of entries for this compilation - // unit, not including the length field itself; a 2-byte version identifier - // containing the value 2 for DWARF Version 2; a 4-byte offset into - // the.debug_infosection; a 1-byte unsigned integer containing the size in - // bytes of an address (or the offset portion of an address for segmented - // addressing) on the target system; and a 1-byte unsigned integer - // containing the size in bytes of a segment descriptor on the target - // system. This header is followed by a series of tuples. Each tuple - // consists of an address and a length, each in the size appropriate for an - // address on the target architecture. - m_header.length = data.GetDWARFInitialLength(offset_ptr); - m_header.version = data.GetU16(offset_ptr); - m_header.cu_offset = data.GetDWARFOffset(offset_ptr); - m_header.addr_size = data.GetU8(offset_ptr); - m_header.seg_size = data.GetU8(offset_ptr); - - // Try to avoid reading invalid arange sets by making sure: - // 1 - the version looks good - // 2 - the address byte size looks plausible - // 3 - the length seems to make sense - // size looks plausible - if ((m_header.version >= 2 && m_header.version <= 5) && - (m_header.addr_size == 4 || m_header.addr_size == 8) && - (m_header.length > 0)) { - if (data.ValidOffset(m_offset + sizeof(m_header.length) + - m_header.length - 1)) { - // The first tuple following the header in each set begins at an offset - // that is a multiple of the size of a single tuple (that is, twice the - // size of an address). The header is padded, if necessary, to the - // appropriate boundary. - const uint32_t header_size = *offset_ptr - m_offset; - const uint32_t tuple_size = m_header.addr_size << 1; - uint32_t first_tuple_offset = 0; - while (first_tuple_offset < header_size) - first_tuple_offset += tuple_size; - - *offset_ptr = m_offset + first_tuple_offset; - - Descriptor arangeDescriptor; - - static_assert( - sizeof(arangeDescriptor.address) == sizeof(arangeDescriptor.length), - "DWARFDebugArangeSet::Descriptor.address and " - "DWARFDebugArangeSet::Descriptor.length must have same size"); - - while (data.ValidOffset(*offset_ptr)) { - arangeDescriptor.address = - data.GetMaxU64(offset_ptr, m_header.addr_size); - arangeDescriptor.length = - data.GetMaxU64(offset_ptr, m_header.addr_size); - - // Each set of tuples is terminated by a 0 for the address and 0 for - // the length. - if (arangeDescriptor.address || arangeDescriptor.length) - m_arange_descriptors.push_back(arangeDescriptor); - else - break; // We are done if we get a zero address and length - } - } -#if defined(LLDB_CONFIGURATION_DEBUG) - else { - printf("warning: .debug_arange set length is too large arange data at " - "0x%8.8x: length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, " - "addr_size=%u, seg_size=%u\n", - m_offset, m_header.length, m_header.version, m_header.cu_offset, - m_header.addr_size, m_header.seg_size); - } -#endif - } -#if defined(LLDB_CONFIGURATION_DEBUG) - else { - printf("warning: .debug_arange set has bad header at 0x%8.8x: " - "length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, " - "addr_size=%u, seg_size=%u\n", - m_offset, m_header.length, m_header.version, m_header.cu_offset, - m_header.addr_size, m_header.seg_size); - } -#endif +llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data, + lldb::offset_t *offset_ptr) { + assert(data.ValidOffset(*offset_ptr)); - return !m_arange_descriptors.empty(); + m_arange_descriptors.clear(); + m_offset = *offset_ptr; + + // 7.20 Address Range Table + // + // Each set of entries in the table of address ranges contained in the + // .debug_aranges section begins with a header consisting of: a 4-byte + // length containing the length of the set of entries for this compilation + // unit, not including the length field itself; a 2-byte version identifier + // containing the value 2 for DWARF Version 2; a 4-byte offset into + // the.debug_infosection; a 1-byte unsigned integer containing the size in + // bytes of an address (or the offset portion of an address for segmented + // addressing) on the target system; and a 1-byte unsigned integer + // containing the size in bytes of a segment descriptor on the target + // system. This header is followed by a series of tuples. Each tuple + // consists of an address and a length, each in the size appropriate for an + // address on the target architecture. + m_header.length = data.GetDWARFInitialLength(offset_ptr); + m_header.version = data.GetU16(offset_ptr); + m_header.cu_offset = data.GetDWARFOffset(offset_ptr); + m_header.addr_size = data.GetU8(offset_ptr); + m_header.seg_size = data.GetU8(offset_ptr); + + // Try to avoid reading invalid arange sets by making sure: + // 1 - the version looks good + // 2 - the address byte size looks plausible + // 3 - the length seems to make sense + // size looks plausible + if (m_header.version < 2 || m_header.version > 5) + return llvm::make_error( + "Invalid arange header version"); + + if (m_header.addr_size != 4 && m_header.addr_size != 8) + return llvm::make_error( + "Invalid arange header address size"); + + if (m_header.length == 0) + return llvm::make_error( + "Invalid arange header length"); + + if (!data.ValidOffset(m_offset + sizeof(m_header.length) + m_header.length - + 1)) + return llvm::make_error( + "Invalid arange header length"); + + // The first tuple following the header in each set begins at an offset + // that is a multiple of the size of a single tuple (that is, twice the + // size of an address). The header is padded, if necessary, to the + // appropriate boundary. + const uint32_t header_size = *offset_ptr - m_offset; + const uint32_t tuple_size = m_header.addr_size << 1; + uint32_t first_tuple_offset = 0; + while (first_tuple_offset < header_size) + first_tuple_offset += tuple_size; + + *offset_ptr = m_offset + first_tuple_offset; + + Descriptor arangeDescriptor; + + static_assert(sizeof(arangeDescriptor.address) == + sizeof(arangeDescriptor.length), + "DWARFDebugArangeSet::Descriptor.address and " + "DWARFDebugArangeSet::Descriptor.length must have same size"); + + while (data.ValidOffset(*offset_ptr)) { + arangeDescriptor.address = data.GetMaxU64(offset_ptr, m_header.addr_size); + arangeDescriptor.length = data.GetMaxU64(offset_ptr, m_header.addr_size); + + // Each set of tuples is terminated by a 0 for the address and 0 for + // the length. + if (!arangeDescriptor.address && !arangeDescriptor.length) + return llvm::ErrorSuccess(); + + m_arange_descriptors.push_back(arangeDescriptor); } - return false; + + return llvm::make_error( + "arange descriptors not terminated by null entry"); } dw_offset_t DWARFDebugArangeSet::GetOffsetOfNextEntry() const { Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h @@ -11,6 +11,7 @@ #include "DWARFDebugArangeSet.h" #include "lldb/Utility/RangeMap.h" +#include "llvm/Support/Error.h" #include class SymbolFileDWARF; @@ -28,7 +29,8 @@ void Clear() { m_aranges.Clear(); } - bool Extract(const lldb_private::DWARFDataExtractor &debug_aranges_data); + llvm::Error + extract(const lldb_private::DWARFDataExtractor &debug_aranges_data); bool Generate(SymbolFileDWARF *dwarf2Data); Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp @@ -47,28 +47,33 @@ //---------------------------------------------------------------------- // Extract //---------------------------------------------------------------------- -bool DWARFDebugAranges::Extract(const DWARFDataExtractor &debug_aranges_data) { - if (debug_aranges_data.ValidOffset(0)) { - lldb::offset_t offset = 0; - - DWARFDebugArangeSet set; - Range range; - while (set.Extract(debug_aranges_data, &offset)) { - const uint32_t num_descriptors = set.NumDescriptors(); - if (num_descriptors > 0) { - const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset(); - - for (uint32_t i = 0; i < num_descriptors; ++i) { - const DWARFDebugArangeSet::Descriptor &descriptor = - set.GetDescriptorRef(i); - m_aranges.Append(RangeToDIE::Entry(descriptor.address, - descriptor.length, cu_offset)); - } +llvm::Error +DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) { + assert(debug_aranges_data.ValidOffset(0)); + + lldb::offset_t offset = 0; + + DWARFDebugArangeSet set; + Range range; + while (debug_aranges_data.ValidOffset(offset)) { + llvm::Error error = set.extract(debug_aranges_data, &offset); + if (!error) + return error; + + const uint32_t num_descriptors = set.NumDescriptors(); + if (num_descriptors > 0) { + const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset(); + + for (uint32_t i = 0; i < num_descriptors; ++i) { + const DWARFDebugArangeSet::Descriptor &descriptor = + set.GetDescriptorRef(i); + m_aranges.Append(RangeToDIE::Entry(descriptor.address, + descriptor.length, cu_offset)); } - set.Clear(); } + set.Clear(); } - return false; + return llvm::ErrorSuccess(); } //---------------------------------------------------------------------- Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -12,11 +12,12 @@ #include #include -#include "DWARFUnit.h" #include "DWARFDIE.h" +#include "DWARFUnit.h" #include "SymbolFileDWARF.h" #include "lldb/Core/STLUtils.h" #include "lldb/lldb-private.h" +#include "llvm/Support/Error.h" typedef std::multimap CStringToDIEMap; @@ -50,7 +51,7 @@ (1 << 2) // Show all parent DIEs when dumping single DIEs }; - DWARFDebugAranges &GetCompileUnitAranges(); + llvm::Expected GetCompileUnitAranges(); protected: static bool OffsetLessThanCompileUnitOffset(dw_offset_t offset, Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -42,69 +42,87 @@ m_compile_units.clear(); } -DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() { - if (m_cu_aranges_up == NULL && m_dwarf2Data) { - Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); - - m_cu_aranges_up.reset(new DWARFDebugAranges()); - const DWARFDataExtractor &debug_aranges_data = - m_dwarf2Data->get_debug_aranges_data(); - if (debug_aranges_data.GetByteSize() > 0) { - if (log) - log->Printf( - "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" from " - ".debug_aranges", - m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str()); - m_cu_aranges_up->Extract(debug_aranges_data); - } +llvm::Expected DWARFDebugInfo::GetCompileUnitAranges() { + if (m_cu_aranges_up) + return *m_cu_aranges_up; + + assert(m_dwarf2Data); + + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); + + m_cu_aranges_up = llvm::make_unique(); + const DWARFDataExtractor &debug_aranges_data = + m_dwarf2Data->get_debug_aranges_data(); + if (debug_aranges_data.GetByteSize() > 0) { + if (log) + log->Printf( + "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" from " + ".debug_aranges", + m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str()); + llvm::Error error = m_cu_aranges_up->extract(debug_aranges_data); + if (error) + return std::move(error); + } - // Make a list of all CUs represented by the arange data in the file. - std::set cus_with_data; - for (size_t n = 0; n < m_cu_aranges_up->GetNumRanges(); n++) { - dw_offset_t offset = m_cu_aranges_up->OffsetAtIndex(n); - if (offset != DW_INVALID_OFFSET) - cus_with_data.insert(offset); - } + // Make a list of all CUs represented by the arange data in the file. + std::set cus_with_data; + for (size_t n = 0; n < m_cu_aranges_up->GetNumRanges(); n++) { + dw_offset_t offset = m_cu_aranges_up->OffsetAtIndex(n); + if (offset != DW_INVALID_OFFSET) + cus_with_data.insert(offset); + } - // Manually build arange data for everything that wasn't in the - // .debug_aranges table. - bool printed = false; - const size_t num_compile_units = GetNumCompileUnits(); - for (size_t idx = 0; idx < num_compile_units; ++idx) { - DWARFUnit *cu = GetCompileUnitAtIndex(idx); - - dw_offset_t offset = cu->GetOffset(); - if (cus_with_data.find(offset) == cus_with_data.end()) { - if (log) { - if (!printed) - log->Printf( - "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" by parsing", - m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str()); - printed = true; - } - cu->BuildAddressRangeTable(m_dwarf2Data, m_cu_aranges_up.get()); + // Manually build arange data for everything that wasn't in the + // .debug_aranges table. + bool printed = false; + const size_t num_compile_units = GetNumCompileUnits(); + for (size_t idx = 0; idx < num_compile_units; ++idx) { + DWARFUnit *cu = GetCompileUnitAtIndex(idx); + + dw_offset_t offset = cu->GetOffset(); + if (cus_with_data.find(offset) == cus_with_data.end()) { + if (log) { + if (!printed) + log->Printf( + "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" by parsing", + m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str()); + printed = true; } + cu->BuildAddressRangeTable(m_dwarf2Data, m_cu_aranges_up.get()); } - - const bool minimize = true; - m_cu_aranges_up->Sort(minimize); } + + const bool minimize = true; + m_cu_aranges_up->Sort(minimize); return *m_cu_aranges_up; } void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() { - if (m_compile_units.empty()) { - if (m_dwarf2Data != NULL) { - lldb::offset_t offset = 0; - DWARFUnitSP cu_sp; - const auto &debug_info_data = m_dwarf2Data->get_debug_info_data(); - while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data, - &offset))) { - m_compile_units.push_back(cu_sp); + if (!m_compile_units.empty()) + return; + if (!m_dwarf2Data) + return; - offset = cu_sp->GetNextCompileUnitOffset(); - } + lldb::offset_t offset = 0; + const auto &debug_info_data = m_dwarf2Data->get_debug_info_data(); + + while (debug_info_data.ValidOffset(offset)) { + llvm::Expected cu_sp = + DWARFCompileUnit::extract(m_dwarf2Data, debug_info_data, &offset); + + if (!cu_sp) { + // FIXME: Propagate this error up. + llvm::consumeError(cu_sp.takeError()); + return; } + + // If it didn't return an error, then it should be returning a valid + // CompileUnit. + assert(*cu_sp); + + m_compile_units.push_back(*cu_sp); + + offset = (*cu_sp)->GetNextCompileUnitOffset(); } } Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1758,8 +1758,18 @@ DWARFDebugInfo *debug_info = DebugInfo(); if (debug_info) { - const dw_offset_t cu_offset = - debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr); + llvm::Expected aranges = + debug_info->GetCompileUnitAranges(); + if (!aranges) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO | + DWARF_LOG_DEBUG_ARANGES); + LLDB_LOG_ERROR(log, aranges.takeError(), + "SymbolFileDWARF::ResolveSymbolContext failed to get cu " + "aranges. {0}"); + return 0; + } + + const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr); if (cu_offset == DW_INVALID_OFFSET) { // Global variables are not in the compile unit address ranges. The // only way to currently find global variables is to iterate over the