llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Jason Molenda (jasonmolenda)

<details>
<summary>Changes</summary>

Add comments and a test for delay-init libraries on macOS.  I originally added 
the support in 954d00e87cdd77d0e9e367be52e62340467bd779 a month ago, but 
without these additional clarifications.

rdar://126885033

---
Full diff: https://github.com/llvm/llvm-project/pull/95067.diff


5 Files Affected:

- (modified) lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (+8) 
- (added) lldb/test/API/macosx/delay-init-dependency/Makefile (+11) 
- (added) lldb/test/API/macosx/delay-init-dependency/TestDelayInitDependency.py 
(+63) 
- (added) lldb/test/API/macosx/delay-init-dependency/foo.c (+1) 
- (added) lldb/test/API/macosx/delay-init-dependency/main.c (+9) 


``````````diff
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 
b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 4dd23bb1e4dbe..2979bf69bf762 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5140,12 +5140,20 @@ uint32_t 
ObjectFileMachO::GetDependentModules(FileSpecList &files) {
       case LC_LOADFVMLIB:
       case LC_LOAD_UPWARD_DYLIB: {
         uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
+        // For LC_LOAD_DYLIB there is an alternate encoding
+        // which adds a uint32_t `flags` field for `DYLD_USE_*`
+        // flags.  This can be detected by a timestamp field with
+        // the `DYLIB_USE_MARKER` constant value.
         bool is_delayed_init = false;
         uint32_t use_command_marker = m_data.GetU32(&offset);
         if (use_command_marker == 0x1a741800 /* DYLIB_USE_MARKER */) {
           offset += 4; /* uint32_t current_version */
           offset += 4; /* uint32_t compat_version */
           uint32_t flags = m_data.GetU32(&offset);
+          // If this LC_LOAD_DYLIB is marked delay-init,
+          // don't report it as a dependent library -- it
+          // may be loaded in the process at some point,
+          // but will most likely not be load at launch.
           if (flags & 0x08 /* DYLIB_USE_DELAYED_INIT */)
             is_delayed_init = true;
         }
diff --git a/lldb/test/API/macosx/delay-init-dependency/Makefile 
b/lldb/test/API/macosx/delay-init-dependency/Makefile
new file mode 100644
index 0000000000000..246ea0f34e1a1
--- /dev/null
+++ b/lldb/test/API/macosx/delay-init-dependency/Makefile
@@ -0,0 +1,11 @@
+C_SOURCES := main.c
+LD_EXTRAS := -L. -Wl,-delay_library,libfoo.dylib
+
+.PHONY: build-libfoo
+all: build-libfoo a.out
+
+include Makefile.rules
+
+build-libfoo: foo.c
+       $(MAKE) -f $(MAKEFILE_RULES) \
+               DYLIB_C_SOURCES=foo.c DYLIB_NAME=foo DYLIB_ONLY=YES
diff --git 
a/lldb/test/API/macosx/delay-init-dependency/TestDelayInitDependency.py 
b/lldb/test/API/macosx/delay-init-dependency/TestDelayInitDependency.py
new file mode 100644
index 0000000000000..9b9b1618ba6de
--- /dev/null
+++ b/lldb/test/API/macosx/delay-init-dependency/TestDelayInitDependency.py
@@ -0,0 +1,63 @@
+"""Test binaries with delay-init dependencies."""
+
+import subprocess
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestDelayInitDependencies(TestBase):
+
+    NO_DEBUG_INFO_TESTCASE = True
+
+    @skipUnlessDarwin
+    def test_delay_init_dependency(self):
+        TestBase.setUp(self)
+        out = subprocess.run(
+            ["xcrun", "ld", "-delay_library"],
+            universal_newlines=True,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+        )
+        if "delay_library missing" not in out.stderr:
+            self.skipTest(
+                "Skipped because the linker doesn't know about -delay_library"
+            )
+        self.build()
+        main_source = "main.c"
+        exe = self.getBuildArtifact("a.out")
+        lib = self.getBuildArtifact("libfoo.dylib")
+
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+        # libfoo.dylib should not be in the target pre-execution
+        for m in target.modules:
+            self.assertNotEqual(m.GetFileSpec().GetFilename(), "libfoo.dylib")
+
+        # This run without arguments will not load libfoo.dylib
+        li = lldb.SBLaunchInfo([])
+        li.SetWorkingDirectory(self.getBuildDir())
+        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.c"), li
+        )
+        for m in target.modules:
+            self.assertNotEqual(m.GetFileSpec().GetFilename(), "libfoo.dylib")
+
+        process.Kill()
+        self.dbg.DeleteTarget(target)
+
+        # This run with one argument will load libfoo.dylib
+        li = lldb.SBLaunchInfo([])
+        li.SetWorkingDirectory(self.getBuildDir())
+        li.SetArguments(["one-argument"], True)
+        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.c"), li
+        )
+
+        found_libfoo = False
+        for m in target.modules:
+            if m.GetFileSpec().GetFilename() == "libfoo.dylib":
+                found_libfoo = True
+        self.assertTrue(found_libfoo)
diff --git a/lldb/test/API/macosx/delay-init-dependency/foo.c 
b/lldb/test/API/macosx/delay-init-dependency/foo.c
new file mode 100644
index 0000000000000..de1cbc4c4648a
--- /dev/null
+++ b/lldb/test/API/macosx/delay-init-dependency/foo.c
@@ -0,0 +1 @@
+int foo() { return 5; }
diff --git a/lldb/test/API/macosx/delay-init-dependency/main.c 
b/lldb/test/API/macosx/delay-init-dependency/main.c
new file mode 100644
index 0000000000000..57d251e6b2abe
--- /dev/null
+++ b/lldb/test/API/macosx/delay-init-dependency/main.c
@@ -0,0 +1,9 @@
+int foo();
+int main(int argc, char **argv) {
+  int retval = 0;
+  // Only call foo() if one argument is passed
+  if (argc == 2)
+    retval = foo();
+
+  return retval; // break here
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/95067
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to