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 33 using namespace lldb; 34 using namespace lldb_private; 35 36 bool 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 134 bool 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