diff options
author | Jason Molenda <jmolenda@apple.com> | 2019-07-18 20:55:24 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 2019-07-18 20:55:24 +0000 |
commit | 956761adb0ffdf6be50018aea1fb804ecb2da9f2 (patch) | |
tree | f4411e548e43eb3f1c731889bf25827c2e16f856 /lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | |
parent | 01963cec9b3fbc8ec98da449180d95be224dfadd (diff) | |
download | bcm5719-llvm-956761adb0ffdf6be50018aea1fb804ecb2da9f2.tar.gz bcm5719-llvm-956761adb0ffdf6be50018aea1fb804ecb2da9f2.zip |
Fall back to dyld's _dyld_start when no LC_MAIN / main() func can be found
The new DriverKit user-land kernel drivers in macOS 10.15 / Catalina
do not have a main() function or an LC_MAIN load command. lldb uses
the address of main() as the return address for inferior function
calls; it puts a breakpoint on main, runs the inferior function call,
and when the main() breakpoint is hit, lldb knows unambiguously that
the inferior function call ran to completion - no other function calls
main.
This change hoists the logic for finding the "entry address" from
ThreadPlanCallFunction to Target. It changes the logic to first
try to get the entry address from the main executable module,
but if that module does not have one, it will iterate through all
modules looking for an entry address.
The patch also adds code to ObjectFileMachO to use dyld's
_dyld_start function as an entry address.
<rdar://problem/52343958>
Differential Revision: https://reviews.llvm.org/D64897
llvm-svn: 366493
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp')
-rw-r--r-- | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index ce928cf375d..050cb78577b 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1144,6 +1144,10 @@ bool ObjectFileMachO::IsExecutable() const { return m_header.filetype == MH_EXECUTE; } +bool ObjectFileMachO::IsDynamicLoader() const { + return m_header.filetype == MH_DYLINKER; +} + uint32_t ObjectFileMachO::GetAddressByteSize() const { return m_data.GetAddressByteSize(); } @@ -5177,8 +5181,10 @@ lldb_private::Address ObjectFileMachO::GetEntryPointAddress() { // return that. If m_entry_point_address is valid it means we've found it // already, so return the cached value. - if (!IsExecutable() || m_entry_point_address.IsValid()) + if ((!IsExecutable() && !IsDynamicLoader()) || + m_entry_point_address.IsValid()) { return m_entry_point_address; + } // Otherwise, look for the UnixThread or Thread command. The data for the // Thread command is given in /usr/include/mach-o.h, but it is basically: @@ -5300,6 +5306,17 @@ lldb_private::Address ObjectFileMachO::GetEntryPointAddress() { offset = cmd_offset + load_cmd.cmdsize; } + if (start_address == LLDB_INVALID_ADDRESS && IsDynamicLoader()) { + if (GetSymtab()) { + Symbol *dyld_start_sym = GetSymtab()->FindFirstSymbolWithNameAndType( + ConstString("_dyld_start"), SymbolType::eSymbolTypeCode, + Symtab::eDebugAny, Symtab::eVisibilityAny); + if (dyld_start_sym && dyld_start_sym->GetAddress().IsValid()) { + start_address = dyld_start_sym->GetAddress().GetFileAddress(); + } + } + } + if (start_address != LLDB_INVALID_ADDRESS) { // We got the start address from the load commands, so now resolve that // address in the sections of this ObjectFile: |