labath updated this revision to Diff 182010.
labath added a comment.

- add a test for the no-DW_AT_comp_dir + relative-DW_AT_name case


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56543/new/

https://reviews.llvm.org/D56543

Files:
  include/lldb/Utility/FileSpec.h
  lit/SymbolFile/DWARF/Inputs/dir-separator-no-comp-dir-relative-name.lldbinit
  lit/SymbolFile/DWARF/Inputs/dir-separator-posix.lldbinit
  lit/SymbolFile/DWARF/Inputs/dir-separator-windows.lldbinit
  lit/SymbolFile/DWARF/dir-separator-no-comp-dir-relative-name.s
  lit/SymbolFile/DWARF/dir-separator-no-comp-dir.s
  lit/SymbolFile/DWARF/dir-separator-posix.s
  lit/SymbolFile/DWARF/dir-separator-windows.s
  source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
  source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFUnit.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  source/Utility/FileSpec.cpp

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<FileSpec>::format(const FileSpec &F,
                                              raw_ostream &Stream,
                                              StringRef Style) {
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/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<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 @@
   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/DWARFDebugLine.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
+++ 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 @@
       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: lit/SymbolFile/DWARF/dir-separator-windows.s
===================================================================
--- /dev/null
+++ 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: lit/SymbolFile/DWARF/dir-separator-posix.s
===================================================================
--- /dev/null
+++ 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-no-comp-dir.s
===================================================================
--- /dev/null
+++ 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-no-comp-dir-relative-name.s
===================================================================
--- /dev/null
+++ 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/Inputs/dir-separator-windows.lldbinit
===================================================================
--- /dev/null
+++ 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/Inputs/dir-separator-posix.lldbinit
===================================================================
--- /dev/null
+++ 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-no-comp-dir-relative-name.lldbinit
===================================================================
--- /dev/null
+++ 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: 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); }
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to