Allow operating system plug-ins to specify the address for registers so we don't have to create data up front.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@166701 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/examples/python/operating_system.py b/examples/python/operating_system.py
index b8bff1b..568b974 100644
--- a/examples/python/operating_system.py
+++ b/examples/python/operating_system.py
@@ -40,7 +40,7 @@
             self.threads = [
                     { 'tid' : 0x111111111, 'name' : 'one'  , 'queue' : 'queue1', 'state' : 'stopped', 'stop_reason' : 'breakpoint'},
                     { 'tid' : 0x222222222, 'name' : 'two'  , 'queue' : 'queue2', 'state' : 'stopped', 'stop_reason' : 'none'      },
-                    { 'tid' : 0x333333333, 'name' : 'three', 'queue' : 'queue3', 'state' : 'stopped', 'stop_reason' : 'trace'     }
+                    { 'tid' : 0x333333333, 'name' : 'three', 'queue' : 'queue3', 'state' : 'stopped', 'stop_reason' : 'trace'     , 'register_data_addr' : 0x100000000 }
                 ]
         return self.threads
     
diff --git a/include/lldb/Target/OperatingSystem.h b/include/lldb/Target/OperatingSystem.h
index 7c5f060..600e36b 100644
--- a/include/lldb/Target/OperatingSystem.h
+++ b/include/lldb/Target/OperatingSystem.h
@@ -71,7 +71,7 @@
     ThreadWasSelected (Thread *thread) = 0;
     
     virtual lldb::RegisterContextSP
-    CreateRegisterContextForThread (Thread *thread) = 0;
+    CreateRegisterContextForThread (Thread *thread, lldb::addr_t reg_data_addr) = 0;
 
     virtual lldb::StopInfoSP
     CreateThreadStopReason (Thread *thread) = 0;
diff --git a/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp b/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp
index e650ad6..8743e2e 100644
--- a/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp
+++ b/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp
@@ -268,7 +268,7 @@
 }
 
 RegisterContextSP
-OperatingSystemDarwinKernel::CreateRegisterContextForThread (Thread *thread)
+OperatingSystemDarwinKernel::CreateRegisterContextForThread (Thread *thread, lldb::addr_t reg_data_addr)
 {
     ThreadMemory *generic_thread = (ThreadMemory *)thread;
     RegisterContextSP reg_ctx_sp;
diff --git a/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.h b/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.h
index 4b9d2ed..8427f56 100644
--- a/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.h
+++ b/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.h
@@ -69,7 +69,8 @@
     ThreadWasSelected (lldb_private::Thread *thread);
 
     virtual lldb::RegisterContextSP
-    CreateRegisterContextForThread (lldb_private::Thread *thread);
+    CreateRegisterContextForThread (lldb_private::Thread *thread,
+                                    lldb::addr_t reg_data_addr);
 
     virtual lldb::StopInfoSP
     CreateThreadStopReason (lldb_private::Thread *thread);
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index 6ff4156..b7a0bb9 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -202,6 +202,7 @@
         PythonDataString queue_pystr("queue");
         PythonDataString state_pystr("state");
         PythonDataString stop_reason_pystr("stop_reason");
+        PythonDataString reg_data_addr_pystr ("register_data_addr");
         
         const uint32_t num_threads = threads_array.GetSize();
         for (uint32_t i=0; i<num_threads; ++i)
@@ -209,7 +210,8 @@
             PythonDataDictionary thread_dict(threads_array.GetItemAtIndex(i).GetDictionaryObject());
             if (thread_dict)
             {
-                const tid_t tid = thread_dict.GetItemForKeyAsInteger(tid_pystr, LLDB_INVALID_THREAD_ID);
+                const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID);
+                const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS);
                 const char *name = thread_dict.GetItemForKeyAsString (name_pystr);
                 const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr);
                 //const char *state = thread_dict.GetItemForKeyAsString (state_pystr);
@@ -220,7 +222,8 @@
                     thread_sp.reset (new ThreadMemory (*m_process,
                                                        tid,
                                                        name,
-                                                       queue));
+                                                       queue,
+                                                       reg_data_addr));
                 new_thread_list.AddThread(thread_sp);
 
             }
@@ -239,7 +242,7 @@
 }
 
 RegisterContextSP
