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