diff options
15 files changed, 382 insertions, 77 deletions
diff --git a/lldb/include/lldb/Utility/FileSpec.h b/lldb/include/lldb/Utility/FileSpec.h index 0699ab7b5c9..03c2fa1d156 100644 --- a/lldb/include/lldb/Utility/FileSpec.h +++ b/lldb/include/lldb/Utility/FileSpec.h @@ -326,6 +326,10 @@ public: //------------------------------------------------------------------ bool IsAbsolute() const; + /// Make the FileSpec absolute by treating it relative to \a dir. Absolute + /// FileSpecs are never changed by this function. + void MakeAbsolute(const FileSpec &dir); + /// Temporary helper for FileSystem change. void SetPath(llvm::StringRef p) { SetFile(p); } diff --git a/lldb/lit/SymbolFile/DWARF/Inputs/dir-separator-no-comp-dir-relative-name.lldbinit b/lldb/lit/SymbolFile/DWARF/Inputs/dir-separator-no-comp-dir-relative-name.lldbinit new file mode 100644 index 00000000000..390408ec8cc --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/Inputs/dir-separator-no-comp-dir-relative-name.lldbinit @@ -0,0 +1,3 @@ +image dump line-table a.c +breakpoint set -f a.c -l 1 +breakpoint set -f foo/b.c -l 1 diff --git a/lldb/lit/SymbolFile/DWARF/Inputs/dir-separator-posix.lldbinit b/lldb/lit/SymbolFile/DWARF/Inputs/dir-separator-posix.lldbinit new file mode 100644 index 00000000000..73a8a491bb2 --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/Inputs/dir-separator-posix.lldbinit @@ -0,0 +1,3 @@ +image dump line-table a.c +breakpoint set -f a.c -l 1 +breakpoint set -f /tmp/b.c -l 1 diff --git a/lldb/lit/SymbolFile/DWARF/Inputs/dir-separator-windows.lldbinit b/lldb/lit/SymbolFile/DWARF/Inputs/dir-separator-windows.lldbinit new file mode 100644 index 00000000000..8737aafc8a2 --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/Inputs/dir-separator-windows.lldbinit @@ -0,0 +1,7 @@ +image dump line-table a.c +breakpoint set -f a.c -l 1 +breakpoint set -f C:/tmp/b.c -l 1 + +# This will fail on non-windows systems because the path will by parsed +# according to posix rules +# breakpoint set -f 'C:\tmp\b.c' -l 1 diff --git a/lldb/lit/SymbolFile/DWARF/dir-separator-no-comp-dir-relative-name.s b/lldb/lit/SymbolFile/DWARF/dir-separator-no-comp-dir-relative-name.s new file mode 100644 index 00000000000..6df3a3d3e48 --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/dir-separator-no-comp-dir-relative-name.s @@ -0,0 +1,62 @@ +# Test that parsing of line tables works reasonably, even if the host directory +# separator does not match the separator of the compile unit. + +# REQUIRES: lld + +# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj > %t.o +# RUN: ld.lld %t.o -o %t +# RUN: %lldb %t -s %S/Inputs/dir-separator-no-comp-dir-relative-name.lldbinit -o exit | FileCheck %s + +# CHECK-LABEL: image dump line-table a.c +# CHECK: Line table for foo/a.c +# CHECK-NEXT: 0x0000000000201000: foo/a.c:1 +# CHECK-NEXT: 0x0000000000201001: foo/b.c:1 +# CHECK-NEXT: 0x0000000000201002: foo/b.c:1 +# CHECK-EMPTY: + +# CHECK-LABEL: breakpoint set -f a.c -l 1 +# CHECK: Breakpoint 1: {{.*}}`_start, + +# CHECK-LABEL: breakpoint set -f foo/b.c -l 1 +# CHECK: Breakpoint 2: {{.*}}`_start + 1, + + .text + .globl _start +_start: + .file 1 "foo/a.c" + .loc 1 1 0 + nop + .file 2 "foo/b.c" + .loc 2 1 0 + nop + + .section .debug_str,"MS",@progbits,1 +.Linfo_string1: + .asciz "foo/a.c" + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Lcu_end0-.Lcu_start0 # Length of Unit +.Lcu_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit + .short 12 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list +.Lcu_end0: + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/lit/SymbolFile/DWARF/dir-separator-no-comp-dir.s b/lldb/lit/SymbolFile/DWARF/dir-separator-no-comp-dir.s new file mode 100644 index 00000000000..9e3281a334f --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/dir-separator-no-comp-dir.s @@ -0,0 +1,62 @@ +# Test that we properly determine the path syntax of a compile unit even if the +# compile unit does not have a DW_AT_comp_dir attribute. + +# REQUIRES: lld + +# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj > %t.o +# RUN: ld.lld %t.o -o %t +# RUN: %lldb %t -s %S/Inputs/dir-separator-windows.lldbinit -o exit | FileCheck %s + +# CHECK-LABEL: image dump line-table a.c +# CHECK: Line table for C:\tmp\a.c +# CHECK-NEXT: 0x0000000000201000: C:\tmp\a.c:1 +# CHECK-NEXT: 0x0000000000201001: C:\tmp\b.c:1 +# CHECK-NEXT: 0x0000000000201002: C:\tmp\b.c:1 +# CHECK-EMPTY: + +# CHECK-LABEL: breakpoint set -f a.c -l 1 +# CHECK: Breakpoint 1: {{.*}}`_start, + +# CHECK-LABEL: breakpoint set -f C:/tmp/b.c -l 1 +# CHECK: Breakpoint 2: {{.*}}`_start + 1, + + .text + .globl _start +_start: + .file 1 "C:\\tmp\\a.c" + .loc 1 1 0 + nop + .file 2 "C:\\tmp\\b.c" + .loc 2 1 0 + nop + + .section .debug_str,"MS",@progbits,1 +.Linfo_string1: + .asciz "C:\\tmp\\a.c" + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Lcu_end0-.Lcu_start0 # Length of Unit +.Lcu_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit + .short 12 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list +.Lcu_end0: + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/lit/SymbolFile/DWARF/dir-separator-posix.s b/lldb/lit/SymbolFile/DWARF/dir-separator-posix.s new file mode 100644 index 00000000000..976038a9f8b --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/dir-separator-posix.s @@ -0,0 +1,67 @@ +# Test that parsing of line tables works reasonably, even if the host directory +# separator does not match the separator of the compile unit. + +# REQUIRES: lld + +# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj > %t.o +# RUN: ld.lld %t.o -o %t +# RUN: %lldb %t -s %S/Inputs/dir-separator-posix.lldbinit -o exit | FileCheck %s + +# CHECK-LABEL: image dump line-table a.c +# CHECK: Line table for /tmp/a.c +# CHECK-NEXT: 0x0000000000201000: /tmp/a.c:1 +# CHECK-NEXT: 0x0000000000201001: /tmp/b.c:1 +# CHECK-NEXT: 0x0000000000201002: /tmp/b.c:1 +# CHECK-EMPTY: + +# CHECK-LABEL: breakpoint set -f a.c -l 1 +# CHECK: Breakpoint 1: {{.*}}`_start, + +# CHECK-LABEL: breakpoint set -f /tmp/b.c -l 1 +# CHECK: Breakpoint 2: {{.*}}`_start + 1, + + .text + .globl _start +_start: + .file 1 "/tmp/a.c" + .loc 1 1 0 + nop + .file 2 "/tmp/b.c" + .loc 2 1 0 + nop + + .section .debug_str,"MS",@progbits,1 +.Linfo_string1: + .asciz "a.c" +.Linfo_string2: + .asciz "/tmp" + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Lcu_end0-.Lcu_start0 # Length of Unit +.Lcu_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit + .short 12 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Linfo_string2 # DW_AT_comp_dir +.Lcu_end0: + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/lit/SymbolFile/DWARF/dir-separator-windows.s b/lldb/lit/SymbolFile/DWARF/dir-separator-windows.s new file mode 100644 index 00000000000..30308ab9dfb --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/dir-separator-windows.s @@ -0,0 +1,67 @@ +# Test that parsing of line tables works reasonably, even if the host directory +# separator does not match the separator of the compile unit. + +# REQUIRES: lld + +# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj > %t.o +# RUN: ld.lld %t.o -o %t +# RUN: %lldb %t -s %S/Inputs/dir-separator-windows.lldbinit -o exit | FileCheck %s + +# CHECK-LABEL: image dump line-table a.c +# CHECK: Line table for C:\tmp\a.c +# CHECK-NEXT: 0x0000000000201000: C:\tmp\a.c:1 +# CHECK-NEXT: 0x0000000000201001: C:\tmp\b.c:1 +# CHECK-NEXT: 0x0000000000201002: C:\tmp\b.c:1 +# CHECK-EMPTY: + +# CHECK-LABEL: breakpoint set -f a.c -l 1 +# CHECK: Breakpoint 1: {{.*}}`_start, + +# CHECK-LABEL: breakpoint set -f C:/tmp/b.c -l 1 +# CHECK: Breakpoint 2: {{.*}}`_start + 1, + + .text + .globl _start +_start: + .file 1 "C:\\tmp\\a.c" + .loc 1 1 0 + nop + .file 2 "C:\\tmp\\b.c" + .loc 2 1 0 + nop + + .section .debug_str,"MS",@progbits,1 +.Linfo_string1: + .asciz "a.c" +.Linfo_string2: + .asciz "C:\\tmp" + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Lcu_end0-.Lcu_start0 # Length of Unit +.Lcu_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit + .short 12 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Linfo_string2 # DW_AT_comp_dir +.Lcu_end0: + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp index d9f50122bd6..cd50d40887e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -18,6 +18,7 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/Timer.h" +#include "DWARFUnit.h" #include "LogChannelDWARF.h" #include "SymbolFileDWARF.h" @@ -528,8 +529,7 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, 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, DWARFUnit *dwarf_cu) { + dw_offset_t stmt_list, FileSpecList &support_files, DWARFUnit *dwarf_cu) { lldb::offset_t offset = stmt_list; Prologue prologue; @@ -545,7 +545,9 @@ bool DWARFDebugLine::ParseSupportFiles( std::string remapped_file; for (uint32_t file_idx = 1; - prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) { + prologue.GetFile(file_idx, dwarf_cu->GetCompilationDirectory(), + dwarf_cu->GetPathStyle(), file_spec); + ++file_idx) { if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file)) file_spec.SetFile(remapped_file, FileSpec::Style::native); support_files.Append(file_spec); @@ -947,10 +949,12 @@ void DWARFDebugLine::Prologue::Dump(Log *log) { //} bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, - const lldb_private::FileSpec &comp_dir, FileSpec &file) const { + const FileSpec &comp_dir, + FileSpec::Style style, + FileSpec &file) const { uint32_t idx = file_idx - 1; // File indexes are 1 based... if (idx < file_names.size()) { - file.SetFile(file_names[idx].name, FileSpec::Style::native); + file.SetFile(file_names[idx].name, style); if (file.IsRelative()) { if (file_names[idx].dir_idx > 0) { const uint32_t dir_idx = file_names[idx].dir_idx - 1; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h index 04f72e03a2d..976e4038c6f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h @@ -14,6 +14,7 @@ #include <string> #include <vector> +#include "lldb/Utility/FileSpec.h" #include "lldb/lldb-private.h" #include "DWARFDataExtractor.h" @@ -99,6 +100,7 @@ public: file_names.clear(); } bool GetFile(uint32_t file_idx, const lldb_private::FileSpec &cu_comp_dir, + lldb_private::FileSpec::Style style, lldb_private::FileSpec &file) const; }; @@ -207,9 +209,9 @@ public: static bool ParseSupportFiles(const lldb::ModuleSP &module_sp, const lldb_private::DWARFDataExtractor &debug_line_data, - const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list, - lldb_private::FileSpecList &support_files, DWARFUnit *dwarf_cu); + 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, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 7afc71bc24f..f794a77587f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -766,6 +766,80 @@ bool DWARFUnit::GetIsOptimized() { return m_is_optimized == eLazyBoolYes; } +FileSpec::Style DWARFUnit::GetPathStyle() { + if (!m_comp_dir) + ComputeCompDirAndGuessPathStyle(); + return m_comp_dir->GetPathStyle(); +} + +const FileSpec &DWARFUnit::GetCompilationDirectory() { + if (!m_comp_dir) + ComputeCompDirAndGuessPathStyle(); + return *m_comp_dir; +} + +// DWARF2/3 suggests the form hostname:pathname for compilation directory. +// Remove the host part if present. +static llvm::StringRef +removeHostnameFromPathname(llvm::StringRef path_from_dwarf) { + llvm::StringRef host, path; + std::tie(host, path) = path_from_dwarf.split(':'); + + if (host.contains('/')) + return path_from_dwarf; + + // check whether we have a windows path, and so the first character is a + // drive-letter not a hostname. + if (host.size() == 1 && llvm::isAlpha(host[0]) && path.startswith("\\")) + return path_from_dwarf; + + return path; +} + +static FileSpec resolveCompDir(const FileSpec &path) { + bool is_symlink = SymbolFileDWARF::GetSymlinkPaths().FindFileIndex( + 0, path, /*full*/ true) != UINT32_MAX; + + if (!is_symlink) + return path; + + namespace fs = llvm::sys::fs; + if (fs::get_file_type(path.GetPath(), false) != fs::file_type::symlink_file) + return path; + + FileSpec resolved_symlink; + const auto error = FileSystem::Instance().Readlink(path, resolved_symlink); + if (error.Success()) + return resolved_symlink; + + return path; +} + +void DWARFUnit::ComputeCompDirAndGuessPathStyle() { + m_comp_dir = FileSpec(); + const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); + if (!die) + return; + + auto guess = [](llvm::StringRef str) { + if (str.startswith("/")) + return FileSpec::Style::posix; + if (str.size() > 3 && llvm::isAlpha(str[0]) && str.substr(1, 2) == ":\\") + return FileSpec::Style::windows; + return FileSpec::Style::native; + }; + llvm::StringRef comp_dir = removeHostnameFromPathname( + die->GetAttributeValueAsString(m_dwarf, this, DW_AT_comp_dir, NULL)); + if (!comp_dir.empty()) { + m_comp_dir = resolveCompDir(FileSpec(comp_dir, guess(comp_dir))); + } else { + // Try to detect the style based on the DW_AT_name attribute, but just store + // the detected style in the m_comp_dir field. + m_comp_dir = FileSpec("", guess(die->GetAttributeValueAsString( + m_dwarf, this, DW_AT_name, NULL))); + } +} + SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() const { return m_dwo_symbol_file.get(); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 178c894686e..c6cff7ac5c6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -169,6 +169,9 @@ public: bool GetIsOptimized(); + const lldb_private::FileSpec &GetCompilationDirectory(); + lldb_private::FileSpec::Style GetPathStyle(); + SymbolFileDWARFDwo *GetDwoSymbolFile() const; dw_offset_t GetBaseObjOffset() const; @@ -214,6 +217,7 @@ protected: lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown; bool m_is_dwarf64 = false; lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate; + llvm::Optional<lldb_private::FileSpec> m_comp_dir; dw_addr_t m_addr_base = 0; // Value of DW_AT_addr_base dw_addr_t m_ranges_base = 0; // Value of DW_AT_ranges_base // If this is a dwo compile unit this is the offset of the base compile unit @@ -249,6 +253,8 @@ private: void AddUnitDIE(const DWARFDebugInfoEntry &cu_die); void ExtractDIEsEndCheck(lldb::offset_t offset) const; + void ComputeCompDirAndGuessPathStyle(); + DISALLOW_COPY_AND_ASSIGN(DWARFUnit); }; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 2a0a89f0b25..33cd2aba496 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -158,64 +158,8 @@ static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() { } // anonymous namespace end -static const char *removeHostnameFromPathname(const char *path_from_dwarf) { - if (!path_from_dwarf || !path_from_dwarf[0]) { - return path_from_dwarf; - } - - const char *colon_pos = strchr(path_from_dwarf, ':'); - if (nullptr == colon_pos) { - return path_from_dwarf; - } - - const char *slash_pos = strchr(path_from_dwarf, '/'); - if (slash_pos && (slash_pos < colon_pos)) { - return path_from_dwarf; - } - - // check whether we have a windows path, and so the first character is a - // drive-letter not a hostname. - if (colon_pos == path_from_dwarf + 1 && isalpha(*path_from_dwarf) && - strlen(path_from_dwarf) > 2 && '\\' == path_from_dwarf[2]) { - return path_from_dwarf; - } - - return colon_pos + 1; -} - -static FileSpec resolveCompDir(const char *path_from_dwarf) { - if (!path_from_dwarf) - return FileSpec(); - - // DWARF2/3 suggests the form hostname:pathname for compilation directory. - // Remove the host part if present. - const char *local_path = removeHostnameFromPathname(path_from_dwarf); - if (!local_path) - return FileSpec(); - - bool is_symlink = false; - // Always normalize our compile unit directory to get rid of redundant - // slashes and other path anomalies before we use it for path prepending - FileSpec local_spec(local_path); - const auto &file_specs = GetGlobalPluginProperties()->GetSymLinkPaths(); - for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i) - is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), - local_spec, true); - - if (!is_symlink) - return local_spec; - - namespace fs = llvm::sys::fs; - if (fs::get_file_type(local_spec.GetPath(), false) != - fs::file_type::symlink_file) - return local_spec; - - FileSpec resolved_symlink; - const auto error = FileSystem::Instance().Readlink(local_spec, resolved_symlink); - if (error.Success()) - return resolved_symlink; - - return local_spec; +const FileSpecList &SymbolFileDWARF::GetSymlinkPaths() { + return GetGlobalPluginProperties()->GetSymLinkPaths(); } DWARFUnit *SymbolFileDWARF::GetBaseCompileUnit() { @@ -810,17 +754,12 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu, if (module_sp) { const DWARFDIE cu_die = dwarf_cu->DIE(); if (cu_die) { - FileSpec cu_file_spec(cu_die.GetName()); + FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu->GetPathStyle()); if (cu_file_spec) { // If we have a full path to the compile unit, we don't need to // resolve the file. This can be expensive e.g. when the source - // files are - // NFS mounted. - if (cu_file_spec.IsRelative()) { - const char *cu_comp_dir{ - cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)}; - cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir)); - } + // files are NFS mounted. + cu_file_spec.MakeAbsolute(dwarf_cu->GetCompilationDirectory()); std::string remapped_file; if (module_sp->RemapSourceFile(cu_file_spec.GetPath(), @@ -947,8 +886,6 @@ bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit, const DWARFBaseDIE cu_die = dwarf_cu->GetUnitDIEOnly(); if (cu_die) { - FileSpec cu_comp_dir = resolveCompDir( - cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)); const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned( DW_AT_stmt_list, DW_INVALID_OFFSET); if (stmt_list != DW_INVALID_OFFSET) { @@ -956,8 +893,8 @@ bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit, // supposed to be the compile unit itself. support_files.Append(comp_unit); return DWARFDebugLine::ParseSupportFiles( - comp_unit.GetModule(), get_debug_line_data(), cu_comp_dir, - stmt_list, support_files, dwarf_cu); + comp_unit.GetModule(), get_debug_line_data(), stmt_list, + support_files, dwarf_cu); } } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index d351289f8b5..e6fe19e75c1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -86,6 +86,8 @@ public: static lldb_private::SymbolFile * CreateInstance(lldb_private::ObjectFile *obj_file); + static const lldb_private::FileSpecList &GetSymlinkPaths(); + //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ diff --git a/lldb/source/Utility/FileSpec.cpp b/lldb/source/Utility/FileSpec.cpp index 954968b7a8a..e621ada794e 100644 --- a/lldb/source/Utility/FileSpec.cpp +++ b/lldb/source/Utility/FileSpec.cpp @@ -557,6 +557,11 @@ bool FileSpec::IsAbsolute() const { return llvm::sys::path::is_absolute(current_path, m_style); } +void FileSpec::MakeAbsolute(const FileSpec &dir) { + if (IsRelative()) + PrependPathComponent(dir); +} + void llvm::format_provider<FileSpec>::format(const FileSpec &F, raw_ostream &Stream, StringRef Style) { |