1//===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "InferiorCallPOSIX.h" 10#include "lldb/Core/Address.h" 11#include "lldb/Core/StreamFile.h" 12#include "lldb/Core/ValueObject.h" 13#include "lldb/Expression/DiagnosticManager.h" 14#include "lldb/Host/Config.h" 15#include "lldb/Symbol/TypeSystem.h" 16#include "lldb/Symbol/SymbolContext.h" 17#include "lldb/Target/ExecutionContext.h" 18#include "lldb/Target/Platform.h" 19#include "lldb/Target/Process.h" 20#include "lldb/Target/Target.h" 21#include "lldb/Target/ThreadPlanCallFunction.h" 22 23#if LLDB_ENABLE_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 lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, 37 addr_t addr, addr_t length, unsigned prot, 38 unsigned flags, addr_t fd, addr_t offset) { 39 Thread *thread = 40 process->GetThreadList().GetExpressionExecutionThread().get(); 41 if (thread == nullptr) 42 return false; 43 44 const bool include_symbols = true; 45 const bool include_inlines = false; 46 SymbolContextList sc_list; 47 process->GetTarget().GetImages().FindFunctions( 48 ConstString("mmap"), eFunctionNameTypeFull, include_symbols, 49 include_inlines, sc_list); 50 const uint32_t count = sc_list.GetSize(); 51 if (count > 0) { 52 SymbolContext sc; 53 if (sc_list.GetContextAtIndex(0, sc)) { 54 const uint32_t range_scope = 55 eSymbolContextFunction | eSymbolContextSymbol; 56 const bool use_inline_block_range = false; 57 EvaluateExpressionOptions options; 58 options.SetStopOthers(true); 59 options.SetUnwindOnError(true); 60 options.SetIgnoreBreakpoints(true); 61 options.SetTryAllThreads(true); 62 options.SetDebug(false); 63 options.SetTimeout(process->GetUtilityExpressionTimeout()); 64 options.SetTrapExceptions(false); 65 66 addr_t prot_arg; 67 if (prot == eMmapProtNone) 68 prot_arg = PROT_NONE; 69 else { 70 prot_arg = 0; 71 if (prot & eMmapProtExec) 72 prot_arg |= PROT_EXEC; 73 if (prot & eMmapProtRead) 74 prot_arg |= PROT_READ; 75 if (prot & eMmapProtWrite) 76 prot_arg |= PROT_WRITE; 77 } 78 79 AddressRange mmap_range; 80 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, 81 mmap_range)) { 82 auto type_system_or_err = 83 process->GetTarget().GetScratchTypeSystemForLanguage( 84 eLanguageTypeC); 85 if (!type_system_or_err) { 86 llvm::consumeError(type_system_or_err.takeError()); 87 return false; 88 } 89 CompilerType void_ptr_type = 90 type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid) 91 .GetPointerType(); 92 const ArchSpec arch = process->GetTarget().GetArchitecture(); 93 MmapArgList args = 94 process->GetTarget().GetPlatform()->GetMmapArgumentList( 95 arch, addr, length, prot_arg, flags, fd, offset); 96 lldb::ThreadPlanSP call_plan_sp( 97 new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(), 98 void_ptr_type, args, options)); 99 if (call_plan_sp) { 100 DiagnosticManager diagnostics; 101 102 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 103 if (frame) { 104 ExecutionContext exe_ctx; 105 frame->CalculateExecutionContext(exe_ctx); 106 ExpressionResults result = process->RunThreadPlan( 107 exe_ctx, call_plan_sp, options, diagnostics); 108 if (result == eExpressionCompleted) { 109 110 allocated_addr = 111 call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned( 112 LLDB_INVALID_ADDRESS); 113 if (process->GetAddressByteSize() == 4) { 114 if (allocated_addr == UINT32_MAX) 115 return false; 116 } else if (process->GetAddressByteSize() == 8) { 117 if (allocated_addr == UINT64_MAX) 118 return false; 119 } 120 return true; 121 } 122 } 123 } 124 } 125 } 126 } 127 128 return false; 129} 130 131bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, 132 addr_t length) { 133 Thread *thread = 134 process->GetThreadList().GetExpressionExecutionThread().get(); 135 if (thread == nullptr) 136 return false; 137 138 const bool include_symbols = true; 139 const bool include_inlines = false; 140 SymbolContextList sc_list; 141 process->GetTarget().GetImages().FindFunctions( 142 ConstString("munmap"), eFunctionNameTypeFull, include_symbols, 143 include_inlines, sc_list); 144 const uint32_t count = sc_list.GetSize(); 145 if (count > 0) { 146 SymbolContext sc; 147 if (sc_list.GetContextAtIndex(0, sc)) { 148 const uint32_t range_scope = 149 eSymbolContextFunction | eSymbolContextSymbol; 150 const bool use_inline_block_range = false; 151 EvaluateExpressionOptions options; 152 options.SetStopOthers(true); 153 options.SetUnwindOnError(true); 154 options.SetIgnoreBreakpoints(true); 155 options.SetTryAllThreads(true); 156 options.SetDebug(false); 157 options.SetTimeout(process->GetUtilityExpressionTimeout()); 158 options.SetTrapExceptions(false); 159 160 AddressRange munmap_range; 161 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, 162 munmap_range)) { 163 lldb::addr_t args[] = {addr, length}; 164 lldb::ThreadPlanSP call_plan_sp( 165 new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), 166 CompilerType(), args, options)); 167 if (call_plan_sp) { 168 DiagnosticManager diagnostics; 169 170 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 171 if (frame) { 172 ExecutionContext exe_ctx; 173 frame->CalculateExecutionContext(exe_ctx); 174 ExpressionResults result = process->RunThreadPlan( 175 exe_ctx, call_plan_sp, options, diagnostics); 176 if (result == eExpressionCompleted) { 177 return true; 178 } 179 } 180 } 181 } 182 } 183 } 184 185 return false; 186} 187