Added the ability to get the return value from a ThreadPlanCallFunction
thread plan. In order to get the return value, you can call:

        void
        ThreadPlanCallFunction::RequestReturnValue (lldb::ValueSP &return_value_sp);
        
This registers a shared pointer to a return value that will get filled in if
everything goes well. After the thread plan is run the return value will be
extracted for you.

Added an ifdef to be able to switch between the LLVM MCJIT and the standand JIT.
We currently have the standard JIT selected because we have some work to do to
get the MCJIT fuctioning properly.

Added the ability to call functions with 6 argument in the x86_64 ABI.

Added the ability for GDBRemoteCommunicationClient to detect if the allocate
and deallocate memory packets are supported and to not call allocate memory 
("_M") or deallocate ("_m") if we find they aren't supported.

Modified the ProcessGDBRemote::DoAllocateMemory(...) and ProcessGDBRemote::DoDeallocateMemory(...) 
to be able to deal with the allocate and deallocate memory packets not being 
supported. If they are not supported, ProcessGDBRemote will switch to calling
"mmap" and "munmap" to allocate and deallocate memory instead using our 
trivial function call support.

Modified the "void ProcessGDBRemote::DidLaunchOrAttach()" to correctly ignore 
the qHostInfo triple information if any was specified in the target. Currently 
if the target only specifies an architecture when creating the target:

(lldb) target create --arch i386 a.out

Then the vendor, os and environemnt will be adopted by the target.

If the target was created with any triple that specifies more than the arch:

(lldb) target create --arch i386-unknown-unknown a.out

Then the target will maintain its triple and not adopt any new values. This
can be used to help force bare board debugging where the dynamic loader for
static files will get used and users can then use "target modules load ..."
to set addressses for any files that are desired.

Added back some convenience functions to the lldb_private::RegisterContext class
for writing registers with unsigned values. Also made all RegisterContext
constructors explicit to make sure we know when an integer is being converted
to a RegisterValue. 



git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@131370 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 5e685e0..fdd3fe2 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -45,8 +45,7 @@
     m_supports_vCont_s (eLazyBoolCalculate),
     m_supports_vCont_S (eLazyBoolCalculate),
     m_qHostInfo_is_valid (eLazyBoolCalculate),
-    m_supports__m (eLazyBoolCalculate),
-    m_supports__M (eLazyBoolCalculate),
+    m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
     m_supports_qProcessInfoPID (true),
     m_supports_qfProcessInfo (true),
     m_supports_qUserName (true),
@@ -132,8 +131,7 @@
     m_supports_vCont_s = eLazyBoolCalculate;
     m_supports_vCont_S = eLazyBoolCalculate;
     m_qHostInfo_is_valid = eLazyBoolCalculate;
-    m_supports__m = eLazyBoolCalculate;
-    m_supports__M = eLazyBoolCalculate;
+    m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
 
     m_supports_qProcessInfoPID = true;
     m_supports_qfProcessInfo = true;
@@ -1021,9 +1019,9 @@
 addr_t
 GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
 {
-    if (m_supports__M != eLazyBoolNo)
+    if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
     {
-        m_supports__M = eLazyBoolYes;
+        m_supports_alloc_dealloc_memory = eLazyBoolYes;
         char packet[64];
         const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
                                            permissions & lldb::ePermissionsReadable ? "r" : "",
@@ -1034,7 +1032,7 @@
         if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
         {
             if (response.IsUnsupportedResponse())
-                m_supports__M = eLazyBoolNo;
+                m_supports_alloc_dealloc_memory = eLazyBoolNo;
             else if (!response.IsErrorResponse())
                 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
         }
@@ -1045,9 +1043,9 @@
 bool
 GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
 {
-    if (m_supports__m != eLazyBoolNo)
+    if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
     {
-        m_supports__m = eLazyBoolYes;
+        m_supports_alloc_dealloc_memory = eLazyBoolYes;
         char packet[64];
         const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
         assert (packet_len < sizeof(packet));
@@ -1057,7 +1055,7 @@
             if (response.IsOKResponse())
                 return true;
             else if (response.IsUnsupportedResponse())
-                m_supports__m = eLazyBoolNo;
+                m_supports_alloc_dealloc_memory = eLazyBoolNo;
         }
     }
     return false;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index e1d17be..727bc4e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -306,15 +306,9 @@
     SetCurrentThreadForRun (int tid);
 
     lldb_private::LazyBool
-    SupportsAllocateMemory () const
+    SupportsAllocDeallocMemory () const
     {
-        return m_supports__M;
-    }
-
-    lldb_private::LazyBool
-    SupportsDeallocateMemory () const
-    {
-        return m_supports__m;
+        return m_supports_alloc_dealloc_memory;
     }
 
 protected:
@@ -331,8 +325,7 @@
     lldb_private::LazyBool m_supports_vCont_s;
     lldb_private::LazyBool m_supports_vCont_S;
     lldb_private::LazyBool m_qHostInfo_is_valid;
-    lldb_private::LazyBool m_supports__m;
-    lldb_private::LazyBool m_supports__M;
+    lldb_private::LazyBool m_supports_alloc_dealloc_memory;
 
     bool
         m_supports_qProcessInfoPID:1,
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 14f3100..172a1cf 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -34,6 +34,7 @@
 #include "lldb/Core/State.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Timer.h"
+#include "lldb/Core/Value.h"
 #include "lldb/Host/TimeValue.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/DynamicLoader.h"
@@ -654,14 +655,18 @@
                     // Fill in what is missing in the triple
                     const llvm::Triple &remote_triple = gdb_remote_arch.GetTriple();
                     llvm::Triple &target_triple = target_arch.GetTriple();
-                    if (target_triple.getVendor() == llvm::Triple::UnknownVendor)
+                    if (target_triple.getVendorName().size() == 0)
+                    {
                         target_triple.setVendor (remote_triple.getVendor());
 
-                    if (target_triple.getOS() == llvm::Triple::UnknownOS)
-                        target_triple.setOS (remote_triple.getOS());
+                        if (target_triple.getOSName().size() == 0)
+                        {
+                            target_triple.setOS (remote_triple.getOS());
 
-                    if (target_triple.getEnvironment() == llvm::Triple::UnknownEnvironment)
-                        target_triple.setEnvironment (remote_triple.getEnvironment());
+                            if (target_triple.getEnvironmentName().size() == 0)
+                                target_triple.setEnvironment (remote_triple.getEnvironment());
+                        }
+                    }
                 }
             }
             else
@@ -1545,7 +1550,7 @@
 {
     addr_t allocated_addr = LLDB_INVALID_ADDRESS;
     
-    LazyBool supported = m_gdb_comm.SupportsAllocateMemory();
+    LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();
     switch (supported)
     {
         case eLazyBoolCalculate:
@@ -1596,31 +1601,44 @@
                         AddressRange mmap_range;
                         if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
                         {
-                            lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
-                                                                                         mmap_range.GetBaseAddress(),
-                                                                                         stop_other_threads,
-                                                                                         discard_on_error,
-                                                                                         &arg1_addr,
-                                                                                         &arg2_len,
-                                                                                         &arg3_prot,
-                                                                                         &arg4_flags,
-                                                                                         &arg5_fd,
-                                                                                         &arg6_offset));
+                            ThreadPlanCallFunction *call_function_thread_plan = new ThreadPlanCallFunction (*thread,
+                                                                                                            mmap_range.GetBaseAddress(),
+                                                                                                            stop_other_threads,
+                                                                                                            discard_on_error,
+                                                                                                            &arg1_addr,
+                                                                                                            &arg2_len,
+                                                                                                            &arg3_prot,
+                                                                                                            &arg4_flags,
+                                                                                                            &arg5_fd,
+                                                                                                            &arg6_offset);
+                            lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
                             if (call_plan_sp)
                             {
+                                ValueSP return_value_sp (new Value);
+                                ClangASTContext *clang_ast_context = m_target.GetScratchClangASTContext();
+                                lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+                                return_value_sp->SetValueType (Value::eValueTypeScalar);
+                                return_value_sp->SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+                                call_function_thread_plan->RequestReturnValue (return_value_sp);
+    
                                 StreamFile error_strm;
                                 StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
                                 if (frame)
                                 {
                                     ExecutionContext exe_ctx;
                                     frame->CalculateExecutionContext (exe_ctx);
-                                    ExecutionResults results = RunThreadPlan (exe_ctx,
-                                                                              call_plan_sp,        
-                                                                              stop_other_threads,
-                                                                              try_all_threads,
-                                                                              discard_on_error,
-                                                                              single_thread_timeout_usec,
-                                                                              error_strm);
+                                    ExecutionResults result = RunThreadPlan (exe_ctx,
+                                                                             call_plan_sp,        
+                                                                             stop_other_threads,
+                                                                             try_all_threads,
+                                                                             discard_on_error,
+                                                                             single_thread_timeout_usec,
+                                                                             error_strm);
+                                    if (result == eExecutionCompleted)
+                                    {
+                                        allocated_addr = return_value_sp->GetScalar().ULongLong();
+                                        m_addr_to_mmap_size[allocated_addr] = size;
+                                    }
                                 }
                             }
                         }
@@ -1641,8 +1659,91 @@
 ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr)
 {
     Error error; 
-    if (!m_gdb_comm.DeallocateMemory (addr))
-        error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
+    LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();
+
+    switch (supported)
+    {
+        case eLazyBoolCalculate:
+            // We should never be deallocating memory without allocating memory 
+            // first so we should never get eLazyBoolCalculate
+            error.SetErrorString ("tried to deallocate memory without ever allocating memory");
+            break;
+
+        case eLazyBoolYes:
+            if (!m_gdb_comm.DeallocateMemory (addr))
+                error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
+            break;
+            
+        case eLazyBoolNo:
+            // Call munmap() to create executable memory in the inferior..
+            {
+                MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
+                if (pos != m_addr_to_mmap_size.end())
+                {
+                    Thread *thread = GetThreadList().GetSelectedThread().get();
+                    if (thread == NULL)
+                        thread = GetThreadList().GetThreadAtIndex(0).get();
+                    
+                    const bool append = true;
+                    const bool include_symbols = true;
+                    SymbolContextList sc_list;
+                    const uint32_t count = m_target.GetImages().FindFunctions (ConstString ("munmap"), 
+                                                                               eFunctionNameTypeFull,
+                                                                               include_symbols, 
+                                                                               append, 
+                                                                               sc_list);
+                    if (count > 0)
+                    {
+                        SymbolContext sc;
+                        if (sc_list.GetContextAtIndex(0, sc))
+                        {
+                            const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
+                            const bool use_inline_block_range = false;
+                            const bool stop_other_threads = true;
+                            const bool discard_on_error = true;
+                            const bool try_all_threads = true;
+                            const uint32_t single_thread_timeout_usec = 500000;
+                            addr_t arg1_addr = addr;
+                            addr_t arg2_len = pos->second;
+                            
+                            AddressRange munmap_range;
+                            if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
+                            {
+                                lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
+                                                                                             munmap_range.GetBaseAddress(),
+                                                                                             stop_other_threads,
+                                                                                             discard_on_error,
+                                                                                             &arg1_addr,
+                                                                                             &arg2_len));
+                                if (call_plan_sp)
+                                {
+                                    StreamFile error_strm;
+                                    StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
+                                    if (frame)
+                                    {
+                                        ExecutionContext exe_ctx;
+                                        frame->CalculateExecutionContext (exe_ctx);
+                                        ExecutionResults result = RunThreadPlan (exe_ctx,
+                                                                                 call_plan_sp,        
+                                                                                 stop_other_threads,
+                                                                                 try_all_threads,
+                                                                                 discard_on_error,
+                                                                                 single_thread_timeout_usec,
+                                                                                 error_strm);
+                                        if (result == eExecutionCompleted)
+                                        {
+                                            m_addr_to_mmap_size.erase (pos);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+    }
+
     return error;
 }
 
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index cf03604..21646cb 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -303,6 +303,7 @@
     lldb::thread_t m_async_thread;
     typedef std::vector<lldb::tid_t> tid_collection;
     typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
+    typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
     tid_collection m_continue_c_tids;                  // 'c' for continue
     tid_sig_collection m_continue_C_tids; // 'C' for continue with signal
     tid_collection m_continue_s_tids;                  // 's' for step
@@ -312,7 +313,7 @@
     bool m_waiting_for_attach;
     bool m_local_debugserver;  // Is the debugserver process we are talking to local or on another machine.
     std::vector<lldb::user_id_t>  m_thread_observation_bps;
-
+    MMapMap m_addr_to_mmap_size;
     bool
     StartAsyncThread ();
 
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 3e9cef3..8ed7eda 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -43,7 +43,6 @@
     m_dispatch_queue_name (),
     m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
 {
-//    ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD | GDBR_LOG_VERBOSE, "ThreadGDBRemote::ThreadGDBRemote ( pid = %i, tid = 0x%4.4x, )", m_process.GetID(), GetID());
     ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
 }