Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / source / Plugins / Process / Utility / InferiorCallPOSIX.cpp
blob32c71d87c7f58ca5e296a5d0e6457e82de1b360a
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 //===----------------------------------------------------------------------===//
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"
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
33 using namespace lldb;
34 using namespace lldb_private;
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;
44 ModuleFunctionSearchOptions function_options;
45 function_options.include_symbols = true;
46 function_options.include_inlines = false;
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);
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;
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;
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;
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) {
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;
123 return true;
131 return false;
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;
141 ModuleFunctionSearchOptions function_options;
142 function_options.include_symbols = true;
143 function_options.include_inlines = false;
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);
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;
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;
189 return false;