InferiorCallPOSIX.cpp revision 353358
1254721Semaste//===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#include "InferiorCallPOSIX.h" 10254721Semaste#include "lldb/Core/Address.h" 11254721Semaste#include "lldb/Core/StreamFile.h" 12254721Semaste#include "lldb/Core/ValueObject.h" 13309124Sdim#include "lldb/Expression/DiagnosticManager.h" 14309124Sdim#include "lldb/Host/Config.h" 15254721Semaste#include "lldb/Symbol/ClangASTContext.h" 16254721Semaste#include "lldb/Symbol/SymbolContext.h" 17254721Semaste#include "lldb/Target/ExecutionContext.h" 18288943Sdim#include "lldb/Target/Platform.h" 19254721Semaste#include "lldb/Target/Process.h" 20254721Semaste#include "lldb/Target/Target.h" 21254721Semaste#include "lldb/Target/ThreadPlanCallFunction.h" 22254721Semaste 23258054Semaste#ifndef LLDB_DISABLE_POSIX 24254721Semaste#include <sys/mman.h> 25258054Semaste#else 26258054Semaste// define them 27258054Semaste#define PROT_NONE 0 28258054Semaste#define PROT_READ 1 29258054Semaste#define PROT_WRITE 2 30258054Semaste#define PROT_EXEC 4 31258054Semaste#endif 32254721Semaste 33254721Semasteusing namespace lldb; 34254721Semasteusing namespace lldb_private; 35254721Semaste 36314564Sdimbool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, 37314564Sdim addr_t addr, addr_t length, unsigned prot, 38314564Sdim unsigned flags, addr_t fd, addr_t offset) { 39314564Sdim Thread *thread = 40314564Sdim process->GetThreadList().GetExpressionExecutionThread().get(); 41353358Sdim if (thread == nullptr) 42314564Sdim return false; 43254721Semaste 44314564Sdim const bool append = true; 45314564Sdim const bool include_symbols = true; 46314564Sdim const bool include_inlines = false; 47314564Sdim SymbolContextList sc_list; 48314564Sdim const uint32_t count = process->GetTarget().GetImages().FindFunctions( 49314564Sdim ConstString("mmap"), eFunctionNameTypeFull, include_symbols, 50314564Sdim include_inlines, append, sc_list); 51314564Sdim if (count > 0) { 52314564Sdim SymbolContext sc; 53314564Sdim if (sc_list.GetContextAtIndex(0, sc)) { 54314564Sdim const uint32_t range_scope = 55314564Sdim eSymbolContextFunction | eSymbolContextSymbol; 56314564Sdim const bool use_inline_block_range = false; 57314564Sdim EvaluateExpressionOptions options; 58314564Sdim options.SetStopOthers(true); 59314564Sdim options.SetUnwindOnError(true); 60314564Sdim options.SetIgnoreBreakpoints(true); 61314564Sdim options.SetTryAllThreads(true); 62314564Sdim options.SetDebug(false); 63353358Sdim options.SetTimeout(process->GetUtilityExpressionTimeout()); 64314564Sdim options.SetTrapExceptions(false); 65254721Semaste 66322326Semaste addr_t prot_arg; 67314564Sdim if (prot == eMmapProtNone) 68314564Sdim prot_arg = PROT_NONE; 69314564Sdim else { 70314564Sdim prot_arg = 0; 71314564Sdim if (prot & eMmapProtExec) 72314564Sdim prot_arg |= PROT_EXEC; 73314564Sdim if (prot & eMmapProtRead) 74314564Sdim prot_arg |= PROT_READ; 75314564Sdim if (prot & eMmapProtWrite) 76314564Sdim prot_arg |= PROT_WRITE; 77314564Sdim } 78254721Semaste 79314564Sdim AddressRange mmap_range; 80314564Sdim if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, 81314564Sdim mmap_range)) { 82314564Sdim ClangASTContext *clang_ast_context = 83314564Sdim process->GetTarget().GetScratchClangASTContext(); 84314564Sdim CompilerType clang_void_ptr_type = 85314564Sdim clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 86322326Semaste const ArchSpec arch = process->GetTarget().GetArchitecture(); 87322326Semaste MmapArgList args = 88322326Semaste process->GetTarget().GetPlatform()->GetMmapArgumentList( 89322326Semaste arch, addr, length, prot_arg, flags, fd, offset); 90314564Sdim lldb::ThreadPlanSP call_plan_sp( 91314564Sdim new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(), 92314564Sdim clang_void_ptr_type, args, options)); 93314564Sdim if (call_plan_sp) { 94314564Sdim DiagnosticManager diagnostics; 95309124Sdim 96314564Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 97314564Sdim if (frame) { 98314564Sdim ExecutionContext exe_ctx; 99314564Sdim frame->CalculateExecutionContext(exe_ctx); 100314564Sdim ExpressionResults result = process->RunThreadPlan( 101314564Sdim exe_ctx, call_plan_sp, options, diagnostics); 102314564Sdim if (result == eExpressionCompleted) { 103309124Sdim 104314564Sdim allocated_addr = 105314564Sdim call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned( 106314564Sdim LLDB_INVALID_ADDRESS); 107314564Sdim if (process->GetAddressByteSize() == 4) { 108314564Sdim if (allocated_addr == UINT32_MAX) 109314564Sdim return false; 110314564Sdim } else if (process->GetAddressByteSize() == 8) { 111314564Sdim if (allocated_addr == UINT64_MAX) 112314564Sdim return false; 113314564Sdim } 114314564Sdim return true; 115254721Semaste } 116314564Sdim } 117254721Semaste } 118314564Sdim } 119254721Semaste } 120314564Sdim } 121254721Semaste 122314564Sdim return false; 123254721Semaste} 124254721Semaste 125314564Sdimbool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, 126314564Sdim addr_t length) { 127314564Sdim Thread *thread = 128314564Sdim process->GetThreadList().GetExpressionExecutionThread().get(); 129353358Sdim if (thread == nullptr) 130314564Sdim return false; 131309124Sdim 132314564Sdim const bool append = true; 133314564Sdim const bool include_symbols = true; 134314564Sdim const bool include_inlines = false; 135314564Sdim SymbolContextList sc_list; 136314564Sdim const uint32_t count = process->GetTarget().GetImages().FindFunctions( 137314564Sdim ConstString("munmap"), eFunctionNameTypeFull, include_symbols, 138314564Sdim include_inlines, append, sc_list); 139314564Sdim if (count > 0) { 140314564Sdim SymbolContext sc; 141314564Sdim if (sc_list.GetContextAtIndex(0, sc)) { 142314564Sdim const uint32_t range_scope = 143314564Sdim eSymbolContextFunction | eSymbolContextSymbol; 144314564Sdim const bool use_inline_block_range = false; 145314564Sdim EvaluateExpressionOptions options; 146314564Sdim options.SetStopOthers(true); 147314564Sdim options.SetUnwindOnError(true); 148314564Sdim options.SetIgnoreBreakpoints(true); 149314564Sdim options.SetTryAllThreads(true); 150314564Sdim options.SetDebug(false); 151353358Sdim options.SetTimeout(process->GetUtilityExpressionTimeout()); 152314564Sdim options.SetTrapExceptions(false); 153314564Sdim 154314564Sdim AddressRange munmap_range; 155314564Sdim if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, 156314564Sdim munmap_range)) { 157314564Sdim lldb::addr_t args[] = {addr, length}; 158314564Sdim lldb::ThreadPlanSP call_plan_sp( 159314564Sdim new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), 160314564Sdim CompilerType(), args, options)); 161314564Sdim if (call_plan_sp) { 162314564Sdim DiagnosticManager diagnostics; 163314564Sdim 164314564Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 165314564Sdim if (frame) { 166314564Sdim ExecutionContext exe_ctx; 167314564Sdim frame->CalculateExecutionContext(exe_ctx); 168314564Sdim ExpressionResults result = process->RunThreadPlan( 169314564Sdim exe_ctx, call_plan_sp, options, diagnostics); 170314564Sdim if (result == eExpressionCompleted) { 171314564Sdim return true; 172258884Semaste } 173314564Sdim } 174258884Semaste } 175314564Sdim } 176258884Semaste } 177314564Sdim } 178254721Semaste 179314564Sdim return false; 180254721Semaste} 181254721Semaste 182314564Sdim// FIXME: This has nothing to do with Posix, it is just a convenience function 183314564Sdim// that calls a 184314564Sdim// function of the form "void * (*)(void)". We should find a better place to 185314564Sdim// put this. 186262528Semaste 187314564Sdimbool lldb_private::InferiorCall(Process *process, const Address *address, 188314564Sdim addr_t &returned_func, bool trap_exceptions) { 189314564Sdim Thread *thread = 190314564Sdim process->GetThreadList().GetExpressionExecutionThread().get(); 191353358Sdim if (thread == nullptr || address == nullptr) 192314564Sdim return false; 193254721Semaste 194314564Sdim EvaluateExpressionOptions options; 195314564Sdim options.SetStopOthers(true); 196314564Sdim options.SetUnwindOnError(true); 197314564Sdim options.SetIgnoreBreakpoints(true); 198314564Sdim options.SetTryAllThreads(true); 199314564Sdim options.SetDebug(false); 200353358Sdim options.SetTimeout(process->GetUtilityExpressionTimeout()); 201314564Sdim options.SetTrapExceptions(trap_exceptions); 202254721Semaste 203314564Sdim ClangASTContext *clang_ast_context = 204314564Sdim process->GetTarget().GetScratchClangASTContext(); 205314564Sdim CompilerType clang_void_ptr_type = 206314564Sdim clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 207314564Sdim lldb::ThreadPlanSP call_plan_sp( 208314564Sdim new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type, 209314564Sdim llvm::ArrayRef<addr_t>(), options)); 210314564Sdim if (call_plan_sp) { 211314564Sdim DiagnosticManager diagnostics; 212254721Semaste 213314564Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 214314564Sdim if (frame) { 215314564Sdim ExecutionContext exe_ctx; 216314564Sdim frame->CalculateExecutionContext(exe_ctx); 217314564Sdim ExpressionResults result = 218314564Sdim process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics); 219314564Sdim if (result == eExpressionCompleted) { 220314564Sdim returned_func = 221314564Sdim call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned( 222314564Sdim LLDB_INVALID_ADDRESS); 223254721Semaste 224314564Sdim if (process->GetAddressByteSize() == 4) { 225314564Sdim if (returned_func == UINT32_MAX) 226314564Sdim return false; 227314564Sdim } else if (process->GetAddressByteSize() == 8) { 228314564Sdim if (returned_func == UINT64_MAX) 229314564Sdim return false; 230254721Semaste } 231314564Sdim return true; 232314564Sdim } 233254721Semaste } 234314564Sdim } 235254721Semaste 236314564Sdim return false; 237254721Semaste} 238