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