Expand the ABI prepare trivial function call to allow 6 simple args.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@131334 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/ThreadPlanCallFunction.cpp b/source/Target/ThreadPlanCallFunction.cpp
index 1da0e7b..fee0cbd 100644
--- a/source/Target/ThreadPlanCallFunction.cpp
+++ b/source/Target/ThreadPlanCallFunction.cpp
@@ -37,20 +37,18 @@
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 @@
}
}
- 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 @@
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 @@
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 @@
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 @@
}
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 @@
// 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 @@
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))