blob: 376c41bc002c11c8622d5a0a50a777582da643d0 [file] [log] [blame]
//===-- 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/StreamFile.h"
#include "lldb/Core/ValueObject.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 discard_on_error = true;
const bool try_all_threads = true;
const uint32_t single_thread_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();
lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
ThreadPlanCallFunction *call_function_thread_plan
= new ThreadPlanCallFunction (*thread,
mmap_range.GetBaseAddress(),
ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type),
stop_other_threads,
discard_on_error,
&addr,
&length,
&prot_arg,
&flags_arg,
&fd,
&offset);
lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
if (call_plan_sp)
{
StreamFile error_strm;
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,
discard_on_error,
single_thread_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;
}
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 discard_on_error = true;
const bool try_all_threads = true;
const uint32_t single_thread_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,
discard_on_error,
&addr,
&length));
if (call_plan_sp)
{
StreamFile error_strm;
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,
discard_on_error,
single_thread_timeout_usec,
error_strm);
if (result == eExecutionCompleted)
{
return true;
}
}
}
}
}
}
return false;
}