summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-05-15 01:25:55 +0000
committerGreg Clayton <gclayton@apple.com>2011-05-15 01:25:55 +0000
commit70b57657401ee8d63240d4a4affa8b0180416aaf (patch)
tree3b102f794a7e291fe1c283d2630d78f9465478eb /lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
parentba6685c39053b474d523659b3a0e768b090c74ed (diff)
downloadbcm5719-llvm-70b57657401ee8d63240d4a4affa8b0180416aaf.tar.gz
bcm5719-llvm-70b57657401ee8d63240d4a4affa8b0180416aaf.zip
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. llvm-svn: 131370
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp151
1 files changed, 126 insertions, 25 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 14f31004a85..172a1cf0f77 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/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 @@ ProcessGDBRemote::DidLaunchOrAttach ()
// 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 @@ ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &er
{
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 @@ ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &er
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 @@ Error
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;
}
OpenPOWER on IntegriCloud