diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -237,7 +237,9 @@ llvm::Optional GetRnglistOffset(uint32_t Index) const { if (!m_rnglist_table) return llvm::None; - if (llvm::Optional off = m_rnglist_table->getOffsetEntry(Index)) + if (llvm::Optional off = m_rnglist_table->getOffsetEntry( + m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), + Index)) return *off + m_ranges_base; return llvm::None; } @@ -246,7 +248,8 @@ if (!m_loclist_table_header) return llvm::None; - llvm::Optional Offset = m_loclist_table_header->getOffsetEntry(Index); + llvm::Optional Offset = m_loclist_table_header->getOffsetEntry( + m_dwarf.GetDWARFContext().getOrLoadLocListsData().GetAsLLVM(), Index); if (!Offset) return llvm::None; return *Offset + m_loclists_base; diff --git a/lldb/test/Shell/SymbolFile/DWARF/DW_AT_loclists_base.s b/lldb/test/Shell/SymbolFile/DWARF/DW_AT_loclists_base.s --- a/lldb/test/Shell/SymbolFile/DWARF/DW_AT_loclists_base.s +++ b/lldb/test/Shell/SymbolFile/DWARF/DW_AT_loclists_base.s @@ -5,7 +5,7 @@ # CHECK-LABEL: image lookup -v -s lookup_loclists # CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX, -# CHECK: Variable: {{.*}}, name = "x1", type = "int", location = , +# CHECK-NOT: Variable: loclists: nop @@ -28,7 +28,7 @@ .short 5 # Version .byte 8 # Address size .byte 0 # Segment selector size - .long 1 # Offset entry count + .long 2 # Offset entry count .Lloclists_table_base: .long .Ldebug_loc0-.Lloclists_table_base .long .Ldebug_loc1-.Lloclists_table_base diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -72,6 +72,8 @@ std::function(uint32_t)> LookupAddr, function_ref)> Callback) const; + const DWARFDataExtractor &getData() { return Data; } + protected: DWARFDataExtractor Data; diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h @@ -72,10 +72,6 @@ }; Header HeaderData; - /// The offset table, which contains offsets to the individual list entries. - /// It is used by forms such as DW_FORM_rnglistx. - /// FIXME: Generate the table and use the appropriate forms. - std::vector Offsets; /// The table's format, either DWARF32 or DWARF64. dwarf::DwarfFormat Format; /// The offset at which the header (and hence the table) is located within @@ -93,7 +89,6 @@ void clear() { HeaderData = {}; - Offsets.clear(); } uint64_t getHeaderOffset() const { return HeaderOffset; } uint8_t getAddrSize() const { return HeaderData.AddrSize; } @@ -115,11 +110,17 @@ llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64"); } - void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const; - Optional getOffsetEntry(uint32_t Index) const { - if (Index < Offsets.size()) - return Offsets[Index]; - return None; + void dump(DataExtractor Data, raw_ostream &OS, + DIDumpOptions DumpOpts = {}) const; + Optional getOffsetEntry(DataExtractor Data, uint32_t Index) const { + if (Index > HeaderData.OffsetEntryCount) + return None; + + uint8_t OffsetByteSize = Format == dwarf::DWARF64 ? 8 : 4; + uint64_t Offset = + getHeaderOffset() + getHeaderSize(Format) + OffsetByteSize * Index; + auto R = Data.getUnsigned(&Offset, OffsetByteSize); + return R; } /// Extract the table header and the array of offsets. @@ -169,14 +170,14 @@ uint8_t getAddrSize() const { return Header.getAddrSize(); } dwarf::DwarfFormat getFormat() const { return Header.getFormat(); } - void dump(raw_ostream &OS, + void dump(DWARFDataExtractor Data, raw_ostream &OS, llvm::function_ref(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts = {}) const; /// Return the contents of the offset entry designated by a given index. - Optional getOffsetEntry(uint32_t Index) const { - return Header.getOffsetEntry(Index); + Optional getOffsetEntry(DataExtractor Data, uint32_t Index) const { + return Header.getOffsetEntry(Data, Index); } /// Return the size of the table header including the length but not including /// the offsets. This is dependent on the table format, which is unambiguously @@ -240,11 +241,11 @@ template void DWARFListTableBase::dump( - raw_ostream &OS, + DWARFDataExtractor Data, raw_ostream &OS, llvm::function_ref(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts) const { - Header.dump(OS, DumpOpts); + Header.dump(Data, OS, DumpOpts); OS << HeaderString << "\n"; // Determine the length of the longest encoding string we have in the table, diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -412,18 +412,13 @@ /// Return a rangelist's offset based on an index. The index designates /// an entry in the rangelist table's offset array and is supplied by /// DW_FORM_rnglistx. - Optional getRnglistOffset(uint32_t Index) { - if (!RngListTable) - return None; - if (Optional Off = RngListTable->getOffsetEntry(Index)) - return *Off + RangeSectionBase; - return None; - } + Optional getRnglistOffset(uint32_t Index); Optional getLoclistOffset(uint32_t Index) { if (!LoclistTableHeader) return None; - if (Optional Off = LoclistTableHeader->getOffsetEntry(Index)) + if (Optional Off = + LoclistTableHeader->getOffsetEntry(LocTable->getData(), Index)) return *Off + getLocSectionBase(); return None; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -255,7 +255,7 @@ break; Offset = TableOffset + Length; } else { - Rnglists.dump(OS, LookupPooledAddress, DumpOpts); + Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts); } } } @@ -316,7 +316,7 @@ return; } - Header.dump(OS, DumpOpts); + Header.dump(Data, OS, DumpOpts); uint64_t EndOffset = Header.length() + Header.getHeaderOffset(); Data.setAddressSize(Header.getAddrSize()); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp @@ -71,12 +71,12 @@ ") than there is space for", SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount); Data.setAddressSize(HeaderData.AddrSize); - for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) - Offsets.push_back(Data.getRelocatedValue(OffsetByteSize, OffsetPtr)); + *OffsetPtr += HeaderData.OffsetEntryCount * OffsetByteSize; return Error::success(); } -void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { +void DWARFListTableHeader::dump(DataExtractor Data, raw_ostream &OS, + DIDumpOptions DumpOpts) const { if (DumpOpts.Verbose) OS << format("0x%8.8" PRIx64 ": ", HeaderOffset); int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format); @@ -91,7 +91,8 @@ if (HeaderData.OffsetEntryCount > 0) { OS << "offsets: ["; - for (const auto &Off : Offsets) { + for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) { + auto Off = *getOffsetEntry(Data, I); OS << format("\n0x%0*" PRIx64, OffsetDumpWidth, Off); if (DumpOpts.Verbose) OS << format(" => 0x%08" PRIx64, diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -548,17 +548,13 @@ uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Header.getFormat()); uint64_t Offset = getLocSectionBase(); - DWARFDataExtractor Data(Context.getDWARFObj(), *LocSection, - isLittleEndian, getAddressByteSize()); + const DWARFDataExtractor &Data = LocTable->getData(); if (Offset < HeaderSize) return createStringError(errc::invalid_argument, "did not detect a valid" " list table with base = 0x%" PRIx64 "\n", Offset); Offset -= HeaderSize; - if (auto *IndexEntry = Header.getIndexEntry()) - if (const auto *Contrib = IndexEntry->getContribution(DW_SECT_LOCLISTS)) - Offset += Contrib->Offset; if (Error E = LoclistTableHeader->extract(Data, &Offset)) return createStringError(errc::invalid_argument, "parsing a loclist table: " + @@ -1009,3 +1005,13 @@ return DescOrError.takeError(); return *DescOrError; } + +Optional DWARFUnit::getRnglistOffset(uint32_t Index) { + if (!RngListTable) + return None; + DataExtractor RangesData(RangeSection->Data, isLittleEndian, + getAddressByteSize()); + if (Optional Off = RngListTable->getOffsetEntry(RangesData, Index)) + return *Off + RangeSectionBase; + return None; +}