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/Address.h" 12 #include "lldb/Core/StreamFile.h" 13 #include "lldb/Core/ValueObject.h" 14 #include "lldb/Expression/DiagnosticManager.h" 15 #include "lldb/Host/Config.h" 16 #include "lldb/Symbol/ClangASTContext.h" 17 #include "lldb/Symbol/SymbolContext.h" 18 #include "lldb/Target/ExecutionContext.h" 19 #include "lldb/Target/Platform.h" 20 #include "lldb/Target/Process.h" 21 #include "lldb/Target/Target.h" 22 #include "lldb/Target/ThreadPlanCallFunction.h" 23 24 #ifndef LLDB_DISABLE_POSIX 25 #include <sys/mman.h> 26 #else 27 // define them 28 #define PROT_NONE 0 29 #define PROT_READ 1 30 #define PROT_WRITE 2 31 #define PROT_EXEC 4 32 #endif 33 34 using namespace lldb; 35 using namespace lldb_private; 36 37 bool 38 lldb_private::InferiorCallMmap (Process *process, 39 addr_t &allocated_addr, 40 addr_t addr, 41 addr_t length, 42 unsigned prot, 43 unsigned flags, 44 addr_t fd, 45 addr_t offset) 46 { 47 Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get(); 48 if (thread == NULL) 49 return false; 50 51 const bool append = true; 52 const bool include_symbols = true; 53 const bool include_inlines = false; 54 SymbolContextList sc_list; 55 const uint32_t count 56 = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"), 57 eFunctionNameTypeFull, 58 include_symbols, 59 include_inlines, 60 append, 61 sc_list); 62 if (count > 0) 63 { 64 SymbolContext sc; 65 if (sc_list.GetContextAtIndex(0, sc)) 66 { 67 const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; 68 const bool use_inline_block_range = false; 69 EvaluateExpressionOptions options; 70 options.SetStopOthers(true); 71 options.SetUnwindOnError(true); 72 options.SetIgnoreBreakpoints(true); 73 options.SetTryAllThreads(true); 74 options.SetDebug (false); 75 options.SetTimeoutUsec(500000); 76 options.SetTrapExceptions(false); 77 78 addr_t prot_arg, flags_arg = 0; 79 if (prot == eMmapProtNone) 80 prot_arg = PROT_NONE; 81 else { 82 prot_arg = 0; 83 if (prot & eMmapProtExec) 84 prot_arg |= PROT_EXEC; 85 if (prot & eMmapProtRead) 86 prot_arg |= PROT_READ; 87 if (prot & eMmapProtWrite) 88 prot_arg |= PROT_WRITE; 89 } 90 91 const ArchSpec arch = process->GetTarget().GetArchitecture(); 92 flags_arg = process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,flags); 93 94 AddressRange mmap_range; 95 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range)) 96 { 97 ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); 98 CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 99 lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset }; 100 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(), 101 clang_void_ptr_type, args, options)); 102 if (call_plan_sp) 103 { 104 DiagnosticManager diagnostics; 105 106 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 107 if (frame) 108 { 109 ExecutionContext exe_ctx; 110 frame->CalculateExecutionContext (exe_ctx); 111 ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics); 112 if (result == eExpressionCompleted) 113 { 114 115 allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 116 if (process->GetAddressByteSize() == 4) 117 { 118 if (allocated_addr == UINT32_MAX) 119 return false; 120 } 121 else if (process->GetAddressByteSize() == 8) 122 { 123 if (allocated_addr == UINT64_MAX) 124 return false; 125 } 126 return true; 127 } 128 } 129 } 130 } 131 } 132 } 133 134 return false; 135 } 136 137 bool 138 lldb_private::InferiorCallMunmap (Process *process, 139 addr_t addr, 140 addr_t length) 141 { 142 Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get(); 143 if (thread == NULL) 144 return false; 145 146 const bool append = true; 147 const bool include_symbols = true; 148 const bool include_inlines = false; 149 SymbolContextList sc_list; 150 const uint32_t count 151 = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"), 152 eFunctionNameTypeFull, 153 include_symbols, 154 include_inlines, 155 append, 156 sc_list); 157 if (count > 0) 158 { 159 SymbolContext sc; 160 if (sc_list.GetContextAtIndex(0, sc)) 161 { 162 const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; 163 const bool use_inline_block_range = false; 164 EvaluateExpressionOptions options; 165 options.SetStopOthers(true); 166 options.SetUnwindOnError(true); 167 options.SetIgnoreBreakpoints(true); 168 options.SetTryAllThreads(true); 169 options.SetDebug (false); 170 options.SetTimeoutUsec(500000); 171 options.SetTrapExceptions(false); 172 173 AddressRange munmap_range; 174 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range)) 175 { 176 lldb::addr_t args[] = { addr, length }; 177 lldb::ThreadPlanSP call_plan_sp( 178 new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), CompilerType(), args, options)); 179 if (call_plan_sp) 180 { 181 DiagnosticManager diagnostics; 182 183 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 184 if (frame) 185 { 186 ExecutionContext exe_ctx; 187 frame->CalculateExecutionContext (exe_ctx); 188 ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics); 189 if (result == eExpressionCompleted) 190 { 191 return true; 192 } 193 } 194 } 195 } 196 } 197 } 198 199 return false; 200 } 201 202 // FIXME: This has nothing to do with Posix, it is just a convenience function that calls a 203 // function of the form "void * (*)(void)". We should find a better place to put this. 204 205 bool 206 lldb_private::InferiorCall (Process *process, 207 const Address *address, 208 addr_t &returned_func, 209 bool trap_exceptions) 210 { 211 Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get(); 212 if (thread == NULL || address == NULL) 213 return false; 214 215 EvaluateExpressionOptions options; 216 options.SetStopOthers(true); 217 options.SetUnwindOnError(true); 218 options.SetIgnoreBreakpoints(true); 219 options.SetTryAllThreads(true); 220 options.SetDebug (false); 221 options.SetTimeoutUsec(500000); 222 options.SetTrapExceptions(trap_exceptions); 223 224 ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); 225 CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 226 lldb::ThreadPlanSP call_plan_sp( 227 new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type, llvm::ArrayRef<addr_t>(), options)); 228 if (call_plan_sp) 229 { 230 DiagnosticManager diagnostics; 231 232 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 233 if (frame) 234 { 235 ExecutionContext exe_ctx; 236 frame->CalculateExecutionContext (exe_ctx); 237 ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics); 238 if (result == eExpressionCompleted) 239 { 240 returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 241 242 if (process->GetAddressByteSize() == 4) 243 { 244 if (returned_func == UINT32_MAX) 245 return false; 246 } 247 else if (process->GetAddressByteSize() == 8) 248 { 249 if (returned_func == UINT64_MAX) 250 return false; 251 } 252 return true; 253 } 254 } 255 } 256 257 return false; 258 } 259