IRExecutionUnit.h revision 779e6ac7d5622ad35f482633b1145c82dbc6c3ce
1a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown//===-- IRExecutionUnit.h ---------------------------------------*- C++ -*-===//
2a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown//
3a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown//                     The LLVM Compiler Infrastructure
4a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown//
5a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown// This file is distributed under the University of Illinois Open Source
6a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown// License. See LICENSE.TXT for details.
7a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown//
8a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown//===----------------------------------------------------------------------===//
9a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown
10a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#ifndef lldb_IRExecutionUnit_h_
11a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#define lldb_IRExecutionUnit_h_
12a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown
13a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown// C Includes
14a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown// C++ Includes
15a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#include <atomic>
16a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#include <string>
17a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#include <vector>
18a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#include <map>
19a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown
20a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown// Other libraries and framework includes
21f68200ab1a5c559866a87e51d0d52e3c74b02343Lorenzo Colitti#include "llvm/IR/Module.h"
22a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown
23a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown// Project includes
24a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#include "lldb/lldb-forward.h"
25#include "lldb/lldb-private.h"
26#include "lldb/Core/ClangForward.h"
27#include "lldb/Core/DataBufferHeap.h"
28#include "llvm/ExecutionEngine/JITMemoryManager.h"
29#include "lldb/Expression/ClangExpression.h"
30#include "lldb/Expression/ClangExpressionParser.h"
31#include "lldb/Expression/IRMemoryMap.h"
32#include "lldb/Host/Mutex.h"
33
34namespace llvm {
35
36class Module;
37class ExecutionEngine;
38
39}
40
41namespace lldb_private {
42
43class Error;
44
45//----------------------------------------------------------------------
46/// @class IRExecutionUnit IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
47/// @brief Contains the IR and, optionally, JIT-compiled code for a module.
48///
49/// This class encapsulates the compiled version of an expression, in IR
50/// form (for interpretation purposes) and in raw machine code form (for
51/// execution in the target).
52///
53/// This object wraps an IR module that comes from the expression parser,
54/// and knows how to use the JIT to make it into executable code.  It can
55/// then be used as input to the IR interpreter, or the address of the
56/// executable code can be passed to a thread plan to run in the target.
57///
58/// This class creates a subclass of LLVM's JITMemoryManager, because that is
59/// how the JIT emits code.  Because LLDB needs to move JIT-compiled code
60/// into the target process, the IRExecutionUnit knows how to copy the
61/// emitted code into the target process.
62//----------------------------------------------------------------------
63class IRExecutionUnit : public IRMemoryMap
64{
65public:
66    //------------------------------------------------------------------
67    /// Constructor
68    //------------------------------------------------------------------
69    IRExecutionUnit (std::unique_ptr<llvm::LLVMContext> &context_ap,
70                     std::unique_ptr<llvm::Module> &module_ap,
71                     ConstString &name,
72                     const lldb::TargetSP &target_sp,
73                     std::vector<std::string> &cpu_features);
74
75    //------------------------------------------------------------------
76    /// Destructor
77    //------------------------------------------------------------------
78    ~IRExecutionUnit();
79
80    llvm::Module *GetModule()
81    {
82        return m_module;
83    }
84
85    llvm::Function *GetFunction()
86    {
87        if (m_module)
88            return m_module->getFunction (m_name.AsCString());
89        else
90            return NULL;
91    }
92
93    void GetRunnableInfo(Error &error,
94                         lldb::addr_t &func_addr,
95                         lldb::addr_t &func_end);
96
97    //------------------------------------------------------------------
98    /// Accessors for IRForTarget and other clients that may want binary
99    /// data placed on their behalf.  The binary data is owned by the
100    /// IRExecutionUnit unless the client explicitly chooses to free it.
101    //------------------------------------------------------------------
102
103    lldb::addr_t WriteNow(const uint8_t *bytes,
104                          size_t size,
105                          Error &error);
106
107    void FreeNow(lldb::addr_t allocation);
108
109private:
110    //------------------------------------------------------------------
111    /// Look up the object in m_address_map that contains a given address,
112    /// find where it was copied to, and return the remote address at the
113    /// same offset into the copied entity
114    ///
115    /// @param[in] local_address
116    ///     The address in the debugger.
117    ///
118    /// @return
119    ///     The address in the target process.
120    //------------------------------------------------------------------
121    lldb::addr_t
122    GetRemoteAddressForLocal (lldb::addr_t local_address);
123
124    //------------------------------------------------------------------
125    /// Look up the object in m_address_map that contains a given address,
126    /// find where it was copied to, and return its address range in the
127    /// target process
128    ///
129    /// @param[in] local_address
130    ///     The address in the debugger.
131    ///
132    /// @return
133    ///     The range of the containing object in the target process.
134    //------------------------------------------------------------------
135    typedef std::pair <lldb::addr_t, uintptr_t> AddrRange;
136    AddrRange
137    GetRemoteRangeForLocal (lldb::addr_t local_address);
138
139    //------------------------------------------------------------------
140    /// Commit all allocations to the process and record where they were stored.
141    ///
142    /// @param[in] process
143    ///     The process to allocate memory in.
144    ///
145    /// @return
146    ///     True <=> all allocations were performed successfully.
147    ///     This method will attempt to free allocated memory if the
148    ///     operation fails.
149    //------------------------------------------------------------------
150    bool
151    CommitAllocations (lldb::ProcessSP &process_sp);
152
153    //------------------------------------------------------------------
154    /// Report all committed allocations to the execution engine.
155    ///
156    /// @param[in] engine
157    ///     The execution engine to notify.
158    //------------------------------------------------------------------
159    void
160    ReportAllocations (llvm::ExecutionEngine &engine);
161
162    //------------------------------------------------------------------
163    /// Write the contents of all allocations to the process.
164    ///
165    /// @param[in] local_address
166    ///     The process containing the allocations.
167    ///
168    /// @return
169    ///     True <=> all allocations were performed successfully.
170    //------------------------------------------------------------------
171    bool
172    WriteData (lldb::ProcessSP &process_sp);
173
174    Error
175    DisassembleFunction (Stream &stream,
176                         lldb::ProcessSP &process_sp);
177
178    class MemoryManager : public llvm::JITMemoryManager
179    {
180    public:
181        MemoryManager (IRExecutionUnit &parent);
182
183        //------------------------------------------------------------------
184        /// Passthrough interface stub
185        //------------------------------------------------------------------
186        virtual void setMemoryWritable ();
187
188        //------------------------------------------------------------------
189        /// Passthrough interface stub
190        //------------------------------------------------------------------
191        virtual void setMemoryExecutable ();
192
193        //------------------------------------------------------------------
194        /// Passthrough interface stub
195        //------------------------------------------------------------------
196        virtual void setPoisonMemory (bool poison)
197        {
198            m_default_mm_ap->setPoisonMemory (poison);
199        }
200
201        //------------------------------------------------------------------
202        /// Passthrough interface stub
203        //------------------------------------------------------------------
204        virtual void AllocateGOT()
205        {
206            m_default_mm_ap->AllocateGOT();
207        }
208
209        //------------------------------------------------------------------
210        /// Passthrough interface stub
211        //------------------------------------------------------------------
212        virtual uint8_t *getGOTBase() const
213        {
214            return m_default_mm_ap->getGOTBase();
215        }
216
217        //------------------------------------------------------------------
218        /// Passthrough interface stub
219        //------------------------------------------------------------------
220        virtual uint8_t *startFunctionBody(const llvm::Function *F,
221                                           uintptr_t &ActualSize);
222
223        //------------------------------------------------------------------
224        /// Allocate room for a dyld stub for a lazy-referenced function,
225        /// and add it to the m_stubs map
226        ///
227        /// @param[in] F
228        ///     The function being referenced.
229        ///
230        /// @param[in] StubSize
231        ///     The size of the stub.
232        ///
233        /// @param[in] Alignment
234        ///     The required alignment of the stub.
235        ///
236        /// @return
237        ///     Allocated space for the stub.
238        //------------------------------------------------------------------
239        virtual uint8_t *allocateStub(const llvm::GlobalValue* F,
240                                      unsigned StubSize,
241                                      unsigned Alignment);
242
243        //------------------------------------------------------------------
244        /// Complete the body of a function, and add it to the m_functions map
245        ///
246        /// @param[in] F
247        ///     The function being completed.
248        ///
249        /// @param[in] FunctionStart
250        ///     The first instruction of the function.
251        ///
252        /// @param[in] FunctionEnd
253        ///     The last byte of the last instruction of the function.
254        //------------------------------------------------------------------
255        virtual void endFunctionBody(const llvm::Function *F,
256                                     uint8_t *FunctionStart,
257                                     uint8_t *FunctionEnd);
258        //------------------------------------------------------------------
259        /// Allocate space for an unspecified purpose, and add it to the
260        /// m_spaceBlocks map
261        ///
262        /// @param[in] Size
263        ///     The size of the area.
264        ///
265        /// @param[in] Alignment
266        ///     The required alignment of the area.
267        ///
268        /// @return
269        ///     Allocated space.
270        //------------------------------------------------------------------
271        virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
272
273        //------------------------------------------------------------------
274        /// Allocate space for executable code, and add it to the
275        /// m_spaceBlocks map
276        ///
277        /// @param[in] Size
278        ///     The size of the area.
279        ///
280        /// @param[in] Alignment
281        ///     The required alignment of the area.
282        ///
283        /// @param[in] SectionID
284        ///     A unique identifier for the section.
285        ///
286        /// @return
287        ///     Allocated space.
288        //------------------------------------------------------------------
289        virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
290                                             unsigned SectionID);
291
292        //------------------------------------------------------------------
293        /// Allocate space for data, and add it to the m_spaceBlocks map
294        ///
295        /// @param[in] Size
296        ///     The size of the area.
297        ///
298        /// @param[in] Alignment
299        ///     The required alignment of the area.
300        ///
301        /// @param[in] SectionID
302        ///     A unique identifier for the section.
303        ///
304        /// @param[in] IsReadOnly
305        ///     Flag indicating the section is read-only.
306        ///
307        /// @return
308        ///     Allocated space.
309        //------------------------------------------------------------------
310        virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
311                                             unsigned SectionID, bool IsReadOnly);
312
313        //------------------------------------------------------------------
314        /// Allocate space for a global variable, and add it to the
315        /// m_spaceBlocks map
316        ///
317        /// @param[in] Size
318        ///     The size of the variable.
319        ///
320        /// @param[in] Alignment
321        ///     The required alignment of the variable.
322        ///
323        /// @return
324        ///     Allocated space for the global.
325        //------------------------------------------------------------------
326        virtual uint8_t *allocateGlobal(uintptr_t Size,
327                                        unsigned Alignment);
328
329        //------------------------------------------------------------------
330        /// Called when object loading is complete and section page
331        /// permissions can be applied. Currently unimplemented for LLDB.
332        ///
333        /// @param[out] ErrMsg
334        ///     The error that prevented the page protection from succeeding.
335        ///
336        /// @return
337        ///     True in case of failure, false in case of success.
338        //------------------------------------------------------------------
339        bool applyPermissions(std::string *ErrMsg) { return false; }
340
341        //------------------------------------------------------------------
342        /// Passthrough interface stub
343        //------------------------------------------------------------------
344        virtual void deallocateFunctionBody(void *Body);
345
346        //------------------------------------------------------------------
347        /// Passthrough interface stub
348        //------------------------------------------------------------------
349        virtual size_t GetDefaultCodeSlabSize() {
350            return m_default_mm_ap->GetDefaultCodeSlabSize();
351        }
352
353        //------------------------------------------------------------------
354        /// Passthrough interface stub
355        //------------------------------------------------------------------
356        virtual size_t GetDefaultDataSlabSize() {
357            return m_default_mm_ap->GetDefaultDataSlabSize();
358        }
359
360        virtual size_t GetDefaultStubSlabSize() {
361            return m_default_mm_ap->GetDefaultStubSlabSize();
362        }
363
364        //------------------------------------------------------------------
365        /// Passthrough interface stub
366        //------------------------------------------------------------------
367        virtual unsigned GetNumCodeSlabs() {
368            return m_default_mm_ap->GetNumCodeSlabs();
369        }
370
371        //------------------------------------------------------------------
372        /// Passthrough interface stub
373        //------------------------------------------------------------------
374        virtual unsigned GetNumDataSlabs() {
375            return m_default_mm_ap->GetNumDataSlabs();
376        }
377
378        //------------------------------------------------------------------
379        /// Passthrough interface stub
380        //------------------------------------------------------------------
381        virtual unsigned GetNumStubSlabs() {
382            return m_default_mm_ap->GetNumStubSlabs();
383        }
384
385        //------------------------------------------------------------------
386        /// Passthrough interface stub
387        //------------------------------------------------------------------
388        virtual void *getPointerToNamedFunction(const std::string &Name,
389                                                bool AbortOnFailure = true) {
390            return m_default_mm_ap->getPointerToNamedFunction(Name, AbortOnFailure);
391        }
392    private:
393        std::unique_ptr<JITMemoryManager>    m_default_mm_ap;    ///< The memory allocator to use in actually creating space.  All calls are passed through to it.
394        IRExecutionUnit                    &m_parent;           ///< The execution unit this is a proxy for.
395    };
396
397    //----------------------------------------------------------------------
398    /// @class JittedFunction IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
399    /// @brief Encapsulates a single function that has been generated by the JIT.
400    ///
401    /// Functions that have been generated by the JIT are first resident in the
402    /// local process, and then placed in the target process.  JittedFunction
403    /// represents a function possibly resident in both.
404    //----------------------------------------------------------------------
405    struct JittedFunction {
406        std::string m_name;             ///< The function's name
407        lldb::addr_t m_local_addr;      ///< The address of the function in LLDB's memory
408        lldb::addr_t m_remote_addr;     ///< The address of the function in the target's memory
409
410        //------------------------------------------------------------------
411        /// Constructor
412        ///
413        /// Initializes class variabes.
414        ///
415        /// @param[in] name
416        ///     The name of the function.
417        ///
418        /// @param[in] local_addr
419        ///     The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
420        ///     it is not present in LLDB's memory.
421        ///
422        /// @param[in] remote_addr
423        ///     The address of the function in the target, or LLDB_INVALID_ADDRESS
424        ///     if it is not present in the target's memory.
425        //------------------------------------------------------------------
426        JittedFunction (const char *name,
427                        lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
428                        lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
429            m_name (name),
430            m_local_addr (local_addr),
431            m_remote_addr (remote_addr)
432        {
433        }
434    };
435
436    static const unsigned eSectionIDInvalid = (unsigned)-1;
437
438    //----------------------------------------------------------------------
439    /// @class AllocationRecord IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
440    /// @brief Enacpsulates a single allocation request made by the JIT.
441    ///
442    /// Allocations made by the JIT are first queued up and then applied in
443    /// bulk to the underlying process.
444    //----------------------------------------------------------------------
445    struct AllocationRecord {
446        lldb::addr_t    m_process_address;
447        uintptr_t       m_host_address;
448        uint32_t        m_permissions;
449        size_t          m_size;
450        unsigned        m_alignment;
451        unsigned        m_section_id;
452
453        AllocationRecord (uintptr_t host_address,
454                          uint32_t permissions,
455                          size_t size,
456                          unsigned alignment,
457                          unsigned section_id = eSectionIDInvalid) :
458            m_process_address(LLDB_INVALID_ADDRESS),
459            m_host_address(host_address),
460            m_permissions(permissions),
461            m_size(size),
462            m_alignment(alignment),
463            m_section_id(section_id)
464        {
465        }
466
467        void dump (Log *log);
468    };
469
470    typedef std::vector<AllocationRecord>   RecordVector;
471    RecordVector                            m_records;
472
473    std::unique_ptr<llvm::LLVMContext>       m_context_ap;
474    std::unique_ptr<llvm::ExecutionEngine>   m_execution_engine_ap;
475    std::unique_ptr<llvm::Module>            m_module_ap;            ///< Holder for the module until it's been handed off
476    llvm::Module                           *m_module;               ///< Owned by the execution engine
477    std::vector<std::string>                m_cpu_features;
478    llvm::SmallVector<JittedFunction, 1>    m_jitted_functions;     ///< A vector of all functions that have been JITted into machine code
479    const ConstString                       m_name;
480
481    std::atomic<bool>                       m_did_jit;
482
483    lldb::addr_t                            m_function_load_addr;
484    lldb::addr_t                            m_function_end_load_addr;
485};
486
487} // namespace lldb_private
488
489#endif  // lldb_IRExecutionUnit_h_
490