https://github.com/JDevlieghere updated 
https://github.com/llvm/llvm-project/pull/77966

>From ca65108fe01931482110bf6dabef1550fd6a307e Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jo...@devlieghere.com>
Date: Thu, 11 Jan 2024 09:19:31 -0800
Subject: [PATCH 1/2] [lldb] Move CanBeTarget logic into the ObjectFile plugin
 (NFC)

---
 lldb/include/lldb/Symbol/ObjectFile.h |  4 ++++
 lldb/source/Symbol/ObjectFile.cpp     | 33 +++++++++++++++++++++++++++
 lldb/source/Target/Target.cpp         | 33 +++------------------------
 3 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/lldb/include/lldb/Symbol/ObjectFile.h 
b/lldb/include/lldb/Symbol/ObjectFile.h
index 6348d8103f85de..31dc43f469587f 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -698,6 +698,10 @@ class ObjectFile : public 
std::enable_shared_from_this<ObjectFile>,
   /// file to be complete.
   virtual bool CanTrustAddressRanges() { return false; }
 
+  /// Can this object file serve as a valid target module. If a Status is 
passed
+  /// and the answer is no, it will be populated with the reason.
+  virtual bool CanBeTargetModule(Status *status = nullptr);
+
   static lldb::SymbolType GetSymbolTypeFromName(
       llvm::StringRef name,
       lldb::SymbolType symbol_type_hint = lldb::eSymbolTypeUndefined);
diff --git a/lldb/source/Symbol/ObjectFile.cpp 
b/lldb/source/Symbol/ObjectFile.cpp
index d890ad92e83122..cc63c05a4c5ec8 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/source/Symbol/ObjectFile.cpp
@@ -764,6 +764,39 @@ uint32_t ObjectFile::GetCacheHash() {
   return *m_cache_hash;
 }
 
