]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
MFC r258054: Update LLDB to upstream r194122 snapshot
[FreeBSD/stable/10.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 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 = process->GetThreadList().GetSelectedThread().get();
41     if (thread == NULL)
42         return false;
43
44     const bool append = true;
45     const bool include_symbols = true;
46     const bool include_inlines = false;
47     SymbolContextList sc_list;
48     const uint32_t count
49       = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"), 
50                                                         eFunctionNameTypeFull,
51                                                         include_symbols,
52                                                         include_inlines,
53                                                         append, 
54                                                         sc_list);
55     if (count > 0)
56     {
57         SymbolContext sc;
58         if (sc_list.GetContextAtIndex(0, sc))
59         {
60             const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
61             const bool use_inline_block_range = false;
62             const bool stop_other_threads = true;
63             const bool unwind_on_error = true;
64             const bool ignore_breakpoints = true;
65             const bool try_all_threads = true;
66             const uint32_t timeout_usec = 500000;
67
68             addr_t prot_arg, flags_arg = 0;
69             if (prot == eMmapProtNone)
70               prot_arg = PROT_NONE;
71             else {
72               prot_arg = 0;
73               if (prot & eMmapProtExec)
74                 prot_arg |= PROT_EXEC;
75               if (prot & eMmapProtRead)
76                 prot_arg |= PROT_READ;
77               if (prot & eMmapProtWrite)
78                 prot_arg |= PROT_WRITE;
79             }
80
81             if (flags & eMmapFlagsPrivate)
82               flags_arg |= MAP_PRIVATE;
83             if (flags & eMmapFlagsAnon)
84               flags_arg |= MAP_ANON;
85
86             AddressRange mmap_range;
87             if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
88             {
89                 ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
90                 ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
91                 ThreadPlanCallFunction *call_function_thread_plan
92                   = new ThreadPlanCallFunction (*thread,
93                                                 mmap_range.GetBaseAddress(),
94                                                 clang_void_ptr_type,
95                                                 stop_other_threads,
96                                                 unwind_on_error,
97                                                 ignore_breakpoints,
98                                                 &addr,
99                                                 &length,
100                                                 &prot_arg,
101                                                 &flags_arg,
102                                                 &fd,
103                                                 &offset);
104                 lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
105                 if (call_plan_sp)
106                 {
107                     StreamFile error_strm;
108                     // This plan is a utility plan, so set it to discard itself when done.
109                     call_plan_sp->SetIsMasterPlan (true);
110                     call_plan_sp->SetOkayToDiscard(true);
111                     
112                     StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
113                     if (frame)
114                     {
115                         ExecutionContext exe_ctx;
116                         frame->CalculateExecutionContext (exe_ctx);
117                         ExecutionResults result = process->RunThreadPlan (exe_ctx,
118                                                                           call_plan_sp,        
119                                                                           stop_other_threads,
120                                                                           try_all_threads,
121                                                                           unwind_on_error,
122                                                                           ignore_breakpoints,
123                                                                           timeout_usec,
124                                                                           error_strm);
125                         if (result == eExecutionCompleted)
126                         {
127                             
128                             allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
129                             if (process->GetAddressByteSize() == 4)
130                             {
131                                 if (allocated_addr == UINT32_MAX)
132                                     return false;
133                             }
134                             else if (process->GetAddressByteSize() == 8)
135                             {
136                                 if (allocated_addr == UINT64_MAX)
137                                     return false;
138                             }
139                             return true;
140                         }
141                     }
142                 }
143             }
144         }
145     }
146
147     return false;
148 }
149
150 bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
151                                       addr_t length) {
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            const bool stop_other_threads = true;
175            const bool unwind_on_error = true;
176            const bool ignore_breakpoints = true;
177            const bool try_all_threads = true;
178            const uint32_t timeout_usec = 500000;
179            
180            AddressRange munmap_range;
181            if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
182            {
183                lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
184                                                                             munmap_range.GetBaseAddress(),
185                                                                             ClangASTType(),
186                                                                             stop_other_threads,
187                                                                             unwind_on_error,
188                                                                             ignore_breakpoints,
189                                                                             &addr,
190                                                                             &length));
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                        ExecutionResults result = process->RunThreadPlan (exe_ctx,
204                                                                          call_plan_sp,        
205                                                                          stop_other_threads,
206                                                                          try_all_threads,
207                                                                          unwind_on_error,
208                                                                          ignore_breakpoints,
209                                                                          timeout_usec,
210                                                                          error_strm);
211                        if (result == eExecutionCompleted)
212                        {
213                            return true;
214                        }
215                    }
216                }
217            }
218        }
219    }
220
221    return false;
222 }
223
224 bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t &returned_func) {
225     Thread *thread = process->GetThreadList().GetSelectedThread().get();
226     if (thread == NULL || address == NULL)
227         return false;
228
229     const bool stop_other_threads = true;
230     const bool unwind_on_error = true;
231     const bool ignore_breakpoints = true;
232     const bool try_all_threads = true;
233     const uint32_t timeout_usec = 500000;
234
235     ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
236     ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
237     ThreadPlanCallFunction *call_function_thread_plan
238         = new ThreadPlanCallFunction (*thread,
239                                       *address,
240                                       clang_void_ptr_type,
241                                       stop_other_threads,
242                                       unwind_on_error,
243                                       ignore_breakpoints);
244     lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
245     if (call_plan_sp)
246     {
247         StreamFile error_strm;
248         // This plan is a utility plan, so set it to discard itself when done.
249         call_plan_sp->SetIsMasterPlan (true);
250         call_plan_sp->SetOkayToDiscard(true);
251
252         StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
253         if (frame)
254         {
255             ExecutionContext exe_ctx;
256             frame->CalculateExecutionContext (exe_ctx);
257             ExecutionResults result = process->RunThreadPlan (exe_ctx,
258                                                               call_plan_sp,
259                                                               stop_other_threads,
260                                                               try_all_threads,
261                                                               unwind_on_error,
262                                                               ignore_breakpoints,
263                                                               timeout_usec,
264                                                               error_strm);
265             if (result == eExecutionCompleted)
266             {
267                 returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
268
269                 if (process->GetAddressByteSize() == 4)
270                 {
271                     if (returned_func == UINT32_MAX)
272                         return false;
273                 }
274                 else if (process->GetAddressByteSize() == 8)
275                 {
276                     if (returned_func == UINT64_MAX)
277                         return false;
278                 }
279                 return true;
280             }
281         }
282     }
283
284     return false;
285 }