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/Expression/ObjectFileJIT.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 §ion_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 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, 225 const lldb_private::SymbolContext &sc, 226 bool &symbol_was_missing_weak); 227 228 lldb::addr_t FindInRuntimes(const std::vector<ConstString> &names, 229 const lldb_private::SymbolContext &sc); 230 231 lldb::addr_t FindInUserDefinedSymbols(const std::vector<ConstString> &names, 232 const lldb_private::SymbolContext &sc); 233 234 void ReportSymbolLookupError(ConstString name); 235 236 class MemoryManager : public llvm::SectionMemoryManager { 237 public: 238 MemoryManager(IRExecutionUnit &parent); 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. finalizeMemory(std::string * ErrMsg)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. registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)298 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 299 size_t Size) override {} deregisterEHFrames()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 327 enum class AllocationKind { Stub, Code, Data, Global, Bytes }; 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. 337 struct AllocationRecord { 338 std::string m_name; 339 lldb::addr_t m_process_address; 340 uintptr_t m_host_address; 341 uint32_t m_permissions; 342 lldb::SectionType m_sect_type; 343 size_t m_size; 344 unsigned m_alignment; 345 unsigned m_section_id; 346 AllocationRecordAllocationRecord347 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) 350 : m_process_address(LLDB_INVALID_ADDRESS), m_host_address(host_address), 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 360 bool CommitOneAllocation(lldb::ProcessSP &process_sp, Status &error, 361 AllocationRecord &record); 362 363 typedef std::vector<AllocationRecord> RecordVector; 364 RecordVector m_records; 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 381 const ConstString m_name; 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 387 lldb::addr_t m_function_load_addr; 388 lldb::addr_t m_function_end_load_addr; 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 404