InferiorCallPOSIX.cpp revision e6bd142d9fa7ed149bd37efd8a75637375f165b7
1//===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "InferiorCallPOSIX.h" 11#include "lldb/Core/StreamFile.h" 12#include "lldb/Core/Value.h" 13#include "lldb/Symbol/SymbolContext.h" 14#include "lldb/Target/ExecutionContext.h" 15#include "lldb/Target/Process.h" 16#include "lldb/Target/Target.h" 17#include "lldb/Target/ThreadPlanCallFunction.h" 18 19#include <sys/mman.h> 20 21using namespace lldb; 22using namespace lldb_private; 23 24bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, 25 addr_t addr, addr_t length, unsigned prot, 26 unsigned flags, addr_t fd, addr_t offset) { 27 Thread *thread = process->GetThreadList().GetSelectedThread().get(); 28 if (thread == NULL) 29 thread = process->GetThreadList().GetThreadAtIndex(0).get(); 30 if (thread == NULL) 31 return false; 32 33 const bool append = true; 34 const bool include_symbols = true; 35 SymbolContextList sc_list; 36 const uint32_t count 37 = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"), 38 eFunctionNameTypeFull, 39 include_symbols, 40 append, 41 sc_list); 42 if (count > 0) 43 { 44 SymbolContext sc; 45 if (sc_list.GetContextAtIndex(0, sc)) 46 { 47 const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; 48 const bool use_inline_block_range = false; 49 const bool stop_other_threads = true; 50 const bool discard_on_error = true; 51 const bool try_all_threads = true; 52 const uint32_t single_thread_timeout_usec = 500000; 53 54 addr_t prot_arg, flags_arg = 0; 55 if (prot == eMmapProtNone) 56 prot_arg = PROT_NONE; 57 else { 58 prot_arg = 0; 59 if (prot & eMmapProtExec) 60 prot_arg |= PROT_EXEC; 61 if (prot & eMmapProtRead) 62 prot_arg |= PROT_READ; 63 if (prot & eMmapProtWrite) 64 prot_arg |= PROT_WRITE; 65 } 66 67 if (flags & eMmapFlagsPrivate) 68 flags_arg |= MAP_PRIVATE; 69 if (flags & eMmapFlagsAnon) 70 flags_arg |= MAP_ANON; 71 72 AddressRange mmap_range; 73 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range)) 74 { 75 ThreadPlanCallFunction *call_function_thread_plan 76 = new ThreadPlanCallFunction (*thread, 77 mmap_range.GetBaseAddress(), 78 stop_other_threads, 79 discard_on_error, 80 &addr, 81 &length, 82 &prot_arg, 83 &flags_arg, 84 &fd, 85 &offset); 86 lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan); 87 if (call_plan_sp) 88 { 89 ValueSP return_value_sp (new Value); 90 ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); 91 lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); 92 return_value_sp->SetValueType (Value::eValueTypeScalar); 93 return_value_sp->SetContext (Value::eContextTypeClangType, clang_void_ptr_type); 94 call_function_thread_plan->RequestReturnValue (return_value_sp); 95 96 StreamFile error_strm; 97 StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); 98 if (frame) 99 { 100 ExecutionContext exe_ctx; 101 frame->CalculateExecutionContext (exe_ctx); 102 ExecutionResults result = process->RunThreadPlan (exe_ctx, 103 call_plan_sp, 104 stop_other_threads, 105 try_all_threads, 106 discard_on_error, 107 single_thread_timeout_usec, 108 error_strm); 109 if (result == eExecutionCompleted) 110 { 111 allocated_addr = return_value_sp->GetScalar().ULongLong(); 112 if (process->GetAddressByteSize() == 4) 113 { 114 if (allocated_addr == UINT32_MAX) 115 return false; 116 } 117 return true; 118 } 119 } 120 } 121 } 122 } 123 } 124 125 return false; 126} 127 128bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, 129 addr_t length) { 130 Thread *thread = process->GetThreadList().GetSelectedThread().get(); 131 if (thread == NULL) 132 thread = process->GetThreadList().GetThreadAtIndex(0).get(); 133 134 const bool append = true; 135 const bool include_symbols = true; 136 SymbolContextList sc_list; 137 const uint32_t count 138 = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"), 139 eFunctionNameTypeFull, 140 include_symbols, 141 append, 142 sc_list); 143 if (count > 0) 144 { 145 SymbolContext sc; 146 if (sc_list.GetContextAtIndex(0, sc)) 147 { 148 const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; 149 const bool use_inline_block_range = false; 150 const bool stop_other_threads = true; 151 const bool discard_on_error = true; 152 const bool try_all_threads = true; 153 const uint32_t single_thread_timeout_usec = 500000; 154 155 AddressRange munmap_range; 156 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range)) 157 { 158 lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread, 159 munmap_range.GetBaseAddress(), 160 stop_other_threads, 161 discard_on_error, 162 &addr, 163 &length)); 164 if (call_plan_sp) 165 { 166 StreamFile error_strm; 167 StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); 168 if (frame) 169 { 170 ExecutionContext exe_ctx; 171 frame->CalculateExecutionContext (exe_ctx); 172 ExecutionResults result = process->RunThreadPlan (exe_ctx, 173 call_plan_sp, 174 stop_other_threads, 175 try_all_threads, 176 discard_on_error, 177 single_thread_timeout_usec, 178 error_strm); 179 if (result == eExecutionCompleted) 180 { 181 return true; 182 } 183 } 184 } 185 } 186 } 187 } 188 189 return false; 190} 191