summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp23
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp12
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp8
-rw-r--r--lldb/source/Symbol/CompileUnit.cpp36
-rw-r--r--lldb/test/Shell/SymbolFile/DWARF/dwarf5-debug_line.s129
5 files changed, 163 insertions, 45 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index b8575d13d45..fc8fe30101c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -198,15 +198,23 @@ GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx,
return std::move(rel_path);
}
-static FileSpecList ParseSupportFilesFromPrologue(
- const lldb::ModuleSP &module,
- const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style,
- llvm::StringRef compile_dir = {}, FileSpec first_file = {}) {
+static FileSpecList
+ParseSupportFilesFromPrologue(const lldb::ModuleSP &module,
+ const llvm::DWARFDebugLine::Prologue &prologue,
+ FileSpec::Style style,
+ llvm::StringRef compile_dir = {}) {
FileSpecList support_files;
- support_files.Append(first_file);
+ size_t first_file = 0;
+ if (prologue.getVersion() <= 4) {
+ // File index 0 is not valid before DWARF v5. Add a dummy entry to ensure
+ // support file list indices match those we get from the debug info and line
+ // tables.
+ support_files.Append(FileSpec());
+ first_file = 1;
+ }
const size_t number_of_files = prologue.FileNames.size();
- for (size_t idx = 1; idx <= number_of_files; ++idx) {
+ for (size_t idx = first_file; idx <= number_of_files; ++idx) {
std::string remapped_file;
if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style))
if (!module->RemapSourceFile(llvm::StringRef(*file_path), remapped_file))
@@ -1046,8 +1054,7 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue(
comp_unit.GetModule(), line_table->Prologue, dwarf_cu->GetPathStyle(),
- dwarf_cu->GetCompilationDirectory().GetCString(),
- comp_unit.GetPrimaryFile()));
+ dwarf_cu->GetCompilationDirectory().GetCString()));
return true;
}
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index f0308e23c9d..22d1b08ea9e 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1110,9 +1110,7 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
// LLDB wants the index of the file in the list of support files.
auto fn_iter = llvm::find(cci->m_file_list, *efn);
lldbassert(fn_iter != cci->m_file_list.end());
- // LLDB support file indices are 1-based.
- uint32_t file_index =
- 1 + std::distance(cci->m_file_list.begin(), fn_iter);
+ uint32_t file_index = std::distance(cci->m_file_list.begin(), fn_iter);
std::unique_ptr<LineSequence> sequence(
line_table->CreateLineSequenceContainer());
@@ -1155,14 +1153,6 @@ bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
FileSpec spec(f, style);
support_files.Append(spec);
}
-
- llvm::SmallString<64> main_source_file =
- m_index->compilands().GetMainSourceFile(*cci);
- FileSpec::Style style = main_source_file.startswith("/")
- ? FileSpec::Style::posix
- : FileSpec::Style::windows;
- FileSpec spec(main_source_file, style);
- support_files.Insert(0, spec);
return true;
}
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index dcbefdcbb6f..b3e06fdd1a5 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -371,10 +371,6 @@ bool SymbolFilePDB::ParseSupportFiles(
support_files.AppendIfUnique(spec);
}
- // LLDB uses the DWARF-like file numeration (one based),
- // the zeroth file is the compile unit itself
- support_files.Insert(0, comp_unit.GetPrimaryFile());
-
return true;
}
@@ -1881,9 +1877,7 @@ void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(
if (!source_files)
return;
- // LLDB uses the DWARF-like file numeration (one based)
- int index = 1;
-
+ int index = 0;
while (auto file = source_files->getNext()) {
uint32_t source_id = file->getUniqueId();
index_map[source_id] = index++;
diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp
index 98cf675fb37..b05036e27fc 100644
--- a/lldb/source/Symbol/CompileUnit.cpp
+++ b/lldb/source/Symbol/CompileUnit.cpp
@@ -207,30 +207,28 @@ VariableListSP CompileUnit::GetVariableList(bool can_create) {
return m_variables;
}
+std::vector<uint32_t> FindFileIndexes(const FileSpecList &files, const FileSpec &file) {
+ std::vector<uint32_t> result;
+ uint32_t idx = -1;
+ while ((idx = files.FindFileIndex(idx + 1, file, /*full=*/true)) !=
+ UINT32_MAX)
+ result.push_back(idx);
+ return result;
+}
+
uint32_t CompileUnit::FindLineEntry(uint32_t start_idx, uint32_t line,
const FileSpec *file_spec_ptr, bool exact,
LineEntry *line_entry_ptr) {
- uint32_t file_idx = 0;
+ if (!file_spec_ptr)
+ file_spec_ptr = &GetPrimaryFile();
+ std::vector<uint32_t> file_indexes = FindFileIndexes(GetSupportFiles(), *file_spec_ptr);
+ if (file_indexes.empty())
+ return UINT32_MAX;
- if (file_spec_ptr) {
- file_idx = GetSupportFiles().FindFileIndex(1, *file_spec_ptr, true);
- if (file_idx == UINT32_MAX)
- return UINT32_MAX;
- } else {
- // All the line table entries actually point to the version of the Compile
- // Unit that is in the support files (the one at 0 was artificially added.)
- // So prefer the one further on in the support files if it exists...
- const FileSpecList &support_files = GetSupportFiles();
- const bool full = true;
- file_idx = support_files.FindFileIndex(
- 1, support_files.GetFileSpecAtIndex(0), full);
- if (file_idx == UINT32_MAX)
- file_idx = 0;
- }
LineTable *line_table = GetLineTable();
if (line_table)
- return line_table->FindLineEntryIndexByFileIndex(start_idx, file_idx, line,
- exact, line_entry_ptr);
+ return line_table->FindLineEntryIndexByFileIndex(
+ start_idx, file_indexes, line, exact, line_entry_ptr);
return UINT32_MAX;
}
@@ -252,7 +250,7 @@ void CompileUnit::ResolveSymbolContext(const FileSpec &file_spec,
return;
uint32_t file_idx =
- GetSupportFiles().FindFileIndex(1, file_spec, true);
+ GetSupportFiles().FindFileIndex(0, file_spec, true);
while (file_idx != UINT32_MAX) {
file_indexes.push_back(file_idx);
file_idx = GetSupportFiles().FindFileIndex(file_idx + 1, file_spec, true);
diff --git a/lldb/test/Shell/SymbolFile/DWARF/dwarf5-debug_line.s b/lldb/test/Shell/SymbolFile/DWARF/dwarf5-debug_line.s
new file mode 100644
index 00000000000..d15f31039bb
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/dwarf5-debug_line.s
@@ -0,0 +1,129 @@
+# Test handling of DWARF5 line tables. In particular, test that we handle files
+# which are present in the line table more than once.
+
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -o %t -triple x86_64-pc-linux %s
+# RUN: %lldb %t -o "source info -f file0.c" -o "source info -f file1.c" \
+# RUN: -o "breakpoint set -f file0.c -l 42" \
+# RUN: -o "breakpoint set -f file0.c -l 47" \
+# RUN: -o exit | FileCheck %s
+
+# CHECK-LABEL: source info -f file0.c
+# CHECK: [0x0000000000000000-0x0000000000000001): /file0.c:42
+# CHECK-LABEL: source info -f file1.c
+# CHECK: [0x0000000000000001-0x0000000000000002): /file1.c:47
+# CHECK-LABEL: breakpoint set -f file0.c -l 42
+# CHECK: Breakpoint 1: {{.*}}`foo,
+# CHECK-LABEL: breakpoint set -f file0.c -l 47
+# CHECK: Breakpoint 2: {{.*}}`foo + 2,
+
+ .text
+ .globl foo
+foo:
+ nop
+ nop
+ nop
+.Lfoo_end:
+
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 37 # DW_AT_producer
+ .byte 8 # DW_FORM_string
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 8 # DW_FORM_string
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 8 # DW_FORM_string
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] 0xc:0x23 DW_TAG_compile_unit
+ .asciz "Hand-written DWARF" # DW_AT_producer
+ .short 12 # DW_AT_language
+ .asciz "file0.c" # DW_AT_name
+ .long .Lline_table_begin # DW_AT_stmt_list
+ .asciz "/" # DW_AT_comp_dir
+ .quad foo # DW_AT_low_pc
+ .long .Lfoo_end-foo # DW_AT_high_pc
+.Ldebug_info_end0:
+
+ .section .debug_line,"",@progbits
+.Lline_table_begin:
+ .long .Lline_end-.Lline_start
+.Lline_start:
+ .short 5 # DWARF version number
+ .byte 8 # Address Size (in bytes)
+ .byte 0 # Segment Selector Size
+ .long .Lheader_end-.Lheader_start
+.Lheader_start:
+ .byte 1 # Minimum Instruction Length
+ .byte 1 # Maximum Operations per Instruction
+ .byte 1 # Default is_stmt
+ .byte 0 # Line Base
+ .byte 0 # Line Range
+ .byte 5 # Opcode Base
+ .byte 0, 1, 1, 1 # Standard Opcode Lengths
+
+ # Directory table format
+ .byte 1 # One element per directory entry
+ .byte 1 # DW_LNCT_path
+ .byte 0x08 # DW_FORM_string
+
+ # Directory table entries
+ .byte 1 # 1 directory
+ .asciz "/"
+
+ # File table format
+ .byte 2 # 2 elements per file entry
+ .byte 1 # DW_LNCT_path
+ .byte 0x08 # DW_FORM_string
+ .byte 2 # DW_LNCT_directory_index
+ .byte 0x0b # DW_FORM_data1
+
+ # File table entries
+ .byte 3 # 3 files
+ .asciz "file0.c"
+ .byte 0
+ .asciz "file1.c"
+ .byte 0
+ .asciz "file0.c"
+ .byte 0
+.Lheader_end:
+
+ .byte 4, 0 # DW_LNS_set_file 0
+ .byte 0, 9, 2 # DW_LNE_set_address
+ .quad foo
+ .byte 3, 41 # DW_LNS_advance_line 41
+ .byte 1 # DW_LNS_copy
+
+ .byte 4, 1 # DW_LNS_set_file 1
+ .byte 2, 1 # DW_LNS_advance_pc 1
+ .byte 3, 5 # DW_LNS_advance_line 5
+ .byte 1 # DW_LNS_copy
+
+ .byte 4, 2 # DW_LNS_set_file 2
+ .byte 2, 1 # DW_LNS_advance_pc 1
+ .byte 1 # DW_LNS_copy
+
+ .byte 2, 1 # DW_LNS_advance_pc 1
+ .byte 0, 1, 1 # DW_LNE_end_sequence
+.Lline_end:
OpenPOWER on IntegriCloud