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))