]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
Merge llvm release_80 branch r351543, and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / Utility / InferiorCallPOSIX.cpp
1 //===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "InferiorCallPOSIX.h"
11 #include "lldb/Core/Address.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/ClangASTContext.h"
17 #include "lldb/Symbol/SymbolContext.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 #ifndef LLDB_DISABLE_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 == NULL)
43     return false;
44
45   const bool append = true;
46   const bool include_symbols = true;
47   const bool include_inlines = false;
48   SymbolContextList sc_list;
49   const uint32_t count = process->GetTarget().GetImages().FindFunctions(
50       ConstString("mmap"), eFunctionNameTypeFull, include_symbols,
51       include_inlines, append, sc_list);
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(std::chrono::milliseconds(500));
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         ClangASTContext *clang_ast_context =
84             process->GetTarget().GetScratchClangASTContext();
85         CompilerType clang_void_ptr_type =
86             clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
87         const ArchSpec arch = process->GetTarget().GetArchitecture();
88         MmapArgList args =
89             process->GetTarget().GetPlatform()->GetMmapArgumentList(
90                 arch, addr, length, prot_arg, flags, fd, offset);
91         lldb::ThreadPlanSP call_plan_sp(
92             new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
93                                        clang_void_ptr_type, args, options));
94         if (call_plan_sp) {
95           DiagnosticManager diagnostics;
96
97           StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
98           if (frame) {
99             ExecutionContext exe_ctx;
100             frame->CalculateExecutionContext(exe_ctx);
101             ExpressionResults result = process->RunThreadPlan(
102                 exe_ctx, call_plan_sp, options, diagnostics);
103             if (result == eExpressionCompleted) {
104
105               allocated_addr =
106                   call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
107                       LLDB_INVALID_ADDRESS);
108               if (process->GetAddressByteSize() == 4) {
109                 if (allocated_addr == UINT32_MAX)
110                   return false;
111               } else if (process->GetAddressByteSize() == 8) {
112                 if (allocated_addr == UINT64_MAX)
113                   return false;
114               }
115               return true;
116             }
117           }
118         }
119       }
120     }
121   }
122
123   return false;
124 }
125
126 bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
127                                       addr_t length) {
128   Thread *thread =
129       process->GetThreadList().GetExpressionExecutionThread().get();
130   if (thread == NULL)
131     return false;
132
133   const bool append = true;
134   const bool include_symbols = true;
135   const bool include_inlines = false;
136   SymbolContextList sc_list;
137   const uint32_t count = process->GetTarget().GetImages().FindFunctions(
138       ConstString("munmap"), eFunctionNameTypeFull, include_symbols,
139       include_inlines, append, sc_list);
140   if (count > 0) {
141     SymbolContext sc;
142     if (sc_list.GetContextAtIndex(0, sc)) {
143       const uint32_t range_scope =
144           eSymbolContextFunction | eSymbolContextSymbol;
145       const bool use_inline_block_range = false;
146       EvaluateExpressionOptions options;
147       options.SetStopOthers(true);
148       options.SetUnwindOnError(true);
149       options.SetIgnoreBreakpoints(true);
150       options.SetTryAllThreads(true);
151       options.SetDebug(false);
152       options.SetTimeout(std::chrono::milliseconds(500));
153       options.SetTrapExceptions(false);
154
155       AddressRange munmap_range;
156       if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
157                              munmap_range)) {
158         lldb::addr_t args[] = {addr, length};
159         lldb::ThreadPlanSP call_plan_sp(
160             new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(),
161                                        CompilerType(), args, options));
162         if (call_plan_sp) {
163           DiagnosticManager diagnostics;
164
165           StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
166           if (frame) {
167             ExecutionContext exe_ctx;
168             frame->CalculateExecutionContext(exe_ctx);
169             ExpressionResults result = process->RunThreadPlan(
170                 exe_ctx, call_plan_sp, options, diagnostics);
171             if (result == eExpressionCompleted) {
172               return true;
173             }
174           }
175         }
176       }
177     }
178   }
179
180   return false;
181 }
182
183 // FIXME: This has nothing to do with Posix, it is just a convenience function
184 // that calls a
185 // function of the form "void * (*)(void)".  We should find a better place to
186 // put this.
187
188 bool lldb_private::InferiorCall(Process *process, const Address *address,
189                                 addr_t &returned_func, bool trap_exceptions) {
190   Thread *thread =
191       process->GetThreadList().GetExpressionExecutionThread().get();
192   if (thread == NULL || address == NULL)
193     return false;
194
195   EvaluateExpressionOptions options;
196   options.SetStopOthers(true);
197   options.SetUnwindOnError(true);
198   options.SetIgnoreBreakpoints(true);
199   options.SetTryAllThreads(true);
200   options.SetDebug(false);
201   options.SetTimeout(std::chrono::milliseconds(500));
202   options.SetTrapExceptions(trap_exceptions);
203
204   ClangASTContext *clang_ast_context =
205       process->GetTarget().GetScratchClangASTContext();
206   CompilerType clang_void_ptr_type =
207       clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
208   lldb::ThreadPlanSP call_plan_sp(
209       new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type,
210                                  llvm::ArrayRef<addr_t>(), options));
211   if (call_plan_sp) {
212     DiagnosticManager diagnostics;
213
214     StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
215     if (frame) {
216       ExecutionContext exe_ctx;
217       frame->CalculateExecutionContext(exe_ctx);
218       ExpressionResults result =
219           process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
220       if (result == eExpressionCompleted) {
221         returned_func =
222             call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
223                 LLDB_INVALID_ADDRESS);
224
225         if (process->GetAddressByteSize() == 4) {
226           if (returned_func == UINT32_MAX)
227             return false;
228         } else if (process->GetAddressByteSize() == 8) {
229           if (returned_func == UINT64_MAX)
230             return false;
231         }
232         return true;
233       }
234     }
235   }
236
237   return false;
238 }