• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 LLDB_EXPRESSION_IREXECUTIONUNIT_H
10 #define LLDB_EXPRESSION_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 
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 
GetFunctionName()69   ConstString GetFunctionName() { return m_name; }
70 
GetModule()71   llvm::Module *GetModule() { return m_module; }
72 
GetFunction()73   llvm::Function *GetFunction() {
74     return ((m_module != nullptr) ? m_module->getFunction(m_name.GetStringRef())
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)
m_nameJittedEntity138         : 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)
JittedEntityJittedFunction146         : 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)
JittedEntityJittedGlobalVariable153         : JittedEntity(name, local_addr, remote_addr) {}
154   };
155 
GetJittedFunctions()156   const std::vector<JittedFunction> &GetJittedFunctions() {
157     return m_jitted_functions;
158   }
159 
GetJittedGlobalVariables()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   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.
finalizeMemory(std::string * ErrMsg)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.
registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)303     void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
304                           size_t Size) override {}
deregisterEHFrames()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 
AllocationRecordAllocationRecord352     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 // LLDB_EXPRESSION_IREXECUTIONUNIT_H
410