InferiorCallPOSIX.cpp revision 314564
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 37314564Sdimbool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, 38314564Sdim addr_t addr, addr_t length, unsigned prot, 39314564Sdim unsigned flags, addr_t fd, addr_t offset) { 40314564Sdim Thread *thread = 41314564Sdim process->GetThreadList().GetExpressionExecutionThread().get(); 42314564Sdim if (thread == NULL) 43314564Sdim return false; 44254721Semaste 45314564Sdim const bool append = true; 46314564Sdim const bool include_symbols = true; 47314564Sdim const bool include_inlines = false; 48314564Sdim SymbolContextList sc_list; 49314564Sdim const uint32_t count = process->GetTarget().GetImages().FindFunctions( 50314564Sdim ConstString("mmap"), eFunctionNameTypeFull, include_symbols, 51314564Sdim include_inlines, append, sc_list); 52314564Sdim if (count > 0) { 53314564Sdim SymbolContext sc; 54314564Sdim if (sc_list.GetContextAtIndex(0, sc)) { 55314564Sdim const uint32_t range_scope = 56314564Sdim eSymbolContextFunction | eSymbolContextSymbol; 57314564Sdim const bool use_inline_block_range = false; 58314564Sdim EvaluateExpressionOptions options; 59314564Sdim options.SetStopOthers(true); 60314564Sdim options.SetUnwindOnError(true); 61314564Sdim options.SetIgnoreBreakpoints(true); 62314564Sdim options.SetTryAllThreads(true); 63314564Sdim options.SetDebug(false); 64314564Sdim options.SetTimeout(std::chrono::milliseconds(500)); 65314564Sdim options.SetTrapExceptions(false); 66254721Semaste 67314564Sdim addr_t prot_arg, flags_arg = 0; 68314564Sdim if (prot == eMmapProtNone) 69314564Sdim prot_arg = PROT_NONE; 70314564Sdim else { 71314564Sdim prot_arg = 0; 72314564Sdim if (prot & eMmapProtExec) 73314564Sdim prot_arg |= PROT_EXEC; 74314564Sdim if (prot & eMmapProtRead) 75314564Sdim prot_arg |= PROT_READ; 76314564Sdim if (prot & eMmapProtWrite) 77314564Sdim prot_arg |= PROT_WRITE; 78314564Sdim } 79254721Semaste 80314564Sdim const ArchSpec arch = process->GetTarget().GetArchitecture(); 81314564Sdim flags_arg = 82314564Sdim process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch, 83314564Sdim flags); 84254721Semaste 85314564Sdim AddressRange mmap_range; 86314564Sdim if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, 87314564Sdim mmap_range)) { 88314564Sdim ClangASTContext *clang_ast_context = 89314564Sdim process->GetTarget().GetScratchClangASTContext(); 90314564Sdim CompilerType clang_void_ptr_type = 91314564Sdim clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 92314564Sdim lldb::addr_t args[] = {addr, length, prot_arg, flags_arg, fd, offset}; 93314564Sdim lldb::ThreadPlanSP call_plan_sp( 94314564Sdim new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(), 95314564Sdim clang_void_ptr_type, args, options)); 96314564Sdim if (call_plan_sp) { 97314564Sdim DiagnosticManager diagnostics; 98309124Sdim 99314564Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 100314564Sdim if (frame) { 101314564Sdim ExecutionContext exe_ctx; 102314564Sdim frame->CalculateExecutionContext(exe_ctx); 103314564Sdim ExpressionResults result = process->RunThreadPlan( 104314564Sdim exe_ctx, call_plan_sp, options, diagnostics); 105314564Sdim if (result == eExpressionCompleted) { 106309124Sdim 107314564Sdim allocated_addr = 108314564Sdim call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned( 109314564Sdim LLDB_INVALID_ADDRESS); 110314564Sdim if (process->GetAddressByteSize() == 4) { 111314564Sdim if (allocated_addr == UINT32_MAX) 112314564Sdim return false; 113314564Sdim } else if (process->GetAddressByteSize() == 8) { 114314564Sdim if (allocated_addr == UINT64_MAX) 115314564Sdim return false; 116314564Sdim } 117314564Sdim return true; 118254721Semaste } 119314564Sdim } 120254721Semaste } 121314564Sdim } 122254721Semaste } 123314564Sdim } 124254721Semaste 125314564Sdim return false; 126254721Semaste} 127254721Semaste 128314564Sdimbool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, 129314564Sdim addr_t length) { 130314564Sdim Thread *thread = 131314564Sdim process->GetThreadList().GetExpressionExecutionThread().get(); 132314564Sdim if (thread == NULL) 133314564Sdim return false; 134309124Sdim 135314564Sdim const bool append = true; 136314564Sdim const bool include_symbols = true; 137314564Sdim const bool include_inlines = false; 138314564Sdim SymbolContextList sc_list; 139314564Sdim const uint32_t count = process->GetTarget().GetImages().FindFunctions( 140314564Sdim ConstString("munmap"), eFunctionNameTypeFull, include_symbols, 141314564Sdim include_inlines, append, sc_list); 142314564Sdim if (count > 0) { 143314564Sdim SymbolContext sc; 144314564Sdim if (sc_list.GetContextAtIndex(0, sc)) { 145314564Sdim const uint32_t range_scope = 146314564Sdim eSymbolContextFunction | eSymbolContextSymbol; 147314564Sdim const bool use_inline_block_range = false; 148314564Sdim EvaluateExpressionOptions options; 149314564Sdim options.SetStopOthers(true); 150314564Sdim options.SetUnwindOnError(true); 151314564Sdim options.SetIgnoreBreakpoints(true); 152314564Sdim options.SetTryAllThreads(true); 153314564Sdim options.SetDebug(false); 154314564Sdim options.SetTimeout(std::chrono::milliseconds(500)); 155314564Sdim options.SetTrapExceptions(false); 156314564Sdim 157314564Sdim AddressRange munmap_range; 158314564Sdim if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, 159314564Sdim munmap_range)) { 160314564Sdim lldb::addr_t args[] = {addr, length}; 161314564Sdim lldb::ThreadPlanSP call_plan_sp( 162314564Sdim new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), 163314564Sdim CompilerType(), args, options)); 164314564Sdim if (call_plan_sp) { 165314564Sdim DiagnosticManager diagnostics; 166314564Sdim 167314564Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 168314564Sdim if (frame) { 169314564Sdim ExecutionContext exe_ctx; 170314564Sdim frame->CalculateExecutionContext(exe_ctx); 171314564Sdim ExpressionResults result = process->RunThreadPlan( 172314564Sdim exe_ctx, call_plan_sp, options, diagnostics); 173314564Sdim if (result == eExpressionCompleted) { 174314564Sdim return true; 175258884Semaste } 176314564Sdim } 177258884Semaste } 178314564Sdim } 179258884Semaste } 180314564Sdim } 181254721Semaste 182314564Sdim return false; 183254721Semaste} 184254721Semaste 185314564Sdim// FIXME: This has nothing to do with Posix, it is just a convenience function 186314564Sdim// that calls a 187314564Sdim// function of the form "void * (*)(void)". We should find a better place to 188314564Sdim// put this. 189262528Semaste 190314564Sdimbool lldb_private::InferiorCall(Process *process, const Address *address, 191314564Sdim addr_t &returned_func, bool trap_exceptions) { 192314564Sdim Thread *thread = 193314564Sdim process->GetThreadList().GetExpressionExecutionThread().get(); 194314564Sdim if (thread == NULL || address == NULL) 195314564Sdim return false; 196254721Semaste 197314564Sdim EvaluateExpressionOptions options; 198314564Sdim options.SetStopOthers(true); 199314564Sdim options.SetUnwindOnError(true); 200314564Sdim options.SetIgnoreBreakpoints(true); 201314564Sdim options.SetTryAllThreads(true); 202314564Sdim options.SetDebug(false); 203314564Sdim options.SetTimeout(std::chrono::milliseconds(500)); 204314564Sdim options.SetTrapExceptions(trap_exceptions); 205254721Semaste 206314564Sdim ClangASTContext *clang_ast_context = 207314564Sdim process->GetTarget().GetScratchClangASTContext(); 208314564Sdim CompilerType clang_void_ptr_type = 209314564Sdim clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 210314564Sdim lldb::ThreadPlanSP call_plan_sp( 211314564Sdim new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type, 212314564Sdim llvm::ArrayRef<addr_t>(), options)); 213314564Sdim if (call_plan_sp) { 214314564Sdim DiagnosticManager diagnostics; 215254721Semaste 216314564Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 217314564Sdim if (frame) { 218314564Sdim ExecutionContext exe_ctx; 219314564Sdim frame->CalculateExecutionContext(exe_ctx); 220314564Sdim ExpressionResults result = 221314564Sdim process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics); 222314564Sdim if (result == eExpressionCompleted) { 223314564Sdim returned_func = 224314564Sdim call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned( 225314564Sdim LLDB_INVALID_ADDRESS); 226254721Semaste 227314564Sdim if (process->GetAddressByteSize() == 4) { 228314564Sdim if (returned_func == UINT32_MAX) 229314564Sdim return false; 230314564Sdim } else if (process->GetAddressByteSize() == 8) { 231314564Sdim if (returned_func == UINT64_MAX) 232314564Sdim return false; 233254721Semaste } 234314564Sdim return true; 235314564Sdim } 236254721Semaste } 237314564Sdim } 238254721Semaste 239314564Sdim return false; 240254721Semaste} 241