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