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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
11 changes: 11 additions & 0 deletions lldb/test/API/macosx/delay-init-dependency/Makefile
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""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)
1 change: 1 addition & 0 deletions lldb/test/API/macosx/delay-init-dependency/foo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int foo() { return 5; }
9 changes: 9 additions & 0 deletions lldb/test/API/macosx/delay-init-dependency/main.c
Original file line number Diff line number Diff line change
@@ -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
}
Loading