IRExecutionUnit.h revision 360784
1//===-- IRExecutionUnit.h ---------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef liblldb_IRExecutionUnit_h_
10#define liblldb_IRExecutionUnit_h_
11
12#include <atomic>
13#include <memory>
14#include <string>
15#include <vector>
16
17#include "llvm/ExecutionEngine/SectionMemoryManager.h"
18#include "llvm/IR/Module.h"
19
20#include "lldb/Expression/IRMemoryMap.h"
21#include "lldb/Symbol/ObjectFile.h"
22#include "lldb/Symbol/SymbolContext.h"
23#include "lldb/Utility/DataBufferHeap.h"
24#include "lldb/lldb-forward.h"
25#include "lldb/lldb-private.h"
26
27namespace llvm {
28
29class Module;
30class ExecutionEngine;
31class ObjectCache;
32
33} // namespace llvm
34
35namespace lldb_private {
36
37class Status;
38
39/// \class IRExecutionUnit IRExecutionUnit.h
40/// "lldb/Expression/IRExecutionUnit.h" Contains the IR and, optionally, JIT-
41/// compiled code for a module.
42///
43/// This class encapsulates the compiled version of an expression, in IR form
44/// (for interpretation purposes) and in raw machine code form (for execution
45/// in the target).
46///
47/// This object wraps an IR module that comes from the expression parser, and
48/// knows how to use the JIT to make it into executable code.  It can then be
49/// used as input to the IR interpreter, or the address of the executable code
50/// can be passed to a thread plan to run in the target.
51///
52/// This class creates a subclass of LLVM's SectionMemoryManager, because that
53/// is how the JIT emits code.  Because LLDB needs to move JIT-compiled code
54/// into the target process, the IRExecutionUnit knows how to copy the emitted
55/// code into the target process.
56class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>,
57                        public IRMemoryMap,
58                        public ObjectFileJITDelegate {
59public:
60  /// Constructor
61  IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_up,
62                  std::unique_ptr<llvm::Module> &module_up, ConstString &name,
63                  const lldb::TargetSP &target_sp, const SymbolContext &sym_ctx,
64                  std::vector<std::string> &cpu_features);
65
66  /// Destructor
67  ~IRExecutionUnit() override;
68
69  ConstString GetFunctionName() { return m_name; }
70
71  llvm::Module *GetModule() { return m_module; }
72
73  llvm::Function *GetFunction() {
74    return ((m_module != nullptr) ? m_module->getFunction(m_name.AsCString())
75                                  : nullptr);
76  }
77
78  void GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
79                       lldb::addr_t &func_end);
80
81  /// Accessors for IRForTarget and other clients that may want binary data
82  /// placed on their behalf.  The binary data is owned by the IRExecutionUnit
83  /// unless the client explicitly chooses to free it.
84
85  lldb::addr_t WriteNow(const uint8_t *bytes, size_t size, Status &error);
86
87  void FreeNow(lldb::addr_t allocation);
88
89  /// ObjectFileJITDelegate overrides
90  lldb::ByteOrder GetByteOrder() const override;
91
92  uint32_t GetAddressByteSize() const override;
93
94  void PopulateSymtab(lldb_private::ObjectFile *obj_file,
95                      lldb_private::Symtab &symtab) override;
96
97  void PopulateSectionList(lldb_private::ObjectFile *obj_file,
98                           lldb_private::SectionList &section_list) override;
99
100  ArchSpec GetArchitecture() override;
101
102  lldb::ModuleSP GetJITModule();
103
104  lldb::addr_t FindSymbol(ConstString name, bool &missing_weak);
105
106  void GetStaticInitializers(std::vector<lldb::addr_t> &static_initializers);
107
108  /// \class JittedFunction IRExecutionUnit.h
109  /// "lldb/Expression/IRExecutionUnit.h"
110  /// Encapsulates a single function that has been generated by the JIT.
111  ///
112  /// Functions that have been generated by the JIT are first resident in the
113  /// local process, and then placed in the target process.  JittedFunction
114  /// represents a function possibly resident in both.
115  struct JittedEntity {
116    ConstString m_name;        ///< The function's name
117    lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory
118    lldb::addr_t
119        m_remote_addr; ///< The address of the function in the target's memory
120
121    /// Constructor
122    ///
123    /// Initializes class variabes.
124    ///
125    /// \param[in] name
126    ///     The name of the function.
127    ///
128    /// \param[in] local_addr
129    ///     The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
130    ///     it is not present in LLDB's memory.
131    ///
132    /// \param[in] remote_addr
133    ///     The address of the function in the target, or LLDB_INVALID_ADDRESS
134    ///     if it is not present in the target's memory.
135    JittedEntity(const char *name,
136                 lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
137                 lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
138        : m_name(name), m_local_addr(local_addr), m_remote_addr(remote_addr) {}
139  };
140
141  struct JittedFunction : JittedEntity {
142    bool m_external;
143    JittedFunction(const char *name, bool external,
144                   lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
145                   lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
146        : JittedEntity(name, local_addr, remote_addr), m_external(external) {}
147  };
148
149  struct JittedGlobalVariable : JittedEntity {
150    JittedGlobalVariable(const char *name,
151                         lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
152                         lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
153        : JittedEntity(name, local_addr, remote_addr) {}
154  };
155
156  const std::vector<JittedFunction> &GetJittedFunctions() {
157    return m_jitted_functions;
158  }
159
160  const std::vector<JittedGlobalVariable> &GetJittedGlobalVariables() {
161    return m_jitted_global_variables;
162  }
163
164private:
165  /// Look up the object in m_address_map that contains a given address, find
166  /// where it was copied to, and return the remote address at the same offset
167  /// into the copied entity
168  ///
169  /// \param[in] local_address
170  ///     The address in the debugger.
171  ///
172  /// \return
173  ///     The address in the target process.
174  lldb::addr_t GetRemoteAddressForLocal(lldb::addr_t local_address);
175
176  typedef std::pair<lldb::addr_t, uintptr_t> AddrRange;
177
178  /// Look up the object in m_address_map that contains a given address, find
179  /// where it was copied to, and return its address range in the target
180  /// process
181  ///
182  /// \param[in] local_address
183  ///     The address in the debugger.
184  ///
185  /// \return
186  ///     The range of the containing object in the target process.
187  AddrRange GetRemoteRangeForLocal(lldb::addr_t local_address);
188
189  /// Commit all allocations to the process and record where they were stored.
190  ///
191  /// \param[in] process_sp
192  ///     The process to allocate memory in.
193  ///
194  /// \return
195  ///     True <=> all allocations were performed successfully.
196  ///     This method will attempt to free allocated memory if the
197  ///     operation fails.
198  bool CommitAllocations(lldb::ProcessSP &process_sp);
199
200  /// Report all committed allocations to the execution engine.
201  ///
202  /// \param[in] engine
203  ///     The execution engine to notify.
204  void ReportAllocations(llvm::ExecutionEngine &engine);
205
206  /// Write the contents of all allocations to the process.
207  ///
208  /// \param[in] process_sp
209  ///     The process containing the allocations.
210  ///
211  /// \return
212  ///     True <=> all allocations were performed successfully.
213  bool WriteData(lldb::ProcessSP &process_sp);
214
215  Status DisassembleFunction(Stream &stream, lldb::ProcessSP &process_sp);
216
217  struct SearchSpec;
218
219  void CollectCandidateCNames(std::vector<SearchSpec> &C_specs,
220                              ConstString name);
221
222  void CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs,
223                                      const std::vector<SearchSpec> &C_specs,
224                                      const SymbolContext &sc);
225
226  void CollectFallbackNames(std::vector<SearchSpec> &fallback_specs,
227                            const std::vector<SearchSpec> &C_specs);
228
229  lldb::addr_t FindInSymbols(const std::vector<SearchSpec> &specs,
230                             const lldb_private::SymbolContext &sc,
231                             bool &symbol_was_missing_weak);
232
233  lldb::addr_t FindInRuntimes(const std::vector<SearchSpec> &specs,
234                              const lldb_private::SymbolContext &sc);
235
236  lldb::addr_t FindInUserDefinedSymbols(const std::vector<SearchSpec> &specs,
237                                        const lldb_private::SymbolContext &sc);
238
239  void ReportSymbolLookupError(ConstString name);
240
241  class MemoryManager : public llvm::SectionMemoryManager {
242  public:
243    MemoryManager(IRExecutionUnit &parent);
244
245    ~MemoryManager() override;
246
247    /// Allocate space for executable code, and add it to the m_spaceBlocks
248    /// map
249    ///
250    /// \param[in] Size
251    ///     The size of the area.
252    ///
253    /// \param[in] Alignment
254    ///     The required alignment of the area.
255    ///
256    /// \param[in] SectionID
257    ///     A unique identifier for the section.
258    ///
259    /// \return
260    ///     Allocated space.
261    uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
262                                 unsigned SectionID,
263                                 llvm::StringRef SectionName) override;
264
265    /// Allocate space for data, and add it to the m_spaceBlocks map
266    ///
267    /// \param[in] Size
268    ///     The size of the area.
269    ///
270    /// \param[in] Alignment
271    ///     The required alignment of the area.
272    ///
273    /// \param[in] SectionID
274    ///     A unique identifier for the section.
275    ///
276    /// \param[in] IsReadOnly
277    ///     Flag indicating the section is read-only.
278    ///
279    /// \return
280    ///     Allocated space.
281    uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
282                                 unsigned SectionID,
283                                 llvm::StringRef SectionName,
284                                 bool IsReadOnly) override;
285
286    /// Called when object loading is complete and section page permissions
287    /// can be applied. Currently unimplemented for LLDB.
288    ///
289    /// \param[out] ErrMsg
290    ///     The error that prevented the page protection from succeeding.
291    ///
292    /// \return
293    ///     True in case of failure, false in case of success.
294    bool finalizeMemory(std::string *ErrMsg) override {
295      // TODO: Ensure that the instruction cache is flushed because
296      // relocations are updated by dy-load.  See:
297      //   sys::Memory::InvalidateInstructionCache
298      //   llvm::SectionMemoryManager
299      return false;
300    }
301
302    // Ignore any EHFrame registration.
303    void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
304                          size_t Size) override {}
305    void deregisterEHFrames() override {}
306
307    uint64_t getSymbolAddress(const std::string &Name) override;
308
309    // Find the address of the symbol Name.  If Name is a missing weak symbol
310    // then missing_weak will be true.
311    uint64_t GetSymbolAddressAndPresence(const std::string &Name,
312                                         bool &missing_weak);
313
314    llvm::JITSymbol findSymbol(const std::string &Name) override;
315
316    void *getPointerToNamedFunction(const std::string &Name,
317                                    bool AbortOnFailure = true) override;
318
319  private:
320    std::unique_ptr<SectionMemoryManager> m_default_mm_up; ///< The memory
321                                                           /// allocator to use
322                                                           /// in actually
323                                                           /// creating space.
324                                                           /// All calls are
325                                                           /// passed through to
326                                                           /// it.
327    IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
328  };
329
330  static const unsigned eSectionIDInvalid = (unsigned)-1;
331
332  enum class AllocationKind { Stub, Code, Data, Global, Bytes };
333
334  static lldb::SectionType
335  GetSectionTypeFromSectionName(const llvm::StringRef &name,
336                                AllocationKind alloc_kind);
337
338  /// Encapsulates a single allocation request made by the JIT.
339  ///
340  /// Allocations made by the JIT are first queued up and then applied in bulk
341  /// to the underlying process.
342  struct AllocationRecord {
343    std::string m_name;
344    lldb::addr_t m_process_address;
345    uintptr_t m_host_address;
346    uint32_t m_permissions;
347    lldb::SectionType m_sect_type;
348    size_t m_size;
349    unsigned m_alignment;
350    unsigned m_section_id;
351
352    AllocationRecord(uintptr_t host_address, uint32_t permissions,
353                     lldb::SectionType sect_type, size_t size,
354                     unsigned alignment, unsigned section_id, const char *name)
355        : m_name(), m_process_address(LLDB_INVALID_ADDRESS),
356          m_host_address(host_address), m_permissions(permissions),
357          m_sect_type(sect_type), m_size(size), m_alignment(alignment),
358          m_section_id(section_id) {
359      if (name && name[0])
360        m_name = name;
361    }
362
363    void dump(Log *log);
364  };
365
366  bool CommitOneAllocation(lldb::ProcessSP &process_sp, Status &error,
367                           AllocationRecord &record);
368
369  typedef std::vector<AllocationRecord> RecordVector;
370  RecordVector m_records;
371
372  std::unique_ptr<llvm::LLVMContext> m_context_up;
373  std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_up;
374  std::unique_ptr<llvm::ObjectCache> m_object_cache_up;
375  std::unique_ptr<llvm::Module>
376      m_module_up;        ///< Holder for the module until it's been handed off
377  llvm::Module *m_module; ///< Owned by the execution engine
378  std::vector<std::string> m_cpu_features;
379  std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions
380                                                  ///that have been JITted into
381                                                  ///machine code
382  std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of
383                                                               ///all functions
384                                                               ///that have been
385                                                               ///JITted into
386                                                               ///machine code
387  const ConstString m_name;
388  SymbolContext m_sym_ctx; ///< Used for symbol lookups
389  std::vector<ConstString> m_failed_lookups;
390
391  std::atomic<bool> m_did_jit;
392
393  lldb::addr_t m_function_load_addr;
394  lldb::addr_t m_function_end_load_addr;
395
396  bool m_strip_underscore = true; ///< True for platforms where global symbols
397                                  ///  have a _ prefix
398  bool m_reported_allocations; ///< True after allocations have been reported.
399                               ///It is possible that
400  ///< sections will be allocated when this is true, in which case they weren't
401  ///< depended on by any function.  (Top-level code defining a variable, but
402  ///< defining no functions using that variable, would do this.)  If this
403  ///< is true, any allocations need to be committed immediately -- no
404  ///< opportunity for relocation.
405};
406
407} // namespace lldb_private
408
409#endif // liblldb_IRExecutionUnit_h_
410