[Lldb-commits] [lldb] [lldb] NFC add comments and test case for ObjectFileMachO delay-init (PR #95067)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Jun 10 18:09:34 PDT 2024
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
More information about the lldb-commits
mailing list