InferiorCallPOSIX.cpp revision 258054
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" 14254721Semaste#include "lldb/Symbol/ClangASTContext.h" 15254721Semaste#include "lldb/Symbol/SymbolContext.h" 16254721Semaste#include "lldb/Target/ExecutionContext.h" 17254721Semaste#include "lldb/Target/Process.h" 18254721Semaste#include "lldb/Target/Target.h" 19254721Semaste#include "lldb/Target/ThreadPlanCallFunction.h" 20258054Semaste#include "lldb/Host/Config.h" 21254721Semaste 22258054Semaste#ifndef LLDB_DISABLE_POSIX 23254721Semaste#include <sys/mman.h> 24258054Semaste#else 25258054Semaste// define them 26258054Semaste#define PROT_NONE 0 27258054Semaste#define PROT_READ 1 28258054Semaste#define PROT_WRITE 2 29258054Semaste#define PROT_EXEC 4 30258054Semaste#define MAP_PRIVATE 2 31258054Semaste#define MAP_ANON 0x1000 32258054Semaste#endif 33254721Semaste 34254721Semasteusing namespace lldb; 35254721Semasteusing namespace lldb_private; 36254721Semaste 37254721Semastebool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, 38254721Semaste addr_t addr, addr_t length, unsigned prot, 39254721Semaste unsigned flags, addr_t fd, addr_t offset) { 40254721Semaste Thread *thread = process->GetThreadList().GetSelectedThread().get(); 41254721Semaste if (thread == NULL) 42254721Semaste return false; 43254721Semaste 44254721Semaste const bool append = true; 45254721Semaste const bool include_symbols = true; 46254721Semaste const bool include_inlines = false; 47254721Semaste SymbolContextList sc_list; 48254721Semaste const uint32_t count 49254721Semaste = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"), 50254721Semaste eFunctionNameTypeFull, 51254721Semaste include_symbols, 52254721Semaste include_inlines, 53254721Semaste append, 54254721Semaste sc_list); 55254721Semaste if (count > 0) 56254721Semaste { 57254721Semaste SymbolContext sc; 58254721Semaste if (sc_list.GetContextAtIndex(0, sc)) 59254721Semaste { 60254721Semaste const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; 61254721Semaste const bool use_inline_block_range = false; 62254721Semaste const bool stop_other_threads = true; 63254721Semaste const bool unwind_on_error = true; 64254721Semaste const bool ignore_breakpoints = true; 65254721Semaste const bool try_all_threads = true; 66254721Semaste const uint32_t timeout_usec = 500000; 67254721Semaste 68254721Semaste addr_t prot_arg, flags_arg = 0; 69254721Semaste if (prot == eMmapProtNone) 70254721Semaste prot_arg = PROT_NONE; 71254721Semaste else { 72254721Semaste prot_arg = 0; 73254721Semaste if (prot & eMmapProtExec) 74254721Semaste prot_arg |= PROT_EXEC; 75254721Semaste if (prot & eMmapProtRead) 76254721Semaste prot_arg |= PROT_READ; 77254721Semaste if (prot & eMmapProtWrite) 78254721Semaste prot_arg |= PROT_WRITE; 79254721Semaste } 80254721Semaste 81254721Semaste if (flags & eMmapFlagsPrivate) 82254721Semaste flags_arg |= MAP_PRIVATE; 83254721Semaste if (flags & eMmapFlagsAnon) 84254721Semaste flags_arg |= MAP_ANON; 85254721Semaste 86254721Semaste AddressRange mmap_range; 87254721Semaste if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range)) 88254721Semaste { 89254721Semaste ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); 90254721Semaste ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 91254721Semaste ThreadPlanCallFunction *call_function_thread_plan 92254721Semaste = new ThreadPlanCallFunction (*thread, 93254721Semaste mmap_range.GetBaseAddress(), 94254721Semaste clang_void_ptr_type, 95254721Semaste stop_other_threads, 96254721Semaste unwind_on_error, 97254721Semaste ignore_breakpoints, 98254721Semaste &addr, 99254721Semaste &length, 100254721Semaste &prot_arg, 101254721Semaste &flags_arg, 102254721Semaste &fd, 103254721Semaste &offset); 104254721Semaste lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan); 105254721Semaste if (call_plan_sp) 106254721Semaste { 107254721Semaste StreamFile error_strm; 108254721Semaste // This plan is a utility plan, so set it to discard itself when done. 109254721Semaste call_plan_sp->SetIsMasterPlan (true); 110254721Semaste call_plan_sp->SetOkayToDiscard(true); 111254721Semaste 112254721Semaste StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); 113254721Semaste if (frame) 114254721Semaste { 115254721Semaste ExecutionContext exe_ctx; 116254721Semaste frame->CalculateExecutionContext (exe_ctx); 117254721Semaste ExecutionResults result = process->RunThreadPlan (exe_ctx, 118254721Semaste call_plan_sp, 119254721Semaste stop_other_threads, 120254721Semaste try_all_threads, 121254721Semaste unwind_on_error, 122254721Semaste ignore_breakpoints, 123254721Semaste timeout_usec, 124254721Semaste error_strm); 125254721Semaste if (result == eExecutionCompleted) 126254721Semaste { 127254721Semaste 128254721Semaste allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 129254721Semaste if (process->GetAddressByteSize() == 4) 130254721Semaste { 131254721Semaste if (allocated_addr == UINT32_MAX) 132254721Semaste return false; 133254721Semaste } 134254721Semaste else if (process->GetAddressByteSize() == 8) 135254721Semaste { 136254721Semaste if (allocated_addr == UINT64_MAX) 137254721Semaste return false; 138254721Semaste } 139254721Semaste return true; 140254721Semaste } 141254721Semaste } 142254721Semaste } 143254721Semaste } 144254721Semaste } 145254721Semaste } 146254721Semaste 147254721Semaste return false; 148254721Semaste} 149254721Semaste 150254721Semastebool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, 151254721Semaste addr_t length) { 152254721Semaste Thread *thread = process->GetThreadList().GetSelectedThread().get(); 153254721Semaste if (thread == NULL) 154254721Semaste return false; 155254721Semaste 156254721Semaste const bool append = true; 157254721Semaste const bool include_symbols = true; 158254721Semaste const bool include_inlines = false; 159254721Semaste SymbolContextList sc_list; 160254721Semaste const uint32_t count 161254721Semaste = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"), 162254721Semaste eFunctionNameTypeFull, 163254721Semaste include_symbols, 164254721Semaste include_inlines, 165254721Semaste append, 166254721Semaste sc_list); 167254721Semaste if (count > 0) 168254721Semaste { 169254721Semaste SymbolContext sc; 170254721Semaste if (sc_list.GetContextAtIndex(0, sc)) 171254721Semaste { 172254721Semaste const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; 173254721Semaste const bool use_inline_block_range = false; 174254721Semaste const bool stop_other_threads = true; 175254721Semaste const bool unwind_on_error = true; 176254721Semaste const bool ignore_breakpoints = true; 177254721Semaste const bool try_all_threads = true; 178254721Semaste const uint32_t timeout_usec = 500000; 179254721Semaste 180254721Semaste AddressRange munmap_range; 181254721Semaste if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range)) 182254721Semaste { 183254721Semaste lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread, 184254721Semaste munmap_range.GetBaseAddress(), 185254721Semaste ClangASTType(), 186254721Semaste stop_other_threads, 187254721Semaste unwind_on_error, 188254721Semaste ignore_breakpoints, 189254721Semaste &addr, 190254721Semaste &length)); 191254721Semaste if (call_plan_sp) 192254721Semaste { 193254721Semaste StreamFile error_strm; 194254721Semaste // This plan is a utility plan, so set it to discard itself when done. 195254721Semaste call_plan_sp->SetIsMasterPlan (true); 196254721Semaste call_plan_sp->SetOkayToDiscard(true); 197254721Semaste 198254721Semaste StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); 199254721Semaste if (frame) 200254721Semaste { 201254721Semaste ExecutionContext exe_ctx; 202254721Semaste frame->CalculateExecutionContext (exe_ctx); 203254721Semaste ExecutionResults result = process->RunThreadPlan (exe_ctx, 204254721Semaste call_plan_sp, 205254721Semaste stop_other_threads, 206254721Semaste try_all_threads, 207254721Semaste unwind_on_error, 208254721Semaste ignore_breakpoints, 209254721Semaste timeout_usec, 210254721Semaste error_strm); 211254721Semaste if (result == eExecutionCompleted) 212254721Semaste { 213254721Semaste return true; 214254721Semaste } 215254721Semaste } 216254721Semaste } 217254721Semaste } 218254721Semaste } 219254721Semaste } 220254721Semaste 221254721Semaste return false; 222254721Semaste} 223254721Semaste 224254721Semastebool lldb_private::InferiorCall(Process *process, const Address *address, addr_t &returned_func) { 225254721Semaste Thread *thread = process->GetThreadList().GetSelectedThread().get(); 226254721Semaste if (thread == NULL || address == NULL) 227254721Semaste return false; 228254721Semaste 229254721Semaste const bool stop_other_threads = true; 230254721Semaste const bool unwind_on_error = true; 231254721Semaste const bool ignore_breakpoints = true; 232254721Semaste const bool try_all_threads = true; 233254721Semaste const uint32_t timeout_usec = 500000; 234254721Semaste 235254721Semaste ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); 236254721Semaste ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 237254721Semaste ThreadPlanCallFunction *call_function_thread_plan 238254721Semaste = new ThreadPlanCallFunction (*thread, 239254721Semaste *address, 240254721Semaste clang_void_ptr_type, 241254721Semaste stop_other_threads, 242254721Semaste unwind_on_error, 243254721Semaste ignore_breakpoints); 244254721Semaste lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan); 245254721Semaste if (call_plan_sp) 246254721Semaste { 247254721Semaste StreamFile error_strm; 248254721Semaste // This plan is a utility plan, so set it to discard itself when done. 249254721Semaste call_plan_sp->SetIsMasterPlan (true); 250254721Semaste call_plan_sp->SetOkayToDiscard(true); 251254721Semaste 252254721Semaste StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); 253254721Semaste if (frame) 254254721Semaste { 255254721Semaste ExecutionContext exe_ctx; 256254721Semaste frame->CalculateExecutionContext (exe_ctx); 257254721Semaste ExecutionResults result = process->RunThreadPlan (exe_ctx, 258254721Semaste call_plan_sp, 259254721Semaste stop_other_threads, 260254721Semaste try_all_threads, 261254721Semaste unwind_on_error, 262254721Semaste ignore_breakpoints, 263254721Semaste timeout_usec, 264254721Semaste error_strm); 265254721Semaste if (result == eExecutionCompleted) 266254721Semaste { 267254721Semaste returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 268254721Semaste 269254721Semaste if (process->GetAddressByteSize() == 4) 270254721Semaste { 271254721Semaste if (returned_func == UINT32_MAX) 272254721Semaste return false; 273254721Semaste } 274254721Semaste else if (process->GetAddressByteSize() == 8) 275254721Semaste { 276254721Semaste if (returned_func == UINT64_MAX) 277254721Semaste return false; 278254721Semaste } 279254721Semaste return true; 280254721Semaste } 281254721Semaste } 282254721Semaste } 283254721Semaste 284254721Semaste return false; 285254721Semaste} 286