diff options
author | Greg Clayton <gclayton@apple.com> | 2011-05-14 01:50:35 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2011-05-14 01:50:35 +0000 |
commit | 2a48f525cdbd043ac6be814542a034aa09d25e0b (patch) | |
tree | d145a110aede294740bfa6f4fe678da78adff488 /lldb/source/Target/ThreadPlanCallFunction.cpp | |
parent | a16b5be727be41439f086ca466bf3d5a726bd288 (diff) | |
download | bcm5719-llvm-2a48f525cdbd043ac6be814542a034aa09d25e0b.tar.gz bcm5719-llvm-2a48f525cdbd043ac6be814542a034aa09d25e0b.zip |
Expand the ABI prepare trivial function call to allow 6 simple args.
llvm-svn: 131334
Diffstat (limited to 'lldb/source/Target/ThreadPlanCallFunction.cpp')
-rw-r--r-- | lldb/source/Target/ThreadPlanCallFunction.cpp | 140 |
1 files changed, 114 insertions, 26 deletions
diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp index 1da0e7b7945..fee0cbd1c7c 100644 --- a/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -37,20 +37,18 @@ using namespace lldb_private; ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, Address &function, - lldb::addr_t arg, + addr_t arg, bool stop_other_threads, bool discard_on_error, - lldb::addr_t *this_arg, - lldb::addr_t *cmd_arg) : + 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_arg_addr (arg), - m_args (NULL), m_process (thread.GetProcess()), m_thread (thread), m_takedown_done (false), - m_function_sp(NULL) + m_function_sp (NULL) { SetOkayToDiscard (discard_on_error); @@ -92,7 +90,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, } } - lldb::addr_t StartLoadAddr = m_start_addr.GetLoadAddress(&target); + addr_t start_load_addr = m_start_addr.GetLoadAddress(&target); // Checkpoint the thread state so we can restore it later. if (log && log->GetVerbose()) @@ -108,17 +106,17 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, thread.SetStopInfoToNothing(); m_function_addr = function; - lldb::addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target); + addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target); if (this_arg && cmd_arg) { if (!abi->PrepareTrivialCall (thread, m_function_sp, FunctionLoadAddr, - StartLoadAddr, + start_load_addr, this_arg, cmd_arg, - &m_arg_addr)) + &arg)) return; } else if (this_arg) @@ -126,10 +124,9 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, if (!abi->PrepareTrivialCall (thread, m_function_sp, FunctionLoadAddr, - StartLoadAddr, + start_load_addr, this_arg, - &m_arg_addr, - NULL)) + &arg)) return; } else @@ -137,10 +134,104 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, if (!abi->PrepareTrivialCall (thread, m_function_sp, FunctionLoadAddr, - StartLoadAddr, - &m_arg_addr, - NULL, - NULL)) + start_load_addr, + &arg)) + return; + } + + ReportRegisterState ("Function call was set up. Register state was:"); + + m_valid = true; +} + + +ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, + Address &function, + bool stop_other_threads, + bool discard_on_error, + addr_t *arg1_ptr, + addr_t *arg2_ptr, + addr_t *arg3_ptr, + addr_t *arg4_ptr, + addr_t *arg5_ptr, + addr_t *arg6_ptr) : + ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), + m_valid (false), + m_stop_other_threads (stop_other_threads), + m_process (thread.GetProcess()), + m_thread (thread), + m_takedown_done (false), + m_function_sp(NULL) +{ + SetOkayToDiscard (discard_on_error); + + Process& process = thread.GetProcess(); + Target& target = process.GetTarget(); + const ABI *abi = process.GetABI().get(); + + if (!abi) + return; + + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + + SetBreakpoints(); + + m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); + + ModuleSP executableModuleSP (target.GetExecutableModule()); + + if (!executableModuleSP) + { + log->Printf ("Can't execute code without an executable module."); + return; + } + else + { + ObjectFile *objectFile = executableModuleSP->GetObjectFile(); + if (!objectFile) + { + log->Printf ("Could not find object file for module \"%s\".", + executableModuleSP->GetFileSpec().GetFilename().AsCString()); + return; + } + m_start_addr = objectFile->GetEntryPointAddress(); + if (!m_start_addr.IsValid()) + { + log->Printf ("Could not find entry point address for executable module \"%s\".", + executableModuleSP->GetFileSpec().GetFilename().AsCString()); + return; + } + } + + addr_t start_load_addr = m_start_addr.GetLoadAddress(&target); + + // 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(); + + m_function_addr = function; + addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target); + + if (!abi->PrepareTrivialCall (thread, + m_function_sp, + FunctionLoadAddr, + start_load_addr, + arg1_ptr, + arg2_ptr, + arg3_ptr, + arg4_ptr, + arg5_ptr, + arg6_ptr)) + { return; } @@ -205,18 +296,15 @@ ThreadPlanCallFunction::WillPop () } void -ThreadPlanCallFunction::GetDescription (Stream *s, lldb::DescriptionLevel level) +ThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level) { - if (level == lldb::eDescriptionLevelBrief) + if (level == eDescriptionLevelBrief) { s->Printf("Function call thread plan"); } else { - if (m_args) - s->Printf("Thread plan to call 0x%llx with parsed arguments", m_function_addr.GetLoadAddress(&m_process.GetTarget()), m_arg_addr); - else - s->Printf("Thread plan to call 0x%llx void * argument at: 0x%llx", m_function_addr.GetLoadAddress(&m_process.GetTarget()), m_arg_addr); + s->Printf("Thread plan to call 0x%llx", m_function_addr.GetLoadAddress(&m_process.GetTarget())); } } @@ -248,12 +336,12 @@ ThreadPlanCallFunction::PlanExplainsStop () // Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on. // If it is not an internal breakpoint, consult OkayToDiscard. - lldb::StopInfoSP stop_info_sp = GetPrivateStopReason(); + StopInfoSP stop_info_sp = GetPrivateStopReason(); if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint) { uint64_t break_site_id = stop_info_sp->GetValue(); - lldb::BreakpointSiteSP bp_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID(break_site_id); + BreakpointSiteSP bp_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID(break_site_id); if (bp_site_sp) { uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); @@ -386,7 +474,7 @@ ThreadPlanCallFunction::ClearBreakpoints () bool ThreadPlanCallFunction::BreakpointsExplainStop() { - lldb::StopInfoSP stop_info_sp = GetPrivateStopReason(); + StopInfoSP stop_info_sp = GetPrivateStopReason(); if (m_cxx_language_runtime && m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) |