diff --git a/lldb/include/lldb/API/SBModule.h b/lldb/include/lldb/API/SBModule.h index 85332066ee687..4009ca1461e51 100644 --- a/lldb/include/lldb/API/SBModule.h +++ b/lldb/include/lldb/API/SBModule.h @@ -296,6 +296,11 @@ class LLDB_API SBModule { /// Remove any global modules which are no longer needed. static void GarbageCollectAllocatedModules(); + /// If this Module represents a specific object or part within a larger file, + /// returns the name of that object or part. Otherwise, returns + /// nullptr. + const char *GetObjectName() const; + private: friend class SBAddress; friend class SBFrame; diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp index 985107ec68efd..5a57f45f0d475 100644 --- a/lldb/source/API/SBModule.cpp +++ b/lldb/source/API/SBModule.cpp @@ -671,3 +671,11 @@ void SBModule::GarbageCollectAllocatedModules() { const bool mandatory = false; ModuleList::RemoveOrphanSharedModules(mandatory); } + +const char *SBModule::GetObjectName() const { + LLDB_INSTRUMENT_VA(this); + + if (!m_opaque_sp) + return nullptr; + return m_opaque_sp->GetObjectName().AsCString(); +} diff --git a/lldb/test/API/python_api/sbmodule/Makefile b/lldb/test/API/python_api/sbmodule/Makefile index 10495940055b6..81df9049e13cd 100644 --- a/lldb/test/API/python_api/sbmodule/Makefile +++ b/lldb/test/API/python_api/sbmodule/Makefile @@ -1,3 +1,12 @@ -C_SOURCES := main.c +C_SOURCES := main.c a.c b.c +MAKE_DSYM := NO + +all: a.out + +a.out: main.o libfoo.a + $(LD) $(LDFLAGS) $^ -o $@ + +libfoo.a: a.o b.o + $(AR) $(ARFLAGS) $@ $^ include Makefile.rules diff --git a/lldb/test/API/python_api/sbmodule/TestSBModule.py b/lldb/test/API/python_api/sbmodule/TestSBModule.py index c04e2fa55e8cf..096eadd410cfe 100644 --- a/lldb/test/API/python_api/sbmodule/TestSBModule.py +++ b/lldb/test/API/python_api/sbmodule/TestSBModule.py @@ -18,6 +18,45 @@ def tearDown(self): if self.background_pid: os.kill(self.background_pid, signal.SIGKILL) + @skipIfRemote + def test_GetObjectName(self): + """Test the SBModule::GetObjectName() method""" + self.build() + exe = self.getBuildArtifact("a.out") + libfoo_path = self.getBuildArtifact("libfoo.a") + target_exe = self.dbg.CreateTarget(exe) + self.assertTrue(target_exe.IsValid(), "Target for a.out is valid") + + # Test that the executable module has no object name (usually the first module in the target) + exe_module = target_exe.GetModuleAtIndex(0) + self.assertTrue(exe_module.IsValid(), "Executable module is valid") + self.assertIsNone( + exe_module.GetObjectName(), "a.out should have no object name" + ) + + # check archive member names + module_specs = lldb.SBModuleSpecList.GetModuleSpecifications(libfoo_path) + self.assertGreater( + module_specs.GetSize(), 0, "Archive should have at least one module spec" + ) + found = set() + expected = {"a.o", "b.o"} + for i in range(module_specs.GetSize()): + spec = module_specs.GetSpecAtIndex(i) + obj_name = spec.GetObjectName() + self.assertIsInstance(obj_name, str) + self.assertIn(obj_name, expected, f"Unexpected object name: {obj_name}") + # create a module from the arhive using the sepc + module = lldb.SBModule(spec) + self.assertTrue(module.IsValid(), "Module is valid") + self.assertTrue(module.IsValid(), f"Module for {obj_name} is valid") + self.assertEqual( + module.GetObjectName(), obj_name, f"Object name for {obj_name} matches" + ) + found.add(obj_name) + + self.assertEqual(found, expected, "Did not find all expected archive members") + @skipUnlessDarwin @skipIfRemote def test_module_is_file_backed(self): diff --git a/lldb/test/API/python_api/sbmodule/a.c b/lldb/test/API/python_api/sbmodule/a.c new file mode 100644 index 0000000000000..49f5fffe53b49 --- /dev/null +++ b/lldb/test/API/python_api/sbmodule/a.c @@ -0,0 +1,11 @@ +int __a_global = 1; + +int a(int arg) { + int result = arg + __a_global; + return result; +} + +int aa(int arg1) { + int result1 = arg1 - __a_global; + return result1; +} diff --git a/lldb/test/API/python_api/sbmodule/b.c b/lldb/test/API/python_api/sbmodule/b.c new file mode 100644 index 0000000000000..4c7011b682be1 --- /dev/null +++ b/lldb/test/API/python_api/sbmodule/b.c @@ -0,0 +1,11 @@ +static int __b_global = 2; +char __extra[4096]; // Make sure sizeof b.o differs from a.o +int b(int arg) { + int result = arg + __b_global; + return result; +} + +int bb(int arg1) { + int result2 = arg1 - __b_global; + return result2; +} diff --git a/lldb/test/API/python_api/sbmodule/main.c b/lldb/test/API/python_api/sbmodule/main.c index 101d495698f45..574d57d5fd0bb 100644 --- a/lldb/test/API/python_api/sbmodule/main.c +++ b/lldb/test/API/python_api/sbmodule/main.c @@ -1,3 +1,5 @@ +extern int a(int); +extern int b(int); int main() { while (1) // break here ;