Skip to content

[lldb] NFC add comments and test case for ObjectFileMachO delay-init #95067

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

jasonmolenda
Copy link
Collaborator

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

rdar://126885033

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

rdar://126885033
@llvmbot
Copy link
Member

llvmbot commented Jun 11, 2024

@llvm/pr-subscribers-lldb

Author: Jason Molenda (jasonmolenda)

Changes

Add comments and a test for delay-init libraries on macOS. I originally added the support in 954d00e 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 --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
+}

Copy link

github-actions bot commented Jun 11, 2024

✅ With the latest revision this PR passed the Python code formatter.

Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if the formatter's happy.

@jasonmolenda
Copy link
Collaborator Author

the formatter is whining about an extra newline in a test file

@jasonmolenda jasonmolenda merged commit 1934208 into llvm:main Jun 11, 2024
4 of 5 checks passed
@jasonmolenda jasonmolenda deleted the add-delay-init-library-comments-and-test branch June 11, 2024 03:33
jasonmolenda added a commit to jasonmolenda/llvm-project that referenced this pull request Jun 11, 2024
…lvm#95067)

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

rdar://126885033
(cherry picked from commit 1934208)
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Jun 12, 2024
…lvm#95067)

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

rdar://126885033
@HerrCai0907 HerrCai0907 mentioned this pull request Jun 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants