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/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;
 }