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