Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:47

0001 //===-- IRExecutionUnit.h ---------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_EXPRESSION_IREXECUTIONUNIT_H
0010 #define LLDB_EXPRESSION_IREXECUTIONUNIT_H
0011 
0012 #include <atomic>
0013 #include <memory>
0014 #include <string>
0015 #include <vector>
0016 
0017 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
0018 #include "llvm/IR/Module.h"
0019 
0020 #include "lldb/Expression/IRMemoryMap.h"
0021 #include "lldb/Expression/ObjectFileJIT.h"
0022 #include "lldb/Symbol/SymbolContext.h"
0023 #include "lldb/Utility/DataBufferHeap.h"
0024 #include "lldb/lldb-forward.h"
0025 #include "lldb/lldb-private.h"
0026 
0027 namespace llvm {
0028 
0029 class Module;
0030 class ExecutionEngine;
0031 class ObjectCache;
0032 
0033 } // namespace llvm
0034 
0035 namespace lldb_private {
0036 
0037 class Status;
0038 
0039 /// \class IRExecutionUnit IRExecutionUnit.h
0040 /// "lldb/Expression/IRExecutionUnit.h" Contains the IR and, optionally, JIT-
0041 /// compiled code for a module.
0042 ///
0043 /// This class encapsulates the compiled version of an expression, in IR form
0044 /// (for interpretation purposes) and in raw machine code form (for execution
0045 /// in the target).
0046 ///
0047 /// This object wraps an IR module that comes from the expression parser, and
0048 /// knows how to use the JIT to make it into executable code.  It can then be
0049 /// used as input to the IR interpreter, or the address of the executable code
0050 /// can be passed to a thread plan to run in the target.
0051 ///
0052 /// This class creates a subclass of LLVM's SectionMemoryManager, because that
0053 /// is how the JIT emits code.  Because LLDB needs to move JIT-compiled code
0054 /// into the target process, the IRExecutionUnit knows how to copy the emitted
0055 /// code into the target process.
0056 class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>,
0057                         public IRMemoryMap,
0058                         public ObjectFileJITDelegate {
0059 public:
0060   /// Constructor
0061   IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_up,
0062                   std::unique_ptr<llvm::Module> &module_up, ConstString &name,
0063                   const lldb::TargetSP &target_sp, const SymbolContext &sym_ctx,
0064                   std::vector<std::string> &cpu_features);
0065 
0066   /// Destructor
0067   ~IRExecutionUnit() override;
0068 
0069   ConstString GetFunctionName() { return m_name; }
0070 
0071   llvm::Module *GetModule() { return m_module; }
0072 
0073   llvm::Function *GetFunction() {
0074     return ((m_module != nullptr) ? m_module->getFunction(m_name.GetStringRef())
0075                                   : nullptr);
0076   }
0077 
0078   void GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
0079                        lldb::addr_t &func_end);
0080 
0081   /// Accessors for IRForTarget and other clients that may want binary data
0082   /// placed on their behalf.  The binary data is owned by the IRExecutionUnit
0083   /// unless the client explicitly chooses to free it.
0084 
0085   lldb::addr_t WriteNow(const uint8_t *bytes, size_t size, Status &error);
0086 
0087   void FreeNow(lldb::addr_t allocation);
0088 
0089   /// ObjectFileJITDelegate overrides
0090   lldb::ByteOrder GetByteOrder() const override;
0091 
0092   uint32_t GetAddressByteSize() const override;
0093 
0094   void PopulateSymtab(lldb_private::ObjectFile *obj_file,
0095                       lldb_private::Symtab &symtab) override;
0096 
0097   void PopulateSectionList(lldb_private::ObjectFile *obj_file,
0098                            lldb_private::SectionList &section_list) override;
0099 
0100   ArchSpec GetArchitecture() override;
0101 
0102   lldb::ModuleSP GetJITModule();
0103 
0104   lldb::addr_t FindSymbol(ConstString name, bool &missing_weak);
0105 
0106   void GetStaticInitializers(std::vector<lldb::addr_t> &static_initializers);
0107 
0108   /// \class JittedFunction IRExecutionUnit.h
0109   /// "lldb/Expression/IRExecutionUnit.h"
0110   /// Encapsulates a single function that has been generated by the JIT.
0111   ///
0112   /// Functions that have been generated by the JIT are first resident in the
0113   /// local process, and then placed in the target process.  JittedFunction
0114   /// represents a function possibly resident in both.
0115   struct JittedEntity {
0116     ConstString m_name;        ///< The function's name
0117     lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory
0118     lldb::addr_t
0119         m_remote_addr; ///< The address of the function in the target's memory
0120 
0121     /// Constructor
0122     ///
0123     /// Initializes class variabes.
0124     ///
0125     /// \param[in] name
0126     ///     The name of the function.
0127     ///
0128     /// \param[in] local_addr
0129     ///     The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
0130     ///     it is not present in LLDB's memory.
0131     ///
0132     /// \param[in] remote_addr
0133     ///     The address of the function in the target, or LLDB_INVALID_ADDRESS
0134     ///     if it is not present in the target's memory.
0135     JittedEntity(const char *name,
0136                  lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
0137                  lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
0138         : m_name(name), m_local_addr(local_addr), m_remote_addr(remote_addr) {}
0139   };
0140 
0141   struct JittedFunction : JittedEntity {
0142     bool m_external;
0143     JittedFunction(const char *name, bool external,
0144                    lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
0145                    lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
0146         : JittedEntity(name, local_addr, remote_addr), m_external(external) {}
0147   };
0148 
0149   struct JittedGlobalVariable : JittedEntity {
0150     JittedGlobalVariable(const char *name,
0151                          lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
0152                          lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
0153         : JittedEntity(name, local_addr, remote_addr) {}
0154   };
0155 
0156   const std::vector<JittedFunction> &GetJittedFunctions() {
0157     return m_jitted_functions;
0158   }
0159 
0160   const std::vector<JittedGlobalVariable> &GetJittedGlobalVariables() {
0161     return m_jitted_global_variables;
0162   }
0163 
0164 private:
0165   /// Look up the object in m_address_map that contains a given address, find
0166   /// where it was copied to, and return the remote address at the same offset
0167   /// into the copied entity
0168   ///
0169   /// \param[in] local_address
0170   ///     The address in the debugger.
0171   ///
0172   /// \return
0173   ///     The address in the target process.
0174   lldb::addr_t GetRemoteAddressForLocal(lldb::addr_t local_address);
0175 
0176   typedef std::pair<lldb::addr_t, uintptr_t> AddrRange;
0177 
0178   /// Look up the object in m_address_map that contains a given address, find
0179   /// where it was copied to, and return its address range in the target
0180   /// process
0181   ///
0182   /// \param[in] local_address
0183   ///     The address in the debugger.
0184   ///
0185   /// \return
0186   ///     The range of the containing object in the target process.
0187   AddrRange GetRemoteRangeForLocal(lldb::addr_t local_address);
0188 
0189   /// Commit all allocations to the process and record where they were stored.
0190   ///
0191   /// \param[in] process_sp
0192   ///     The process to allocate memory in.
0193   ///
0194   /// \return
0195   ///     True <=> all allocations were performed successfully.
0196   ///     This method will attempt to free allocated memory if the
0197   ///     operation fails.
0198   bool CommitAllocations(lldb::ProcessSP &process_sp);
0199 
0200   /// Report all committed allocations to the execution engine.
0201   ///
0202   /// \param[in] engine
0203   ///     The execution engine to notify.
0204   void ReportAllocations(llvm::ExecutionEngine &engine);
0205 
0206   /// Write the contents of all allocations to the process.
0207   ///
0208   /// \param[in] process_sp
0209   ///     The process containing the allocations.
0210   ///
0211   /// \return
0212   ///     True <=> all allocations were performed successfully.
0213   bool WriteData(lldb::ProcessSP &process_sp);
0214 
0215   Status DisassembleFunction(Stream &stream, lldb::ProcessSP &process_sp);
0216 
0217   void CollectCandidateCNames(std::vector<ConstString> &C_names,
0218                               ConstString name);
0219 
0220   void CollectCandidateCPlusPlusNames(std::vector<ConstString> &CPP_names,
0221                                       const std::vector<ConstString> &C_names,
0222                                       const SymbolContext &sc);
0223 
0224   lldb::addr_t FindInSymbols(const std::vector<ConstString> &names,
0225                              const lldb_private::SymbolContext &sc,
0226                              bool &symbol_was_missing_weak);
0227 
0228   lldb::addr_t FindInRuntimes(const std::vector<ConstString> &names,
0229                               const lldb_private::SymbolContext &sc);
0230 
0231   lldb::addr_t FindInUserDefinedSymbols(const std::vector<ConstString> &names,
0232                                         const lldb_private::SymbolContext &sc);
0233 
0234   void ReportSymbolLookupError(ConstString name);
0235 
0236   class MemoryManager : public llvm::SectionMemoryManager {
0237   public:
0238     MemoryManager(IRExecutionUnit &parent);
0239 
0240     ~MemoryManager() override;
0241 
0242     /// Allocate space for executable code, and add it to the m_spaceBlocks
0243     /// map
0244     ///
0245     /// \param[in] Size
0246     ///     The size of the area.
0247     ///
0248     /// \param[in] Alignment
0249     ///     The required alignment of the area.
0250     ///
0251     /// \param[in] SectionID
0252     ///     A unique identifier for the section.
0253     ///
0254     /// \return
0255     ///     Allocated space.
0256     uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
0257                                  unsigned SectionID,
0258                                  llvm::StringRef SectionName) override;
0259 
0260     /// Allocate space for data, and add it to the m_spaceBlocks map
0261     ///
0262     /// \param[in] Size
0263     ///     The size of the area.
0264     ///
0265     /// \param[in] Alignment
0266     ///     The required alignment of the area.
0267     ///
0268     /// \param[in] SectionID
0269     ///     A unique identifier for the section.
0270     ///
0271     /// \param[in] IsReadOnly
0272     ///     Flag indicating the section is read-only.
0273     ///
0274     /// \return
0275     ///     Allocated space.
0276     uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
0277                                  unsigned SectionID,
0278                                  llvm::StringRef SectionName,
0279                                  bool IsReadOnly) override;
0280 
0281     /// Called when object loading is complete and section page permissions
0282     /// can be applied. Currently unimplemented for LLDB.
0283     ///
0284     /// \param[out] ErrMsg
0285     ///     The error that prevented the page protection from succeeding.
0286     ///
0287     /// \return
0288     ///     True in case of failure, false in case of success.
0289     bool finalizeMemory(std::string *ErrMsg) override {
0290       // TODO: Ensure that the instruction cache is flushed because
0291       // relocations are updated by dy-load.  See:
0292       //   sys::Memory::InvalidateInstructionCache
0293       //   llvm::SectionMemoryManager
0294       return false;
0295     }
0296 
0297     // Ignore any EHFrame registration.
0298     void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
0299                           size_t Size) override {}
0300     void deregisterEHFrames() override {}
0301 
0302     uint64_t getSymbolAddress(const std::string &Name) override;
0303 
0304     // Find the address of the symbol Name.  If Name is a missing weak symbol
0305     // then missing_weak will be true.
0306     uint64_t GetSymbolAddressAndPresence(const std::string &Name,
0307                                          bool &missing_weak);
0308 
0309     llvm::JITSymbol findSymbol(const std::string &Name) override;
0310 
0311     void *getPointerToNamedFunction(const std::string &Name,
0312                                     bool AbortOnFailure = true) override;
0313 
0314   private:
0315     std::unique_ptr<SectionMemoryManager> m_default_mm_up; ///< The memory
0316                                                            /// allocator to use
0317                                                            /// in actually
0318                                                            /// creating space.
0319                                                            /// All calls are
0320                                                            /// passed through to
0321                                                            /// it.
0322     IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
0323   };
0324 
0325   static const unsigned eSectionIDInvalid = (unsigned)-1;
0326 
0327   enum class AllocationKind { Stub, Code, Data, Global, Bytes };
0328 
0329   static lldb::SectionType
0330   GetSectionTypeFromSectionName(const llvm::StringRef &name,
0331                                 AllocationKind alloc_kind);
0332 
0333   /// Encapsulates a single allocation request made by the JIT.
0334   ///
0335   /// Allocations made by the JIT are first queued up and then applied in bulk
0336   /// to the underlying process.
0337   struct AllocationRecord {
0338     std::string m_name;
0339     lldb::addr_t m_process_address;
0340     uintptr_t m_host_address;
0341     uint32_t m_permissions;
0342     lldb::SectionType m_sect_type;
0343     size_t m_size;
0344     unsigned m_alignment;
0345     unsigned m_section_id;
0346 
0347     AllocationRecord(uintptr_t host_address, uint32_t permissions,
0348                      lldb::SectionType sect_type, size_t size,
0349                      unsigned alignment, unsigned section_id, const char *name)
0350         : m_process_address(LLDB_INVALID_ADDRESS), m_host_address(host_address),
0351           m_permissions(permissions), m_sect_type(sect_type), m_size(size),
0352           m_alignment(alignment), m_section_id(section_id) {
0353       if (name && name[0])
0354         m_name = name;
0355     }
0356 
0357     void dump(Log *log);
0358   };
0359 
0360   bool CommitOneAllocation(lldb::ProcessSP &process_sp, Status &error,
0361                            AllocationRecord &record);
0362 
0363   typedef std::vector<AllocationRecord> RecordVector;
0364   RecordVector m_records;
0365 
0366   std::unique_ptr<llvm::LLVMContext> m_context_up;
0367   std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_up;
0368   std::unique_ptr<llvm::ObjectCache> m_object_cache_up;
0369   std::unique_ptr<llvm::Module>
0370       m_module_up;        ///< Holder for the module until it's been handed off
0371   llvm::Module *m_module; ///< Owned by the execution engine
0372   std::vector<std::string> m_cpu_features;
0373   std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions
0374                                                   ///that have been JITted into
0375                                                   ///machine code
0376   std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of
0377                                                                ///all functions
0378                                                                ///that have been
0379                                                                ///JITted into
0380                                                                ///machine code
0381   const ConstString m_name;
0382   SymbolContext m_sym_ctx; ///< Used for symbol lookups
0383   std::vector<ConstString> m_failed_lookups;
0384 
0385   std::atomic<bool> m_did_jit;
0386 
0387   lldb::addr_t m_function_load_addr;
0388   lldb::addr_t m_function_end_load_addr;
0389 
0390   bool m_strip_underscore = true; ///< True for platforms where global symbols
0391                                   ///  have a _ prefix
0392   bool m_reported_allocations; ///< True after allocations have been reported.
0393                                ///It is possible that
0394   ///< sections will be allocated when this is true, in which case they weren't
0395   ///< depended on by any function.  (Top-level code defining a variable, but
0396   ///< defining no functions using that variable, would do this.)  If this
0397   ///< is true, any allocations need to be committed immediately -- no
0398   ///< opportunity for relocation.
0399 };
0400 
0401 } // namespace lldb_private
0402 
0403 #endif // LLDB_EXPRESSION_IREXECUTIONUNIT_H