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" 15360784Sdim#include "lldb/Symbol/TypeSystem.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 23360784Sdim#if LLDB_ENABLE_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 include_symbols = true; 45314564Sdim const bool include_inlines = false; 46314564Sdim SymbolContextList sc_list; 47360784Sdim process->GetTarget().GetImages().FindFunctions( 48314564Sdim ConstString("mmap"), eFunctionNameTypeFull, include_symbols, 49360784Sdim include_inlines, sc_list); 50360784Sdim const uint32_t count = sc_list.GetSize(); 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)) { 82360784Sdim auto type_system_or_err = 83360784Sdim process->GetTarget().GetScratchTypeSystemForLanguage( 84360784Sdim eLanguageTypeC); 85360784Sdim if (!type_system_or_err) { 86360784Sdim llvm::consumeError(type_system_or_err.takeError()); 87360784Sdim return false; 88360784Sdim } 89360784Sdim CompilerType void_ptr_type = 90360784Sdim type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid) 91360784Sdim .GetPointerType(); 92322326Semaste const ArchSpec arch = process->GetTarget().GetArchitecture(); 93322326Semaste MmapArgList args = 94322326Semaste process->GetTarget().GetPlatform()->GetMmapArgumentList( 95322326Semaste arch, addr, length, prot_arg, flags, fd, offset); 96314564Sdim lldb::ThreadPlanSP call_plan_sp( 97314564Sdim new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(), 98360784Sdim void_ptr_type, args, options)); 99314564Sdim if (call_plan_sp) { 100314564Sdim DiagnosticManager diagnostics; 101309124Sdim 102314564Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 103314564Sdim if (frame) { 104314564Sdim ExecutionContext exe_ctx; 105314564Sdim frame->CalculateExecutionContext(exe_ctx); 106314564Sdim ExpressionResults result = process->RunThreadPlan( 107314564Sdim exe_ctx, call_plan_sp, options, diagnostics); 108314564Sdim if (result == eExpressionCompleted) { 109309124Sdim 110314564Sdim allocated_addr = 111314564Sdim call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned( 112314564Sdim LLDB_INVALID_ADDRESS); 113314564Sdim if (process->GetAddressByteSize() == 4) { 114314564Sdim if (allocated_addr == UINT32_MAX) 115314564Sdim return false; 116314564Sdim } else if (process->GetAddressByteSize() == 8) { 117314564Sdim if (allocated_addr == UINT64_MAX) 118314564Sdim return false; 119314564Sdim } 120314564Sdim return true; 121254721Semaste } 122314564Sdim } 123254721Semaste } 124314564Sdim } 125254721Semaste } 126314564Sdim } 127254721Semaste 128314564Sdim return false; 129254721Semaste} 130254721Semaste 131314564Sdimbool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, 132314564Sdim addr_t length) { 133314564Sdim Thread *thread = 134314564Sdim process->GetThreadList().GetExpressionExecutionThread().get(); 135353358Sdim if (thread == nullptr) 136314564Sdim return false; 137309124Sdim 138314564Sdim const bool include_symbols = true; 139314564Sdim const bool include_inlines = false; 140314564Sdim SymbolContextList sc_list; 141360784Sdim process->GetTarget().GetImages().FindFunctions( 142314564Sdim ConstString("munmap"), eFunctionNameTypeFull, include_symbols, 143360784Sdim include_inlines, sc_list); 144360784Sdim const uint32_t count = sc_list.GetSize(); 145314564Sdim if (count > 0) { 146314564Sdim SymbolContext sc; 147314564Sdim if (sc_list.GetContextAtIndex(0, sc)) { 148314564Sdim const uint32_t range_scope = 149314564Sdim eSymbolContextFunction | eSymbolContextSymbol; 150314564Sdim const bool use_inline_block_range = false; 151314564Sdim EvaluateExpressionOptions options; 152314564Sdim options.SetStopOthers(true); 153314564Sdim options.SetUnwindOnError(true); 154314564Sdim options.SetIgnoreBreakpoints(true); 155314564Sdim options.SetTryAllThreads(true); 156314564Sdim options.SetDebug(false); 157353358Sdim options.SetTimeout(process->GetUtilityExpressionTimeout()); 158314564Sdim options.SetTrapExceptions(false); 159314564Sdim 160314564Sdim AddressRange munmap_range; 161314564Sdim if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, 162314564Sdim munmap_range)) { 163314564Sdim lldb::addr_t args[] = {addr, length}; 164314564Sdim lldb::ThreadPlanSP call_plan_sp( 165314564Sdim new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), 166314564Sdim CompilerType(), args, options)); 167314564Sdim if (call_plan_sp) { 168314564Sdim DiagnosticManager diagnostics; 169314564Sdim 170314564Sdim StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 171314564Sdim if (frame) { 172314564Sdim ExecutionContext exe_ctx; 173314564Sdim frame->CalculateExecutionContext(exe_ctx); 174314564Sdim ExpressionResults result = process->RunThreadPlan( 175314564Sdim exe_ctx, call_plan_sp, options, diagnostics); 176314564Sdim if (result == eExpressionCompleted) { 177314564Sdim return true; 178258884Semaste } 179314564Sdim } 180258884Semaste } 181314564Sdim } 182258884Semaste } 183314564Sdim } 184254721Semaste 185314564Sdim return false; 186254721Semaste} 187