diff options
author | Jim Ingham <jingham@apple.com> | 2012-04-13 20:38:13 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2012-04-13 20:38:13 +0000 |
commit | 0092c8eb2fd0984f2c77e391e8069739e56c1879 (patch) | |
tree | eaf19dc14dea5b40c94955bca20151d8aada7bfc /lldb/source/Target/ThreadPlanCallFunction.cpp | |
parent | de0e9d04ad175d567be0230b6c785d8bada531ec (diff) | |
download | bcm5719-llvm-0092c8eb2fd0984f2c77e391e8069739e56c1879.tar.gz bcm5719-llvm-0092c8eb2fd0984f2c77e391e8069739e56c1879.zip |
Factor out a bunch of common code in the two ThreadPlanCallFunction constructors. Also add a sanity check - try reading the frame, and if we fail bag out.
llvm-svn: 154698
Diffstat (limited to 'lldb/source/Target/ThreadPlanCallFunction.cpp')
-rw-r--r-- | lldb/source/Target/ThreadPlanCallFunction.cpp | 159 |
1 files changed, 62 insertions, 97 deletions
diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp index a01b5b725d8..8e1d018e85f 100644 --- a/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -34,23 +34,12 @@ using namespace lldb_private; //---------------------------------------------------------------------- // ThreadPlanCallFunction: Plan to call a single function //---------------------------------------------------------------------- - -ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, - Address &function, - const ClangASTType &return_type, - addr_t arg, - bool stop_other_threads, - bool discard_on_error, - addr_t *this_arg, - addr_t *cmd_arg) : - ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), - m_valid (false), - m_stop_other_threads (stop_other_threads), - m_function_addr (function), - m_function_sp (NULL), - m_return_type (return_type), - m_takedown_done (false), - m_stop_address (LLDB_INVALID_ADDRESS) +bool +ThreadPlanCallFunction::ConstructorSetup (Thread &thread, + bool discard_on_error, + ABI *& abi, + lldb::addr_t &start_load_addr, + lldb::addr_t &function_load_addr) { // Call function thread plans need to be master plans so that they can potentially stay on the stack when // a breakpoint is hit during the function call. @@ -59,12 +48,12 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, ProcessSP process_sp (thread.GetProcess()); if (!process_sp) - return; + return false; - const ABI *abi = process_sp->GetABI().get(); + abi = process_sp->GetABI().get(); if (!abi) - return; + return false; TargetSP target_sp (thread.CalculateTarget()); @@ -73,6 +62,16 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, SetBreakpoints(); m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); + // If we can't read memory at the point of the process where we are planning to put our function, we're + // not going to get any further... + Error error; + process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error); + if (!error.Success()) + { + if (log) + log->Printf ("Trying to put the stack in unreadable memory at: 0x%llx.", m_function_sp); + return false; + } Module *exe_module = target_sp->GetExecutableModulePointer(); @@ -80,7 +79,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, { if (log) log->Printf ("Can't execute code without an executable module."); - return; + return false; } else { @@ -90,7 +89,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, if (log) log->Printf ("Could not find object file for module \"%s\".", exe_module->GetFileSpec().GetFilename().AsCString()); - return; + return false; } m_start_addr = objectFile->GetEntryPointAddress(); if (!m_start_addr.IsValid()) @@ -98,11 +97,11 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, if (log) log->Printf ("Could not find entry point address for executable module \"%s\".", exe_module->GetFileSpec().GetFilename().AsCString()); - return; + return false; } } - addr_t start_load_addr = m_start_addr.GetLoadAddress (target_sp.get()); + start_load_addr = m_start_addr.GetLoadAddress (target_sp.get()); // Checkpoint the thread state so we can restore it later. if (log && log->GetVerbose()) @@ -112,18 +111,44 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, { if (log) log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); - return; + return false; } // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... thread.SetStopInfoToNothing(); - addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress (target_sp.get()); + function_load_addr = m_function_addr.GetLoadAddress (target_sp.get()); + + return true; +} + +ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, + Address &function, + const ClangASTType &return_type, + addr_t arg, + bool stop_other_threads, + bool discard_on_error, + addr_t *this_arg, + addr_t *cmd_arg) : + ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), + m_valid (false), + m_stop_other_threads (stop_other_threads), + m_function_addr (function), + m_function_sp (NULL), + m_return_type (return_type), + m_takedown_done (false), + m_stop_address (LLDB_INVALID_ADDRESS) +{ + lldb::addr_t start_load_addr; + ABI *abi; + lldb::addr_t function_load_addr; + if (!ConstructorSetup (thread, discard_on_error, abi, start_load_addr, function_load_addr)) + return; if (this_arg && cmd_arg) { if (!abi->PrepareTrivialCall (thread, m_function_sp, - FunctionLoadAddr, + function_load_addr, start_load_addr, this_arg, cmd_arg, @@ -134,7 +159,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, { if (!abi->PrepareTrivialCall (thread, m_function_sp, - FunctionLoadAddr, + function_load_addr, start_load_addr, this_arg, &arg)) @@ -144,7 +169,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, { if (!abi->PrepareTrivialCall (thread, m_function_sp, - FunctionLoadAddr, + function_load_addr, start_load_addr, &arg)) return; @@ -173,78 +198,18 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, m_function_addr (function), m_function_sp(NULL), m_return_type (return_type), - m_takedown_done (false) + m_takedown_done (false), + m_stop_address (LLDB_INVALID_ADDRESS) { - // Call function thread plans need to be master plans so that they can potentially stay on the stack when - // a breakpoint is hit during the function call. - SetIsMasterPlan (true); - SetOkayToDiscard (discard_on_error); - - ProcessSP process_sp (thread.GetProcess()); - if (!process_sp) - return; - - const ABI *abi = process_sp->GetABI().get(); - - if (!abi) - return; - - TargetSP target_sp (thread.CalculateTarget()); - - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); - - SetBreakpoints(); - - m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); - - Module *exe_module = target_sp->GetExecutableModulePointer(); - - if (exe_module == NULL) - { - if (log) - log->Printf ("Can't execute code without an executable module."); + lldb::addr_t start_load_addr; + ABI *abi; + lldb::addr_t function_load_addr; + if (!ConstructorSetup (thread, discard_on_error, abi, start_load_addr, function_load_addr)) return; - } - else - { - ObjectFile *objectFile = exe_module->GetObjectFile(); - if (!objectFile) - { - if (log) - log->Printf ("Could not find object file for module \"%s\".", - exe_module->GetFileSpec().GetFilename().AsCString()); - return; - } - m_start_addr = objectFile->GetEntryPointAddress(); - if (!m_start_addr.IsValid()) - { - if (log) - log->Printf ("Could not find entry point address for executable module \"%s\".", - exe_module->GetFileSpec().GetFilename().AsCString()); - return; - } - } - - addr_t start_load_addr = m_start_addr.GetLoadAddress(target_sp.get()); - - // Checkpoint the thread state so we can restore it later. - if (log && log->GetVerbose()) - ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); - - if (!thread.CheckpointThreadState (m_stored_thread_state)) - { - if (log) - log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); - return; - } - // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... - thread.SetStopInfoToNothing(); - - addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(target_sp.get()); if (!abi->PrepareTrivialCall (thread, - m_function_sp, - FunctionLoadAddr, + m_function_sp, + function_load_addr, start_load_addr, arg1_ptr, arg2_ptr, |