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;
38 lldb_private::InferiorCallMmap (Process *process,
39 addr_t &allocated_addr,
47 Thread *thread = process->GetThreadList().GetSelectedThread().get();
51 const bool append = true;
52 const bool include_symbols = true;
53 const bool include_inlines = false;
54 SymbolContextList sc_list;
56 = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"),
57 eFunctionNameTypeFull,
65 if (sc_list.GetContextAtIndex(0, sc))
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);
77 addr_t prot_arg, flags_arg = 0;
78 if (prot == eMmapProtNone)
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;
90 if (flags & eMmapFlagsPrivate)
91 flags_arg |= MAP_PRIVATE;
92 if (flags & eMmapFlagsAnon)
93 flags_arg |= MAP_ANON;
95 AddressRange mmap_range;
96 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
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(),
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);
113 StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
116 ExecutionContext exe_ctx;
117 frame->CalculateExecutionContext (exe_ctx);
118 ExpressionResults result = process->RunThreadPlan (exe_ctx,
122 if (result == eExpressionCompleted)
125 allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
126 if (process->GetAddressByteSize() == 4)
128 if (allocated_addr == UINT32_MAX)
131 else if (process->GetAddressByteSize() == 8)
133 if (allocated_addr == UINT64_MAX)
148 lldb_private::InferiorCallMunmap (Process *process,
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 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);
182 AddressRange munmap_range;
183 if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
185 lldb::addr_t args[] = { addr, length };
186 lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
187 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 ExpressionResults result = process->RunThreadPlan (exe_ctx,
207 if (result == eExpressionCompleted)
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.
224 lldb_private::InferiorCall (Process *process,
225 const Address *address,
226 addr_t &returned_func)
228 Thread *thread = process->GetThreadList().GetSelectedThread().get();
229 if (thread == NULL || address == NULL)
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);
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,
245 llvm::ArrayRef<addr_t>(),
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);
254 StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
257 ExecutionContext exe_ctx;
258 frame->CalculateExecutionContext (exe_ctx);
259 ExpressionResults result = process->RunThreadPlan (exe_ctx,
263 if (result == eExpressionCompleted)
265 returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
267 if (process->GetAddressByteSize() == 4)
269 if (returned_func == UINT32_MAX)
272 else if (process->GetAddressByteSize() == 8)
274 if (returned_func == UINT64_MAX)