]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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                 ThreadPlanCallFunction *call_function_thread_plan
102                   = new ThreadPlanCallFunction (*thread,
103                                                 mmap_range.GetBaseAddress(),
104                                                 clang_void_ptr_type,
105                                                 args,
106                                                 options);
107                 lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
108                 if (call_plan_sp)
109                 {
110                     StreamFile error_strm;
111                     // This plan is a utility plan, so set it to discard itself when done.
112                     call_plan_sp->SetIsMasterPlan (true);
113                     call_plan_sp->SetOkayToDiscard(true);
114                     
115                     StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
116                     if (frame)
117                     {
118                         ExecutionContext exe_ctx;
119                         frame->CalculateExecutionContext (exe_ctx);
120                         ExecutionResults result = process->RunThreadPlan (exe_ctx,
121                                                                           call_plan_sp,
122                                                                           options,
123                                                                           error_strm);
124                         if (result == eExecutionCompleted)
125                         {
126                             
127                             allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
128                             if (process->GetAddressByteSize() == 4)
129                             {
130                                 if (allocated_addr == UINT32_MAX)
131                                     return false;
132                             }
133                             else if (process->GetAddressByteSize() == 8)
134                             {
135                                 if (allocated_addr == UINT64_MAX)
136                                     return false;
137                             }
138                             return true;
139                         }
140                     }
141                 }
142             }
143         }
144     }
145
146     return false;
147 }
148
149 bool
150 lldb_private::InferiorCallMunmap (Process *process,
151                                   addr_t addr,
152                                   addr_t length)
153 {
154    Thread *thread = process->GetThreadList().GetSelectedThread().get();
155    if (thread == NULL)
156        return false;
157    
158    const bool append = true;
159    const bool include_symbols = true;
160    const bool include_inlines = false;
161    SymbolContextList sc_list;
162    const uint32_t count
163      = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"), 
164                                                        eFunctionNameTypeFull,
165                                                        include_symbols, 
166                                                        include_inlines,
167                                                        append, 
168                                                        sc_list);
169    if (count > 0)
170    {
171        SymbolContext sc;
172        if (sc_list.GetContextAtIndex(0, sc))
173        {
174             const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
175             const bool use_inline_block_range = false;
176             EvaluateExpressionOptions options;
177             options.SetStopOthers(true);
178             options.SetUnwindOnError(true);
179             options.SetIgnoreBreakpoints(true);
180             options.SetTryAllThreads(true);
181             options.SetDebug (false);
182             options.SetTimeoutUsec(500000);
183            
184             AddressRange munmap_range;
185             if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
186             {
187                 lldb::addr_t args[] = { addr, length };
188                 lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
189                                                                             munmap_range.GetBaseAddress(),
190                                                                             ClangASTType(),
191                                                                             args,
192                                                                             options));
193                 if (call_plan_sp)
194                 {
195                     StreamFile error_strm;
196                     // This plan is a utility plan, so set it to discard itself when done.
197                     call_plan_sp->SetIsMasterPlan (true);
198                     call_plan_sp->SetOkayToDiscard(true);
199                    
200                     StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
201                     if (frame)
202                     {
203                         ExecutionContext exe_ctx;
204                         frame->CalculateExecutionContext (exe_ctx);
205                         ExecutionResults result = process->RunThreadPlan (exe_ctx,
206                                                                           call_plan_sp,
207                                                                           options,
208                                                                           error_strm);
209                         if (result == eExecutionCompleted)
210                         {
211                             return true;
212                         }
213                     }
214                 }
215             }
216         }
217     }
218
219     return false;
220 }
221
222 // FIXME: This has nothing to do with Posix, it is just a convenience function that calls a
223 // function of the form "void * (*)(void)".  We should find a better place to put this.
224
225 bool
226 lldb_private::InferiorCall (Process *process,
227                             const Address *address,
228                             addr_t &returned_func)
229 {
230     Thread *thread = process->GetThreadList().GetSelectedThread().get();
231     if (thread == NULL || address == NULL)
232         return false;
233
234     EvaluateExpressionOptions options;
235     options.SetStopOthers(true);
236     options.SetUnwindOnError(true);
237     options.SetIgnoreBreakpoints(true);
238     options.SetTryAllThreads(true);
239     options.SetDebug (false);
240     options.SetTimeoutUsec(500000);
241
242     ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
243     ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
244     ThreadPlanCallFunction *call_function_thread_plan
245         = new ThreadPlanCallFunction (*thread,
246                                       *address,
247                                       clang_void_ptr_type,
248                                       llvm::ArrayRef<addr_t>(),
249                                       options);
250     lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
251     if (call_plan_sp)
252     {
253         StreamString error_strm;
254         // This plan is a utility plan, so set it to discard itself when done.
255         call_plan_sp->SetIsMasterPlan (true);
256         call_plan_sp->SetOkayToDiscard(true);
257
258         StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
259         if (frame)
260         {
261             ExecutionContext exe_ctx;
262             frame->CalculateExecutionContext (exe_ctx);
263             ExecutionResults result = process->RunThreadPlan (exe_ctx,
264                                                               call_plan_sp,
265                                                               options,
266                                                               error_strm);
267             if (result == eExecutionCompleted)
268             {
269                 returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
270
271                 if (process->GetAddressByteSize() == 4)
272                 {
273                     if (returned_func == UINT32_MAX)
274                         return false;
275                 }
276                 else if (process->GetAddressByteSize() == 8)
277                 {
278                     if (returned_func == UINT64_MAX)
279                         return false;
280                 }
281                 return true;
282             }
283         }
284     }
285
286     return false;
287 }