Author: jingham Date: Mon Mar 20 14:21:31 2017 New Revision: 298290 URL: http://llvm.org/viewvc/llvm-project?rev=298290&view=rev Log: Get ObjectFileMachO to handle @executable_path
Only do this when we are debugging an executable, since we don't have a good way to trace from an ObjectFile back to its containing executable. Detecting pre-run libs before running is "best effort" in lldb, but this one is pretty easy. Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/ lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/Makefile lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/TestPreRunDylibs.py lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/foo.cpp lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/foo.h lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/main.cpp Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/Makefile?rev=298290&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/Makefile (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/Makefile Mon Mar 20 14:21:31 2017 @@ -0,0 +1,8 @@ +LEVEL = ../../make + +DYLIB_NAME := unlikely_name +DYLIB_CXX_SOURCES := foo.cpp +CXX_SOURCES := main.cpp +CFLAGS_EXTRAS += -fPIC + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/TestPreRunDylibs.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/TestPreRunDylibs.py?rev=298290&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/TestPreRunDylibs.py (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/TestPreRunDylibs.py Mon Mar 20 14:21:31 2017 @@ -0,0 +1,38 @@ +from __future__ import print_function + +import unittest2 +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * + +class TestPreRunLibraries(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + @skipIf(oslist=no_match(['darwin','macos'])) + def test(self): + """Test that we find directly linked dylib pre-run.""" + + self.build() + target = self.dbg.CreateTarget("a.out") + self.assertTrue(target, VALID_TARGET) + + # I don't know what the name of a shared library + # extension is in general, so instead of using FindModule, + # I'll iterate through the module and do a basename match. + found_it = False + for module in target.modules: + file_name = module.GetFileSpec().GetFilename() + if file_name.find("unlikely_name") != -1: + found_it = True + break + + self.assertTrue(found_it, "Couldn't find unlikely_to_occur_name in loaded libraries.") + + Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/foo.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/foo.cpp?rev=298290&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/foo.cpp (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/foo.cpp Mon Mar 20 14:21:31 2017 @@ -0,0 +1,3 @@ +#include "foo.h" + +int call_foo1() { return foo1(); } Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/foo.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/foo.h?rev=298290&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/foo.h (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/foo.h Mon Mar 20 14:21:31 2017 @@ -0,0 +1,6 @@ +LLDB_TEST_API inline int foo1() { return 1; } // !BR1 + +LLDB_TEST_API inline int foo2() { return 2; } // !BR2 + +LLDB_TEST_API extern int call_foo1(); +LLDB_TEST_API extern int call_foo2(); Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/main.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/main.cpp?rev=298290&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/main.cpp (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/main.cpp Mon Mar 20 14:21:31 2017 @@ -0,0 +1,9 @@ +#include "foo.h" + +int call_foo2() { return foo2(); } + +int +main() // !BR_main +{ + return call_foo1() + call_foo2(); +} Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=298290&r1=298289&r2=298290&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Mon Mar 20 14:21:31 2017 @@ -5052,6 +5052,7 @@ uint32_t ObjectFileMachO::GetDependentMo lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); std::vector<std::string> rpath_paths; std::vector<std::string> rpath_relative_paths; + std::vector<std::string> at_exec_relative_paths; const bool resolve_path = false; // Don't resolve the dependent file paths // since they may not reside on this system uint32_t i; @@ -5077,6 +5078,10 @@ uint32_t ObjectFileMachO::GetDependentMo if (path[0] == '@') { if (strncmp(path, "@rpath", strlen("@rpath")) == 0) rpath_relative_paths.push_back(path + strlen("@rpath")); + else if (strncmp(path, "@executable_path", + strlen("@executable_path")) == 0) + at_exec_relative_paths.push_back(path + + strlen("@executable_path")); } else { FileSpec file_spec(path, resolve_path); if (files.AppendIfUnique(file_spec)) @@ -5092,10 +5097,11 @@ uint32_t ObjectFileMachO::GetDependentMo offset = cmd_offset + load_cmd.cmdsize; } + FileSpec this_file_spec(m_file); + this_file_spec.ResolvePath(); + if (!rpath_paths.empty()) { // Fixup all LC_RPATH values to be absolute paths - FileSpec this_file_spec(m_file); - this_file_spec.ResolvePath(); std::string loader_path("@loader_path"); std::string executable_path("@executable_path"); for (auto &rpath : rpath_paths) { @@ -5125,6 +5131,23 @@ uint32_t ObjectFileMachO::GetDependentMo } } } + + // We may have @executable_paths but no RPATHS. Figure those out here. + // Only do this if this object file is the executable. We have no way to + // get back to the actual executable otherwise, so we won't get the right + // path. + if (!at_exec_relative_paths.empty() && CalculateType() == eTypeExecutable) { + FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent(); + for (const auto &at_exec_relative_path : at_exec_relative_paths) { + FileSpec file_spec = + exec_dir.CopyByAppendingPathComponent(at_exec_relative_path); + file_spec = file_spec.GetNormalizedPath(); + if (file_spec.Exists() && files.AppendIfUnique(file_spec)) { + count++; + break; + } + } + } } return count; } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits