InferiorCallPOSIX.cpp revision 309124
1254721Semaste//===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "InferiorCallPOSIX.h"
11254721Semaste#include "lldb/Core/Address.h"
12254721Semaste#include "lldb/Core/StreamFile.h"
13254721Semaste#include "lldb/Core/ValueObject.h"
14309124Sdim#include "lldb/Expression/DiagnosticManager.h"
15309124Sdim#include "lldb/Host/Config.h"
16254721Semaste#include "lldb/Symbol/ClangASTContext.h"
17254721Semaste#include "lldb/Symbol/SymbolContext.h"
18254721Semaste#include "lldb/Target/ExecutionContext.h"
19288943Sdim#include "lldb/Target/Platform.h"
20254721Semaste#include "lldb/Target/Process.h"
21254721Semaste#include "lldb/Target/Target.h"
22254721Semaste#include "lldb/Target/ThreadPlanCallFunction.h"
23254721Semaste
24258054Semaste#ifndef LLDB_DISABLE_POSIX
25254721Semaste#include <sys/mman.h>
26258054Semaste#else
27258054Semaste// define them
28258054Semaste#define PROT_NONE 0
29258054Semaste#define PROT_READ 1
30258054Semaste#define PROT_WRITE 2
31258054Semaste#define PROT_EXEC 4
32258054Semaste#endif
33254721Semaste
34254721Semasteusing namespace lldb;
35254721Semasteusing namespace lldb_private;
36254721Semaste
37262528Semastebool
38262528Semastelldb_private::InferiorCallMmap (Process *process,
39262528Semaste                                addr_t &allocated_addr,
40262528Semaste                                addr_t addr,
41262528Semaste                                addr_t length,
42262528Semaste                                unsigned prot,
43262528Semaste                                unsigned flags,
44262528Semaste                                addr_t fd,
45262528Semaste                                addr_t offset)
46262528Semaste{
47309124Sdim    Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
48254721Semaste    if (thread == NULL)
49254721Semaste        return false;
50254721Semaste
51254721Semaste    const bool append = true;
52254721Semaste    const bool include_symbols = true;
53254721Semaste    const bool include_inlines = false;
54254721Semaste    SymbolContextList sc_list;
55254721Semaste    const uint32_t count
56254721Semaste      = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"),
57254721Semaste                                                        eFunctionNameTypeFull,
58254721Semaste                                                        include_symbols,
59254721Semaste                                                        include_inlines,
60254721Semaste                                                        append,
61254721Semaste                                                        sc_list);
62254721Semaste    if (count > 0)
63254721Semaste    {
64254721Semaste        SymbolContext sc;
65254721Semaste        if (sc_list.GetContextAtIndex(0, sc))
66254721Semaste        {
67254721Semaste            const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
68254721Semaste            const bool use_inline_block_range = false;
69258884Semaste            EvaluateExpressionOptions options;
70258884Semaste            options.SetStopOthers(true);
71258884Semaste            options.SetUnwindOnError(true);
72258884Semaste            options.SetIgnoreBreakpoints(true);
73258884Semaste            options.SetTryAllThreads(true);
74258884Semaste            options.SetDebug (false);
75258884Semaste            options.SetTimeoutUsec(500000);
76296417Sdim            options.SetTrapExceptions(false);
77254721Semaste
78254721Semaste            addr_t prot_arg, flags_arg = 0;
79254721Semaste            if (prot == eMmapProtNone)
80254721Semaste              prot_arg = PROT_NONE;
81254721Semaste            else {
82254721Semaste              prot_arg = 0;
83254721Semaste              if (prot & eMmapProtExec)
84254721Semaste                prot_arg |= PROT_EXEC;
85254721Semaste              if (prot & eMmapProtRead)
86254721Semaste                prot_arg |= PROT_READ;
87254721Semaste              if (prot & eMmapProtWrite)
88254721Semaste                prot_arg |= PROT_WRITE;
89254721Semaste            }
90254721Semaste
91288943Sdim            const ArchSpec arch =  process->GetTarget().GetArchitecture();
92288943Sdim            flags_arg = process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,flags);
93254721Semaste
94254721Semaste            AddressRange mmap_range;
95254721Semaste            if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
96254721Semaste            {
97254721Semaste                ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
98296417Sdim                CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
99258884Semaste                lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset };
100309124Sdim                lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
101309124Sdim                                                                           clang_void_ptr_type, args, options));
102254721Semaste                if (call_plan_sp)
103254721Semaste                {
104309124Sdim                    DiagnosticManager diagnostics;
105309124Sdim
106309124Sdim                    StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
107254721Semaste                    if (frame)
108254721Semaste                    {
109254721Semaste                        ExecutionContext exe_ctx;
110254721Semaste                        frame->CalculateExecutionContext (exe_ctx);
111309124Sdim                        ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
112276479Sdim                        if (result == eExpressionCompleted)
113254721Semaste                        {
114309124Sdim
115254721Semaste                            allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
116254721Semaste                            if (process->GetAddressByteSize() == 4)
117254721Semaste                            {
118254721Semaste                                if (allocated_addr == UINT32_MAX)
119254721Semaste                                    return false;
120254721Semaste                            }
121254721Semaste                            else if (process->GetAddressByteSize() == 8)
122254721Semaste                            {
123254721Semaste                                if (allocated_addr == UINT64_MAX)
124254721Semaste                                    return false;
125254721Semaste                            }
126254721Semaste                            return true;
127254721Semaste                        }
128254721Semaste                    }
129254721Semaste                }
130254721Semaste            }
131254721Semaste        }
132254721Semaste    }
133254721Semaste
134254721Semaste    return false;
135254721Semaste}
136254721Semaste
137262528Semastebool
138262528Semastelldb_private::InferiorCallMunmap (Process *process,
139262528Semaste                                  addr_t addr,
140262528Semaste                                  addr_t length)
141262528Semaste{
142309124Sdim   Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
143254721Semaste   if (thread == NULL)
144254721Semaste       return false;
145254721Semaste
146254721Semaste   const bool append = true;
147254721Semaste   const bool include_symbols = true;
148254721Semaste   const bool include_inlines = false;
149254721Semaste   SymbolContextList sc_list;
150254721Semaste   const uint32_t count
151254721Semaste     = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"),
152254721Semaste                                                       eFunctionNameTypeFull,
153254721Semaste                                                       include_symbols,
154254721Semaste                                                       include_inlines,
155254721Semaste                                                       append,
156254721Semaste                                                       sc_list);
157254721Semaste   if (count > 0)
158254721Semaste   {
159254721Semaste       SymbolContext sc;
160254721Semaste       if (sc_list.GetContextAtIndex(0, sc))
161254721Semaste       {
162258884Semaste            const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
163258884Semaste            const bool use_inline_block_range = false;
164258884Semaste            EvaluateExpressionOptions options;
165258884Semaste            options.SetStopOthers(true);
166258884Semaste            options.SetUnwindOnError(true);
167258884Semaste            options.SetIgnoreBreakpoints(true);
168258884Semaste            options.SetTryAllThreads(true);
169258884Semaste            options.SetDebug (false);
170258884Semaste            options.SetTimeoutUsec(500000);
171296417Sdim            options.SetTrapExceptions(false);
172254721Semaste
173258884Semaste            AddressRange munmap_range;
174258884Semaste            if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
175258884Semaste            {
176258884Semaste                lldb::addr_t args[] = { addr, length };
177309124Sdim                lldb::ThreadPlanSP call_plan_sp(
178309124Sdim                    new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), CompilerType(), args, options));
179258884Semaste                if (call_plan_sp)
180258884Semaste                {
181309124Sdim                    DiagnosticManager diagnostics;
182309124Sdim
183309124Sdim                    StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
184258884Semaste                    if (frame)
185258884Semaste                    {
186258884Semaste                        ExecutionContext exe_ctx;
187258884Semaste                        frame->CalculateExecutionContext (exe_ctx);
188309124Sdim                        ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
189276479Sdim                        if (result == eExpressionCompleted)
190258884Semaste                        {
191258884Semaste                            return true;
192258884Semaste                        }
193258884Semaste                    }
194258884Semaste                }
195258884Semaste            }
196258884Semaste        }
197258884Semaste    }
198254721Semaste
199258884Semaste    return false;
200254721Semaste}
201254721Semaste
202262528Semaste// FIXME: This has nothing to do with Posix, it is just a convenience function that calls a
203262528Semaste// function of the form "void * (*)(void)".  We should find a better place to put this.
204262528Semaste
205262528Semastebool
206262528Semastelldb_private::InferiorCall (Process *process,
207262528Semaste                            const Address *address,
208296417Sdim                            addr_t &returned_func,
209296417Sdim                            bool trap_exceptions)
210262528Semaste{
211309124Sdim    Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
212254721Semaste    if (thread == NULL || address == NULL)
213254721Semaste        return false;
214254721Semaste
215258884Semaste    EvaluateExpressionOptions options;
216258884Semaste    options.SetStopOthers(true);
217258884Semaste    options.SetUnwindOnError(true);
218258884Semaste    options.SetIgnoreBreakpoints(true);
219258884Semaste    options.SetTryAllThreads(true);
220258884Semaste    options.SetDebug (false);
221258884Semaste    options.SetTimeoutUsec(500000);
222296417Sdim    options.SetTrapExceptions(trap_exceptions);
223254721Semaste
224254721Semaste    ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
225296417Sdim    CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
226309124Sdim    lldb::ThreadPlanSP call_plan_sp(
227309124Sdim        new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type, llvm::ArrayRef<addr_t>(), options));
228254721Semaste    if (call_plan_sp)
229254721Semaste    {
230309124Sdim        DiagnosticManager diagnostics;
231254721Semaste
232309124Sdim        StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
233254721Semaste        if (frame)
234254721Semaste        {
235254721Semaste            ExecutionContext exe_ctx;
236254721Semaste            frame->CalculateExecutionContext (exe_ctx);
237309124Sdim            ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
238276479Sdim            if (result == eExpressionCompleted)
239254721Semaste            {
240254721Semaste                returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
241254721Semaste
242254721Semaste                if (process->GetAddressByteSize() == 4)
243254721Semaste                {
244254721Semaste                    if (returned_func == UINT32_MAX)
245254721Semaste                        return false;
246254721Semaste                }
247254721Semaste                else if (process->GetAddressByteSize() == 8)
248254721Semaste                {
249254721Semaste                    if (returned_func == UINT64_MAX)
250254721Semaste                        return false;
251254721Semaste                }
252254721Semaste                return true;
253254721Semaste            }
254254721Semaste        }
255254721Semaste    }
256254721Semaste
257254721Semaste    return false;
258254721Semaste}
259