-OperatingSystemPython::CreateRegisterContextForThread (Thread *thread)
+OperatingSystemPython::CreateRegisterContextForThread (Thread *thread, lldb::addr_t reg_data_addr)
 {
     RegisterContextSP reg_ctx_sp;
     if (!m_interpreter || !m_python_object || !thread)
@@ -247,27 +250,40 @@
     
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
 
-    if (log)
-        log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%llx) fetching register data from python", thread->GetID());
-
-    auto object_sp = m_interpreter->OSPlugin_QueryForRegisterContextData (m_interpreter->MakeScriptObject(m_python_object),
-                                                                          thread->GetID());
-    
-    if (!object_sp)
-        return RegisterContextSP();
-    
-    PythonDataString reg_context_data((PyObject*)object_sp->GetObject());
-    if (reg_context_data)
+    if (reg_data_addr != LLDB_INVALID_ADDRESS)
     {
-        DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(),
-                                                  reg_context_data.GetSize()));
-        if (data_sp->GetByteSize())
+        // The registers data is in contiguous memory, just create the register
+        // context using the address provided
+        if (log)
+            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%llx, reg_data_addr = 0x%llx) creating memory register context", thread->GetID(), reg_data_addr);
+        reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), reg_data_addr));
+    }
+    else
+    {
+        // No register data address is provided, query the python plug-in to let
+        // it make up the data as it sees fit
+        if (log)
+            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%llx) fetching register data from python", thread->GetID());
+
+        auto object_sp = m_interpreter->OSPlugin_QueryForRegisterContextData (m_interpreter->MakeScriptObject(m_python_object),
+                                                                              thread->GetID());
+        
+        if (!object_sp)
+            return RegisterContextSP();
+        
+        PythonDataString reg_context_data((PyObject*)object_sp->GetObject());
+        if (reg_context_data)
         {
-            RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS);
-            if (reg_ctx_memory)
+            DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(),
+                                                      reg_context_data.GetSize()));
+            if (data_sp->GetByteSize())
             {
-                reg_ctx_sp.reset(reg_ctx_memory);
-                reg_ctx_memory->SetAllRegisterData (data_sp);
+                RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS);
+                if (reg_ctx_memory)
+                {
+                    reg_ctx_sp.reset(reg_ctx_memory);
+                    reg_ctx_memory->SetAllRegisterData (data_sp);
+                }
             }
         }
     }
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
index 8dccf24..d89a7ab 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
@@ -72,7 +72,8 @@
     ThreadWasSelected (lldb_private::Thread *thread);
 
     virtual lldb::RegisterContextSP
-    CreateRegisterContextForThread (lldb_private::Thread *thread);
+    CreateRegisterContextForThread (lldb_private::Thread *thread,
+                                    lldb::addr_t reg_data_addr);
 
     virtual lldb::StopInfoSP
     CreateThreadStopReason (lldb_private::Thread *thread);
diff --git a/source/Plugins/Process/Utility/ThreadMemory.cpp b/source/Plugins/Process/Utility/ThreadMemory.cpp
index cd3bd8c..6afa01d 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.cpp
+++ b/source/Plugins/Process/Utility/ThreadMemory.cpp
@@ -18,8 +18,8 @@
 using namespace lldb_private;
 
 ThreadMemory::ThreadMemory (Process &process,
-                              tid_t tid, 
-                              const ValueObjectSP &thread_info_valobj_sp) :
+                            tid_t tid,
+                            const ValueObjectSP &thread_info_valobj_sp) :
     Thread (process, tid),
     m_thread_info_valobj_sp (thread_info_valobj_sp),
     m_name(),
@@ -31,11 +31,13 @@
 ThreadMemory::ThreadMemory (Process &process,
                             lldb::tid_t tid,
                             const char *name,
-                            const char *queue) :
+                            const char *queue,
+                            lldb::addr_t register_data_addr) :
     Thread (process, tid),
     m_thread_info_valobj_sp (),
     m_name(),
-    m_queue()
+    m_queue(),
+    m_register_data_addr (register_data_addr)
 {
     if (name)
         m_name = name;
@@ -70,7 +72,7 @@
         {
             OperatingSystem *os = process_sp->GetOperatingSystem ();
             if (os)
-                m_reg_context_sp = os->CreateRegisterContextForThread (this);
+                m_reg_context_sp = os->CreateRegisterContextForThread (this, m_register_data_addr);
         }
     }
     return m_reg_context_sp;
diff --git a/source/Plugins/Process/Utility/ThreadMemory.h b/source/Plugins/Process/Utility/ThreadMemory.h
index 1880c5a..7ee9758 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.h
+++ b/source/Plugins/Process/Utility/ThreadMemory.h
@@ -24,7 +24,8 @@
     ThreadMemory (lldb_private::Process &process,
                   lldb::tid_t tid,
                   const char *name,
-                  const char *queue);
+                  const char *queue,
+                  lldb::addr_t register_data_addr);
 
     virtual
     ~ThreadMemory();
@@ -72,6 +73,7 @@
     lldb::ValueObjectSP m_thread_info_valobj_sp;
     std::string m_name;
     std::string m_queue;
+    lldb::addr_t m_register_data_addr;
 private:
     //------------------------------------------------------------------
     // For ThreadMemory only