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/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" 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 struct SearchSpec; 218 219 void CollectCandidateCNames(std::vector<SearchSpec> &C_specs, 220 ConstString name); 221 222 void CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs, 223 const std::vector<SearchSpec> &C_specs, 224 const SymbolContext &sc); 225 226 void CollectFallbackNames(std::vector<SearchSpec> &fallback_specs, 227 const std::vector<SearchSpec> &C_specs); 228 229 lldb::addr_t FindInSymbols(const std::vector<SearchSpec> &specs, 230 const lldb_private::SymbolContext &sc, 231 bool &symbol_was_missing_weak); 232 233 lldb::addr_t FindInRuntimes(const std::vector<SearchSpec> &specs, 234 const lldb_private::SymbolContext &sc); 235 236 lldb::addr_t FindInUserDefinedSymbols(const std::vector<SearchSpec> &specs, 237 const lldb_private::SymbolContext &sc); 238 239 void ReportSymbolLookupError(ConstString name); 240 241 class MemoryManager : public llvm::SectionMemoryManager { 242 public: 243 MemoryManager(IRExecutionUnit &parent); 244 245 ~MemoryManager() override; 246 247 /// Allocate space for executable code, and add it to the m_spaceBlocks 248 /// map 249 /// 250 /// \param[in] Size 251 /// The size of the area. 252 /// 253 /// \param[in] Alignment 254 /// The required alignment of the area. 255 /// 256 /// \param[in] SectionID 257 /// A unique identifier for the section. 258 /// 259 /// \return 260 /// Allocated space. 261 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 262 unsigned SectionID, 263 llvm::StringRef SectionName) override; 264 265 /// Allocate space for data, and add it to the m_spaceBlocks map 266 /// 267 /// \param[in] Size 268 /// The size of the area. 269 /// 270 /// \param[in] Alignment 271 /// The required alignment of the area. 272 /// 273 /// \param[in] SectionID 274 /// A unique identifier for the section. 275 /// 276 /// \param[in] IsReadOnly 277 /// Flag indicating the section is read-only. 278 /// 279 /// \return 280 /// Allocated space. 281 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 282 unsigned SectionID, 283 llvm::StringRef SectionName, 284 bool IsReadOnly) override; 285 286 /// Called when object loading is complete and section page permissions 287 /// can be applied. Currently unimplemented for LLDB. 288 /// 289 /// \param[out] ErrMsg 290 /// The error that prevented the page protection from succeeding. 291 /// 292 /// \return 293 /// True in case of failure, false in case of success. finalizeMemory(std::string * ErrMsg)294 bool finalizeMemory(std::string *ErrMsg) override { 295 // TODO: Ensure that the instruction cache is flushed because 296 // relocations are updated by dy-load. See: 297 // sys::Memory::InvalidateInstructionCache 298 // llvm::SectionMemoryManager 299 return false; 300 } 301 302 // Ignore any EHFrame registration. registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)303 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 304 size_t Size) override {} deregisterEHFrames()305 void deregisterEHFrames() override {} 306 307 uint64_t getSymbolAddress(const std::string &Name) override; 308 309 // Find the address of the symbol Name. If Name is a missing weak symbol 310 // then missing_weak will be true. 311 uint64_t GetSymbolAddressAndPresence(const std::string &Name, 312 bool &missing_weak); 313 314 llvm::JITSymbol findSymbol(const std::string &Name) override; 315 316 void *getPointerToNamedFunction(const std::string &Name, 317 bool AbortOnFailure = true) override; 318 319 private: 320 std::unique_ptr<SectionMemoryManager> m_default_mm_up; ///< The memory 321 /// allocator to use 322 /// in actually 323 /// creating space. 324 /// All calls are 325 /// passed through to 326 /// it. 327 IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for. 328 }; 329 330 static const unsigned eSectionIDInvalid = (unsigned)-1; 331 332 enum class AllocationKind { Stub, Code, Data, Global, Bytes }; 333 334 static lldb::SectionType 335 GetSectionTypeFromSectionName(const llvm::StringRef &name, 336 AllocationKind alloc_kind); 337 338 /// Encapsulates a single allocation request made by the JIT. 339 /// 340 /// Allocations made by the JIT are first queued up and then applied in bulk 341 /// to the underlying process. 342 struct AllocationRecord { 343 std::string m_name; 344 lldb::addr_t m_process_address; 345 uintptr_t m_host_address; 346 uint32_t m_permissions; 347 lldb::SectionType m_sect_type; 348 size_t m_size; 349 unsigned m_alignment; 350 unsigned m_section_id; 351 AllocationRecordAllocationRecord352 AllocationRecord(uintptr_t host_address, uint32_t permissions, 353 lldb::SectionType sect_type, size_t size, 354 unsigned alignment, unsigned section_id, const char *name) 355 : m_name(), m_process_address(LLDB_INVALID_ADDRESS), 356 m_host_address(host_address), m_permissions(permissions), 357 m_sect_type(sect_type), m_size(size), m_alignment(alignment), 358 m_section_id(section_id) { 359 if (name && name[0]) 360 m_name = name; 361 } 362 363 void dump(Log *log); 364 }; 365 366 bool CommitOneAllocation(lldb::ProcessSP &process_sp, Status &error, 367 AllocationRecord &record); 368 369 typedef std::vector<AllocationRecord> RecordVector; 370 RecordVector m_records; 371 372 std::unique_ptr<llvm::LLVMContext> m_context_up; 373 std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_up; 374 std::unique_ptr<llvm::ObjectCache> m_object_cache_up; 375 std::unique_ptr<llvm::Module> 376 m_module_up; ///< Holder for the module until it's been handed off 377 llvm::Module *m_module; ///< Owned by the execution engine 378 std::vector<std::string> m_cpu_features; 379 std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions 380 ///that have been JITted into 381 ///machine code 382 std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of 383 ///all functions 384 ///that have been 385 ///JITted into 386 ///machine code 387 const ConstString m_name; 388 SymbolContext m_sym_ctx; ///< Used for symbol lookups 389 std::vector<ConstString> m_failed_lookups; 390 391 std::atomic<bool> m_did_jit; 392 393 lldb::addr_t m_function_load_addr; 394 lldb::addr_t m_function_end_load_addr; 395 396 bool m_strip_underscore = true; ///< True for platforms where global symbols 397 /// have a _ prefix 398 bool m_reported_allocations; ///< True after allocations have been reported. 399 ///It is possible that 400 ///< sections will be allocated when this is true, in which case they weren't 401 ///< depended on by any function. (Top-level code defining a variable, but 402 ///< defining no functions using that variable, would do this.) If this 403 ///< is true, any allocations need to be committed immediately -- no 404 ///< opportunity for relocation. 405 }; 406 407 } // namespace lldb_private 408 409 #endif // LLDB_EXPRESSION_IREXECUTIONUNIT_H 410