xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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/Expression/DiagnosticManager.h"
13 #include "lldb/Host/Config.h"
14 #include "lldb/Symbol/SymbolContext.h"
15 #include "lldb/Symbol/TypeSystem.h"
16 #include "lldb/Target/ExecutionContext.h"
17 #include "lldb/Target/Platform.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Target/ThreadPlanCallFunction.h"
21 #include "lldb/ValueObject/ValueObject.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 
InferiorCallMmap(Process * process,addr_t & allocated_addr,addr_t addr,addr_t length,unsigned prot,unsigned flags,addr_t fd,addr_t offset)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       EvaluateExpressionOptions options;
56       options.SetStopOthers(true);
57       options.SetUnwindOnError(true);
58       options.SetIgnoreBreakpoints(true);
59       options.SetTryAllThreads(true);
60       options.SetDebug(false);
61       options.SetTimeout(process->GetUtilityExpressionTimeout());
62       options.SetTrapExceptions(false);
63 
64       addr_t prot_arg;
65       if (prot == eMmapProtNone)
66         prot_arg = PROT_NONE;
67       else {
68         prot_arg = 0;
69         if (prot & eMmapProtExec)
70           prot_arg |= PROT_EXEC;
71         if (prot & eMmapProtRead)
72           prot_arg |= PROT_READ;
73         if (prot & eMmapProtWrite)
74           prot_arg |= PROT_WRITE;
75       }
76 
77       Address mmap_addr = sc.GetFunctionOrSymbolAddress();
78       if (mmap_addr.IsValid()) {
79         auto type_system_or_err =
80             process->GetTarget().GetScratchTypeSystemForLanguage(
81                 eLanguageTypeC);
82         if (!type_system_or_err) {
83           llvm::consumeError(type_system_or_err.takeError());
84           return false;
85         }
86         auto ts = *type_system_or_err;
87         if (!ts)
88           return false;
89         CompilerType void_ptr_type =
90             ts->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
91         const ArchSpec arch = process->GetTarget().GetArchitecture();
92         MmapArgList args =
93             process->GetTarget().GetPlatform()->GetMmapArgumentList(
94                 arch, addr, length, prot_arg, flags, fd, offset);
95         lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(
96             *thread, mmap_addr, void_ptr_type, args, options));
97         if (call_plan_sp) {
98           DiagnosticManager diagnostics;
99 
100           StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
101           if (frame) {
102             ExecutionContext exe_ctx;
103             frame->CalculateExecutionContext(exe_ctx);
104             ExpressionResults result = process->RunThreadPlan(
105                 exe_ctx, call_plan_sp, options, diagnostics);
106             if (result == eExpressionCompleted) {
107 
108               allocated_addr =
109                   call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
110                       LLDB_INVALID_ADDRESS);
111               if (process->GetAddressByteSize() == 4) {
112                 if (allocated_addr == UINT32_MAX)
113                   return false;
114               } else if (process->GetAddressByteSize() == 8) {
115                 if (allocated_addr == UINT64_MAX)
116                   return false;
117               }
118               return true;
119             }
120           }
121         }
122       }
123     }
124   }
125 
126   return false;
127 }
128 
InferiorCallMunmap(Process * process,addr_t addr,addr_t length)129 bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
130                                       addr_t length) {
131   Thread *thread =
132       process->GetThreadList().GetExpressionExecutionThread().get();
133   if (thread == nullptr)
134     return false;
135 
136   ModuleFunctionSearchOptions function_options;
137   function_options.include_symbols = true;
138   function_options.include_inlines = false;
139 
140   SymbolContextList sc_list;
141   process->GetTarget().GetImages().FindFunctions(
142       ConstString("munmap"), eFunctionNameTypeFull, function_options, sc_list);
143   const uint32_t count = sc_list.GetSize();
144   if (count > 0) {
145     SymbolContext sc;
146     if (sc_list.GetContextAtIndex(0, sc)) {
147       EvaluateExpressionOptions options;
148       options.SetStopOthers(true);
149       options.SetUnwindOnError(true);
150       options.SetIgnoreBreakpoints(true);
151       options.SetTryAllThreads(true);
152       options.SetDebug(false);
153       options.SetTimeout(process->GetUtilityExpressionTimeout());
154       options.SetTrapExceptions(false);
155 
156       Address munmap_addr = sc.GetFunctionOrSymbolAddress();
157       if (munmap_addr.IsValid()) {
158         lldb::addr_t args[] = {addr, length};
159         lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(
160             *thread, munmap_addr, CompilerType(), args, options));
161         if (call_plan_sp) {
162           DiagnosticManager diagnostics;
163 
164           StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
165           if (frame) {
166             ExecutionContext exe_ctx;
167             frame->CalculateExecutionContext(exe_ctx);
168             ExpressionResults result = process->RunThreadPlan(
169                 exe_ctx, call_plan_sp, options, diagnostics);
170             if (result == eExpressionCompleted) {
171               return true;
172             }
173           }
174         }
175       }
176     }
177   }
178 
179   return false;
180 }
181