diff options
| author | Ed Maste <emaste@FreeBSD.org> | 2013-08-23 17:46:38 +0000 |
|---|---|---|
| committer | Ed Maste <emaste@FreeBSD.org> | 2013-08-23 17:46:38 +0000 |
| commit | f034231a6a1fd5d6395206c1651de8cd9402cca3 (patch) | |
| tree | f561dabc721ad515599172c16da3a4400b7f4aec /source/Plugins/Process/Utility/InferiorCallPOSIX.cpp | |
Notes
Diffstat (limited to 'source/Plugins/Process/Utility/InferiorCallPOSIX.cpp')
| -rw-r--r-- | source/Plugins/Process/Utility/InferiorCallPOSIX.cpp | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp new file mode 100644 index 000000000000..499d6d766150 --- /dev/null +++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -0,0 +1,274 @@ +//===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "InferiorCallPOSIX.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/ThreadPlanCallFunction.h" + +#include <sys/mman.h> + +using namespace lldb; +using namespace lldb_private; + +bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, + addr_t addr, addr_t length, unsigned prot, + unsigned flags, addr_t fd, addr_t offset) { + Thread *thread = process->GetThreadList().GetSelectedThread().get(); + if (thread == NULL) + return false; + + const bool append = true; + const bool include_symbols = true; + const bool include_inlines = false; + SymbolContextList sc_list; + const uint32_t count + = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"), + eFunctionNameTypeFull, + include_symbols, + include_inlines, + 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 unwind_on_error = true; + const bool ignore_breakpoints = true; + const bool try_all_threads = true; + const uint32_t timeout_usec = 500000; + + addr_t prot_arg, flags_arg = 0; + if (prot == eMmapProtNone) + prot_arg = PROT_NONE; + else { + prot_arg = 0; + if (prot & eMmapProtExec) + prot_arg |= PROT_EXEC; + if (prot & eMmapProtRead) + prot_arg |= PROT_READ; + if (prot & eMmapProtWrite) + prot_arg |= PROT_WRITE; + } + + if (flags & eMmapFlagsPrivate) + flags_arg |= MAP_PRIVATE; + if (flags & eMmapFlagsAnon) + flags_arg |= MAP_ANON; + + AddressRange mmap_range; + if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range)) + { + ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); + ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); + ThreadPlanCallFunction *call_function_thread_plan + = new ThreadPlanCallFunction (*thread, + mmap_range.GetBaseAddress(), + clang_void_ptr_type, + stop_other_threads, + unwind_on_error, + ignore_breakpoints, + &addr, + &length, + &prot_arg, + &flags_arg, + &fd, + &offset); + lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan); + if (call_plan_sp) + { + StreamFile error_strm; + // This plan is a utility plan, so set it to discard itself when done. + call_plan_sp->SetIsMasterPlan (true); + call_plan_sp->SetOkayToDiscard(true); + + StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); + if (frame) + { + ExecutionContext exe_ctx; + frame->CalculateExecutionContext (exe_ctx); + ExecutionResults result = process->RunThreadPlan (exe_ctx, + call_plan_sp, + stop_other_threads, + try_all_threads, + unwind_on_error, + ignore_breakpoints, + timeout_usec, + error_strm); + if (result == eExecutionCompleted) + { + + allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); + if (process->GetAddressByteSize() == 4) + { + if (allocated_addr == UINT32_MAX) + return false; + } + else if (process->GetAddressByteSize() == 8) + { + if (allocated_addr == UINT64_MAX) + return false; + } + return true; + } + } + } + } + } + } + + return false; +} + +bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, + addr_t length) { + Thread *thread = process->GetThreadList().GetSelectedThread().get(); + if (thread == NULL) + return false; + + const bool append = true; + const bool include_symbols = true; + const bool include_inlines = false; + SymbolContextList sc_list; + const uint32_t count + = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"), + eFunctionNameTypeFull, + include_symbols, + include_inlines, + 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 unwind_on_error = true; + const bool ignore_breakpoints = true; + const bool try_all_threads = true; + const uint32_t timeout_usec = 500000; + + 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(), + ClangASTType(), + stop_other_threads, + unwind_on_error, + ignore_breakpoints, + &addr, + &length)); + if (call_plan_sp) + { + StreamFile error_strm; + // This plan is a utility plan, so set it to discard itself when done. + call_plan_sp->SetIsMasterPlan (true); + call_plan_sp->SetOkayToDiscard(true); + + StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); + if (frame) + { + ExecutionContext exe_ctx; + frame->CalculateExecutionContext (exe_ctx); + ExecutionResults result = process->RunThreadPlan (exe_ctx, + call_plan_sp, + stop_other_threads, + try_all_threads, + unwind_on_error, + ignore_breakpoints, + timeout_usec, + error_strm); + if (result == eExecutionCompleted) + { + return true; + } + } + } + } + } + } + + return false; +} + +bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t &returned_func) { + Thread *thread = process->GetThreadList().GetSelectedThread().get(); + if (thread == NULL || address == NULL) + return false; + + const bool stop_other_threads = true; + const bool unwind_on_error = true; + const bool ignore_breakpoints = true; + const bool try_all_threads = true; + const uint32_t timeout_usec = 500000; + + ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); + ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); + ThreadPlanCallFunction *call_function_thread_plan + = new ThreadPlanCallFunction (*thread, + *address, + clang_void_ptr_type, + stop_other_threads, + unwind_on_error, + ignore_breakpoints); + lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan); + if (call_plan_sp) + { + StreamFile error_strm; + // This plan is a utility plan, so set it to discard itself when done. + call_plan_sp->SetIsMasterPlan (true); + call_plan_sp->SetOkayToDiscard(true); + + StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); + if (frame) + { + ExecutionContext exe_ctx; + frame->CalculateExecutionContext (exe_ctx); + ExecutionResults result = process->RunThreadPlan (exe_ctx, + call_plan_sp, + stop_other_threads, + try_all_threads, + unwind_on_error, + ignore_breakpoints, + timeout_usec, + error_strm); + if (result == eExecutionCompleted) + { + returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); + + if (process->GetAddressByteSize() == 4) + { + if (returned_func == UINT32_MAX) + return false; + } + else if (process->GetAddressByteSize() == 8) + { + if (returned_func == UINT64_MAX) + return false; + } + return true; + } + } + } + + return false; +} |
