InferiorCallPOSIX.cpp revision 4d623e869516c30d46d6d20d339a0e03116e7ac1
1#include "InferiorCallPOSIX.h"
2#include "lldb/Core/StreamFile.h"
3#include "lldb/Core/Value.h"
4#include "lldb/Symbol/SymbolContext.h"
5#include "lldb/Target/ExecutionContext.h"
6#include "lldb/Target/Process.h"
7#include "lldb/Target/Target.h"
8#include "lldb/Target/ThreadPlanCallFunction.h"
9
10#include <sys/mman.h>
11
12using namespace lldb;
13using namespace lldb_private;
14
15bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
16                                    addr_t addr, addr_t length, unsigned prot,
17                                    unsigned flags, addr_t fd, addr_t offset) {
18    Thread *thread = process->GetThreadList().GetSelectedThread().get();
19    if (thread == NULL)
20        thread = process->GetThreadList().GetThreadAtIndex(0).get();
21
22    const bool append = true;
23    const bool include_symbols = true;
24    SymbolContextList sc_list;
25    const uint32_t count
26      = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"),
27                                                        eFunctionNameTypeFull,
28                                                        include_symbols,
29                                                        append,
30                                                        sc_list);
31    if (count > 0)
32    {
33        SymbolContext sc;
34        if (sc_list.GetContextAtIndex(0, sc))
35        {
36            const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
37            const bool use_inline_block_range = false;
38            const bool stop_other_threads = true;
39            const bool discard_on_error = true;
40            const bool try_all_threads = true;
41            const uint32_t single_thread_timeout_usec = 500000;
42
43            addr_t prot_arg, flags_arg = 0;
44            if (prot == eMmapProtNone)
45              prot_arg = PROT_NONE;
46            else {
47              prot_arg = 0;
48              if (prot & eMmapProtExec)
49                prot_arg |= PROT_EXEC;
50              if (prot & eMmapProtRead)
51                prot_arg |= PROT_READ;
52              if (prot & eMmapProtWrite)
53                prot_arg |= PROT_WRITE;
54            }
55
56            if (flags & eMmapFlagsPrivate)
57              flags_arg |= MAP_PRIVATE;
58            if (flags & eMmapFlagsAnon)
59              flags_arg |= MAP_ANON;
60
61            AddressRange mmap_range;
62            if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
63            {
64                ThreadPlanCallFunction *call_function_thread_plan
65                  = new ThreadPlanCallFunction (*thread,
66                                                mmap_range.GetBaseAddress(),
67                                                stop_other_threads,
68                                                discard_on_error,
69                                                &addr,
70                                                &length,
71                                                &prot_arg,
72                                                &flags_arg,
73                                                &fd,
74                                                &offset);
75                lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
76                if (call_plan_sp)
77                {
78                    ValueSP return_value_sp (new Value);
79                    ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
80                    lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
81                    return_value_sp->SetValueType (Value::eValueTypeScalar);
82                    return_value_sp->SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
83                    call_function_thread_plan->RequestReturnValue (return_value_sp);
84
85                    StreamFile error_strm;
86                    StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
87                    if (frame)
88                    {
89                        ExecutionContext exe_ctx;
90                        frame->CalculateExecutionContext (exe_ctx);
91                        ExecutionResults result = process->RunThreadPlan (exe_ctx,
92                                                                          call_plan_sp,
93                                                                          stop_other_threads,
94                                                                          try_all_threads,
95                                                                          discard_on_error,
96                                                                          single_thread_timeout_usec,
97                                                                          error_strm);
98                        if (result == eExecutionCompleted)
99                        {
100                            allocated_addr = return_value_sp->GetScalar().ULongLong();
101                            if (process->GetAddressByteSize() == 4)
102                            {
103                                if (allocated_addr == UINT32_MAX)
104                                    return false;
105                            }
106                            return true;
107                        }
108                    }
109                }
110            }
111        }
112    }
113
114    return false;
115}
116
117bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
118                                      addr_t length) {
119   Thread *thread = process->GetThreadList().GetSelectedThread().get();
120   if (thread == NULL)
121       thread = process->GetThreadList().GetThreadAtIndex(0).get();
122
123   const bool append = true;
124   const bool include_symbols = true;
125   SymbolContextList sc_list;
126   const uint32_t count
127     = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"),
128                                                       eFunctionNameTypeFull,
129                                                       include_symbols,
130                                                       append,
131                                                       sc_list);
132   if (count > 0)
133   {
134       SymbolContext sc;
135       if (sc_list.GetContextAtIndex(0, sc))
136       {
137           const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
138           const bool use_inline_block_range = false;
139           const bool stop_other_threads = true;
140           const bool discard_on_error = true;
141           const bool try_all_threads = true;
142           const uint32_t single_thread_timeout_usec = 500000;
143
144           AddressRange munmap_range;
145           if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
146           {
147               lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
148                                                                            munmap_range.GetBaseAddress(),
149                                                                            stop_other_threads,
150                                                                            discard_on_error,
151                                                                            &addr,
152                                                                            &length));
153               if (call_plan_sp)
154               {
155                   StreamFile error_strm;
156                   StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
157                   if (frame)
158                   {
159                       ExecutionContext exe_ctx;
160                       frame->CalculateExecutionContext (exe_ctx);
161                       ExecutionResults result = process->RunThreadPlan (exe_ctx,
162                                                                         call_plan_sp,
163                                                                         stop_other_threads,
164                                                                         try_all_threads,
165                                                                         discard_on_error,
166                                                                         single_thread_timeout_usec,
167                                                                         error_strm);
168                       if (result == eExecutionCompleted)
169                       {
170                           return true;
171                       }
172                   }
173               }
174           }
175       }
176   }
177
178   return false;
179}
180