+bool ObjectFile::CanBeTargetModule(Status *status) {
+  switch (GetType()) {
+  case ObjectFile::eTypeCoreFile:      /// A core file that has a checkpoint of
+                                       /// a program's execution state
+  case ObjectFile::eTypeExecutable:    /// A normal executable
+  case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker
+                                       /// executable
+  case ObjectFile::eTypeObjectFile:    /// An intermediate object file
+  case ObjectFile::eTypeSharedLibrary: /// A shared library that can be
+                                       /// used during execution
+    return true;
+  case ObjectFile::eTypeDebugInfo: /// An object file that contains only
+                                   /// debug information
+    if (status)
+      status->SetErrorString("debug info files aren't valid target "
+                             "modules, please specify an executable");
+    return false;
+  case ObjectFile::eTypeStubLibrary: /// A library that can be linked
+                                     /// against but not used for
+                                     /// execution
+    if (status)
+      status->SetErrorString("stub libraries aren't valid target "
+                             "modules, please specify an executable");
+    return false;
+  default:
+    if (status)
+      status->SetErrorString(
+          "unsupported file type, please specify an executable");
+    return false;
+  }
+  llvm_unreachable("Fully covered switch above!");
+}
+
 namespace llvm {
 namespace json {
 
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 302c2bad7021b9..d0975d6c378c50 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -2254,37 +2254,10 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec 
&module_spec, bool notify,
     // there wasn't an equivalent module in the list already, and if there was,
     // let's remove it.
     if (module_sp) {
-      ObjectFile *objfile = module_sp->GetObjectFile();
-      if (objfile) {
-        switch (objfile->GetType()) {
-        case ObjectFile::eTypeCoreFile: /// A core file that has a checkpoint 
of
-                                        /// a program's execution state
-        case ObjectFile::eTypeExecutable:    /// A normal executable
-        case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker
-                                             /// executable
-        case ObjectFile::eTypeObjectFile:    /// An intermediate object file
-        case ObjectFile::eTypeSharedLibrary: /// A shared library that can be
-                                             /// used during execution
-          break;
-        case ObjectFile::eTypeDebugInfo: /// An object file that contains only
-                                         /// debug information
-          if (error_ptr)
-            error_ptr->SetErrorString("debug info files aren't valid target "
-                                      "modules, please specify an executable");
-          return ModuleSP();
-        case ObjectFile::eTypeStubLibrary: /// A library that can be linked
-                                           /// against but not used for
-                                           /// execution
-          if (error_ptr)
-            error_ptr->SetErrorString("stub libraries aren't valid target "
-                                      "modules, please specify an executable");
-          return ModuleSP();
-        default:
-          if (error_ptr)
-            error_ptr->SetErrorString(
-                "unsupported file type, please specify an executable");
+      if (ObjectFile *objfile = module_sp->GetObjectFile()) {
+        if (!objfile->CanBeTargetModule(error_ptr))
           return ModuleSP();
-        }
+
         // GetSharedModule is not guaranteed to find the old shared module, for
         // instance in the common case where you pass in the UUID, it is only
         // going to find the one module matching the UUID.  In fact, it has no

>From 761f4c18a13d0e50f570bf1d3a8d79ce8b26ddc0 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jo...@devlieghere.com>
Date: Fri, 12 Jan 2024 11:13:47 -0800
Subject: [PATCH 2/2] [lldb] Support dSYMs as modules

Generally, separate debug info files are not object files. The exception
are dSYMs which are Mach-O and often contain enough information to be
used as a module.

This patch allows users to add dSYM symbol files as target modules to
support use cases where the executable isn't available. This scenario is
common when doing core file debugging and Jason has a follow up patch
that allows core file debugging without just the dSYM.

rdar://117773589
---
 .../ObjectFile/Mach-O/ObjectFileMachO.cpp     |  6 ++++++
 .../ObjectFile/Mach-O/ObjectFileMachO.h       |  3 +++
 lldb/test/API/macosx/dsym-module/Makefile     |  3 +++
 .../dsym-module/TestTargetModuleAddDsym.py    | 21 +++++++++++++++++++
 lldb/test/API/macosx/dsym-module/main.c       |  5 +++++
 5 files changed, 38 insertions(+)
 create mode 100644 lldb/test/API/macosx/dsym-module/Makefile
 create mode 100644 lldb/test/API/macosx/dsym-module/TestTargetModuleAddDsym.py
 create mode 100644 lldb/test/API/macosx/dsym-module/main.c

diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 
b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index d7a2846200fcaf..ece416ac999744 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -6128,6 +6128,12 @@ Section *ObjectFileMachO::GetMachHeaderSection() {
   return nullptr;
 }
 
+bool ObjectFileMachO::CanBeTargetModule(Status *status) {
+  if (m_header.filetype == MH_DSYM)
+    return true;
+  return ObjectFile::CanBeTargetModule(status);
+}
+
 bool ObjectFileMachO::SectionIsLoadable(const Section *section) {
   if (!section)
     return false;
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h 
b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index 0a47f3a7dd1861..9950e412b5fda1 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -160,6 +160,9 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
 
   lldb_private::Section *GetMachHeaderSection();
 
+  virtual bool
+  CanBeTargetModule(lldb_private::Status *status = nullptr) override;
+
   // PluginInterface protocol
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
 
diff --git a/lldb/test/API/macosx/dsym-module/Makefile 
b/lldb/test/API/macosx/dsym-module/Makefile
new file mode 100644
index 00000000000000..99998b20bcb050
--- /dev/null
+++ b/lldb/test/API/macosx/dsym-module/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/macosx/dsym-module/TestTargetModuleAddDsym.py 
b/lldb/test/API/macosx/dsym-module/TestTargetModuleAddDsym.py
new file mode 100644
index 00000000000000..2034a6491c4571
--- /dev/null
+++ b/lldb/test/API/macosx/dsym-module/TestTargetModuleAddDsym.py
@@ -0,0 +1,21 @@
+import os
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+
+@skipUnlessDarwin
+class TargetModuleAddDsymTest(TestBase):
+    @no_debug_info_test
+    def test_target_module_add(self):
+        """Test that you can add a dSYM as a module."""
+        self.build(debug_info="dsym")
+
+        exe_path = self.getBuildArtifact("a.out")
+        dsym_path = exe_path + ".dSYM"
+        sym_path = os.path.join(dsym_path, "Contents", "Resources", "DWARF", 
"a.out")
+
+        exe = self.getBuildArtifact("a.out")
+        self.dbg.CreateTarget(exe)
+
+        self.runCmd("target module add %s" % sym_path)
+        self.expect("image list", substrs=[sym_path])
diff --git a/lldb/test/API/macosx/dsym-module/main.c 
b/lldb/test/API/macosx/dsym-module/main.c
new file mode 100644
index 00000000000000..b5c9a5152d61d9
--- /dev/null
+++ b/lldb/test/API/macosx/dsym-module/main.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+int main(int argc, char const *argv[]) {
+  return argc + 1;
+}

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to