]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
Merge ^/head r294169 through r294598.
[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/Symbol/ClangASTContext.h"
15 #include "lldb/Symbol/SymbolContext.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/Host/Config.h"
22
23 #ifndef LLDB_DISABLE_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
37 lldb_private::InferiorCallMmap (Process *process,
38                                 addr_t &allocated_addr,
39                                 addr_t addr,
40                                 addr_t length,
41                                 unsigned prot,
42                                 unsigned flags,
43                                 addr_t fd,
44                                 addr_t offset)
45 {
46     Thread *thread = process->GetThreadList().GetSelectedThread().get();
47     if (thread == NULL)
48         return false;
49
50     const bool append = true;
51     const bool include_symbols = true;
52     const bool include_inlines = false;
53     SymbolContextList sc_list;
54     const uint32_t count
55       = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"), 
56                                                         eFunctionNameTypeFull,
57                                                         include_symbols,
58                                                         include_inlines,
59                                                         append, 
60                                                         sc_list);
61     if (count > 0)
62     {
63         SymbolContext sc;
64         if (sc_list.GetContextAtIndex(0, sc))
65         {
66             const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
67             const bool use_inline_block_range = false;
68             EvaluateExpressionOptions options;
69             options.SetStopOthers(true);
70             options.SetUnwindOnError(true);
71             options.SetIgnoreBreakpoints(true);
72             options.SetTryAllThreads(true);
73             options.SetDebug (false);
74             options.SetTimeoutUsec(500000);
75             options.SetTrapExceptions(false);
76
77             addr_t prot_arg, flags_arg = 0;
78             if (prot == eMmapProtNone)
79               prot_arg = PROT_NONE;
80             else {
81               prot_arg = 0;
82               if (prot & eMmapProtExec)
83                 prot_arg |= PROT_EXEC;
84               if (prot & eMmapProtRead)
85                 prot_arg |= PROT_READ;
86               if (prot & eMmapProtWrite)
87                 prot_arg |= PROT_WRITE;
88             }
89
90             const ArchSpec arch =  process->GetTarget().GetArchitecture();
91             flags_arg = process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,flags);
92
93             AddressRange mmap_range;
94             if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
95             {
96                 ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
97                 CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
98                 lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset };
99                 lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
100                                                                              mmap_range.GetBaseAddress(),
101                                                                              clang_void_ptr_type,
102                                                                              args,
103                                                                              options));
104                 if (call_plan_sp)
105                 {
106                     StreamFile error_strm;
107                     
108                     StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
109                     if (frame)
110                     {
111                         ExecutionContext exe_ctx;
112                         frame->CalculateExecutionContext (exe_ctx);
113                         ExpressionResults result = process->RunThreadPlan (exe_ctx,
114                                                                           call_plan_sp,
115                                                                           options,
116                                                                           error_strm);
117                         if (result == eExpressionCompleted)
118                         {
119                             
120                             allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
121                             if (process->GetAddressByteSize() == 4)
122                             {
123                                 if (allocated_addr == UINT32_MAX)
124                                     return false;
125                             }
126                             else if (process->GetAddressByteSize() == 8)
127                             {
128                                 if (allocated_addr == UINT64_MAX)
129                                     return false;
130                             }
131                             return true;
132                         }
133                     }
134                 }
135             }
136         }
137     }
138
139     return false;
140 }
141
142 bool
143 lldb_private::InferiorCallMunmap (Process *process,
144                                   addr_t addr,
145                                   addr_t length)
146 {
147    Thread *thread = process->GetThreadList().GetSelectedThread().get();
148    if (thread == NULL)
149        return false;
150    
151    const bool append = true;
152    const bool include_symbols = true;
153    const bool include_inlines = false;
154    SymbolContextList sc_list;
155    const uint32_t count
156      = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"), 
157                                                        eFunctionNameTypeFull,
158                                                        include_symbols, 
159                                                        include_inlines,
160                                                        append, 
161                                                        sc_list);
162    if (count > 0)
163    {
164        SymbolContext sc;
165        if (sc_list.GetContextAtIndex(0, sc))
166        {
167             const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
168             const bool use_inline_block_range = false;
169             EvaluateExpressionOptions options;
170             options.SetStopOthers(true);
171             options.SetUnwindOnError(true);
172             options.SetIgnoreBreakpoints(true);
173             options.SetTryAllThreads(true);
174             options.SetDebug (false);
175             options.SetTimeoutUsec(500000);
176             options.SetTrapExceptions(false);
177            
178             AddressRange munmap_range;
179             if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
180             {
181                 lldb::addr_t args[] = { addr, length };
182                 lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
183                                                                             munmap_range.GetBaseAddress(),
184                                                                             CompilerType(),
185                                                                             args,
186                                                                             options));
187                 if (call_plan_sp)
188                 {
189                     StreamFile error_strm;
190                    
191                     StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
192                     if (frame)
193                     {
194                         ExecutionContext exe_ctx;
195                         frame->CalculateExecutionContext (exe_ctx);
196                         ExpressionResults result = process->RunThreadPlan (exe_ctx,
197                                                                           call_plan_sp,
198                                                                           options,
199                                                                           error_strm);
200                         if (result == eExpressionCompleted)
201                         {
202                             return true;
203                         }
204                     }
205                 }
206             }
207         }
208     }
209
210     return false;
211 }
212
213 // FIXME: This has nothing to do with Posix, it is just a convenience function that calls a
214 // function of the form "void * (*)(void)".  We should find a better place to put this.
215
216 bool
217 lldb_private::InferiorCall (Process *process,
218                             const Address *address,
219                             addr_t &returned_func,
220                             bool trap_exceptions)
221 {
222     Thread *thread = process->GetThreadList().GetSelectedThread().get();
223     if (thread == NULL || address == NULL)
224         return false;
225
226     EvaluateExpressionOptions options;
227     options.SetStopOthers(true);
228     options.SetUnwindOnError(true);
229     options.SetIgnoreBreakpoints(true);
230     options.SetTryAllThreads(true);
231     options.SetDebug (false);
232     options.SetTimeoutUsec(500000);
233     options.SetTrapExceptions(trap_exceptions);
234
235     ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
236     CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
237     lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
238                                                                  *address,
239                                                                  clang_void_ptr_type,
240                                                                  llvm::ArrayRef<addr_t>(),
241                                                                  options));
242     if (call_plan_sp)
243     {
244         StreamString error_strm;
245
246         StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
247         if (frame)
248         {
249             ExecutionContext exe_ctx;
250             frame->CalculateExecutionContext (exe_ctx);
251             ExpressionResults result = process->RunThreadPlan (exe_ctx,
252                                                               call_plan_sp,
253                                                               options,
254                                                               error_strm);
255             if (result == eExpressionCompleted)
256             {
257                 returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
258
259                 if (process->GetAddressByteSize() == 4)
260                 {
261                     if (returned_func == UINT32_MAX)
262                         return false;
263                 }
264                 else if (process->GetAddressByteSize() == 8)
265                 {
266                     if (returned_func == UINT64_MAX)
267                         return false;
268                 }
269                 return true;
270             }
271         }
272     }
273
274     return false;
275 }