jankratochvil updated this revision to Diff 170342.
jankratochvil added a comment.
Herald added a subscriber: arphaman.
Patch `concat` = original posting with `DWARFConcatenatingDataExtractor` used
only for `.debug_info`(+`.debug_types`) section. download
<https://people.redhat.com/jkratoch/concat.patch>
Patch `concat2` = used `DWARFDataExtractor` with integrated concatenation for
all DWARF sections. download <https://people.redhat.com/jkratoch/concat2.patch>
master real=0.996s user=14.744s sys=1.050s
concat real=0.994s user=15.524s sys=1.117s
concat2 real=1.001s user=15.580s sys=1.334s
`concat` vs. `concat2` benchmark difference was mostly a measurement error. It
is now 5% slowdown compared to trunk - even for former `concat` which I do not
understand now, I will investigate it more as my original measured slowdown was
just 1% before.
`concat2` sometimes needs to cast `DWARFDataExtractor` to `DataExtractor` by
`.AsDataExtractor()` as some functions expected a contiguous block of memory.
That is a method applicable only for non-`.debug_info` sections (it would
assert on `.debug_info`). It needs to be called as `DWARFDataExtractor` can no
longer inherit `DataExtractor`. I did not use `operator DataExtractor &` as it
could accidentally by applied to `.debug_info` which may be difficult to catch
when not tested with `-fdebug-types-section`.
`DataExtractorConcat` is a separate class but it is never used separately
without `DWARFDataExtractor` inheriting it.
Greg, do you mean it somehow way or do I miss something? Personally I may like
a bit more `concat` but then the patch size is almost the same for both.
Repository:
rLLDB LLDB
https://reviews.llvm.org/D51578
Files:
source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
source/Plugins/SymbolFile/DWARF/DWARFUnit.h
source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
@@ -105,9 +105,11 @@
auto *offsets =
it->second->getOffset(lldbSectTypeToLlvmSectionKind(sect_type));
if (offsets) {
- data.SetData(section_data, offsets->Offset, offsets->Length);
+ data.AsDataExtractor().SetData(
+ section_data.AsDataExtractor(), offsets->Offset, offsets->Length);
} else {
- data.SetData(section_data, 0, section_data.GetByteSize());
+ data.AsDataExtractor().SetData(
+ section_data.AsDataExtractor(), 0, section_data.GetByteSize());
}
return true;
}
@@ -131,12 +133,13 @@
lldb::SectionSP section_sp(
section_list->FindSectionByType(sect_type, true));
if (section_sp) {
- if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) {
+ if (m_obj_file->ReadSectionData(
+ section_sp.get(), data.AsDataExtractor()) != 0) {
m_sections[sect_type] = data;
return true;
}
}
}
- m_sections[sect_type].Clear();
+ m_sections[sect_type].AsDataExtractor().Clear();
return false;
}
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -36,15 +36,17 @@
if (section_sp) {
// See if we memory mapped the DWARF segment?
if (m_dwarf_data.GetByteSize()) {
- data.SetData(m_dwarf_data, section_sp->GetOffset(),
- section_sp->GetFileSize());
+ data.AsDataExtractor().SetData(m_dwarf_data.AsDataExtractor(),
+ section_sp->GetOffset(),
+ section_sp->GetFileSize());
return;
}
- if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
+ if (m_obj_file->ReadSectionData(
+ section_sp.get(), data.AsDataExtractor()) != 0)
return;
- data.Clear();
+ data.AsDataExtractor().Clear();
}
}
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -240,15 +240,16 @@
const lldb_private::DWARFDataExtractor &get_debug_aranges_data();
const lldb_private::DWARFDataExtractor &get_debug_frame_data();
const lldb_private::DWARFDataExtractor &get_debug_info_data();
+ const lldb_private::DWARFDataExtractor &get_raw_debug_info_data();
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();
const lldb_private::DWARFDataExtractor &get_debug_loc_data();
const lldb_private::DWARFDataExtractor &get_debug_ranges_data();
const lldb_private::DWARFDataExtractor &get_debug_rnglists_data();
const lldb_private::DWARFDataExtractor &get_debug_str_data();
const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data();
- const lldb_private::DWARFDataExtractor &get_debug_types_data();
+ const lldb_private::DWARFDataExtractor &get_raw_debug_types_data();
const lldb_private::DWARFDataExtractor &get_apple_names_data();
const lldb_private::DWARFDataExtractor &get_apple_types_data();
const lldb_private::DWARFDataExtractor &get_apple_namespaces_data();
@@ -486,6 +487,9 @@
DWARFDataSegment m_data_apple_objc;
DWARFDataSegment m_data_gnu_debugaltlink;
+ llvm::once_flag m_concatenated_data_once;
+ lldb_private::DWARFDataExtractor m_data_debug_info_concatenated;
+
// The unique pointer items below are generated on demand if and when someone
// accesses
// them through a non const version of this class.
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -453,7 +453,7 @@
section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
if (section)
- m_obj_file->ReadSectionData(section, m_dwarf_data);
+ m_obj_file->ReadSectionData(section, m_dwarf_data.AsDataExtractor());
}
if (!GetGlobalPluginProperties()->IgnoreFileIndexes()) {
@@ -577,24 +577,8 @@
const DWARFDataExtractor &
SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type,
DWARFDataSegment &data_segment) {
- llvm::call_once(data_segment.m_flag, [&] {
+ llvm::call_once(data_segment.m_flag, [this, sect_type, &data_segment] {
this->LoadSectionData(sect_type, std::ref(data_segment.m_data));
- if (sect_type == eSectionTypeDWARFDebugTypes) {
- // To add .debug_types support in DWARF 4 and earlier with minimally
- // invasive changes to the current DWARF parsing code, we pretend that
- // any DIEs in .debug_types start at the end of the .debug_info section.
- // All info in .debug_types is relative and has no external DIE
- // references unless thay are DW_AT_signature references, so the DIE
- // offset for things in the .debug_types. If we do this, then we can
- // just add the type units to the compile units collection and treat all
- // information just as we do for all other information in the DWARF and
- // everything just works. If we were to try to split this out, we would
- // end up having to change a TON of code. Also DWARF 5 will have compile
- // and type units in the .debug_info, so coding it this way will prepare
- // use for an easy transition to DWARF 5.
- uint64_t debug_info_size = get_debug_info_data().GetByteSize();
- data_segment.m_data.OffsetData(debug_info_size);
- }
});
return data_segment.m_data;
}
@@ -608,11 +592,13 @@
if (section_sp) {
// See if we memory mapped the DWARF segment?
if (m_dwarf_data.GetByteSize()) {
- data.SetData(m_dwarf_data, section_sp->GetOffset(),
- section_sp->GetFileSize());
+ data.AsDataExtractor().SetData(
+ m_dwarf_data.AsDataExtractor(), section_sp->GetOffset(),
+ section_sp->GetFileSize());
} else {
- if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0)
- data.Clear();
+ if (m_obj_file->ReadSectionData(
+ section_sp.get(), data.AsDataExtractor()) == 0)
+ data.AsDataExtractor().Clear();
}
}
}
@@ -636,7 +622,7 @@
return GetCachedSectionData(eSectionTypeDWARFDebugFrame, m_data_debug_frame);
}
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() {
+const DWARFDataExtractor &SymbolFileDWARF::get_raw_debug_info_data() {
return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info);
}
@@ -675,7 +661,7 @@
m_data_debug_str_offsets);
}
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_types_data() {
+const DWARFDataExtractor &SymbolFileDWARF::get_raw_debug_types_data() {
return GetCachedSectionData(eSectionTypeDWARFDebugTypes, m_data_debug_types);
}
@@ -701,6 +687,18 @@
m_data_gnu_debugaltlink);
}
+const DWARFDataExtractor &
+ SymbolFileDWARF::get_debug_info_data() {
+ llvm::call_once(m_concatenated_data_once, [&] {
+ m_data_debug_info_concatenated.SetDataExtractors(
+ const_cast<DWARFDataExtractor &>(get_raw_debug_info_data())
+ .AsDataExtractor(),
+ const_cast<DWARFDataExtractor &>(get_raw_debug_types_data())
+ .AsDataExtractor());
+ });
+ return m_data_debug_info_concatenated;
+}
+
DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
if (m_abbr.get() == NULL) {
const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
@@ -3248,10 +3246,12 @@
auto debug_info_data = die.GetData();
if (DWARFFormValue::IsBlockForm(form_value.Form())) {
// Retrieve the value as a block expression.
+ const DataExtractor &block_extractor =
+ debug_info_data.GetDataExtractor(form_value.BlockData());
uint32_t block_offset =
- form_value.BlockData() - debug_info_data.GetDataStart();
+ form_value.BlockData() - block_extractor.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location.CopyOpcodeData(module, debug_info_data, block_offset,
+ location.CopyOpcodeData(module, block_extractor, block_offset,
block_length);
} else if (DWARFFormValue::IsDataForm(form_value.Form())) {
// Retrieve the value as a data expression.
@@ -3271,9 +3271,15 @@
// create the variable
const_value = form_value;
}
- } else
- location.CopyOpcodeData(module, debug_info_data, data_offset,
- data_length);
+ } else {
+ lldb::offset_t block_extractor_offset;
+ const DataExtractor &block_extractor =
+ debug_info_data.GetDataExtractor(
+ data_offset, &block_extractor_offset);
+ location.CopyOpcodeData(
+ module, block_extractor,
+ data_offset - block_extractor_offset, data_length);
+ }
} else {
// Retrieve the value as a string expression.
if (form_value.Form() == DW_FORM_strp) {
@@ -3283,16 +3289,24 @@
->GetAddressByteSize(),
attributes.CompileUnitAtIndex(i)->IsDWARF64());
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
+ lldb::offset_t block_extractor_offset;
+ const DataExtractor &block_extractor =
+ debug_info_data.GetDataExtractor(
+ data_offset, &block_extractor_offset);
uint32_t data_length =
fixed_form_sizes.GetSize(form_value.Form());
- location.CopyOpcodeData(module, debug_info_data, data_offset,
- data_length);
+ location.CopyOpcodeData(
+ module, block_extractor,
+ data_offset - block_extractor_offset, data_length);
} else {
const char *str = form_value.AsCString();
+ const DataExtractor &block_extractor =
+ debug_info_data.GetDataExtractor(
+ (const uint8_t *)str);
uint32_t string_offset =
- str - (const char *)debug_info_data.GetDataStart();
+ str - (const char *)block_extractor.GetDataStart();
uint32_t string_length = strlen(str) + 1;
- location.CopyOpcodeData(module, debug_info_data,
+ location.CopyOpcodeData(module, block_extractor,
string_offset, string_length);
}
}
@@ -3304,19 +3318,24 @@
if (DWARFFormValue::IsBlockForm(form_value.Form())) {
auto data = die.GetData();
+ const DataExtractor &block_extractor =
+ data.GetDataExtractor(form_value.BlockData());
uint32_t block_offset =
- form_value.BlockData() - data.GetDataStart();
+ form_value.BlockData() - block_extractor.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location.CopyOpcodeData(module, data, block_offset, block_length);
+ location.CopyOpcodeData(
+ module, block_extractor, block_offset, block_length);
} else {
const DWARFDataExtractor &debug_loc_data = get_debug_loc_data();
const dw_offset_t debug_loc_offset = form_value.Unsigned();
size_t loc_list_length = DWARFExpression::LocationListSize(
- die.GetCU(), debug_loc_data, debug_loc_offset);
+ die.GetCU(), debug_loc_data.AsDataExtractor(),
+ debug_loc_offset);
if (loc_list_length > 0) {
- location.CopyOpcodeData(module, debug_loc_data,
- debug_loc_offset, loc_list_length);
+ location.CopyOpcodeData(
+ module, debug_loc_data.AsDataExtractor(), debug_loc_offset,
+ loc_list_length);
assert(func_low_pc != LLDB_INVALID_ADDRESS);
location.SetLocationListSlide(
func_low_pc -
Index: source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -348,7 +348,8 @@
DWARFMappedHash::MemoryTable::MemoryTable(
lldb_private::DWARFDataExtractor &table_data,
const lldb_private::DWARFDataExtractor &string_table, const char *name)
- : MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray>(table_data),
+ : MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray>(
+ table_data.AsDataExtractor()),
m_data(table_data), m_string_table(string_table), m_name(name) {}
const char *
Index: source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -17,7 +17,7 @@
using namespace lldb_private;
using namespace lldb;
-static llvm::DWARFDataExtractor ToLLVM(const DWARFDataExtractor &data) {
+static llvm::DWARFDataExtractor ToLLVM(const DataExtractor &data) {
return llvm::DWARFDataExtractor(
llvm::StringRef(reinterpret_cast<const char *>(data.GetDataStart()),
data.GetByteSize()),
@@ -32,8 +32,9 @@
return llvm::make_error<llvm::StringError>("debug info null",
llvm::inconvertibleErrorCode());
}
- auto index_up =
- llvm::make_unique<DebugNames>(ToLLVM(debug_names), ToLLVM(debug_str));
+ auto index_up = llvm::make_unique<DebugNames>(
+ ToLLVM(debug_names.AsDataExtractor()),
+ ToLLVM(debug_str.AsDataExtractor()));
if (llvm::Error E = index_up->extract())
return std::move(E);
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -79,7 +79,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: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -829,3 +829,6 @@
return false;
}
+const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const {
+ return m_dwarf->get_debug_info_data();
+}
Index: source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
@@ -24,17 +24,6 @@
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: source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
@@ -51,13 +51,3 @@
// unit offset to ensure we get the correct DIE.
return GetDIE(GetTypeUnitDIEOffset());
}
-
-const lldb_private::DWARFDataExtractor &DWARFTypeUnit::GetData() const {
- // In DWARF 5, type units are in the .debug_info section. Prior to DWARF 5
- // type units are in the .debug_types section.
- if (GetVersion() < 5)
- return m_dwarf->get_debug_types_data();
- else
- return m_dwarf->get_debug_info_data();
-}
-
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -524,20 +524,23 @@
case DW_AT_frame_base:
if (frame_base) {
if (form_value.BlockData()) {
- uint32_t block_offset =
- form_value.BlockData() - debug_info_data.GetDataStart();
+ const DataExtractor &block_extractor =
+ debug_info_data.GetDataExtractor(form_value.BlockData());
+ uint32_t block_offset = form_value.BlockData()
+ - block_extractor.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- frame_base->SetOpcodeData(module, debug_info_data, block_offset,
+ frame_base->SetOpcodeData(module, block_extractor, 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);
+ cu, debug_loc_data.AsDataExtractor(), debug_loc_offset);
if (loc_list_length > 0) {
- frame_base->SetOpcodeData(module, debug_loc_data,
+ frame_base->SetOpcodeData(module,
+ debug_loc_data.AsDataExtractor(),
debug_loc_offset, loc_list_length);
if (lo_pc != LLDB_INVALID_ADDRESS) {
assert(lo_pc >= cu->GetBaseAddress());
@@ -621,8 +624,8 @@
dw_attr_t attr;
abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
- DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr,
- form_value);
+ DumpAttribute(dwarf2Data, cu, debug_info_data, &offset,
+ s, attr, form_value);
}
const DWARFDebugInfoEntry *child = GetFirstChild();
@@ -714,19 +717,23 @@
case DW_AT_data_member_location: {
const uint8_t *blockData = form_value.BlockData();
if (blockData) {
+ uint64_t form_data_offset;
+ const DataExtractor &form_data =
+ debug_info_data.GetDataExtractor(blockData, &form_data_offset);
// Location description is inlined in data in the form value
- DWARFDataExtractor locationData(debug_info_data,
- (*offset_ptr) - form_value.Unsigned(),
- form_value.Unsigned());
+ DataExtractor locationData(
+ form_data, (*offset_ptr) - form_value.Unsigned() - form_data_offset,
+ form_value.Unsigned());
DWARFExpression::PrintDWARFExpression(
s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false);
} 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) {
DWARFExpression::PrintDWARFLocationList(
- s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
+ s, cu, dwarf2Data->get_debug_loc_data().AsDataExtractor(),
+ debug_loc_offset);
}
}
} break;
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -104,8 +104,11 @@
lldb::offset_t offset = 0;
DWARFCompileUnitSP cu_sp;
const auto &debug_info_data = m_dwarf2Data->get_debug_info_data();
- while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data,
- &offset))) {
+ const uint64_t raw_debug_info_data_size =
+ m_dwarf2Data->get_raw_debug_info_data().GetByteSize();
+ while (offset < raw_debug_info_data_size
+ && (cu_sp = DWARFCompileUnit::Extract(
+ m_dwarf2Data, debug_info_data, &offset))) {
m_compile_units.push_back(cu_sp);
offset = cu_sp->GetNextCompileUnitOffset();
}
@@ -119,15 +122,8 @@
// types in the .debug_types to have a unique DIE offset that is:
// offset = sizeof(.debug_info) + debug_type_offset
//
- // So below we set "offset" to be the size of the .debug_info section. We have
- // modified the debug_types_data to know that its first byte starts at this
- // offset.
- auto debug_types_data = m_dwarf2Data->get_debug_types_data();
- if (debug_types_data.GetByteSize() == 0)
- return;
- offset = debug_info_data.GetByteSize();
DWARFTypeUnitSP tu_sp;
- while ((tu_sp = DWARFTypeUnit::Extract(m_dwarf2Data, debug_types_data,
+ while ((tu_sp = DWARFTypeUnit::Extract(m_dwarf2Data, debug_info_data,
&offset))) {
m_type_sig_to_cu_index[tu_sp->GetTypeSignature()] = m_compile_units.size();
m_compile_units.push_back(tu_sp);
Index: source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
@@ -10,55 +10,191 @@
#ifndef liblldb_DWARFDataExtractor_h_
#define liblldb_DWARFDataExtractor_h_
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/LLDBAssert.h"
+
// Other libraries and framework includes.
#include "lldb/Core/dwarf.h"
-#include "lldb/Utility/DataExtractor.h"
namespace lldb_private {
-class DWARFDataExtractor : public DataExtractor {
+class DataExtractorConcat {
public:
- DWARFDataExtractor() : DataExtractor(), m_is_dwarf64(false) {}
+ DataExtractorConcat();
+ void SetDataExtractors(DataExtractor &extractor1, DataExtractor &extractor2);
+ inline const DataExtractor &GetDataExtractor(
+ const uint8_t *inner, uint64_t *extractor_offsetp = nullptr) const;
+ inline const DataExtractor &GetDataExtractor(
+ lldb::offset_t offset, lldb::offset_t *extractor_offsetp) const {
+ return offset_to_extractor(offset, extractor_offsetp);
+ }
+ inline DataExtractor &AsDataExtractor();
+ inline const DataExtractor &AsDataExtractor() const;
+ inline uint64_t GetByteSize() const;
+ inline uint32_t GetAddressByteSize() const;
+ inline lldb::ByteOrder GetByteOrder() const;
+ // forwarder-based implementation would assert on out of bound 'offset'.
+ bool ValidOffset(lldb::offset_t offset) const;
- DWARFDataExtractor(const DWARFDataExtractor &data, lldb::offset_t offset,
- lldb::offset_t length)
- : DataExtractor(data, offset, length), m_is_dwarf64(false) {}
+#define FORWARDER(FuncName, RetType, ParamListParen, ...) \
+ inline RetType FuncName ParamListParen const { \
+ return forwarder<RetType, DataExtractor>( \
+ &DataExtractor::FuncName, __VA_ARGS__); \
+ }
+ FORWARDER(GetFloat, float,
+ (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetDouble, double,
+ (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetLongDouble, long double,
+ (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetMaxU32, uint32_t,
+ (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size)
+ FORWARDER(GetMaxU64, uint64_t,
+ (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size)
+ FORWARDER(GetMaxU64_unchecked, uint64_t,
+ (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size)
+ FORWARDER(GetMaxS64, int64_t,
+ (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size)
+ FORWARDER(GetMaxU64Bitfield, uint64_t,
+ (lldb::offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset),
+ offset_ptr, size, bitfield_bit_size, bitfield_bit_offset)
+ FORWARDER(GetMaxS64Bitfield, int64_t,
+ (lldb::offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset),
+ offset_ptr, size, bitfield_bit_size, bitfield_bit_offset)
+ FORWARDER(GetPointer, uint64_t, (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetU8, uint8_t, (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetU8_unchecked, uint8_t, (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetU16_unchecked, uint16_t,
+ (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetU32_unchecked, uint32_t,
+ (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetU64_unchecked, uint64_t,
+ (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetU8, void *,
+ (lldb::offset_t *offset_ptr, void *dst, uint32_t count),
+ offset_ptr, dst, count)
+ FORWARDER(GetU16, uint16_t, (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetU16, void *,
+ (lldb::offset_t *offset_ptr, void *dst, uint32_t count),
+ offset_ptr, dst, count)
+ FORWARDER(GetU32, uint32_t, (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetU32, void *,
+ (lldb::offset_t *offset_ptr, void *dst, uint32_t count),
+ offset_ptr, dst, count)
+ FORWARDER(GetU64, uint64_t, (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetU64, void *,
+ (lldb::offset_t *offset_ptr, void *dst, uint32_t count),
+ offset_ptr, dst, count)
+ FORWARDER(GetSLEB128, int64_t, (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(GetULEB128, uint64_t, (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(PeekCStr, const char *, (lldb::offset_t offset), offset)
+ FORWARDER(PeekData, const uint8_t *,
+ (lldb::offset_t offset, lldb::offset_t length), offset, length)
+ FORWARDER(GetCStr, const char *, (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(Skip_LEB128, uint32_t, (lldb::offset_t *offset_ptr), offset_ptr)
+ FORWARDER(ValidOffsetForDataOfSize, bool,
+ (lldb::offset_t offset, lldb::offset_t length), offset, length)
+#undef FORWARDER
- uint64_t GetDWARFInitialLength(lldb::offset_t *offset_ptr) const;
+private:
+ const DataExtractor &offset_to_extractor_slow(lldb::offset_t offset,
+ lldb::offset_t *extractor_offsetp) const;
+ inline const DataExtractor &offset_to_extractor(lldb::offset_t offset,
+ lldb::offset_t *extractor_offsetp) const;
+ const DataExtractor &GetDataExtractor_slow(
+ const uint8_t *inner, uint64_t *extractor_offsetp) const;
+ uint64_t GetByteSize_slow() const;
+ uint32_t GetAddressByteSize_slow() const;
+ lldb::ByteOrder GetByteOrder_slow() const;
+ template<class RetType, class Extractor, class... Args>
+ inline RetType forwarder(
+ RetType (Extractor::*mptr)(lldb::offset_t *offset_ptr, Args...) const,
+ lldb::offset_t *offset_ptr, Args... args) const {
+ lldb::offset_t extractor_offset;
+ const Extractor &extractor =
+ offset_to_extractor(*offset_ptr, &extractor_offset);
+ *offset_ptr -= extractor_offset;
+ RetType retval = (extractor.*mptr)(offset_ptr, std::forward<Args>(args)...);
+ *offset_ptr += extractor_offset;
+ return retval;
+ }
+ template<class RetType, class Extractor, class... Args>
+ inline RetType forwarder(
+ RetType (Extractor::*mptr)(lldb::offset_t offset, Args...) const,
+ lldb::offset_t offset, Args... args) const {
+ lldb::offset_t extractor_offset;
+ const Extractor &extractor = offset_to_extractor(offset, &extractor_offset);
+ offset -= extractor_offset;
+ return (extractor.*mptr)(offset, std::forward<Args>(args)...);
+ }
- dw_offset_t GetDWARFOffset(lldb::offset_t *offset_ptr) const;
+ llvm::SmallVector<DataExtractor *, 2> m_extractors;
+ DataExtractor m_extractor_local;
+};
+
+const DataExtractor &DataExtractorConcat::offset_to_extractor(
+ lldb::offset_t offset, lldb::offset_t *extractor_offsetp) const {
+ if (extractor_offsetp)
+ *extractor_offsetp = 0;
+ if (m_extractors.size() == 1)
+ return *m_extractors[0];
+ return offset_to_extractor_slow(offset, extractor_offsetp);
+}
+
+uint64_t DataExtractorConcat::GetByteSize() const {
+ if (m_extractors.size() == 1)
+ return m_extractors[0]->GetByteSize();
+ return GetByteSize_slow();
+}
+
+uint32_t DataExtractorConcat::GetAddressByteSize() const {
+ if (m_extractors.size() == 1)
+ return m_extractors[0]->GetAddressByteSize();
+ return GetAddressByteSize_slow();
+}
+lldb::ByteOrder DataExtractorConcat::GetByteOrder() const {
+ if (m_extractors.size() == 1)
+ return m_extractors[0]->GetByteOrder();
+ return GetByteOrder_slow();
+}
+
+const DataExtractor &DataExtractorConcat::GetDataExtractor(
+ const uint8_t *inner, uint64_t *extractor_offsetp) const {
+ if (m_extractors.size() == 1) {
+ if (extractor_offsetp)
+ *extractor_offsetp = 0;
+ return *m_extractors[0];
+ }
+ return GetDataExtractor_slow(inner, extractor_offsetp);
+}
+
+// Use only if you are sure it is not .debug_info section.
+DataExtractor &DataExtractorConcat::AsDataExtractor() {
+ lldbassert(m_extractors.size() == 1);
+ return *m_extractors[0];
+}
+const DataExtractor &DataExtractorConcat::AsDataExtractor() const {
+ lldbassert(m_extractors.size() == 1);
+ return *m_extractors[0];
+}
+
+class DWARFDataExtractor : public DataExtractorConcat {
+public:
+ using DataExtractorConcat::DataExtractorConcat;
+
+ uint64_t GetDWARFInitialLength(lldb::offset_t *offset_ptr) const;
+ dw_offset_t GetDWARFOffset(lldb::offset_t *offset_ptr) const;
size_t GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; }
size_t GetDWARFSizeOfOffset() const { return m_is_dwarf64 ? 8 : 4; }
bool IsDWARF64() const { return m_is_dwarf64; }
- //------------------------------------------------------------------
- /// Slide the data in the buffer so that access to the data will
- /// start at offset \a offset.
- ///
- /// This is currently used to provide access to the .debug_types
- /// section and pretend it starts at at offset of the size of the
- /// .debug_info section. This allows a minimally invasive change to
- /// add support for .debug_types by allowing all DIEs to have unique
- /// offsets and thus allowing no code to change in the DWARF parser.
- /// Modifying the offsets in the .debug_types doesn't affect
- /// anything because since all info in the .debug_types is type unit
- /// relative and no types within a type unit can refer to any DIEs
- /// outside of the type unit without using DW_AT_signature. It also
- /// sets us up to move to DWARF5 where there is no .debug_types
- /// section as compile units and type units are in the .debug_info.
- ///
- /// @param[in] offset
- /// The amount to slide the data contents by.
- //------------------------------------------------------------------
- void OffsetData(lldb::offset_t offset) {
- if (GetByteSize())
- m_start -= offset;
- }
-
-protected:
- mutable bool m_is_dwarf64;
+private:
+ mutable bool m_is_dwarf64 = false;
};
+
}
#endif // liblldb_DWARFDataExtractor_h_
Index: source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
@@ -8,9 +8,80 @@
//===----------------------------------------------------------------------===//
#include "DWARFDataExtractor.h"
+#include "lldb/Utility/LLDBAssert.h"
namespace lldb_private {
+DataExtractorConcat::DataExtractorConcat()
+ : m_extractors({&m_extractor_local}) {}
+
+void DataExtractorConcat::SetDataExtractors(
+ DataExtractor &extractor1, DataExtractor &extractor2) {
+ m_extractors.clear();
+ if (extractor1.GetByteSize()||!extractor2.GetByteSize())
+ m_extractors.push_back(&extractor1);
+ if (extractor2.GetByteSize())
+ m_extractors.push_back(&extractor2);
+}
+
+const DataExtractor &
+ DataExtractorConcat::offset_to_extractor_slow(
+ lldb::offset_t offset, lldb::offset_t *extractor_offsetp) const {
+ for (const DataExtractor *extractorp : m_extractors) {
+ if (offset < extractorp->GetByteSize())
+ return *extractorp;
+ offset -= extractorp->GetByteSize();
+ if (extractor_offsetp)
+ *extractor_offsetp += extractorp->GetByteSize();
+ }
+ llvm_unreachable("offset out of range");
+}
+
+const DataExtractor &DataExtractorConcat::GetDataExtractor_slow(
+ const uint8_t *inner, uint64_t *extractor_offsetp) const {
+ if (extractor_offsetp)
+ *extractor_offsetp = 0;
+ for (const DataExtractor *extractorp : m_extractors) {
+ if (inner >= extractorp->GetDataStart() && inner < extractorp->GetDataEnd())
+ return *extractorp;
+ if (extractor_offsetp)
+ *extractor_offsetp += extractorp->GetByteSize();
+ }
+ llvm_unreachable("pointer out of range");
+}
+
+uint64_t DataExtractorConcat::GetByteSize_slow() const {
+ uint64_t retval = 0;
+ for (const DataExtractor *extractorp : m_extractors)
+ retval += extractorp->GetByteSize();
+ return retval;
+}
+
+uint32_t DataExtractorConcat::GetAddressByteSize_slow() const {
+ lldbassert(!m_extractors.empty());
+ for (size_t ix = 0; ix < m_extractors.size(); ++ix)
+ lldbassert(m_extractors[0]->GetAddressByteSize()
+ == m_extractors[ix]->GetAddressByteSize());
+ return m_extractors[0]->GetAddressByteSize();
+}
+
+lldb::ByteOrder DataExtractorConcat::GetByteOrder_slow() const {
+ lldbassert(!m_extractors.empty());
+ for (size_t ix = 0; ix < m_extractors.size(); ++ix)
+ lldbassert(m_extractors[0]->GetByteOrder()
+ == m_extractors[ix]->GetByteOrder());
+ return m_extractors[0]->GetByteOrder();
+}
+
+bool DataExtractorConcat::ValidOffset(lldb::offset_t offset) const {
+ for (const DataExtractor *extractorp : m_extractors) {
+ if (offset < extractorp->GetByteSize())
+ return true;
+ offset -= extractorp->GetByteSize();
+ }
+ return false;
+}
+
uint64_t
DWARFDataExtractor::GetDWARFInitialLength(lldb::offset_t *offset_ptr) const {
uint64_t length = GetU32(offset_ptr);
@@ -24,4 +95,5 @@
DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const {
return GetMaxU64(offset_ptr, GetDWARFSizeOfOffset());
}
+
}
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -19,16 +19,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: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -53,7 +53,3 @@
}
llvm_unreachable("invalid UnitType.");
}
-
-const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
- return m_dwarf->get_debug_info_data();
-}
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -655,7 +655,8 @@
if (form_value.BlockData()) {
Value initialValue(0);
Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data = die.GetData();
+ const DataExtractor &debug_info_data =
+ die.GetData().GetDataExtractor(form_value.BlockData());
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2778,7 +2778,8 @@
if (form_value.BlockData()) {
Value initialValue(0);
Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data = die.GetData();
+ const DataExtractor &debug_info_data =
+ die.GetData().GetDataExtractor(form_value.BlockData());
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
@@ -3230,7 +3231,8 @@
if (form_value.BlockData()) {
Value initialValue(0);
Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data = die.GetData();
+ const DataExtractor &debug_info_data =
+ die.GetData().GetDataExtractor(form_value.BlockData());
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits