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