1 //===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
22 #ifndef LLDB_DISABLE_POSIX
31 #define MAP_ANON 0x1000
35 using namespace lldb_private;
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();
44 const bool append = true;
45 const bool include_symbols = true;
46 const bool include_inlines = false;
47 SymbolContextList sc_list;
49 = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"),
50 eFunctionNameTypeFull,
58 if (sc_list.GetContextAtIndex(0, sc))
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;
68 addr_t prot_arg, flags_arg = 0;
69 if (prot == eMmapProtNone)
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;
81 if (flags & eMmapFlagsPrivate)
82 flags_arg |= MAP_PRIVATE;
83 if (flags & eMmapFlagsAnon)
84 flags_arg |= MAP_ANON;
86 AddressRange mmap_range;
87 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
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(),
104 lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
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);
112 StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
115 ExecutionContext exe_ctx;
116 frame->CalculateExecutionContext (exe_ctx);
117 ExecutionResults result = process->RunThreadPlan (exe_ctx,
125 if (result == eExecutionCompleted)
128 allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
129 if (process->GetAddressByteSize() == 4)
131 if (allocated_addr == UINT32_MAX)
134 else if (process->GetAddressByteSize() == 8)
136 if (allocated_addr == UINT64_MAX)
150 bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
152 Thread *thread = process->GetThreadList().GetSelectedThread().get();
156 const bool append = true;
157 const bool include_symbols = true;
158 const bool include_inlines = false;
159 SymbolContextList sc_list;
161 = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"),
162 eFunctionNameTypeFull,
170 if (sc_list.GetContextAtIndex(0, sc))
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;
180 AddressRange munmap_range;
181 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
183 lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
184 munmap_range.GetBaseAddress(),
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);
198 StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
201 ExecutionContext exe_ctx;
202 frame->CalculateExecutionContext (exe_ctx);
203 ExecutionResults result = process->RunThreadPlan (exe_ctx,
211 if (result == eExecutionCompleted)
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)
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;
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,
244 lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
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);
252 StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
255 ExecutionContext exe_ctx;
256 frame->CalculateExecutionContext (exe_ctx);
257 ExecutionResults result = process->RunThreadPlan (exe_ctx,
265 if (result == eExecutionCompleted)
267 returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
269 if (process->GetAddressByteSize() == 4)
271 if (returned_func == UINT32_MAX)
274 else if (process->GetAddressByteSize() == 8)
276 if (returned_func == UINT64_MAX)