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