[Lldb-commits] [lldb] 00539d8 - [lldb/DWARF] Support the debug_str_offsets section in dwp files
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Tue Feb 18 02:02:46 PST 2020
Author: Pavel Labath
Date: 2020-02-18T11:02:34+01:00
New Revision: 00539d8b6425529240d970082c23e6ee1263669b
URL: https://github.com/llvm/llvm-project/commit/00539d8b6425529240d970082c23e6ee1263669b
DIFF: https://github.com/llvm/llvm-project/commit/00539d8b6425529240d970082c23e6ee1263669b.diff
LOG: [lldb/DWARF] Support the debug_str_offsets section in dwp files
Summary:
In dwp files a constant (from the debug_cu_index section) needs to be
added to each reference into the debug_str_offsets section.
I've tried to implement this to roughly match the llvm flow: I've
changed the DWARFormValue to stop resolving the indirect string
references directly -- instead, it calls into DWARFUnit, which resolves
this for it (similar to how it already resolves indirect range and
location list references). I've also done a small refactor of the string
offset base computation code in DWARFUnit in order to make it easier to
access the debug_cu_index base offset.
Reviewers: JDevlieghere, aprantl, clayborg
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D74723
Added:
Modified:
lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
lldb/test/Shell/SymbolFile/DWARF/dwp.s
Removed:
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index d1a27981f025..83cda24a27d2 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -454,40 +454,26 @@ void DWARFFormValue::Dump(Stream &s) const {
}
const char *DWARFFormValue::AsCString() const {
- SymbolFileDWARF &symbol_file = m_unit->GetSymbolFileDWARF();
+ DWARFContext &context = m_unit->GetSymbolFileDWARF().GetDWARFContext();
- if (m_form == DW_FORM_string) {
+ if (m_form == DW_FORM_string)
return m_value.value.cstr;
- } else if (m_form == DW_FORM_strp) {
- return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(
- m_value.value.uval);
- } else if (m_form == DW_FORM_GNU_str_index) {
- uint32_t index_size = 4;
- lldb::offset_t offset = m_value.value.uval * index_size;
- dw_offset_t str_offset =
- symbol_file.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64(
- &offset, index_size);
- return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(
- str_offset);
- }
-
- if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 ||
- m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 ||
- m_form == DW_FORM_strx4) {
-
- // The same code as above.
- uint32_t indexSize = 4;
- lldb::offset_t offset =
- m_unit->GetStrOffsetsBase() + m_value.value.uval * indexSize;
- dw_offset_t strOffset =
- symbol_file.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64(
- &offset, indexSize);
- return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(strOffset);
+ if (m_form == DW_FORM_strp)
+ return context.getOrLoadStrData().PeekCStr(m_value.value.uval);
+
+ if (m_form == DW_FORM_GNU_str_index || m_form == DW_FORM_strx ||
+ m_form == DW_FORM_strx1 || m_form == DW_FORM_strx2 ||
+ m_form == DW_FORM_strx3 || m_form == DW_FORM_strx4) {
+
+ llvm::Optional<uint64_t> offset =
+ m_unit->GetStringOffsetSectionItem(m_value.value.uval);
+ if (!offset)
+ return nullptr;
+ return context.getOrLoadStrData().PeekCStr(*offset);
}
if (m_form == DW_FORM_line_strp)
- return symbol_file.GetDWARFContext().getOrLoadLineStrData().PeekCStr(
- m_value.value.uval);
+ return context.getOrLoadLineStrData().PeekCStr(m_value.value.uval);
return nullptr;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 37e52331faca..6ff3601ab049 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -259,23 +259,32 @@ void DWARFUnit::ExtractDIEsRWLocked() {
// .debug_str_offsets. At the same time, the corresponding split debug unit also
// may use DW_FORM_strx* forms pointing to its own .debug_str_offsets.dwo and
// for that case, we should find the offset (skip the section header).
-static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) {
+void DWARFUnit::SetDwoStrOffsetsBase() {
lldb::offset_t baseOffset = 0;
- const DWARFDataExtractor &strOffsets =
- dwo_cu->GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData();
- uint64_t length = strOffsets.GetU32(&baseOffset);
- if (length == 0xffffffff)
- length = strOffsets.GetU64(&baseOffset);
+ if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
+ if (const auto *contribution = entry->getOffset(llvm::DW_SECT_STR_OFFSETS))
+ baseOffset = contribution->Offset;
+ else
+ return;
+ }
- // Check version.
- if (strOffsets.GetU16(&baseOffset) < 5)
- return;
+ if (GetVersion() >= 5) {
+ const DWARFDataExtractor &strOffsets =
+ GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData();
+ uint64_t length = strOffsets.GetU32(&baseOffset);
+ if (length == 0xffffffff)
+ length = strOffsets.GetU64(&baseOffset);
- // Skip padding.
- baseOffset += 2;
+ // Check version.
+ if (strOffsets.GetU16(&baseOffset) < 5)
+ return;
+
+ // Skip padding.
+ baseOffset += 2;
+ }
- dwo_cu->SetStrOffsetsBase(baseOffset);
+ SetStrOffsetsBase(baseOffset);
}
// m_die_array_mutex must be already held as read/write.
@@ -334,8 +343,10 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
}
}
- if (m_is_dwo)
+ if (m_is_dwo) {
+ SetDwoStrOffsetsBase();
return;
+ }
std::shared_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
m_dwarf.GetDwoSymbolFileForCompileUnit(*this, cu_die);
@@ -377,10 +388,6 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
dwo_cu->SetLoclistsBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32));
dwo_cu->SetBaseAddress(GetBaseAddress());
- for (size_t i = 0; i < dwo_symbol_file->DebugInfo()->GetNumUnits(); ++i) {
- DWARFUnit *unit = dwo_symbol_file->DebugInfo()->GetUnitAtIndex(i);
- SetDwoStrOffsetsBase(unit);
- }
m_dwo = std::shared_ptr<DWARFUnit>(std::move(dwo_symbol_file), dwo_cu);
}
@@ -900,6 +907,12 @@ uint32_t DWARFUnit::GetHeaderByteSize() const {
llvm_unreachable("invalid UnitType.");
}
+llvm::Optional<uint64_t>
+DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const {
+ offset_t offset = GetStrOffsetsBase() + index * 4;
+ return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetU32(&offset);
+}
+
llvm::Expected<DWARFRangeList>
DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
if (GetVersion() <= 4) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index f0f293f64a39..f15086d9504d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -59,6 +59,9 @@ class DWARFUnitHeader {
dw_offset_t GetLength() const { return m_length; }
dw_offset_t GetAbbrOffset() const { return m_abbr_offset; }
uint8_t GetUnitType() const { return m_unit_type; }
+ const llvm::DWARFUnitIndex::Entry *GetIndexEntry() const {
+ return m_index_entry;
+ }
uint64_t GetTypeHash() const { return m_type_hash; }
dw_offset_t GetTypeOffset() const { return m_type_offset; }
bool IsTypeUnit() const {
@@ -215,6 +218,8 @@ class DWARFUnit : public lldb_private::UserID {
uint8_t GetUnitType() const { return m_header.GetUnitType(); }
bool IsTypeUnit() const { return m_header.IsTypeUnit(); }
+ llvm::Optional<uint64_t> GetStringOffsetSectionItem(uint32_t index) const;
+
/// Return a list of address ranges resulting from a (possibly encoded)
/// range list starting at a given offset in the appropriate ranges section.
llvm::Expected<DWARFRangeList> FindRnglistFromOffset(dw_offset_t offset);
@@ -331,6 +336,7 @@ class DWARFUnit : public lldb_private::UserID {
void ClearDIEsRWLocked();
void AddUnitDIE(const DWARFDebugInfoEntry &cu_die);
+ void SetDwoStrOffsetsBase();
void ComputeCompDirAndGuessPathStyle();
void ComputeAbsolutePath();
diff --git a/lldb/test/Shell/SymbolFile/DWARF/dwp.s b/lldb/test/Shell/SymbolFile/DWARF/dwp.s
index 47ac804efd2c..23fcde872947 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/dwp.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/dwp.s
@@ -5,10 +5,10 @@
# RUN: %lldb %t -o "target variable A" -b | FileCheck %s
# RUN: lldb-test symbols %t | FileCheck %s --check-prefix=SYMBOLS
-# CHECK: (int) A = 0
-# CHECK: (int) A = 1
-# CHECK: (int) A = 2
-# CHECK: (int) A = 3
+# CHECK: (INT0) A = 0
+# CHECK: (INT1) A = 1
+# CHECK: (INT2) A = 2
+# CHECK: (INT3) A = 3
# SYMBOLS: Compile units:
# SYMBOLS-NEXT: CompileUnit{0x00000000}, language = "unknown", file = '0.c'
@@ -64,6 +64,15 @@ A\I:
# This deliberately excludes compile unit 4 to check test the case of a missing
# split unit.
.irpc I,0123
+ .section .debug_str.dwo,"e", at progbits
+.Lstr\I:
+ .byte 'I', 'N', 'T', '0'+\I, 0
+
+ .section .debug_str_offsets.dwo,"e", at progbits
+.Lstr_offsets\I:
+ .long .Lstr\I-.debug_str.dwo
+.Lstr_offsets_end\I:
+
.section .debug_abbrev.dwo,"e", at progbits
.Labbrev\I:
.byte \I*10+1 # Abbreviation Code
@@ -90,13 +99,22 @@ A\I:
.byte 36 # DW_TAG_base_type
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
- .byte 14 # DW_FORM_string
+ .byte 8 # DW_FORM_string
.byte 62 # DW_AT_encoding
.byte 11 # DW_FORM_data1
.byte 11 # DW_AT_byte_size
.byte 11 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
+ .byte \I*10+4 # Abbreviation Code
+ .byte 22 # DW_TAG_typedef
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .uleb128 0x1f02 # DW_FORM_GNU_str_index
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
.byte 0 # EOM(3)
.Labbrev_end\I:
@@ -112,10 +130,14 @@ A\I:
.byte '0'+\I, '.', 'c', 0 # DW_AT_name
.byte \I*10+2 # Abbrev DW_TAG_variable
.asciz "A" # DW_AT_name
- .long .Ltype\I-.Lcu_begin\I # DW_AT_type
+ .long .Ltypedef\I-.Lcu_begin\I# DW_AT_type
.byte 2 # DW_AT_location
.byte 0xfb # DW_OP_GNU_addr_index
.byte \I
+.Ltypedef\I:
+ .byte \I*10+4 # Abbrev DW_TAG_typedef
+ .byte 0 # DW_AT_name
+ .long .Ltype\I-.Lcu_begin\I # DW_AT_type
.Ltype\I:
.byte \I*10+3 # Abbrev DW_TAG_base_type
.asciz "int" # DW_AT_name
@@ -128,22 +150,26 @@ A\I:
.section .debug_cu_index,"e", at progbits
.short 2 # DWARF version number
.short 0 # Reserved
- .long 2 # Section count
+ .long 3 # Section count
.long 4 # Unit count
.long 8 # Slot count
.quad 0, 1, 2, 3, 0, 0, 0, 0 # Hash table
.long 1, 2, 3, 4, 0, 0, 0, 0 # Index table
- .long 1, 3 # DW_SECT_INFO, DW_SECT_ABBREV
+ .long 1 # DW_SECT_INFO
+ .long 3 # DW_SECT_ABBREV
+ .long 6 # DW_SECT_STR_OFFSETS
.irpc I,0123
.long .Lcu_begin\I-.debug_info.dwo
.long .Labbrev\I-.debug_abbrev.dwo
+ .long .Lstr_offsets\I-.debug_str_offsets.dwo
.endr
.irpc I,0123
.long .Ldebug_info_end\I-.Lcu_begin\I
.long .Labbrev_end\I-.Labbrev\I
+ .long .Lstr_offsets_end\I-.Lstr_offsets\I
.endr
.endif
More information about the lldb-commits
mailing list