Small further refinement to the check in ObjectFileMachO::ParseSymtab

which looks for binaries missing an LC_FUNCTION_STARTS section because
it was stripped/not emitted.  If we see a normal user process binary
(executable, dylib, framework, bundle) without LC_FUNCTION_STARTS, that
is unusual and we should disallow instruction emulation because that
binary has likely been stripped a lot.

If this is a non-user process binary -- a kernel, a standalone bare-board
binary, a kernel extension (kext) -- and there is no LC_FUNCTION_STARTS,
we should not assume anything about the binary and allow instruction
emulation as we would normally do.

<rdar://problem/26453952> 

llvm-svn: 270818
This commit is contained in:
Jason Molenda
2016-05-26 04:22:47 +00:00
parent d1af08c3d6
commit 0bc8994a4c

View File

@@ -2607,14 +2607,16 @@ ObjectFileMachO::ParseSymtab ()
const size_t function_starts_count = function_starts.GetSize();
// kext bundles don't have LC_FUNCTION_STARTS / eh_frame sections, but we can assume that we have
// accurate symbol boundaries for them, they're a special case.
if (function_starts_count == 0 && m_header.filetype != llvm::MachO::MH_KEXT_BUNDLE)
// For user process binaries (executables, dylibs, frameworks, bundles), if we don't have
// LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume the binary
// has been stripped. Don't allow assembly language instruction emulation because we don't
// know proper function start boundaries.
//
// For all other types of binaries (kernels, stand-alone bare board binaries, kexts), they
// may not have LC_FUNCTION_STARTS / eh_frame sections - we should not make any assumptions
// about them based on that.
if (function_starts_count == 0 && CalculateStrata() == eStrataUser)
{
// No LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume the binary
// has been stripped. Don't allow assembly language instruction emulation because we don't
// know proper function start boundaries.
m_allow_assembly_emulation_unwind_plans = false;
Log *unwind_or_symbol_log (lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_UNWIND));