1 //===-- IRExecutionUnit.h ---------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_IRExecutionUnit_h_ 11 #define liblldb_IRExecutionUnit_h_ 12 13 #include <atomic> 14 #include <memory> 15 #include <string> 16 #include <vector> 17 18 #include "llvm/ExecutionEngine/SectionMemoryManager.h" 19 #include "llvm/IR/Module.h" 20 21 #include "lldb/Expression/IRMemoryMap.h" 22 #include "lldb/Symbol/ObjectFile.h" 23 #include "lldb/Symbol/SymbolContext.h" 24 #include "lldb/Utility/DataBufferHeap.h" 25 #include "lldb/lldb-forward.h" 26 #include "lldb/lldb-private.h" 27 28 namespace llvm { 29 30 class Module; 31 class ExecutionEngine; 32 class ObjectCache; 33 34 } // namespace llvm 35 36 namespace lldb_private { 37 38 class Status; 39 40 //---------------------------------------------------------------------- 41 /// @class IRExecutionUnit IRExecutionUnit.h 42 /// "lldb/Expression/IRExecutionUnit.h" Contains the IR and, optionally, JIT- 43 /// compiled code for a module. 44 /// 45 /// This class encapsulates the compiled version of an expression, in IR form 46 /// (for interpretation purposes) and in raw machine code form (for execution 47 /// in the target). 48 /// 49 /// This object wraps an IR module that comes from the expression parser, and 50 /// knows how to use the JIT to make it into executable code. It can then be 51 /// used as input to the IR interpreter, or the address of the executable code 52 /// can be passed to a thread plan to run in the target. 53 /// 54 /// This class creates a subclass of LLVM's SectionMemoryManager, because that 55 /// is how the JIT emits code. Because LLDB needs to move JIT-compiled code 56 /// into the target process, the IRExecutionUnit knows how to copy the emitted 57 /// code into the target process. 58 //---------------------------------------------------------------------- 59 class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>, 60 public IRMemoryMap, 61 public ObjectFileJITDelegate { 62 public: 63 //------------------------------------------------------------------ 64 /// Constructor 65 //------------------------------------------------------------------ 66 IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_ap, 67 std::unique_ptr<llvm::Module> &module_ap, ConstString &name, 68 const lldb::TargetSP &target_sp, const SymbolContext &sym_ctx, 69 std::vector<std::string> &cpu_features); 70 71 //------------------------------------------------------------------ 72 /// Destructor 73 //------------------------------------------------------------------ 74 ~IRExecutionUnit() override; 75 GetFunctionName()76 ConstString GetFunctionName() { return m_name; } 77 GetModule()78 llvm::Module *GetModule() { return m_module; } 79 GetFunction()80 llvm::Function *GetFunction() { 81 return ((m_module != nullptr) ? m_module->getFunction(m_name.AsCString()) 82 : nullptr); 83 } 84 85 void GetRunnableInfo(Status &error, lldb::addr_t &func_addr, 86 lldb::addr_t &func_end); 87 88 //------------------------------------------------------------------ 89 /// Accessors for IRForTarget and other clients that may want binary data 90 /// placed on their behalf. The binary data is owned by the IRExecutionUnit 91 /// unless the client explicitly chooses to free it. 92 //------------------------------------------------------------------ 93 94 lldb::addr_t WriteNow(const uint8_t *bytes, size_t size, Status &error); 95 96 void FreeNow(lldb::addr_t allocation); 97 98 //------------------------------------------------------------------ 99 /// ObjectFileJITDelegate overrides 100 //------------------------------------------------------------------ 101 lldb::ByteOrder GetByteOrder() const override; 102 103 uint32_t GetAddressByteSize() const override; 104 105 void PopulateSymtab(lldb_private::ObjectFile *obj_file, 106 lldb_private::Symtab &symtab) override; 107 108 void PopulateSectionList(lldb_private::ObjectFile *obj_file, 109 lldb_private::SectionList §ion_list) override; 110 111 ArchSpec GetArchitecture() override; 112 113 lldb::ModuleSP GetJITModule(); 114 115 lldb::addr_t FindSymbol(const ConstString &name); 116 117 void GetStaticInitializers(std::vector<lldb::addr_t> &static_initializers); 118 119 //---------------------------------------------------------------------- 120 /// @class JittedFunction IRExecutionUnit.h 121 /// "lldb/Expression/IRExecutionUnit.h" 122 /// Encapsulates a single function that has been generated by the JIT. 123 /// 124 /// Functions that have been generated by the JIT are first resident in the 125 /// local process, and then placed in the target process. JittedFunction 126 /// represents a function possibly resident in both. 127 //---------------------------------------------------------------------- 128 struct JittedEntity { 129 ConstString m_name; ///< The function's name 130 lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory 131 lldb::addr_t 132 m_remote_addr; ///< The address of the function in the target's memory 133 134 //------------------------------------------------------------------ 135 /// Constructor 136 /// 137 /// Initializes class variabes. 138 /// 139 /// @param[in] name 140 /// The name of the function. 141 /// 142 /// @param[in] local_addr 143 /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if 144 /// it is not present in LLDB's memory. 145 /// 146 /// @param[in] remote_addr 147 /// The address of the function in the target, or LLDB_INVALID_ADDRESS 148 /// if it is not present in the target's memory. 149 //------------------------------------------------------------------ 150 JittedEntity(const char *name, 151 lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, 152 lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) m_nameJittedEntity153 : m_name(name), m_local_addr(local_addr), m_remote_addr(remote_addr) {} 154 }; 155 156 struct JittedFunction : JittedEntity { 157 bool m_external; 158 JittedFunction(const char *name, bool external, 159 lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, 160 lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) JittedEntityJittedFunction161 : JittedEntity(name, local_addr, remote_addr), m_external(external) {} 162 }; 163 164 struct JittedGlobalVariable : JittedEntity { 165 JittedGlobalVariable(const char *name, 166 lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, 167 lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) JittedEntityJittedGlobalVariable168 : JittedEntity(name, local_addr, remote_addr) {} 169 }; 170 GetJittedFunctions()171 const std::vector<JittedFunction> &GetJittedFunctions() { 172 return m_jitted_functions; 173 } 174 GetJittedGlobalVariables()175 const std::vector<JittedGlobalVariable> &GetJittedGlobalVariables() { 176 return m_jitted_global_variables; 177 } 178 179 private: 180 //------------------------------------------------------------------ 181 /// Look up the object in m_address_map that contains a given address, find 182 /// where it was copied to, and return the remote address at the same offset 183 /// into the copied entity 184 /// 185 /// @param[in] local_address 186 /// The address in the debugger. 187 /// 188 /// @return 189 /// The address in the target process. 190 //------------------------------------------------------------------ 191 lldb::addr_t GetRemoteAddressForLocal(lldb::addr_t local_address); 192 193 //------------------------------------------------------------------ 194 /// Look up the object in m_address_map that contains a given address, find 195 /// where it was copied to, and return its address range in the target 196 /// process 197 /// 198 /// @param[in] local_address 199 /// The address in the debugger. 200 /// 201 /// @return 202 /// The range of the containing object in the target process. 203 //------------------------------------------------------------------ 204 typedef std::pair<lldb::addr_t, uintptr_t> AddrRange; 205 AddrRange GetRemoteRangeForLocal(lldb::addr_t local_address); 206 207 //------------------------------------------------------------------ 208 /// Commit all allocations to the process and record where they were stored. 209 /// 210 /// @param[in] process 211 /// The process to allocate memory in. 212 /// 213 /// @return 214 /// True <=> all allocations were performed successfully. 215 /// This method will attempt to free allocated memory if the 216 /// operation fails. 217 //------------------------------------------------------------------ 218 bool CommitAllocations(lldb::ProcessSP &process_sp); 219 220 //------------------------------------------------------------------ 221 /// Report all committed allocations to the execution engine. 222 /// 223 /// @param[in] engine 224 /// The execution engine to notify. 225 //------------------------------------------------------------------ 226 void ReportAllocations(llvm::ExecutionEngine &engine); 227 228 //------------------------------------------------------------------ 229 /// Write the contents of all allocations to the process. 230 /// 231 /// @param[in] local_address 232 /// The process containing the allocations. 233 /// 234 /// @return 235 /// True <=> all allocations were performed successfully. 236 //------------------------------------------------------------------ 237 bool WriteData(lldb::ProcessSP &process_sp); 238 239 Status DisassembleFunction(Stream &stream, lldb::ProcessSP &process_sp); 240 241 struct SearchSpec; 242 243 void CollectCandidateCNames(std::vector<SearchSpec> &C_specs, 244 const ConstString &name); 245 246 void CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs, 247 const std::vector<SearchSpec> &C_specs, 248 const SymbolContext &sc); 249 250 void CollectFallbackNames(std::vector<SearchSpec> &fallback_specs, 251 const std::vector<SearchSpec> &C_specs); 252 253 lldb::addr_t FindInSymbols(const std::vector<SearchSpec> &specs, 254 const lldb_private::SymbolContext &sc); 255 256 lldb::addr_t FindInRuntimes(const std::vector<SearchSpec> &specs, 257 const lldb_private::SymbolContext &sc); 258 259 lldb::addr_t FindInUserDefinedSymbols(const std::vector<SearchSpec> &specs, 260 const lldb_private::SymbolContext &sc); 261 262 void ReportSymbolLookupError(const ConstString &name); 263 264 class MemoryManager : public llvm::SectionMemoryManager { 265 public: 266 MemoryManager(IRExecutionUnit &parent); 267 268 ~MemoryManager() override; 269 270 //------------------------------------------------------------------ 271 /// Allocate space for executable code, and add it to the m_spaceBlocks 272 /// map 273 /// 274 /// @param[in] Size 275 /// The size of the area. 276 /// 277 /// @param[in] Alignment 278 /// The required alignment of the area. 279 /// 280 /// @param[in] SectionID 281 /// A unique identifier for the section. 282 /// 283 /// @return 284 /// Allocated space. 285 //------------------------------------------------------------------ 286 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 287 unsigned SectionID, 288 llvm::StringRef SectionName) override; 289 290 //------------------------------------------------------------------ 291 /// Allocate space for data, and add it to the m_spaceBlocks map 292 /// 293 /// @param[in] Size 294 /// The size of the area. 295 /// 296 /// @param[in] Alignment 297 /// The required alignment of the area. 298 /// 299 /// @param[in] SectionID 300 /// A unique identifier for the section. 301 /// 302 /// @param[in] IsReadOnly 303 /// Flag indicating the section is read-only. 304 /// 305 /// @return 306 /// Allocated space. 307 //------------------------------------------------------------------ 308 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 309 unsigned SectionID, 310 llvm::StringRef SectionName, 311 bool IsReadOnly) override; 312 313 //------------------------------------------------------------------ 314 /// Called when object loading is complete and section page permissions 315 /// can be applied. Currently unimplemented for LLDB. 316 /// 317 /// @param[out] ErrMsg 318 /// The error that prevented the page protection from succeeding. 319 /// 320 /// @return 321 /// True in case of failure, false in case of success. 322 //------------------------------------------------------------------ finalizeMemory(std::string * ErrMsg)323 bool finalizeMemory(std::string *ErrMsg) override { 324 // TODO: Ensure that the instruction cache is flushed because 325 // relocations are updated by dy-load. See: 326 // sys::Memory::InvalidateInstructionCache 327 // llvm::SectionMemoryManager 328 return false; 329 } 330 registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)331 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 332 size_t Size) override {} 333 334 uint64_t getSymbolAddress(const std::string &Name) override; 335 336 void *getPointerToNamedFunction(const std::string &Name, 337 bool AbortOnFailure = true) override; 338 339 private: 340 std::unique_ptr<SectionMemoryManager> m_default_mm_ap; ///< The memory 341 ///allocator to use 342 ///in actually 343 ///creating space. 344 ///All calls are 345 ///passed through to 346 ///it. 347 IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for. 348 }; 349 350 static const unsigned eSectionIDInvalid = (unsigned)-1; 351 352 //---------------------------------------------------------------------- 353 /// @class AllocationRecord IRExecutionUnit.h 354 /// "lldb/Expression/IRExecutionUnit.h" Encapsulates a single allocation 355 /// request made by the JIT. 356 /// 357 /// Allocations made by the JIT are first queued up and then applied in bulk 358 /// to the underlying process. 359 //---------------------------------------------------------------------- 360 enum class AllocationKind { Stub, Code, Data, Global, Bytes }; 361 362 static lldb::SectionType 363 GetSectionTypeFromSectionName(const llvm::StringRef &name, 364 AllocationKind alloc_kind); 365 366 struct AllocationRecord { 367 std::string m_name; 368 lldb::addr_t m_process_address; 369 uintptr_t m_host_address; 370 uint32_t m_permissions; 371 lldb::SectionType m_sect_type; 372 size_t m_size; 373 unsigned m_alignment; 374 unsigned m_section_id; 375 AllocationRecordAllocationRecord376 AllocationRecord(uintptr_t host_address, uint32_t permissions, 377 lldb::SectionType sect_type, size_t size, 378 unsigned alignment, unsigned section_id, const char *name) 379 : m_name(), m_process_address(LLDB_INVALID_ADDRESS), 380 m_host_address(host_address), m_permissions(permissions), 381 m_sect_type(sect_type), m_size(size), m_alignment(alignment), 382 m_section_id(section_id) { 383 if (name && name[0]) 384 m_name = name; 385 } 386 387 void dump(Log *log); 388 }; 389 390 bool CommitOneAllocation(lldb::ProcessSP &process_sp, Status &error, 391 AllocationRecord &record); 392 393 typedef std::vector<AllocationRecord> RecordVector; 394 RecordVector m_records; 395 396 std::unique_ptr<llvm::LLVMContext> m_context_ap; 397 std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_ap; 398 std::unique_ptr<llvm::ObjectCache> m_object_cache_ap; 399 std::unique_ptr<llvm::Module> 400 m_module_ap; ///< Holder for the module until it's been handed off 401 llvm::Module *m_module; ///< Owned by the execution engine 402 std::vector<std::string> m_cpu_features; 403 std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions 404 ///that have been JITted into 405 ///machine code 406 std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of 407 ///all functions 408 ///that have been 409 ///JITted into 410 ///machine code 411 const ConstString m_name; 412 SymbolContext m_sym_ctx; ///< Used for symbol lookups 413 std::vector<ConstString> m_failed_lookups; 414 415 std::atomic<bool> m_did_jit; 416 417 lldb::addr_t m_function_load_addr; 418 lldb::addr_t m_function_end_load_addr; 419 420 bool m_strip_underscore = true; ///< True for platforms where global symbols 421 /// have a _ prefix 422 bool m_reported_allocations; ///< True after allocations have been reported. 423 ///It is possible that 424 ///< sections will be allocated when this is true, in which case they weren't 425 ///< depended on by any function. (Top-level code defining a variable, but 426 ///< defining no functions using that variable, would do this.) If this 427 ///< is true, any allocations need to be committed immediately -- no 428 ///< opportunity for relocation. 429 }; 430 431 } // namespace lldb_private 432 433 #endif // liblldb_IRExecutionUnit_h_ 434