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 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
24#include "lldb/lldb-forward.h"
25#include "lldb/lldb-private.h"
26
27namespace llvm {
28
29class Module;
30class ExecutionEngine;
31class ObjectCache;
32
33} // namespace llvm
34
35namespace lldb_private {
36
37class 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.
56class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>,
57 public IRMemoryMap,
59public:
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
70
71 llvm::Module *GetModule() { return m_module; }
72
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
95 lldb_private::Symtab &symtab) override;
96
98 lldb_private::SectionList &section_list) override;
99
100 ArchSpec GetArchitecture() override;
101
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.
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,
138 : m_name(name), m_local_addr(local_addr), m_remote_addr(remote_addr) {}
139 };
140
143 JittedFunction(const char *name, bool external,
146 : JittedEntity(name, local_addr, remote_addr), m_external(external) {}
147 };
148
150 JittedGlobalVariable(const char *name,
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() {
162 }
163
164private:
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.
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.
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 void CollectCandidateCNames(std::vector<ConstString> &C_names,
218 ConstString name);
219
220 void CollectCandidateCPlusPlusNames(std::vector<ConstString> &CPP_names,
221 const std::vector<ConstString> &C_names,
222 const SymbolContext &sc);
223
224 lldb::addr_t FindInSymbols(const std::vector<ConstString> &names,
226 bool &symbol_was_missing_weak);
227
228 lldb::addr_t FindInRuntimes(const std::vector<ConstString> &names,
230
231 lldb::addr_t FindInUserDefinedSymbols(const std::vector<ConstString> &names,
233
235
236 class MemoryManager : public llvm::SectionMemoryManager {
237 public:
239
240 ~MemoryManager() override;
241
242 /// Allocate space for executable code, and add it to the m_spaceBlocks
243 /// map
244 ///
245 /// \param[in] Size
246 /// The size of the area.
247 ///
248 /// \param[in] Alignment
249 /// The required alignment of the area.
250 ///
251 /// \param[in] SectionID
252 /// A unique identifier for the section.
253 ///
254 /// \return
255 /// Allocated space.
256 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
257 unsigned SectionID,
258 llvm::StringRef SectionName) override;
259
260 /// Allocate space for data, and add it to the m_spaceBlocks map
261 ///
262 /// \param[in] Size
263 /// The size of the area.
264 ///
265 /// \param[in] Alignment
266 /// The required alignment of the area.
267 ///
268 /// \param[in] SectionID
269 /// A unique identifier for the section.
270 ///
271 /// \param[in] IsReadOnly
272 /// Flag indicating the section is read-only.
273 ///
274 /// \return
275 /// Allocated space.
276 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
277 unsigned SectionID,
278 llvm::StringRef SectionName,
279 bool IsReadOnly) override;
280
281 /// Called when object loading is complete and section page permissions
282 /// can be applied. Currently unimplemented for LLDB.
283 ///
284 /// \param[out] ErrMsg
285 /// The error that prevented the page protection from succeeding.
286 ///
287 /// \return
288 /// True in case of failure, false in case of success.
289 bool finalizeMemory(std::string *ErrMsg) override {
290 // TODO: Ensure that the instruction cache is flushed because
291 // relocations are updated by dy-load. See:
292 // sys::Memory::InvalidateInstructionCache
293 // llvm::SectionMemoryManager
294 return false;
295 }
296
297 // Ignore any EHFrame registration.
298 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
299 size_t Size) override {}
300 void deregisterEHFrames() override {}
301
302 uint64_t getSymbolAddress(const std::string &Name) override;
303
304 // Find the address of the symbol Name. If Name is a missing weak symbol
305 // then missing_weak will be true.
306 uint64_t GetSymbolAddressAndPresence(const std::string &Name,
307 bool &missing_weak);
308
309 llvm::JITSymbol findSymbol(const std::string &Name) override;
310
311 void *getPointerToNamedFunction(const std::string &Name,
312 bool AbortOnFailure = true) override;
313
314 private:
315 std::unique_ptr<SectionMemoryManager> m_default_mm_up; ///< The memory
316 /// allocator to use
317 /// in actually
318 /// creating space.
319 /// All calls are
320 /// passed through to
321 /// it.
322 IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
323 };
324
325 static const unsigned eSectionIDInvalid = (unsigned)-1;
326
328
329 static lldb::SectionType
330 GetSectionTypeFromSectionName(const llvm::StringRef &name,
331 AllocationKind alloc_kind);
332
333 /// Encapsulates a single allocation request made by the JIT.
334 ///
335 /// Allocations made by the JIT are first queued up and then applied in bulk
336 /// to the underlying process.
338 std::string m_name;
340 uintptr_t m_host_address;
343 size_t m_size;
344 unsigned m_alignment;
345 unsigned m_section_id;
346
347 AllocationRecord(uintptr_t host_address, uint32_t permissions,
348 lldb::SectionType sect_type, size_t size,
349 unsigned alignment, unsigned section_id, const char *name)
351 m_permissions(permissions), m_sect_type(sect_type), m_size(size),
352 m_alignment(alignment), m_section_id(section_id) {
353 if (name && name[0])
354 m_name = name;
355 }
356
357 void dump(Log *log);
358 };
359
361 AllocationRecord &record);
362
363 typedef std::vector<AllocationRecord> RecordVector;
365
366 std::unique_ptr<llvm::LLVMContext> m_context_up;
367 std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_up;
368 std::unique_ptr<llvm::ObjectCache> m_object_cache_up;
369 std::unique_ptr<llvm::Module>
370 m_module_up; ///< Holder for the module until it's been handed off
371 llvm::Module *m_module; ///< Owned by the execution engine
372 std::vector<std::string> m_cpu_features;
373 std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions
374 ///that have been JITted into
375 ///machine code
376 std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of
377 ///all functions
378 ///that have been
379 ///JITted into
380 ///machine code
382 SymbolContext m_sym_ctx; ///< Used for symbol lookups
383 std::vector<ConstString> m_failed_lookups;
384
385 std::atomic<bool> m_did_jit;
386
389
390 bool m_strip_underscore = true; ///< True for platforms where global symbols
391 /// have a _ prefix
392 bool m_reported_allocations; ///< True after allocations have been reported.
393 ///It is possible that
394 ///< sections will be allocated when this is true, in which case they weren't
395 ///< depended on by any function. (Top-level code defining a variable, but
396 ///< defining no functions using that variable, would do this.) If this
397 ///< is true, any allocations need to be committed immediately -- no
398 ///< opportunity for relocation.
399};
400
401} // namespace lldb_private
402
403#endif // LLDB_EXPRESSION_IREXECUTIONUNIT_H
static llvm::raw_ostream & error(Stream &strm)
An architecture specification class.
Definition: ArchSpec.h:31
A uniqued constant string class.
Definition: ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:197
void * getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure=true) override
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override
bool finalizeMemory(std::string *ErrMsg) override
Called when object loading is complete and section page permissions can be applied.
std::unique_ptr< SectionMemoryManager > m_default_mm_up
The memory allocator to use in actually creating space.
uint64_t getSymbolAddress(const std::string &Name) override
uint8_t * allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName, bool IsReadOnly) override
Allocate space for data, and add it to the m_spaceBlocks map.
IRExecutionUnit & m_parent
The execution unit this is a proxy for.
uint64_t GetSymbolAddressAndPresence(const std::string &Name, bool &missing_weak)
llvm::JITSymbol findSymbol(const std::string &Name) override
uint8_t * allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName) override
Allocate space for executable code, and add it to the m_spaceBlocks map.
"lldb/Expression/IRExecutionUnit.h" Contains the IR and, optionally, JIT- compiled code for a module.
std::vector< std::string > m_cpu_features
void CollectCandidateCPlusPlusNames(std::vector< ConstString > &CPP_names, const std::vector< ConstString > &C_names, const SymbolContext &sc)
lldb::addr_t WriteNow(const uint8_t *bytes, size_t size, Status &error)
Accessors for IRForTarget and other clients that may want binary data placed on their behalf.
static const unsigned eSectionIDInvalid
void PopulateSymtab(lldb_private::ObjectFile *obj_file, lldb_private::Symtab &symtab) override
lldb::addr_t FindInSymbols(const std::vector< ConstString > &names, const lldb_private::SymbolContext &sc, bool &symbol_was_missing_weak)
void GetRunnableInfo(Status &error, lldb::addr_t &func_addr, lldb::addr_t &func_end)
lldb::ByteOrder GetByteOrder() const override
ObjectFileJITDelegate overrides.
SymbolContext m_sym_ctx
Used for symbol lookups.
std::vector< JittedFunction > m_jitted_functions
A vector of all functions that have been JITted into machine code.
Status DisassembleFunction(Stream &stream, lldb::ProcessSP &process_sp)
std::vector< ConstString > m_failed_lookups
std::unique_ptr< llvm::Module > m_module_up
Holder for the module until it's been handed off.
lldb::addr_t FindSymbol(ConstString name, bool &missing_weak)
lldb::addr_t FindInRuntimes(const std::vector< ConstString > &names, const lldb_private::SymbolContext &sc)
static lldb::SectionType GetSectionTypeFromSectionName(const llvm::StringRef &name, AllocationKind alloc_kind)
uint32_t GetAddressByteSize() const override
bool CommitAllocations(lldb::ProcessSP &process_sp)
Commit all allocations to the process and record where they were stored.
bool CommitOneAllocation(lldb::ProcessSP &process_sp, Status &error, AllocationRecord &record)
void GetStaticInitializers(std::vector< lldb::addr_t > &static_initializers)
void CollectCandidateCNames(std::vector< ConstString > &C_names, ConstString name)
std::unique_ptr< llvm::ExecutionEngine > m_execution_engine_up
llvm::Module * m_module
Owned by the execution engine.
std::unique_ptr< llvm::LLVMContext > m_context_up
ArchSpec GetArchitecture() override
const std::vector< JittedGlobalVariable > & GetJittedGlobalVariables()
AddrRange GetRemoteRangeForLocal(lldb::addr_t local_address)
Look up the object in m_address_map that contains a given address, find where it was copied to,...
bool m_strip_underscore
True for platforms where global symbols have a _ prefix.
llvm::Function * GetFunction()
void ReportSymbolLookupError(ConstString name)
lldb::addr_t FindInUserDefinedSymbols(const std::vector< ConstString > &names, const lldb_private::SymbolContext &sc)
void PopulateSectionList(lldb_private::ObjectFile *obj_file, lldb_private::SectionList &section_list) override
std::vector< AllocationRecord > RecordVector
const std::vector< JittedFunction > & GetJittedFunctions()
std::pair< lldb::addr_t, uintptr_t > AddrRange
void FreeNow(lldb::addr_t allocation)
std::atomic< bool > m_did_jit
std::vector< JittedGlobalVariable > m_jitted_global_variables
A vector of all functions that have been JITted into machine code.
bool WriteData(lldb::ProcessSP &process_sp)
Write the contents of all allocations to the process.
std::unique_ptr< llvm::ObjectCache > m_object_cache_up
~IRExecutionUnit() override
Destructor.
void ReportAllocations(llvm::ExecutionEngine &engine)
Report all committed allocations to the execution engine.
lldb::addr_t GetRemoteAddressForLocal(lldb::addr_t local_address)
Look up the object in m_address_map that contains a given address, find where it was copied to,...
bool m_reported_allocations
True after allocations have been reported.
Encapsulates memory that may exist in the process but must also be available in the host process.
Definition: IRMemoryMap.h:34
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:44
An error handling class.
Definition: Status.h:115
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:34
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:82
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:389
ByteOrder
Byte ordering definitions.
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
Definition: lldb-forward.h:448
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:373
Definition: Debugger.h:54
Encapsulates a single allocation request made by the JIT.
AllocationRecord(uintptr_t host_address, uint32_t permissions, lldb::SectionType sect_type, size_t size, unsigned alignment, unsigned section_id, const char *name)
JittedEntity(const char *name, lldb::addr_t local_addr=LLDB_INVALID_ADDRESS, lldb::addr_t remote_addr=LLDB_INVALID_ADDRESS)
Constructor.
ConstString m_name
The function's name.
lldb::addr_t m_remote_addr
The address of the function in the target's memory.
lldb::addr_t m_local_addr
The address of the function in LLDB's memory.
"lldb/Expression/IRExecutionUnit.h" Encapsulates a single function that has been generated by the JIT...
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)