LLDB  mainline
IRExecutionUnit.h
Go to the documentation of this file.
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 
21 #include "lldb/Symbol/ObjectFile.h"
24 #include "lldb/lldb-forward.h"
25 #include "lldb/lldb-private.h"
26 
27 namespace llvm {
28 
29 class Module;
30 class ExecutionEngine;
31 class ObjectCache;
32 
33 } // namespace llvm
34 
35 namespace lldb_private {
36 
37 class 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.
56 class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>,
57  public IRMemoryMap,
58  public ObjectFileJITDelegate {
59 public:
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);
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
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 
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 
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 
164 private:
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  /// Look up the object in m_address_map that contains a given address, find
177  /// where it was copied to, and return its address range in the target
178  /// process
179  ///
180  /// \param[in] local_address
181  /// The address in the debugger.
182  ///
183  /// \return
184  /// The range of the containing object in the target process.
185  typedef std::pair<lldb::addr_t, uintptr_t> AddrRange;
186  AddrRange GetRemoteRangeForLocal(lldb::addr_t local_address);
187 
188  /// Commit all allocations to the process and record where they were stored.
189  ///
190  /// \param[in] process
191  /// The process to allocate memory in.
192  ///
193  /// \return
194  /// True <=> all allocations were performed successfully.
195  /// This method will attempt to free allocated memory if the
196  /// operation fails.
197  bool CommitAllocations(lldb::ProcessSP &process_sp);
198 
199  /// Report all committed allocations to the execution engine.
200  ///
201  /// \param[in] engine
202  /// The execution engine to notify.
203  void ReportAllocations(llvm::ExecutionEngine &engine);
204 
205  /// Write the contents of all allocations to the process.
206  ///
207  /// \param[in] local_address
208  /// The process containing the allocations.
209  ///
210  /// \return
211  /// True <=> all allocations were performed successfully.
212  bool WriteData(lldb::ProcessSP &process_sp);
213 
214  Status DisassembleFunction(Stream &stream, lldb::ProcessSP &process_sp);
215 
216  struct SearchSpec;
217 
218  void CollectCandidateCNames(std::vector<SearchSpec> &C_specs,
219  ConstString name);
220 
221  void CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs,
222  const std::vector<SearchSpec> &C_specs,
223  const SymbolContext &sc);
224 
225  void CollectFallbackNames(std::vector<SearchSpec> &fallback_specs,
226  const std::vector<SearchSpec> &C_specs);
227 
228  lldb::addr_t FindInSymbols(const std::vector<SearchSpec> &specs,
229  const lldb_private::SymbolContext &sc);
230 
231  lldb::addr_t FindInRuntimes(const std::vector<SearchSpec> &specs,
232  const lldb_private::SymbolContext &sc);
233 
234  lldb::addr_t FindInUserDefinedSymbols(const std::vector<SearchSpec> &specs,
235  const lldb_private::SymbolContext &sc);
236 
237  void ReportSymbolLookupError(ConstString name);
238 
239  class MemoryManager : public llvm::SectionMemoryManager {
240  public:
241  MemoryManager(IRExecutionUnit &parent);
242 
243  ~MemoryManager() override;
244 
245  /// Allocate space for executable code, and add it to the m_spaceBlocks
246  /// map
247  ///
248  /// \param[in] Size
249  /// The size of the area.
250  ///
251  /// \param[in] Alignment
252  /// The required alignment of the area.
253  ///
254  /// \param[in] SectionID
255  /// A unique identifier for the section.
256  ///
257  /// \return
258  /// Allocated space.
259  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
260  unsigned SectionID,
261  llvm::StringRef SectionName) override;
262 
263  /// Allocate space for data, and add it to the m_spaceBlocks map
264  ///
265  /// \param[in] Size
266  /// The size of the area.
267  ///
268  /// \param[in] Alignment
269  /// The required alignment of the area.
270  ///
271  /// \param[in] SectionID
272  /// A unique identifier for the section.
273  ///
274  /// \param[in] IsReadOnly
275  /// Flag indicating the section is read-only.
276  ///
277  /// \return
278  /// Allocated space.
279  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
280  unsigned SectionID,
281  llvm::StringRef SectionName,
282  bool IsReadOnly) override;
283 
284  /// Called when object loading is complete and section page permissions
285  /// can be applied. Currently unimplemented for LLDB.
286  ///
287  /// \param[out] ErrMsg
288  /// The error that prevented the page protection from succeeding.
289  ///
290  /// \return
291  /// True in case of failure, false in case of success.
292  bool finalizeMemory(std::string *ErrMsg) override {
293  // TODO: Ensure that the instruction cache is flushed because
294  // relocations are updated by dy-load. See:
295  // sys::Memory::InvalidateInstructionCache
296  // llvm::SectionMemoryManager
297  return false;
298  }
299 
300  void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
301  size_t Size) override {}
302 
303  uint64_t getSymbolAddress(const std::string &Name) override;
304 
305  void *getPointerToNamedFunction(const std::string &Name,
306  bool AbortOnFailure = true) override;
307 
308  private:
309  std::unique_ptr<SectionMemoryManager> m_default_mm_up; ///< The memory
310  /// allocator to use
311  /// in actually
312  /// creating space.
313  /// All calls are
314  /// passed through to
315  /// it.
316  IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
317  };
318 
319  static const unsigned eSectionIDInvalid = (unsigned)-1;
320 
321  /// \class AllocationRecord IRExecutionUnit.h
322  /// "lldb/Expression/IRExecutionUnit.h" Encapsulates a single allocation
323  /// request made by the JIT.
324  ///
325  /// Allocations made by the JIT are first queued up and then applied in bulk
326  /// to the underlying process.
327  enum class AllocationKind { Stub, Code, Data, Global, Bytes };
328 
329  static lldb::SectionType
330  GetSectionTypeFromSectionName(const llvm::StringRef &name,
331  AllocationKind alloc_kind);
332 
333  struct AllocationRecord {
334  std::string m_name;
335  lldb::addr_t m_process_address;
336  uintptr_t m_host_address;
337  uint32_t m_permissions;
338  lldb::SectionType m_sect_type;
339  size_t m_size;
340  unsigned m_alignment;
341  unsigned m_section_id;
342 
343  AllocationRecord(uintptr_t host_address, uint32_t permissions,
344  lldb::SectionType sect_type, size_t size,
345  unsigned alignment, unsigned section_id, const char *name)
346  : m_name(), m_process_address(LLDB_INVALID_ADDRESS),
347  m_host_address(host_address), m_permissions(permissions),
348  m_sect_type(sect_type), m_size(size), m_alignment(alignment),
349  m_section_id(section_id) {
350  if (name && name[0])
351  m_name = name;
352  }
353 
354  void dump(Log *log);
355  };
356 
357  bool CommitOneAllocation(lldb::ProcessSP &process_sp, Status &error,
358  AllocationRecord &record);
359 
360  typedef std::vector<AllocationRecord> RecordVector;
361  RecordVector m_records;
362 
363  std::unique_ptr<llvm::LLVMContext> m_context_up;
364  std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_up;
365  std::unique_ptr<llvm::ObjectCache> m_object_cache_up;
366  std::unique_ptr<llvm::Module>
367  m_module_up; ///< Holder for the module until it's been handed off
368  llvm::Module *m_module; ///< Owned by the execution engine
369  std::vector<std::string> m_cpu_features;
370  std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions
371  ///that have been JITted into
372  ///machine code
373  std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of
374  ///all functions
375  ///that have been
376  ///JITted into
377  ///machine code
378  const ConstString m_name;
379  SymbolContext m_sym_ctx; ///< Used for symbol lookups
380  std::vector<ConstString> m_failed_lookups;
381 
382  std::atomic<bool> m_did_jit;
383 
384  lldb::addr_t m_function_load_addr;
385  lldb::addr_t m_function_end_load_addr;
386 
387  bool m_strip_underscore = true; ///< True for platforms where global symbols
388  /// have a _ prefix
389  bool m_reported_allocations; ///< True after allocations have been reported.
390  ///It is possible that
391  ///< sections will be allocated when this is true, in which case they weren't
392  ///< depended on by any function. (Top-level code defining a variable, but
393  ///< defining no functions using that variable, would do this.) If this
394  ///< is true, any allocations need to be committed immediately -- no
395  ///< opportunity for relocation.
396 };
397 
398 } // namespace lldb_private
399 
400 #endif // liblldb_IRExecutionUnit_h_
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
Definition: Debugger.h:71
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
ConstString m_name
The function&#39;s name.
lldb::addr_t m_remote_addr
The address of the function in the target&#39;s memory.
An architecture specification class.
Definition: ArchSpec.h:32
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:58
JittedEntity(const char *name, lldb::addr_t local_addr=LLDB_INVALID_ADDRESS, lldb::addr_t remote_addr=LLDB_INVALID_ADDRESS)
Constructor.
"lldb/Expression/IRExecutionUnit.h" Contains the IR and, optionally, JIT- compiled code for a module...
const std::vector< JittedFunction > & GetJittedFunctions()
llvm::Function * GetFunction()
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
"lldb/Expression/IRExecutionUnit.h" Encapsulates a single function that has been generated by the JIT...
Encapsulates memory that may exist in the process but must also be available in the host process...
Definition: IRMemoryMap.h:34
lldb::addr_t m_local_addr
The address of the function in LLDB&#39;s memory.
const std::vector< JittedGlobalVariable > & GetJittedGlobalVariables()
uint64_t addr_t
Definition: lldb-types.h:83
A uniqued constant string class.
Definition: ConstString.h:38
JittedFunction(const char *name, bool external, lldb::addr_t local_addr=LLDB_INVALID_ADDRESS, lldb::addr_t remote_addr=LLDB_INVALID_ADDRESS)
JittedGlobalVariable(const char *name, lldb::addr_t local_addr=LLDB_INVALID_ADDRESS, lldb::addr_t remote_addr=LLDB_INVALID_ADDRESS)
An error handling class.
Definition: Status.h:44