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