Index: include/lldb/Utility/FileSpec.h =================================================================== --- include/lldb/Utility/FileSpec.h +++ include/lldb/Utility/FileSpec.h @@ -326,6 +326,10 @@ //------------------------------------------------------------------ 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); } Index: lit/SymbolFile/DWARF/Inputs/dir-separator-no-comp-dir-relative-name.lldbinit =================================================================== --- lit/SymbolFile/DWARF/Inputs/dir-separator-no-comp-dir-relative-name.lldbinit +++ 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 Index: lit/SymbolFile/DWARF/Inputs/dir-separator-posix.lldbinit =================================================================== --- lit/SymbolFile/DWARF/Inputs/dir-separator-posix.lldbinit +++ 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 Index: lit/SymbolFile/DWARF/Inputs/dir-separator-windows.lldbinit =================================================================== --- lit/SymbolFile/DWARF/Inputs/dir-separator-windows.lldbinit +++ 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 Index: lit/SymbolFile/DWARF/dir-separator-no-comp-dir-relative-name.s =================================================================== --- lit/SymbolFile/DWARF/dir-separator-no-comp-dir-relative-name.s +++ 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: Index: lit/SymbolFile/DWARF/dir-separator-no-comp-dir.s =================================================================== --- lit/SymbolFile/DWARF/dir-separator-no-comp-dir.s +++ 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: Index: lit/SymbolFile/DWARF/dir-separator-posix.s =================================================================== --- lit/SymbolFile/DWARF/dir-separator-posix.s +++ 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: Index: lit/SymbolFile/DWARF/dir-separator-windows.s =================================================================== --- lit/SymbolFile/DWARF/dir-separator-windows.s +++ 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: Index: source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h +++ source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h @@ -14,6 +14,7 @@ #include #include +#include "lldb/Utility/FileSpec.h" #include "lldb/lldb-private.h" #include "DWARFDataExtractor.h" @@ -99,6 +100,7 @@ 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 @@ 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, Index: source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ 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::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 @@ 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 @@ //} 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; Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -169,6 +169,9 @@ bool GetIsOptimized(); + const lldb_private::FileSpec &GetCompilationDirectory(); + lldb_private::FileSpec::Style GetPathStyle(); + SymbolFileDWARFDwo *GetDwoSymbolFile() const; dw_offset_t GetBaseObjOffset() const; @@ -214,6 +217,7 @@ lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown; bool m_is_dwarf64 = false; lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate; + llvm::Optional 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 @@ void AddUnitDIE(const DWARFDebugInfoEntry &cu_die); void ExtractDIEsEndCheck(lldb::offset_t offset) const; + void ComputeCompDirAndGuessPathStyle(); + DISALLOW_COPY_AND_ASSIGN(DWARFUnit); }; Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -766,6 +766,80 @@ 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(); } Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -86,6 +86,8 @@ static lldb_private::SymbolFile * CreateInstance(lldb_private::ObjectFile *obj_file); + static const lldb_private::FileSpecList &GetSymlinkPaths(); + //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -158,64 +158,8 @@ } // 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 @@ 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 @@ 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 @@ // 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); } } } Index: source/Utility/FileSpec.cpp =================================================================== --- source/Utility/FileSpec.cpp +++ source/Utility/FileSpec.cpp @@ -557,6 +557,11 @@ return llvm::sys::path::is_absolute(current_path, m_style); } +void FileSpec::MakeAbsolute(const FileSpec &dir) { + if (IsRelative()) + PrependPathComponent(dir); +} + void llvm::format_provider::format(const FileSpec &F, raw_ostream &Stream, StringRef Style) {