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