grimar created this revision.
grimar added a reviewer: LLDB.
Herald added subscribers: JDevlieghere, arichardson, aprantl, emaste.
Herald added a reviewer: espindola.
grimar edited the summary of this revision.
This patch improves the support of DWARF5 by lldb.
Imagine we have the following code,
(compiled with `clang++ test.cpp -g -o test -gdwarf-5`):
struct XXX {
int A;
};
int main() {
XXX Obj;
Obj.A = 1;
return Obj.A;
}
Without this patch when lldb stops on a breakpoint or dump variables
the output is:
(lldb) b main
warning: (x86_64) /home/umb/tests_2018/95_lldb/repro/dwarf5_nosplit/test
unsupported DW_FORM value: 0x25
Breakpoint 1: where = test`main, address = 0x0000000000400550
(lldb) run
Process 5589 launched:
'/home/umb/tests_2018/95_lldb/repro/dwarf5_nosplit/test' (x86_64)
Process 5589 stopped
* thread #1, name = 'test', stop reason = breakpoint 1.1
frame #0: 0x0000000000400550 test`main
test`main:
-> 0x400550 <+0>: pushq %rbp
0x400551 <+1>: movq %rsp, %rbp
0x400554 <+4>: movl $0x0, -0x4(%rbp)
0x40055b <+11>: movl $0x1, -0x8(%rbp)
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
>>> print lldb.frame.GetVariables(True, True, True, True)
<empty> lldb.SBValueList()
Note that it complains about unknown forms,
there is no code source lines and output from the `print`
call is empty.
With the patch applied output becomes:
umb@umb-virtual-machine:~/LLVM/build_lldb/bin$ ./lldb
~/tests_2018/95_lldb/repro/dwarf5_nosplit/test
(lldb) target create "/home/umb/tests_2018/95_lldb/repro/dwarf5_nosplit/test"
Current executable set to
'/home/umb/tests_2018/95_lldb/repro/dwarf5_nosplit/test' (x86_64).
(lldb) b main
Breakpoint 1: where = test`main + 11 at test.cpp:7, address =
0x000000000040055b
(lldb) run
Process 63624 launched:
'/home/umb/tests_2018/95_lldb/repro/dwarf5_nosplit/test' (x86_64)
Process 63624 stopped
* thread #1, name = 'test', stop reason = breakpoint 1.1
frame #0: 0x000000000040055b test`main at test.cpp:7
4
5 int main() {
6 XXX Obj;
-> 7 Obj.A = 1;
8
9 return Obj.A;
10 }
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
>>> print lldb.frame.GetVariables(True, True, True, True)
(XXX) Obj = (A = 0)
Note there is no test case yet, I am going to add it to this revision soon.
This is my first patch for lldb and I did not yet learn how to write the
test for the code written.
I would be happy to see any comments/suggestions.
https://reviews.llvm.org/D51935
Files:
include/lldb/lldb-enumerations.h
source/Core/Section.cpp
source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
source/Plugins/SymbolFile/DWARF/DWARFUnit.h
source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
source/Symbol/ObjectFile.cpp
Index: source/Symbol/ObjectFile.cpp
===================================================================
--- source/Symbol/ObjectFile.cpp
+++ source/Symbol/ObjectFile.cpp
@@ -350,6 +350,7 @@
case eSectionTypeDWARFDebugFrame:
case eSectionTypeDWARFDebugInfo:
case eSectionTypeDWARFDebugLine:
+ case eSectionTypeDWARFDebugLineStr:
case eSectionTypeDWARFDebugLoc:
case eSectionTypeDWARFDebugMacInfo:
case eSectionTypeDWARFDebugMacro:
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -240,6 +240,7 @@
const lldb_private::DWARFDataExtractor &get_debug_frame_data();
const lldb_private::DWARFDataExtractor &get_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();
@@ -466,6 +467,7 @@
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;
DWARFDataSegment m_data_debug_loc;
DWARFDataSegment m_data_debug_ranges;
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -494,7 +494,7 @@
}
bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
- return version == 2 || version == 3 || version == 4;
+ return version >= 2 && version <= 5;
}
uint32_t SymbolFileDWARF::CalculateAbilities() {
@@ -645,6 +645,10 @@
return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line);
}
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_str_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugLineStr, m_data_debug_line_str);
+}
+
const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() {
return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro);
}
@@ -933,7 +937,7 @@
support_files.Append(*sc.comp_unit);
return DWARFDebugLine::ParseSupportFiles(
sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir,
- stmt_list, support_files);
+ stmt_list, support_files, dwarf_cu);
}
}
}
@@ -1070,7 +1074,7 @@
lldb::offset_t offset = cu_line_offset;
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset,
ParseDWARFLineTableCallback,
- &info);
+ &info, dwarf_cu);
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
if (debug_map_symfile) {
// We have an object file that has a line table with addresses that
Index: source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -225,7 +225,8 @@
const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
std::vector<DWARFDIE> &dies) {
- m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, dies);
+ std::vector<DWARFDIE> V;
+ m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, V);
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name.GetStringRef())) {
@@ -235,8 +236,13 @@
if (DIERef ref = ToDIERef(entry))
ProcessFunctionDIE(name.GetStringRef(), ref, info, parent_decl_ctx,
- name_type_mask, dies);
+ name_type_mask, V);
}
+
+ std::set<DWARFDebugInfoEntry *> Set;
+ for (DWARFDIE Die : V)
+ if (Set.insert(Die.GetDIE()).second)
+ dies.push_back(Die);
}
void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex,
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -202,6 +202,8 @@
dw_offset_t m_length = 0;
uint16_t m_version = 0;
uint8_t m_addr_size = 0;
+ uint8_t m_unit_type = 0;
+ uint64_t m_dwo_id = 0;
DWARFProducer m_producer = eProducerInvalid;
uint32_t m_producer_version_major = 0;
uint32_t m_producer_version_minor = 0;
Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -14,6 +14,7 @@
#include <stddef.h> // for NULL
class DWARFUnit;
+class SymbolFileDWARF;
class DWARFFormValue {
public:
@@ -73,6 +74,7 @@
int64_t Signed() const { return m_value.value.sval; }
void SetSigned(int64_t sval) { m_value.value.sval = sval; }
const char *AsCString() const;
+ const char *AsCString(SymbolFileDWARF *Dwarf, bool Is64Bit) const;
dw_addr_t Address() const;
bool IsValid() const { return m_form != 0; }
bool SkipValue(const lldb_private::DWARFDataExtractor &debug_info_data,
Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -196,6 +196,10 @@
case DW_FORM_data8:
m_value.value.uval = data.GetU64(offset_ptr);
break;
+ case DW_FORM_data16:
+ m_value.value.uval = 16;
+ is_block = true;
+ break;
case DW_FORM_string:
m_value.value.cstr = data.GetCStr(offset_ptr);
break;
@@ -218,10 +222,26 @@
m_value.value.sval = data.GetSLEB128(offset_ptr);
break;
case DW_FORM_strp:
+ case DW_FORM_line_strp:
assert(m_cu);
m_value.value.uval =
data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
break;
+ case DW_FORM_strx:
+ m_value.value.uval = data.GetULEB128(offset_ptr);
+ break;
+ case DW_FORM_strx1:
+ m_value.value.uval = data.GetU8(offset_ptr);
+ break;
+ case DW_FORM_strx2:
+ m_value.value.uval = data.GetU16(offset_ptr);
+ break;
+ case DW_FORM_strx3:
+ m_value.value.uval = data.GetMaxU64(offset_ptr, 3);
+ break;
+ case DW_FORM_strx4:
+ m_value.value.uval = data.GetU32(offset_ptr);
+ break;
// case DW_FORM_APPLE_db_str:
case DW_FORM_udata:
m_value.value.uval = data.GetULEB128(offset_ptr);
@@ -348,47 +368,56 @@
case DW_FORM_flag_present:
return true;
- // 1 byte values
- case DW_FORM_data1:
- case DW_FORM_flag:
- case DW_FORM_ref1:
- *offset_ptr += 1;
- return true;
+ // 1 byte values
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_ref1:
+ case DW_FORM_strx1:
+ *offset_ptr += 1;
+ return true;
- // 2 byte values
- case DW_FORM_data2:
- case DW_FORM_ref2:
- *offset_ptr += 2;
- return true;
+ // 2 byte values
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ case DW_FORM_strx2:
+ *offset_ptr += 2;
+ return true;
- // 32 bit for DWARF 32, 64 for DWARF 64
- case DW_FORM_sec_offset:
- case DW_FORM_strp:
- assert(cu);
- *offset_ptr += (cu->IsDWARF64() ? 8 : 4);
- return true;
+ // 3 byte values
+ case DW_FORM_strx3:
+ *offset_ptr += 3;
+ return true;
- // 4 byte values
- case DW_FORM_data4:
- case DW_FORM_ref4:
- *offset_ptr += 4;
- return true;
+ // 32 bit for DWARF 32, 64 for DWARF 64
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
+ assert(cu);
+ *offset_ptr += (cu->IsDWARF64() ? 8 : 4);
+ return true;
- // 8 byte values
- case DW_FORM_data8:
- case DW_FORM_ref8:
- case DW_FORM_ref_sig8:
- *offset_ptr += 8;
- return true;
+ // 4 byte values
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ case DW_FORM_strx4:
+ *offset_ptr += 4;
+ return true;
- // signed or unsigned LEB 128 values
- case DW_FORM_sdata:
- case DW_FORM_udata:
- case DW_FORM_ref_udata:
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index:
- debug_info_data.Skip_LEB128(offset_ptr);
- return true;
+ // 8 byte values
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ *offset_ptr += 8;
+ return true;
+
+ // signed or unsigned LEB 128 values
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_strx:
+ debug_info_data.Skip_LEB128(offset_ptr);
+ return true;
case DW_FORM_indirect: {
dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
@@ -525,9 +554,8 @@
}
}
-const char *DWARFFormValue::AsCString() const {
- SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
-
+const char *DWARFFormValue::AsCString(SymbolFileDWARF *symbol_file,
+ bool is64Bit) const {
if (m_form == DW_FORM_string) {
return m_value.value.cstr;
} else if (m_form == DW_FORM_strp) {
@@ -539,16 +567,53 @@
if (!symbol_file)
return nullptr;
- uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
+ uint32_t index_size = is64Bit ? 8 : 4;
lldb::offset_t offset = m_value.value.uval * index_size;
dw_offset_t str_offset =
symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset,
index_size);
return symbol_file->get_debug_str_data().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.
+ if (!symbol_file)
+ return nullptr;
+
+ lldb::offset_t baseOffset = 0;
+ const DWARFDataExtractor &strOffsets =
+ symbol_file->get_debug_str_offsets_data();
+ uint64_t length = strOffsets.GetU32(&baseOffset);
+ if (length == 0xffffffff)
+ length = strOffsets.GetU64(&baseOffset);
+
+ // Check version.
+ if (strOffsets.GetU16(&baseOffset) < 5)
+ return nullptr;
+
+ // Skip padding.
+ baseOffset += 2;
+
+ uint32_t indexSize = is64Bit ? 8 : 4;
+ lldb::offset_t offset = baseOffset + m_value.value.uval * indexSize;
+ dw_offset_t strOffset =
+ symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize);
+ return symbol_file->get_debug_str_data().PeekCStr(strOffset);
+ }
+
+ if (m_form == DW_FORM_line_strp)
+ return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval);
+
return nullptr;
}
+const char *DWARFFormValue::AsCString() const {
+ return AsCString(m_cu->GetSymbolFileDWARF(), m_cu->IsDWARF64());
+}
+
dw_addr_t DWARFFormValue::Address() const {
SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
@@ -755,7 +820,15 @@
case DW_FORM_ref_sig8:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_addr_index:
+ return true;
+
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
return true;
+
default:
break;
}
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
@@ -19,6 +19,9 @@
#include "DWARFDataExtractor.h"
#include "DWARFDefines.h"
+#include "llvm/Support/MD5.h"
+
+class DWARFUnit;
class SymbolFileDWARF;
//----------------------------------------------------------------------
@@ -36,6 +39,7 @@
dw_sleb128_t dir_idx;
dw_sleb128_t mod_time;
dw_sleb128_t length;
+ llvm::MD5::MD5Result Checksum;
};
//------------------------------------------------------------------
@@ -55,6 +59,10 @@
// total_length field itself).
uint16_t
version; // Version identifier for the statement information format.
+
+ uint8_t address_size;
+ uint8_t segment_selector_size;
+
uint32_t prologue_length; // The number of bytes following the
// prologue_length field to the beginning of the
// first byte of the statement program itself.
@@ -201,14 +209,14 @@
const lldb_private::DWARFDataExtractor &debug_line_data,
const lldb_private::FileSpec &cu_comp_dir,
dw_offset_t stmt_list,
- lldb_private::FileSpecList &support_files);
+ lldb_private::FileSpecList &support_files, DWARFUnit *dwarf_cu);
static bool
ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, Prologue *prologue);
+ lldb::offset_t *offset_ptr, Prologue *prologue, DWARFUnit *CU = nullptr);
static bool
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
lldb::offset_t *offset_ptr, State::Callback callback,
- void *userData);
+ void *userData, DWARFUnit *dwarf_cu);
static dw_offset_t
DumpStatementTable(lldb_private::Log *log,
const lldb_private::DWARFDataExtractor &debug_line_data,
@@ -219,7 +227,7 @@
const dw_offset_t line_offset, uint32_t flags);
static bool
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, LineTable *line_table);
+ lldb::offset_t *offset_ptr, LineTable *line_table, DWARFUnit *dwarf_cu);
static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data,
DWARFDebugLine::State::Callback callback, void *userData);
// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue,
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
@@ -41,7 +41,7 @@
if (line_table_sp.get() == NULL)
break;
- if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) {
+ if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) {
// Make sure we don't don't loop infinitely
if (offset <= debug_line_offset)
break;
@@ -127,7 +127,7 @@
"--------\n",
debug_line_offset);
- if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log))
+ if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log, nullptr))
return offset;
else
return debug_line_offset + 1; // Skip to next byte in .debug_line section
@@ -366,17 +366,38 @@
void *userData) {
lldb::offset_t offset = 0;
if (debug_line_data.ValidOffset(offset)) {
- if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
+ if (!ParseStatementTable(debug_line_data, &offset, callback, userData, nullptr))
++offset; // Skip to next byte in .debug_line section
}
}
+namespace {
+struct EntryDescriptor {
+ dw_sleb128_t code;
+ dw_sleb128_t form;
+};
+
+static std::vector<EntryDescriptor>
+ReadDescriptors(const DWARFDataExtractor &debug_line_data,
+ lldb::offset_t *offset_ptr) {
+ std::vector<EntryDescriptor> ret;
+ uint8_t n = debug_line_data.GetU8(offset_ptr);
+ for (uint8_t i = 0; i < n; ++i) {
+ EntryDescriptor ent;
+ ent.code = debug_line_data.GetULEB128(offset_ptr);
+ ent.form = debug_line_data.GetULEB128(offset_ptr);
+ ret.push_back(ent);
+ }
+ return ret;
+}
+} // namespace
+
//----------------------------------------------------------------------
// DWARFDebugLine::ParsePrologue
//----------------------------------------------------------------------
bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
lldb::offset_t *offset_ptr,
- Prologue *prologue) {
+ Prologue *prologue, DWARFUnit *dwarf_cu) {
const lldb::offset_t prologue_offset = *offset_ptr;
// DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
@@ -386,9 +407,14 @@
const char *s;
prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
prologue->version = debug_line_data.GetU16(offset_ptr);
- if (prologue->version < 2 || prologue->version > 4)
+ if (prologue->version < 2 || prologue->version > 5)
return false;
+ if (prologue->version >= 5) {
+ prologue->address_size = debug_line_data.GetU8(offset_ptr);
+ prologue->segment_selector_size = debug_line_data.GetU8(offset_ptr);
+ }
+
prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
const lldb::offset_t end_prologue_offset =
prologue->prologue_length + *offset_ptr;
@@ -410,25 +436,83 @@
prologue->standard_opcode_lengths.push_back(op_len);
}
- while (*offset_ptr < end_prologue_offset) {
- s = debug_line_data.GetCStr(offset_ptr);
- if (s && s[0])
- prologue->include_directories.push_back(s);
- else
- break;
- }
+ if (prologue->version >= 5) {
+ std::vector<EntryDescriptor> dirEntryFormatV =
+ ReadDescriptors(debug_line_data, offset_ptr);
+ uint8_t dirCount = debug_line_data.GetULEB128(offset_ptr);
+ for (int i = 0; i < dirCount; ++i) {
+ for (EntryDescriptor &ent : dirEntryFormatV) {
+ DWARFFormValue value(dwarf_cu, ent.form);
+ if (ent.code != DW_LNCT_path) {
+ if (!value.SkipValue(debug_line_data, offset_ptr))
+ return false;
+ continue;
+ }
- while (*offset_ptr < end_prologue_offset) {
- const char *name = debug_line_data.GetCStr(offset_ptr);
- if (name && name[0]) {
- FileNameEntry fileEntry;
- fileEntry.name = name;
- fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
- prologue->file_names.push_back(fileEntry);
- } else
- break;
+ if (!value.ExtractValue(debug_line_data, offset_ptr))
+ return false;
+ prologue->include_directories.push_back(value.AsCString());
+ }
+ }
+
+ std::vector<EntryDescriptor> filesEntryFormatV =
+ ReadDescriptors(debug_line_data, offset_ptr);
+ llvm::DenseSet<std::pair<uint64_t, uint64_t>> seen;
+ uint8_t n = debug_line_data.GetULEB128(offset_ptr);
+ for (int i = 0; i < n; ++i) {
+ FileNameEntry entry;
+ for (EntryDescriptor &p : filesEntryFormatV) {
+ DWARFFormValue value(dwarf_cu, p.form);
+ if (!value.ExtractValue(debug_line_data, offset_ptr))
+ return false;
+
+ switch (p.code) {
+ case DW_LNCT_path:
+ entry.name = value.AsCString();
+ break;
+ case DW_LNCT_directory_index:
+ entry.dir_idx = value.Unsigned();
+ break;
+ case DW_LNCT_timestamp:
+ entry.mod_time = value.Unsigned();
+ break;
+ case DW_LNCT_size:
+ entry.length = value.Unsigned();
+ break;
+ case DW_LNCT_MD5:
+ assert(value.Unsigned() == 16);
+ std::uninitialized_copy_n(value.BlockData(), 16,
+ entry.Checksum.Bytes.begin());
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (seen.insert(entry.Checksum.words()).second)
+ prologue->file_names.push_back(entry);
+ }
+ } else {
+ while (*offset_ptr < end_prologue_offset) {
+ s = debug_line_data.GetCStr(offset_ptr);
+ if (s && s[0])
+ prologue->include_directories.push_back(s);
+ else
+ break;
+ }
+
+ while (*offset_ptr < end_prologue_offset) {
+ const char *name = debug_line_data.GetCStr(offset_ptr);
+ if (name && name[0]) {
+ FileNameEntry fileEntry;
+ fileEntry.name = name;
+ fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
+ fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
+ fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
+ prologue->file_names.push_back(fileEntry);
+ } else
+ break;
+ }
}
// XXX GNU as is broken for 64-Bit DWARF
@@ -445,11 +529,11 @@
bool DWARFDebugLine::ParseSupportFiles(
const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list,
- FileSpecList &support_files) {
+ FileSpecList &support_files, DWARFUnit *dwarf_cu) {
lldb::offset_t offset = stmt_list;
Prologue prologue;
- if (!ParsePrologue(debug_line_data, &offset, &prologue)) {
+ if (!ParsePrologue(debug_line_data, &offset, &prologue, dwarf_cu)) {
Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
"at 0x%8.8x (parsing ended around "
"0x%8.8" PRIx64 "\n",
@@ -478,7 +562,7 @@
//----------------------------------------------------------------------
bool DWARFDebugLine::ParseStatementTable(
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
- DWARFDebugLine::State::Callback callback, void *userData) {
+ DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
Prologue::shared_ptr prologue(new Prologue());
@@ -489,7 +573,7 @@
func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
debug_line_offset);
- if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) {
+ if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get(), dwarf_cu)) {
if (log)
log->Error("failed to parse DWARF line table prologue");
// Restore our offset and return false to indicate failure!
@@ -775,9 +859,9 @@
//----------------------------------------------------------------------
bool DWARFDebugLine::ParseStatementTable(
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
- LineTable *line_table) {
+ LineTable *line_table, DWARFUnit *dwarf_cu) {
return ParseStatementTable(debug_line_data, offset_ptr,
- ParseStatementTableCallback, line_table);
+ ParseStatementTableCallback, line_table, dwarf_cu);
}
inline bool DWARFDebugLine::Prologue::IsValid() const {
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -122,18 +122,25 @@
case DW_FORM_data1:
case DW_FORM_flag:
case DW_FORM_ref1:
+ case DW_FORM_strx1:
form_size = 1;
break;
// 2 byte values
case DW_FORM_data2:
case DW_FORM_ref2:
+ case DW_FORM_strx2:
form_size = 2;
break;
+ case DW_FORM_strx3:
+ form_size = 3;
+ break;
+
// 4 byte values
case DW_FORM_data4:
case DW_FORM_ref4:
+ case DW_FORM_strx4:
form_size = 4;
break;
@@ -150,6 +157,7 @@
case DW_FORM_ref_udata:
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
+ case DW_FORM_strx:
debug_info_data.Skip_LEB128(&offset);
break;
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -36,10 +36,14 @@
/// Byte size of the compile unit header
//------------------------------------------------------------------
uint32_t GetHeaderByteSize() const override {
+ if (m_version >= 5)
+ return GetDWARF5HeaderSize(m_unit_type);
return m_is_dwarf64 ? 23 : 11;
}
private:
+ static uint32_t GetDWARF5HeaderSize(uint8_t unitType);
+
DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit);
};
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -34,8 +34,18 @@
cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr);
cu_sp->m_is_dwarf64 = debug_info.IsDWARF64();
cu_sp->m_version = debug_info.GetU16(offset_ptr);
- abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
- cu_sp->m_addr_size = debug_info.GetU8(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);
@@ -65,6 +75,20 @@
GetNextCompileUnitOffset());
}
+uint32_t DWARFCompileUnit::GetDWARF5HeaderSize(uint8_t unitType) {
+ switch (unitType) {
+ case llvm::dwarf::DW_UT_compile:
+ case llvm::dwarf::DW_UT_partial:
+ return 12;
+ case llvm::dwarf::DW_UT_skeleton:
+ case llvm::dwarf::DW_UT_split_compile:
+ return 20;
+ case llvm::dwarf::DW_UT_type:
+ case llvm::dwarf::DW_UT_split_type:
+ return 24;
+ }
+ llvm_unreachable("invalid UnitType.");
+}
const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
return m_dwarf->get_debug_info_data();
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1788,6 +1788,7 @@
static ConstString g_sect_name_dwarf_debug_frame(".debug_frame");
static ConstString g_sect_name_dwarf_debug_info(".debug_info");
static ConstString g_sect_name_dwarf_debug_line(".debug_line");
+ static ConstString g_sect_name_dwarf_debug_line_str(".debug_line_str");
static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
static ConstString g_sect_name_dwarf_debug_macro(".debug_macro");
@@ -1802,6 +1803,7 @@
".debug_abbrev.dwo");
static ConstString g_sect_name_dwarf_debug_info_dwo(".debug_info.dwo");
static ConstString g_sect_name_dwarf_debug_line_dwo(".debug_line.dwo");
+ static ConstString g_sect_name_dwarf_debug_line_str_dwo(".debug_line_str.dwo");
static ConstString g_sect_name_dwarf_debug_macro_dwo(".debug_macro.dwo");
static ConstString g_sect_name_dwarf_debug_loc_dwo(".debug_loc.dwo");
static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo");
@@ -1861,6 +1863,8 @@
sect_type = eSectionTypeDWARFDebugInfo;
else if (name == g_sect_name_dwarf_debug_line)
sect_type = eSectionTypeDWARFDebugLine;
+ else if (name == g_sect_name_dwarf_debug_line_str)
+ sect_type = eSectionTypeDWARFDebugLineStr;
else if (name == g_sect_name_dwarf_debug_loc)
sect_type = eSectionTypeDWARFDebugLoc;
else if (name == g_sect_name_dwarf_debug_macinfo)
@@ -1887,6 +1891,8 @@
sect_type = eSectionTypeDWARFDebugInfo;
else if (name == g_sect_name_dwarf_debug_line_dwo)
sect_type = eSectionTypeDWARFDebugLine;
+ else if (name == g_sect_name_dwarf_debug_line_str_dwo)
+ sect_type = eSectionTypeDWARFDebugLineStr;
else if (name == g_sect_name_dwarf_debug_macro_dwo)
sect_type = eSectionTypeDWARFDebugMacro;
else if (name == g_sect_name_dwarf_debug_loc_dwo)
Index: source/Core/Section.cpp
===================================================================
--- source/Core/Section.cpp
+++ source/Core/Section.cpp
@@ -73,6 +73,8 @@
return "dwarf-info";
case eSectionTypeDWARFDebugLine:
return "dwarf-line";
+ case eSectionTypeDWARFDebugLineStr:
+ return "dwarf-line-str";
case eSectionTypeDWARFDebugLoc:
return "dwarf-loc";
case eSectionTypeDWARFDebugMacInfo:
Index: include/lldb/lldb-enumerations.h
===================================================================
--- include/lldb/lldb-enumerations.h
+++ include/lldb/lldb-enumerations.h
@@ -671,6 +671,7 @@
eSectionTypeDWARFGNUDebugAltLink,
eSectionTypeDWARFDebugTypes, // DWARF .debug_types section
eSectionTypeDWARFDebugNames, // DWARF v5 .debug_names
+ eSectionTypeDWARFDebugLineStr, // DWARF v5 .debug_line_str
eSectionTypeOther
};
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits