InferiorCallPOSIX.cpp revision 309124
1254721Semaste//===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "InferiorCallPOSIX.h" 11254721Semaste#include "lldb/Core/Address.h" 12254721Semaste#include "lldb/Core/StreamFile.h" 13254721Semaste#include "lldb/Core/ValueObject.h" 14309124Sdim#include "lldb/Expression/DiagnosticManager.h" 15309124Sdim#include "lldb/Host/Config.h" 16254721Semaste#include "lldb/Symbol/ClangASTContext.h" 17254721Semaste#include "lldb/Symbol/SymbolContext.h" 18254721Semaste#include "lldb/Target/ExecutionContext.h" 19288943Sdim#include "lldb/Target/Platform.h" 20254721Semaste#include "lldb/Target/Process.h" 21254721Semaste#include "lldb/Target/Target.h" 22254721Semaste#include "lldb/Target/ThreadPlanCallFunction.h" 23254721Semaste 24258054Semaste#ifndef LLDB_DISABLE_POSIX 25254721Semaste#include <sys/mman.h> 26258054Semaste#else 27258054Semaste// define them 28258054Semaste#define PROT_NONE 0 29258054Semaste#define PROT_READ 1 30258054Semaste#define PROT_WRITE 2 31258054Semaste#define PROT_EXEC 4 32258054Semaste#endif 33254721Semaste 34254721Semasteusing namespace lldb; 35254721Semasteusing namespace lldb_private; 36254721Semaste 37262528Semastebool 38262528Semastelldb_private::InferiorCallMmap (Process *process, 39262528Semaste addr_t &allocated_addr, 40262528Semaste addr_t addr, 41262528Semaste addr_t length, 42262528Semaste unsigned prot, 43262528Semaste unsigned flags, 44262528Semaste addr_t fd, 45262528Semaste addr_t offset) 46262528Semaste{ 47309124Sdim Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get(); 48254721Semaste if (thread == NULL) 49254721Semaste return false; 50254721Semaste 51254721Semaste const bool append = true; 52254721Semaste const bool include_symbols = true; 53254721Semaste const bool include_inlines = false; 54254721Semaste SymbolContextList sc_list; 55254721Semaste const uint32_t count 56254721Semaste = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"), 57254721Semaste eFunctionNameTypeFull, 58254721Semaste include_symbols, 59254721Semaste include_inlines, 60254721Semaste append, 61254721Semaste sc_list); 62254721Semaste if (count > 0) 63254721Semaste { 64254721Semaste SymbolContext sc; 65254721Semaste if (sc_list.GetContextAtIndex(0, sc)) 66254721Semaste { 67254721Semaste const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; 68254721Semaste const bool use_inline_block_range = false; 69258884Semaste EvaluateExpressionOptions options; 70258884Semaste options.SetStopOthers(true); 71258884Semaste options.SetUnwindOnError(true); 72258884Semaste options.SetIgnoreBreakpoints(true); 73258884Semaste options.SetTryAllThreads(true); 74258884Semaste options.SetDebug (false); 75258884Semaste options.SetTimeoutUsec(500000); 76296417Sdim options.SetTrapExceptions(false); 77254721Semaste 78254721Semaste addr_t prot_arg, flags_arg = 0; 79254721Semaste if (prot == eMmapProtNone) 80254721Semaste prot_arg = PROT_NONE; 81254721Semaste else { 82254721Semaste prot_arg = 0; 83254721Semaste if (prot & eMmapProtExec) 84254721Semaste prot_arg |= PROT_EXEC; 85254721Semaste if (prot & eMmapProtRead) 86254721Semaste prot_arg |= PROT_READ; 87254721Semaste if (prot & eMmapProtWrite) 88254721Semaste prot_arg |= PROT_WRITE; 89254721Semaste } 90254721Semaste 91288943Sdim const ArchSpec arch = process->GetTarget().GetArchitecture(); 92288943Sdim flags_arg = process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,flags); 93254721Semaste 94254721Semaste AddressRange mmap_range; 95254721Semaste if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range)) 96254721Semaste { 97254721Semaste ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); 98296417Sdim CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 99258884Semaste lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset }; 100309124Sdim lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(), 101309124Sdim clang_void_ptr_type, args, options)); 102254721Semaste if (call_plan_sp) 103254721Semaste { 104309124Sdim DiagnosticManager diagnostics; 105309124Sdim 106309124Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 107254721Semaste if (frame) 108254721Semaste { 109254721Semaste ExecutionContext exe_ctx; 110254721Semaste frame->CalculateExecutionContext (exe_ctx); 111309124Sdim ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics); 112276479Sdim if (result == eExpressionCompleted) 113254721Semaste { 114309124Sdim 115254721Semaste allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 116254721Semaste if (process->GetAddressByteSize() == 4) 117254721Semaste { 118254721Semaste if (allocated_addr == UINT32_MAX) 119254721Semaste return false; 120254721Semaste } 121254721Semaste else if (process->GetAddressByteSize() == 8) 122254721Semaste { 123254721Semaste if (allocated_addr == UINT64_MAX) 124254721Semaste return false; 125254721Semaste } 126254721Semaste return true; 127254721Semaste } 128254721Semaste } 129254721Semaste } 130254721Semaste } 131254721Semaste } 132254721Semaste } 133254721Semaste 134254721Semaste return false; 135254721Semaste} 136254721Semaste 137262528Semastebool 138262528Semastelldb_private::InferiorCallMunmap (Process *process, 139262528Semaste addr_t addr, 140262528Semaste addr_t length) 141262528Semaste{ 142309124Sdim Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get(); 143254721Semaste if (thread == NULL) 144254721Semaste return false; 145254721Semaste 146254721Semaste const bool append = true; 147254721Semaste const bool include_symbols = true; 148254721Semaste const bool include_inlines = false; 149254721Semaste SymbolContextList sc_list; 150254721Semaste const uint32_t count 151254721Semaste = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"), 152254721Semaste eFunctionNameTypeFull, 153254721Semaste include_symbols, 154254721Semaste include_inlines, 155254721Semaste append, 156254721Semaste sc_list); 157254721Semaste if (count > 0) 158254721Semaste { 159254721Semaste SymbolContext sc; 160254721Semaste if (sc_list.GetContextAtIndex(0, sc)) 161254721Semaste { 162258884Semaste const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; 163258884Semaste const bool use_inline_block_range = false; 164258884Semaste EvaluateExpressionOptions options; 165258884Semaste options.SetStopOthers(true); 166258884Semaste options.SetUnwindOnError(true); 167258884Semaste options.SetIgnoreBreakpoints(true); 168258884Semaste options.SetTryAllThreads(true); 169258884Semaste options.SetDebug (false); 170258884Semaste options.SetTimeoutUsec(500000); 171296417Sdim options.SetTrapExceptions(false); 172254721Semaste 173258884Semaste AddressRange munmap_range; 174258884Semaste if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range)) 175258884Semaste { 176258884Semaste lldb::addr_t args[] = { addr, length }; 177309124Sdim lldb::ThreadPlanSP call_plan_sp( 178309124Sdim new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), CompilerType(), args, options)); 179258884Semaste if (call_plan_sp) 180258884Semaste { 181309124Sdim DiagnosticManager diagnostics; 182309124Sdim 183309124Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 184258884Semaste if (frame) 185258884Semaste { 186258884Semaste ExecutionContext exe_ctx; 187258884Semaste frame->CalculateExecutionContext (exe_ctx); 188309124Sdim ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics); 189276479Sdim if (result == eExpressionCompleted) 190258884Semaste { 191258884Semaste return true; 192258884Semaste } 193258884Semaste } 194258884Semaste } 195258884Semaste } 196258884Semaste } 197258884Semaste } 198254721Semaste 199258884Semaste return false; 200254721Semaste} 201254721Semaste 202262528Semaste// FIXME: This has nothing to do with Posix, it is just a convenience function that calls a 203262528Semaste// function of the form "void * (*)(void)". We should find a better place to put this. 204262528Semaste 205262528Semastebool 206262528Semastelldb_private::InferiorCall (Process *process, 207262528Semaste const Address *address, 208296417Sdim addr_t &returned_func, 209296417Sdim bool trap_exceptions) 210262528Semaste{ 211309124Sdim Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get(); 212254721Semaste if (thread == NULL || address == NULL) 213254721Semaste return false; 214254721Semaste 215258884Semaste EvaluateExpressionOptions options; 216258884Semaste options.SetStopOthers(true); 217258884Semaste options.SetUnwindOnError(true); 218258884Semaste options.SetIgnoreBreakpoints(true); 219258884Semaste options.SetTryAllThreads(true); 220258884Semaste options.SetDebug (false); 221258884Semaste options.SetTimeoutUsec(500000); 222296417Sdim options.SetTrapExceptions(trap_exceptions); 223254721Semaste 224254721Semaste ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); 225296417Sdim CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 226309124Sdim lldb::ThreadPlanSP call_plan_sp( 227309124Sdim new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type, llvm::ArrayRef<addr_t>(), options)); 228254721Semaste if (call_plan_sp) 229254721Semaste { 230309124Sdim DiagnosticManager diagnostics; 231254721Semaste 232309124Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 233254721Semaste if (frame) 234254721Semaste { 235254721Semaste ExecutionContext exe_ctx; 236254721Semaste frame->CalculateExecutionContext (exe_ctx); 237309124Sdim ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics); 238276479Sdim if (result == eExpressionCompleted) 239254721Semaste { 240254721Semaste returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 241254721Semaste 242254721Semaste if (process->GetAddressByteSize() == 4) 243254721Semaste { 244254721Semaste if (returned_func == UINT32_MAX) 245254721Semaste return false; 246254721Semaste } 247254721Semaste else if (process->GetAddressByteSize() == 8) 248254721Semaste { 249254721Semaste if (returned_func == UINT64_MAX) 250254721Semaste return false; 251254721Semaste } 252254721Semaste return true; 253254721Semaste } 254254721Semaste } 255254721Semaste } 256254721Semaste 257254721Semaste return false; 258254721Semaste} 259