jankratochvil updated this revision to Diff 187169.
jankratochvil added a comment.
> So if we have 3GB of .debug_info and 1GB of .debug_types, we are expecting to
> allocate a heap based buffer and copy all the data into this? This will fail.
That fallback code path is used only when there is no way to access
`.debug_info` and `.debug_types` from mmapped area. I was thinking that
fallback would be used for example for Linux vDSO which needs to be read by
`Process::ReadModuleFromMemory()` but that has only about 16KB so its size does
not matter. But maybe on OSX (or for GDB JIT modules) the data can be bigger
so in this patch I have implemented the most effective merging of non-mmapped
sections.
Repository:
rLLDB LLDB
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D51578/new/
https://reviews.llvm.org/D51578
Files:
lldb/include/lldb/Symbol/ObjectFile.h
lldb/include/lldb/lldb-enumerations.h
lldb/source/Core/Section.cpp
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
lldb/source/Symbol/ObjectFile.cpp
Index: lldb/source/Symbol/ObjectFile.cpp
===================================================================
--- lldb/source/Symbol/ObjectFile.cpp
+++ lldb/source/Symbol/ObjectFile.cpp
@@ -365,6 +365,7 @@
case eSectionTypeDWARFDebugStrOffsets:
case eSectionTypeDWARFDebugStrOffsetsDwo:
case eSectionTypeDWARFDebugTypes:
+ case eSectionTypeDWARFDebugTypesDwo:
case eSectionTypeDWARFAppleNames:
case eSectionTypeDWARFAppleTypes:
case eSectionTypeDWARFAppleNamespaces:
@@ -533,19 +534,54 @@
return 0;
}
-//----------------------------------------------------------------------
-// Get the section data the file on disk
-//----------------------------------------------------------------------
-size_t ObjectFile::ReadSectionData(
- const SectionPart §ion_part, DataExtractor §ion_data) {
+size_t ObjectFile::ReadSectionData(const SectionPart §ion_part,
+ DataExtractor §ion_data) {
Section *section = section_part.GetSection();
// If some other objectfile owns this data, pass this to them.
if (section->GetObjectFile() != this)
return section->GetObjectFile()->ReadSectionData(
section_part, section_data);
- if (IsInMemory()) {
- ProcessSP process_sp(m_process_wp.lock());
+ auto reader_up = SectionReaderFactory(section_part);
+ if (!reader_up)
+ return 0;
+ return reader_up->read(section_data);
+}
+
+ObjectFile::SectionReader::SectionReader(const SectionPart §ion_part_)
+ : section_part(section_part_) {}
+
+std::unique_ptr<ObjectFile::SectionReader>
+ObjectFile::SectionReaderFactory(const SectionPart §ion_part) {
+ // llvm::make_unique() is not a friend like we are.
+ return std::unique_ptr<SectionReader>(new SectionReader(section_part));
+}
+
+ObjectFile::SectionReader::~SectionReader() {}
+
+uint64_t ObjectFile::SectionReader::getDecompressedSize() {
+ return !section_part ? 0 : section_part.GetSection()->GetFileSize();
+}
+
+size_t ObjectFile::SectionReader::read(uint8_t *dst) {
+ if (!section_part)
+ return 0;
+ Section *section = section_part.GetSection();
+ return section->GetObjectFile()->ObjectFile::ReadSectionData(section,
+ section_part.GetOffsetInSection(), dst, section_part.GetLength());
+}
+
+//----------------------------------------------------------------------
+// Get the section data the file on disk
+//----------------------------------------------------------------------
+size_t ObjectFile::SectionReader::read(DataExtractor §ion_data) {
+ if (!section_part)
+ return 0;
+ Section *section = section_part.GetSection();
+ ObjectFile *obj_file = section->GetObjectFile();
+
+ if (obj_file->IsInMemory()) {
+ ProcessSP process_sp(obj_file->GetProcessWP().lock());
if (process_sp) {
const addr_t base_load_addr =
section->GetLoadBaseAddress(&process_sp->GetTarget());
@@ -566,10 +602,10 @@
// The object file now contains a full mmap'ed copy of the object file
// data, so just use this
if (!section->IsRelocated())
- RelocateSection(section);
+ obj_file->RelocateSection(section);
}
- return GetData(section_part.GetOffsetInFile(), section_part.GetLength(),
- section_data);
+ return obj_file->GetData(section_part.GetOffsetInFile(),
+ section_part.GetLength(), section_data);
}
bool ObjectFile::SplitArchivePathWithObject(const char *path_with_object,
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -47,9 +47,10 @@
const lldb_private::DWARFDataExtractor &get_debug_abbrev_data() override;
const lldb_private::DWARFDataExtractor &get_debug_addr_data() override;
- const lldb_private::DWARFDataExtractor &get_debug_info_data() override;
+ lldb_private::SectionPart get_debug_info_section_part() override;
const lldb_private::DWARFDataExtractor &get_debug_str_data() override;
const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data() override;
+ lldb_private::SectionPart get_debug_types_section_part() override;
protected:
lldb_private::SectionPart GetSectionPart(
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -124,8 +124,8 @@
return m_data_debug_addr.m_data;
}
-const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_info_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugInfoDwo, m_data_debug_info);
+SectionPart SymbolFileDWARFDwo::get_debug_info_section_part() {
+ return GetSectionPart(eSectionTypeDWARFDebugInfoDwo);
}
const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_data() {
@@ -137,6 +137,10 @@
m_data_debug_str_offsets);
}
+SectionPart SymbolFileDWARFDwo::get_debug_types_section_part() {
+ return GetSectionPart(eSectionTypeDWARFDebugTypesDwo);
+}
+
SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() {
return m_base_dwarf_cu->GetSymbolFileDWARF();
}
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -234,7 +234,8 @@
virtual const lldb_private::DWARFDataExtractor &get_debug_addr_data();
const lldb_private::DWARFDataExtractor &get_debug_aranges_data();
const lldb_private::DWARFDataExtractor &get_debug_frame_data();
- virtual const lldb_private::DWARFDataExtractor &get_debug_info_data();
+ const lldb_private::DWARFDataExtractor &get_debug_info_data();
+ virtual lldb_private::SectionPart get_debug_info_section_part();
const lldb_private::DWARFDataExtractor &get_debug_line_data();
const lldb_private::DWARFDataExtractor &get_debug_line_str_data();
const lldb_private::DWARFDataExtractor &get_debug_macro_data();
@@ -244,7 +245,7 @@
const lldb_private::DWARFDataExtractor &get_debug_rnglists_data();
virtual const lldb_private::DWARFDataExtractor &get_debug_str_data();
virtual const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data();
- const lldb_private::DWARFDataExtractor &get_debug_types_data();
+ virtual lldb_private::SectionPart get_debug_types_section_part();
const lldb_private::DWARFDataExtractor &get_apple_names_data();
const lldb_private::DWARFDataExtractor &get_apple_types_data();
const lldb_private::DWARFDataExtractor &get_apple_namespaces_data();
@@ -324,6 +325,13 @@
void DumpClangAST(lldb_private::Stream &s) override;
+ uint64_t get_debug_info_size() const {
+ return m_debug_info_concatenated_info_size;
+ }
+ uint64_t get_debug_types_offset() const {
+ return m_debug_info_concatenated_types_offset;
+ }
+
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
DIEToTypePtr;
@@ -474,7 +482,6 @@
DWARFDataSegment m_data_debug_addr;
DWARFDataSegment m_data_debug_aranges;
DWARFDataSegment m_data_debug_frame;
- DWARFDataSegment m_data_debug_info;
DWARFDataSegment m_data_debug_line;
DWARFDataSegment m_data_debug_line_str;
DWARFDataSegment m_data_debug_macro;
@@ -484,13 +491,21 @@
DWARFDataSegment m_data_debug_rnglists;
DWARFDataSegment m_data_debug_str;
DWARFDataSegment m_data_debug_str_offsets;
- DWARFDataSegment m_data_debug_types;
DWARFDataSegment m_data_apple_names;
DWARFDataSegment m_data_apple_types;
DWARFDataSegment m_data_apple_namespaces;
DWARFDataSegment m_data_apple_objc;
DWARFDataSegment m_data_gnu_debugaltlink;
+ llvm::once_flag m_concatenated_data_once;
+ // For get_debug_info_data() containing both '.debug_info' and '.debug_types'.
+ lldb_private::DWARFDataExtractor m_data_debug_info_concatenated;
+ // First part of m_data_debug_info_concatenated containing '.debug_info'.
+ uint64_t m_debug_info_concatenated_info_size;
+ // Start of second part of m_data_debug_info_concatenated containing
+ // '.debug_types'. There may be a gap between those two sections.
+ uint64_t m_debug_info_concatenated_types_offset;
+
// The unique pointer items below are generated on demand if and when someone
// accesses
// them through a non const version of this class.
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -8,6 +8,7 @@
#include "SymbolFileDWARF.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Threading.h"
@@ -356,7 +357,7 @@
// when this class parses .o files to
// contain the .o file index/ID
m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(),
- m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(),
+ m_data_debug_aranges(), m_data_debug_frame(),
m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(),
m_data_debug_ranges(), m_data_debug_rnglists(), m_data_debug_str(),
m_data_apple_names(), m_data_apple_types(), m_data_apple_namespaces(),
@@ -550,7 +551,8 @@
const SectionList *section_list = module_sp->GetSectionList();
if (section_list) {
Section *section = section_list->FindSectionByType(sect_type, true).get();
- if (section)
+ // The size check is just a performance optimization.
+ if (section && (section->GetByteSize() || section->GetFileSize()))
return section;
}
return SectionPart();
@@ -594,8 +596,8 @@
return GetCachedSectionData(eSectionTypeDWARFDebugFrame, m_data_debug_frame);
}
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info);
+SectionPart SymbolFileDWARF::get_debug_info_section_part() {
+ return GetSectionPart(eSectionTypeDWARFDebugInfo);
}
const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() {
@@ -645,8 +647,8 @@
m_data_debug_str_offsets);
}
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_types_data() {
- return GetCachedSectionData(eSectionTypeDWARFDebugTypes, m_data_debug_types);
+SectionPart SymbolFileDWARF::get_debug_types_section_part() {
+ return GetSectionPart(eSectionTypeDWARFDebugTypes);
}
const DWARFDataExtractor &SymbolFileDWARF::get_apple_names_data() {
@@ -671,6 +673,64 @@
m_data_gnu_debugaltlink);
}
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() {
+ llvm::call_once(m_concatenated_data_once, [&] {
+ const SectionPart debug_info_part = get_debug_info_section_part();
+ const SectionPart debug_types_part = get_debug_types_section_part();
+ if (!debug_info_part && !debug_types_part)
+ return;
+ // For this optimization of mmapped sections we do not handle .debug_types
+ // present without .debug_info as that should not happen.
+ if (!m_obj_file->IsInMemory() && debug_info_part
+ && !debug_info_part.GetSection()->Test(llvm::ELF::SHF_COMPRESSED)
+ && (!debug_types_part
+ || (!debug_types_part.GetSection()->Test(llvm::ELF::SHF_COMPRESSED)
+ && debug_info_part.GetOffsetInFile()
+ + debug_info_part.GetLength()
+ <= debug_types_part.GetOffsetInFile()))) {
+ m_debug_info_concatenated_info_size = debug_info_part.GetLength();
+ uint64_t length;
+ if (debug_types_part) {
+ m_debug_info_concatenated_types_offset =
+ debug_types_part.GetOffsetInFile()
+ - debug_info_part.GetOffsetInFile();
+ length = debug_types_part.GetOffsetInFile()
+ + debug_types_part.GetLength() - debug_info_part.GetOffsetInFile();
+ } else {
+ m_debug_info_concatenated_types_offset = debug_info_part.GetLength();
+ length = debug_info_part.GetLength();
+ }
+ if (m_dwarf_data.GetByteSize())
+ m_data_debug_info_concatenated.SetData(m_dwarf_data,
+ debug_info_part.GetOffsetInParentSection(), length);
+ else
+ m_obj_file->GetData(debug_info_part.GetOffsetInFile(),
+ length, m_data_debug_info_concatenated);
+ if (m_data_debug_info_concatenated.GetByteSize() != length)
+ m_data_debug_info_concatenated.Clear();
+ return;
+ }
+ auto debug_info_reader = m_obj_file->SectionReaderFactory(debug_info_part);
+ auto debug_types_reader = m_obj_file->SectionReaderFactory(
+ debug_types_part);
+ const auto info_len = debug_info_reader->getDecompressedSize();
+ const auto types_len = debug_types_reader->getDecompressedSize();
+ DataBufferSP databuffer = DataBufferSP(
+ new DataBufferHeap(info_len + types_len, 0));
+ if (debug_info_reader->read(databuffer->GetBytes()) != info_len
+ || debug_types_reader->read(databuffer->GetBytes() + info_len)
+ != types_len)
+ return;
+ m_debug_info_concatenated_info_size = info_len;
+ m_debug_info_concatenated_types_offset = info_len;
+ m_data_debug_info_concatenated.SetData(databuffer);
+ m_data_debug_info_concatenated.SetByteOrder(m_obj_file->GetByteOrder());
+ m_data_debug_info_concatenated.SetAddressByteSize(
+ m_obj_file->GetAddressByteSize());
+ });
+ return m_data_debug_info_concatenated;
+}
+
DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
if (m_abbr == NULL) {
const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -69,7 +69,7 @@
/// @return
/// The correct data for the DIE information in this unit.
//------------------------------------------------------------------
- virtual const lldb_private::DWARFDataExtractor &GetData() const = 0;
+ const lldb_private::DWARFDataExtractor &GetData() const;
//------------------------------------------------------------------
/// Get the size in bytes of the compile unit header.
///
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -873,3 +873,6 @@
return *m_func_aranges_up;
}
+const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const {
+ return m_dwarf->get_debug_info_data();
+}
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -98,7 +98,8 @@
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,
+ while (offset < m_dwarf2Data->get_debug_info_size()
+ && (cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data,
&offset))) {
m_compile_units.push_back(cu_sp);
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -18,16 +18,6 @@
lldb::offset_t *offset_ptr);
void Dump(lldb_private::Stream *s) const override;
- //------------------------------------------------------------------
- /// Get the data that contains the DIE information for this unit.
- ///
- /// @return
- /// The correct data (.debug_types for DWARF 4 and earlier, and
- /// .debug_info for DWARF 5 and later) for the DIE information in
- /// this unit.
- //------------------------------------------------------------------
- const lldb_private::DWARFDataExtractor &GetData() const override;
-
//------------------------------------------------------------------
/// Get the size in bytes of the header.
///
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -89,7 +89,3 @@
}
llvm_unreachable("invalid UnitType.");
}
-
-const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
- return m_dwarf->get_debug_info_data();
-}
Index: lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1212,6 +1212,7 @@
case eSectionTypeDWARFDebugStrOffsets:
case eSectionTypeDWARFDebugStrOffsetsDwo:
case eSectionTypeDWARFDebugTypes:
+ case eSectionTypeDWARFDebugTypesDwo:
case eSectionTypeDWARFAppleNames:
case eSectionTypeDWARFAppleTypes:
case eSectionTypeDWARFAppleNamespaces:
Index: lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
===================================================================
--- lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -82,9 +82,10 @@
lldb::offset_t section_offset, void *dst,
size_t dst_len) override;
- size_t
- ReadSectionData(const lldb_private::SectionPart §ion_part,
- lldb_private::DataExtractor §ion_data) override;
+ std::unique_ptr<SectionReader> SectionReaderFactory(
+ const lldb_private::SectionPart §ion_part) override;
+
+ class SectionReaderJIT;
lldb_private::Address GetEntryPointAddress() override;
Index: lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -242,21 +242,44 @@
return 0;
}
-size_t ObjectFileJIT::ReadSectionData(
- const lldb_private::SectionPart §ion_part,
- lldb_private::DataExtractor §ion_data) {
- if (section_part.GetLength()) {
- const void *src = (void *)(uintptr_t)section_part.GetOffsetInFile();
-
- DataBufferSP data_sp(
- new lldb_private::DataBufferHeap(src, section_part.GetLength()));
- if (data_sp) {
- section_data.SetData(data_sp, 0, data_sp->GetByteSize());
- section_data.SetByteOrder(GetByteOrder());
- section_data.SetAddressByteSize(GetAddressByteSize());
- return section_data.GetByteSize();
- }
+class ObjectFileJIT::SectionReaderJIT : public ObjectFile::SectionReader {
+public:
+ SectionReaderJIT(const SectionPart §ion_part_);
+ size_t read(DataExtractor §ion_data) override;
+ size_t read(uint8_t *dst) override;
+};
+
+ObjectFileJIT::SectionReaderJIT::SectionReaderJIT(
+ const SectionPart §ion_part_)
+ : ObjectFile::SectionReader(section_part_) {
+ assert(section_part.GetLength());
+}
+
+size_t ObjectFileJIT::SectionReaderJIT::read(DataExtractor §ion_data) {
+ const void *src = (void *)(uintptr_t)section_part.GetOffsetInFile();
+
+ DataBufferSP data_sp(new DataBufferHeap(src, section_part.GetLength()));
+ if (data_sp) {
+ Section *section = section_part.GetSection();
+ ObjectFile *obj_file = section->GetObjectFile();
+
+ section_data.SetData(data_sp, 0, data_sp->GetByteSize());
+ section_data.SetByteOrder(obj_file->GetByteOrder());
+ section_data.SetAddressByteSize(obj_file->GetAddressByteSize());
+ return section_data.GetByteSize();
}
section_data.Clear();
return 0;
}
+
+size_t ObjectFileJIT::SectionReaderJIT::read(uint8_t *dst) {
+ Section *section = section_part.GetSection();
+ ObjectFile *obj_file = section->GetObjectFile();
+ return obj_file->ReadSectionData(section, section_part.GetOffsetInSection(),
+ dst, section_part.GetLength());
+}
+
+std::unique_ptr<ObjectFile::SectionReader>
+ObjectFileJIT::SectionReaderFactory(const SectionPart §ion_part) {
+ return llvm::make_unique<SectionReaderJIT>(section_part);
+}
Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
===================================================================
--- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -139,13 +139,11 @@
ObjectFile::Strata CalculateStrata() override;
+ using lldb_private::ObjectFile::ReadSectionData;
size_t ReadSectionData(lldb_private::Section *section,
lldb::offset_t section_offset, void *dst,
size_t dst_len) override;
- size_t ReadSectionData(const lldb_private::SectionPart §ion_part,
- lldb_private::DataExtractor §ion_data) override;
-
llvm::ArrayRef<elf::ELFProgramHeader> ProgramHeaders();
lldb_private::DataExtractor GetSegmentData(const elf::ELFProgramHeader &H);
@@ -154,6 +152,11 @@
void RelocateSection(lldb_private::Section *section) override;
+ std::unique_ptr<SectionReader> SectionReaderFactory(
+ const lldb_private::SectionPart §ion_part) override;
+
+ class SectionReaderCompressed;
+
protected:
std::vector<LoadableData>
Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -34,6 +34,7 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Decompressor.h"
+#include "llvm/Object/ELF.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -1768,6 +1769,7 @@
.Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets)
.Case(".debug_str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
.Case(".debug_types", eSectionTypeDWARFDebugTypes)
+ .Case(".debug_types.dwo", eSectionTypeDWARFDebugTypesDwo)
.Case(".eh_frame", eSectionTypeEHFrame)
.Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink)
.Case(".gosymtab", eSectionTypeGoSymtab)
@@ -3391,58 +3393,113 @@
return data.CopyData(section_offset, dst_len, dst);
}
-size_t ObjectFileELF::ReadSectionData(const SectionPart §ion_part,
- DataExtractor §ion_data) {
- Section *section = section_part.GetSection();
- // If some other objectfile owns this data, pass this to them.
- if (section->GetObjectFile() != this)
- return section->GetObjectFile()->ReadSectionData(
- section_part, section_data);
+class ObjectFileELF::SectionReaderCompressed
+ : public ObjectFile::SectionReader {
+public:
+ SectionReaderCompressed(const SectionPart §ion_part_);
+ uint64_t getDecompressedSize() override;
+ size_t read(DataExtractor §ion_data) override;
+ size_t read(uint8_t *dst) override;
+ ~SectionReaderCompressed();
+private:
+ static llvm::Expected<llvm::object::Decompressor> Initialize(
+ const SectionPart §ion_part, DataExtractor &compressed_data);
+ DataExtractor compressed_data;
+ // 'decompressor' Initialize() requires already initialized 'compressed_data'.
+ llvm::Expected<llvm::object::Decompressor> decompressor;
+};
- size_t result = ObjectFile::ReadSectionData(section, section_data);
- if (result == 0 || !section->Test(SHF_COMPRESSED))
- return result;
+ObjectFileELF::SectionReaderCompressed::SectionReaderCompressed(
+ const SectionPart §ion_part_)
+ : ObjectFile::SectionReader(section_part_),
+ decompressor(Initialize(section_part_, compressed_data)) {}
+ObjectFileELF::SectionReaderCompressed::~SectionReaderCompressed() {
+ if (decompressor.takeError()) {}
+}
+
+llvm::Expected<llvm::object::Decompressor>
+ObjectFileELF::SectionReaderCompressed::Initialize(
+ const SectionPart §ion_part, DataExtractor &compressed_data) {
+ Section *section = section_part.GetSection();
+ ObjectFile *obj_file = section->GetObjectFile();
if (section_part.GetOffsetInSection() != 0
|| section_part.GetLength() != section->GetFileSize()) {
- GetModule()->ReportWarning(
+ obj_file->GetModule()->ReportWarning(
"Unable to read only part %" PRIu64 "+%" PRIu64
" of compressed section '%s'",
section_part.GetOffsetInSection(), section_part.GetLength(),
section->GetName().GetCString());
- section_data.Clear();
- return 0;
+ return llvm::object::createError(
+ "Unable to read only part of compressed section");
}
-
- auto Decompressor = llvm::object::Decompressor::create(
+ {
+ auto reader_up = obj_file->ObjectFile::SectionReaderFactory(section_part);
+ if (!reader_up
+ || reader_up->read(compressed_data) != section->GetFileSize())
+ return llvm::object::createError("ReadSectionData failed");
+ }
+ auto decompressor = llvm::object::Decompressor::create(
section->GetName().GetStringRef(),
- {reinterpret_cast<const char *>(section_data.GetDataStart()),
- size_t(section_data.GetByteSize())},
- GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8);
- if (!Decompressor) {
- GetModule()->ReportWarning(
+ {reinterpret_cast<const char *>(compressed_data.GetDataStart()),
+ size_t(compressed_data.GetByteSize())},
+ obj_file->GetByteOrder() == eByteOrderLittle,
+ obj_file->GetAddressByteSize() == 8);
+ if (!decompressor)
+ obj_file->GetModule()->ReportWarning(
"Unable to initialize decompressor for section '%s': %s",
section->GetName().GetCString(),
- llvm::toString(Decompressor.takeError()).c_str());
- section_data.Clear();
+ llvm::toString(decompressor.takeError()).c_str());
+ return decompressor;
+}
+
+uint64_t ObjectFileELF::SectionReaderCompressed::getDecompressedSize() {
+ if (!decompressor)
return 0;
+ return decompressor->getDecompressedSize();
+}
+
+size_t ObjectFileELF::SectionReaderCompressed::read(
+ DataExtractor §ion_data) {
+ auto buffer_sp = std::make_shared<DataBufferHeap>(getDecompressedSize(), 0);
+ size_t retval = read(buffer_sp->GetBytes());
+ if (retval == 0)
+ section_data.Clear();
+ else {
+ Section *section = section_part.GetSection();
+ ObjectFile *obj_file = section->GetObjectFile();
+
+ section_data.SetData(buffer_sp);
+ section_data.SetByteOrder(obj_file->GetByteOrder());
+ section_data.SetAddressByteSize(obj_file->GetAddressByteSize());
}
+ return retval;
+}
- auto buffer_sp =
- std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0);
- if (auto error = Decompressor->decompress(
- {reinterpret_cast<char *>(buffer_sp->GetBytes()),
- size_t(buffer_sp->GetByteSize())})) {
- GetModule()->ReportWarning(
+size_t ObjectFileELF::SectionReaderCompressed::read(uint8_t *dst) {
+ if (!decompressor)
+ return 0;
+ if (auto error = decompressor->decompress(
+ {reinterpret_cast<char *>(dst), size_t(getDecompressedSize())})) {
+ Section *section = section_part.GetSection();
+ ObjectFile *obj_file = section->GetObjectFile();
+ obj_file->GetModule()->ReportWarning(
"Decompression of section '%s' failed: %s",
section->GetName().GetCString(),
llvm::toString(std::move(error)).c_str());
- section_data.Clear();
return 0;
}
+ return getDecompressedSize();
+}
- section_data.SetData(buffer_sp);
- return buffer_sp->GetByteSize();
+std::unique_ptr<ObjectFile::SectionReader>
+ObjectFileELF::SectionReaderFactory(const SectionPart §ion_part) {
+ if (!section_part)
+ return ObjectFile::SectionReaderFactory(section_part);
+ Section *section = section_part.GetSection();
+ if (section->GetFileSize() == 0 || !section->Test(SHF_COMPRESSED))
+ return ObjectFile::SectionReaderFactory(section_part);
+ return llvm::make_unique<SectionReaderCompressed>(section_part);
}
llvm::ArrayRef<ELFProgramHeader> ObjectFileELF::ProgramHeaders() {
Index: lldb/source/Core/Section.cpp
===================================================================
--- lldb/source/Core/Section.cpp
+++ lldb/source/Core/Section.cpp
@@ -104,6 +104,8 @@
return "dwarf-str-offsets-dwo";
case eSectionTypeDWARFDebugTypes:
return "dwarf-types";
+ case eSectionTypeDWARFDebugTypesDwo:
+ return "dwarf-types-dwo";
case eSectionTypeDWARFDebugNames:
return "dwarf-names";
case eSectionTypeELFSymbolTable:
Index: lldb/include/lldb/lldb-enumerations.h
===================================================================
--- lldb/include/lldb/lldb-enumerations.h
+++ lldb/include/lldb/lldb-enumerations.h
@@ -718,6 +718,7 @@
eSectionTypeDWARFDebugInfoDwo,
eSectionTypeDWARFDebugStrDwo,
eSectionTypeDWARFDebugStrOffsetsDwo,
+ eSectionTypeDWARFDebugTypesDwo,
};
FLAGS_ENUM(EmulateInstructionOptions){
Index: lldb/include/lldb/Symbol/ObjectFile.h
===================================================================
--- lldb/include/lldb/Symbol/ObjectFile.h
+++ lldb/include/lldb/Symbol/ObjectFile.h
@@ -736,8 +736,8 @@
// This function will transparently decompress section data if the section if
// compressed. Note that for compressed section the resulting data size may
// be larger than what Section::GetFileSize reports.
- virtual size_t ReadSectionData(const SectionPart §ion_part,
- DataExtractor §ion_data);
+ size_t ReadSectionData(const SectionPart §ion_part,
+ DataExtractor §ion_data);
bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; }
@@ -765,6 +765,26 @@
//------------------------------------------------------------------
virtual std::vector<LoadableData> GetLoadableData(Target &target);
+ // Similar to ReadSectionData() but you can ask final (decompressed for
+ // compressed sections) size before really reading the data to an adress.
+ class SectionReader;
+ virtual std::unique_ptr<SectionReader> SectionReaderFactory(
+ const SectionPart §ion_part);
+ class SectionReader {
+ public:
+ virtual uint64_t getDecompressedSize();
+ virtual size_t read(DataExtractor §ion_data);
+ virtual size_t read(uint8_t *dst);
+ virtual ~SectionReader();
+ protected:
+ friend std::unique_ptr<SectionReader> ObjectFile::SectionReaderFactory(
+ const SectionPart §ion_part);
+ SectionReader(const SectionPart §ion_part_);
+ const SectionPart §ion_part;
+ };
+
+ lldb::ProcessWP &GetProcessWP() { return m_process_wp; }
+
protected:
//------------------------------------------------------------------
// Member variables.
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits