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