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 auto ts = *type_system_or_err; 92 if (!ts) 93 return false; 94 CompilerType void_ptr_type = 95 ts->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType(); 96 const ArchSpec arch = process->GetTarget().GetArchitecture(); 97 MmapArgList args = 98 process->GetTarget().GetPlatform()->GetMmapArgumentList( 99 arch, addr, length, prot_arg, flags, fd, offset); 100 lldb::ThreadPlanSP call_plan_sp( 101 new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(), 102 void_ptr_type, args, options)); 103 if (call_plan_sp) { 104 DiagnosticManager diagnostics; 105 106 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 107 if (frame) { 108 ExecutionContext exe_ctx; 109 frame->CalculateExecutionContext(exe_ctx); 110 ExpressionResults result = process->RunThreadPlan( 111 exe_ctx, call_plan_sp, options, diagnostics); 112 if (result == eExpressionCompleted) { 113 114 allocated_addr = 115 call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned( 116 LLDB_INVALID_ADDRESS); 117 if (process->GetAddressByteSize() == 4) { 118 if (allocated_addr == UINT32_MAX) 119 return false; 120 } else if (process->GetAddressByteSize() == 8) { 121 if (allocated_addr == UINT64_MAX) 122 return false; 123 } 124 return true; 125 } 126 } 127 } 128 } 129 } 130 } 131 132 return false; 133 } 134 135 bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, 136 addr_t length) { 137 Thread *thread = 138 process->GetThreadList().GetExpressionExecutionThread().get(); 139 if (thread == nullptr) 140 return false; 141 142 ModuleFunctionSearchOptions function_options; 143 function_options.include_symbols = true; 144 function_options.include_inlines = false; 145 146 SymbolContextList sc_list; 147 process->GetTarget().GetImages().FindFunctions( 148 ConstString("munmap"), eFunctionNameTypeFull, function_options, sc_list); 149 const uint32_t count = sc_list.GetSize(); 150 if (count > 0) { 151 SymbolContext sc; 152 if (sc_list.GetContextAtIndex(0, sc)) { 153 const uint32_t range_scope = 154 eSymbolContextFunction | eSymbolContextSymbol; 155 const bool use_inline_block_range = false; 156 EvaluateExpressionOptions options; 157 options.SetStopOthers(true); 158 options.SetUnwindOnError(true); 159 options.SetIgnoreBreakpoints(true); 160 options.SetTryAllThreads(true); 161 options.SetDebug(false); 162 options.SetTimeout(process->GetUtilityExpressionTimeout()); 163 options.SetTrapExceptions(false); 164 165 AddressRange munmap_range; 166 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, 167 munmap_range)) { 168 lldb::addr_t args[] = {addr, length}; 169 lldb::ThreadPlanSP call_plan_sp( 170 new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), 171 CompilerType(), args, options)); 172 if (call_plan_sp) { 173 DiagnosticManager diagnostics; 174 175 StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); 176 if (frame) { 177 ExecutionContext exe_ctx; 178 frame->CalculateExecutionContext(exe_ctx); 179 ExpressionResults result = process->RunThreadPlan( 180 exe_ctx, call_plan_sp, options, diagnostics); 181 if (result == eExpressionCompleted) { 182 return true; 183 } 184 } 185 } 186 } 187 } 188 } 189 190 return false; 191 } 192