1 //===-- IRExecutionUnit.h ---------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef liblldb_IRExecutionUnit_h_
10 #define liblldb_IRExecutionUnit_h_
17 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
18 #include "llvm/IR/Module.h"
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"
30 class ExecutionEngine;
35 namespace lldb_private {
39 /// \class IRExecutionUnit IRExecutionUnit.h
40 /// "lldb/Expression/IRExecutionUnit.h" Contains the IR and, optionally, JIT-
41 /// compiled code for a module.
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
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.
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>,
58 public ObjectFileJITDelegate {
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);
67 ~IRExecutionUnit() override;
69 ConstString GetFunctionName() { return m_name; }
71 llvm::Module *GetModule() { return m_module; }
73 llvm::Function *GetFunction() {
74 return ((m_module != nullptr) ? m_module->getFunction(m_name.AsCString())
78 void GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
79 lldb::addr_t &func_end);
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.
85 lldb::addr_t WriteNow(const uint8_t *bytes, size_t size, Status &error);
87 void FreeNow(lldb::addr_t allocation);
89 /// ObjectFileJITDelegate overrides
90 lldb::ByteOrder GetByteOrder() const override;
92 uint32_t GetAddressByteSize() const override;
94 void PopulateSymtab(lldb_private::ObjectFile *obj_file,
95 lldb_private::Symtab &symtab) override;
97 void PopulateSectionList(lldb_private::ObjectFile *obj_file,
98 lldb_private::SectionList §ion_list) override;
100 ArchSpec GetArchitecture() override;
102 lldb::ModuleSP GetJITModule();
104 lldb::addr_t FindSymbol(ConstString name, bool &missing_weak);
106 void GetStaticInitializers(std::vector<lldb::addr_t> &static_initializers);
108 /// \class JittedFunction IRExecutionUnit.h
109 /// "lldb/Expression/IRExecutionUnit.h"
110 /// Encapsulates a single function that has been generated by the JIT.
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
123 /// Initializes class variabes.
126 /// The name of the function.
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.
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) {}
141 struct JittedFunction : JittedEntity {
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) {}
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) {}
156 const std::vector<JittedFunction> &GetJittedFunctions() {
157 return m_jitted_functions;
160 const std::vector<JittedGlobalVariable> &GetJittedGlobalVariables() {
161 return m_jitted_global_variables;
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
169 /// \param[in] local_address
170 /// The address in the debugger.
173 /// The address in the target process.
174 lldb::addr_t GetRemoteAddressForLocal(lldb::addr_t local_address);
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
180 /// \param[in] local_address
181 /// The address in the debugger.
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);
188 /// Commit all allocations to the process and record where they were stored.
190 /// \param[in] process
191 /// The process to allocate memory in.
194 /// True <=> all allocations were performed successfully.
195 /// This method will attempt to free allocated memory if the
197 bool CommitAllocations(lldb::ProcessSP &process_sp);
199 /// Report all committed allocations to the execution engine.
201 /// \param[in] engine
202 /// The execution engine to notify.
203 void ReportAllocations(llvm::ExecutionEngine &engine);
205 /// Write the contents of all allocations to the process.
207 /// \param[in] local_address
208 /// The process containing the allocations.
211 /// True <=> all allocations were performed successfully.
212 bool WriteData(lldb::ProcessSP &process_sp);
214 Status DisassembleFunction(Stream &stream, lldb::ProcessSP &process_sp);
218 void CollectCandidateCNames(std::vector<SearchSpec> &C_specs,
221 void CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs,
222 const std::vector<SearchSpec> &C_specs,
223 const SymbolContext &sc);
225 void CollectFallbackNames(std::vector<SearchSpec> &fallback_specs,
226 const std::vector<SearchSpec> &C_specs);
228 lldb::addr_t FindInSymbols(const std::vector<SearchSpec> &specs,
229 const lldb_private::SymbolContext &sc,
230 bool &symbol_was_missing_weak);
232 lldb::addr_t FindInRuntimes(const std::vector<SearchSpec> &specs,
233 const lldb_private::SymbolContext &sc);
235 lldb::addr_t FindInUserDefinedSymbols(const std::vector<SearchSpec> &specs,
236 const lldb_private::SymbolContext &sc);
238 void ReportSymbolLookupError(ConstString name);
240 class MemoryManager : public llvm::SectionMemoryManager {
242 MemoryManager(IRExecutionUnit &parent);
244 ~MemoryManager() override;
246 /// Allocate space for executable code, and add it to the m_spaceBlocks
250 /// The size of the area.
252 /// \param[in] Alignment
253 /// The required alignment of the area.
255 /// \param[in] SectionID
256 /// A unique identifier for the section.
260 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
262 llvm::StringRef SectionName) override;
264 /// Allocate space for data, and add it to the m_spaceBlocks map
267 /// The size of the area.
269 /// \param[in] Alignment
270 /// The required alignment of the area.
272 /// \param[in] SectionID
273 /// A unique identifier for the section.
275 /// \param[in] IsReadOnly
276 /// Flag indicating the section is read-only.
280 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
282 llvm::StringRef SectionName,
283 bool IsReadOnly) override;
285 /// Called when object loading is complete and section page permissions
286 /// can be applied. Currently unimplemented for LLDB.
288 /// \param[out] ErrMsg
289 /// The error that prevented the page protection from succeeding.
292 /// True in case of failure, false in case of success.
293 bool finalizeMemory(std::string *ErrMsg) override {
294 // TODO: Ensure that the instruction cache is flushed because
295 // relocations are updated by dy-load. See:
296 // sys::Memory::InvalidateInstructionCache
297 // llvm::SectionMemoryManager
301 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
302 size_t Size) override {}
304 uint64_t getSymbolAddress(const std::string &Name) override;
306 // Find the address of the symbol Name. If Name is a missing weak symbol
307 // then missing_weak will be true.
308 uint64_t GetSymbolAddressAndPresence(const std::string &Name,
311 llvm::JITSymbol findSymbol(const std::string &Name) override;
313 void *getPointerToNamedFunction(const std::string &Name,
314 bool AbortOnFailure = true) override;
317 std::unique_ptr<SectionMemoryManager> m_default_mm_up; ///< The memory
322 /// passed through to
324 IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
327 static const unsigned eSectionIDInvalid = (unsigned)-1;
329 /// \class AllocationRecord IRExecutionUnit.h
330 /// "lldb/Expression/IRExecutionUnit.h" Encapsulates a single allocation
331 /// request made by the JIT.
333 /// Allocations made by the JIT are first queued up and then applied in bulk
334 /// to the underlying process.
335 enum class AllocationKind { Stub, Code, Data, Global, Bytes };
337 static lldb::SectionType
338 GetSectionTypeFromSectionName(const llvm::StringRef &name,
339 AllocationKind alloc_kind);
341 struct AllocationRecord {
343 lldb::addr_t m_process_address;
344 uintptr_t m_host_address;
345 uint32_t m_permissions;
346 lldb::SectionType m_sect_type;
348 unsigned m_alignment;
349 unsigned m_section_id;
351 AllocationRecord(uintptr_t host_address, uint32_t permissions,
352 lldb::SectionType sect_type, size_t size,
353 unsigned alignment, unsigned section_id, const char *name)
354 : m_name(), m_process_address(LLDB_INVALID_ADDRESS),
355 m_host_address(host_address), m_permissions(permissions),
356 m_sect_type(sect_type), m_size(size), m_alignment(alignment),
357 m_section_id(section_id) {
365 bool CommitOneAllocation(lldb::ProcessSP &process_sp, Status &error,
366 AllocationRecord &record);
368 typedef std::vector<AllocationRecord> RecordVector;
369 RecordVector m_records;
371 std::unique_ptr<llvm::LLVMContext> m_context_up;
372 std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_up;
373 std::unique_ptr<llvm::ObjectCache> m_object_cache_up;
374 std::unique_ptr<llvm::Module>
375 m_module_up; ///< Holder for the module until it's been handed off
376 llvm::Module *m_module; ///< Owned by the execution engine
377 std::vector<std::string> m_cpu_features;
378 std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions
379 ///that have been JITted into
381 std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of
386 const ConstString m_name;
387 SymbolContext m_sym_ctx; ///< Used for symbol lookups
388 std::vector<ConstString> m_failed_lookups;
390 std::atomic<bool> m_did_jit;
392 lldb::addr_t m_function_load_addr;
393 lldb::addr_t m_function_end_load_addr;
395 bool m_strip_underscore = true; ///< True for platforms where global symbols
397 bool m_reported_allocations; ///< True after allocations have been reported.
398 ///It is possible that
399 ///< sections will be allocated when this is true, in which case they weren't
400 ///< depended on by any function. (Top-level code defining a variable, but
401 ///< defining no functions using that variable, would do this.) If this
402 ///< is true, any allocations need to be committed immediately -- no
403 ///< opportunity for relocation.
406 } // namespace lldb_private
408 #endif // liblldb_IRExecutionUnit_h_