IRExecutionUnit.h revision 263363
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 lldb_IRExecutionUnit_h_ 11#define lldb_IRExecutionUnit_h_ 12 13// C Includes 14// C++ Includes 15#include <atomic> 16#include <string> 17#include <vector> 18#include <map> 19 20// Other libraries and framework includes 21#include "llvm/ADT/StringRef.h" 22#include "llvm/IR/Module.h" 23 24// Project includes 25#include "lldb/lldb-forward.h" 26#include "lldb/lldb-private.h" 27#include "lldb/Core/ClangForward.h" 28#include "lldb/Core/DataBufferHeap.h" 29#include "llvm/ExecutionEngine/JITMemoryManager.h" 30#include "lldb/Expression/ClangExpression.h" 31#include "lldb/Expression/ClangExpressionParser.h" 32#include "lldb/Expression/IRMemoryMap.h" 33#include "lldb/Host/Mutex.h" 34 35namespace llvm { 36 37class Module; 38class ExecutionEngine; 39 40} 41 42namespace lldb_private { 43 44class Error; 45 46//---------------------------------------------------------------------- 47/// @class IRExecutionUnit IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h" 48/// @brief Contains the IR and, optionally, JIT-compiled code for a module. 49/// 50/// This class encapsulates the compiled version of an expression, in IR 51/// form (for interpretation purposes) and in raw machine code form (for 52/// execution in the target). 53/// 54/// This object wraps an IR module that comes from the expression parser, 55/// and knows how to use the JIT to make it into executable code. It can 56/// then be used as input to the IR interpreter, or the address of the 57/// executable code can be passed to a thread plan to run in the target. 58/// 59/// This class creates a subclass of LLVM's JITMemoryManager, because that is 60/// how the JIT emits code. Because LLDB needs to move JIT-compiled code 61/// into the target process, the IRExecutionUnit knows how to copy the 62/// emitted code into the target process. 63//---------------------------------------------------------------------- 64class IRExecutionUnit : public IRMemoryMap 65{ 66public: 67 //------------------------------------------------------------------ 68 /// Constructor 69 //------------------------------------------------------------------ 70 IRExecutionUnit (std::unique_ptr<llvm::LLVMContext> &context_ap, 71 std::unique_ptr<llvm::Module> &module_ap, 72 ConstString &name, 73 const lldb::TargetSP &target_sp, 74 std::vector<std::string> &cpu_features); 75 76 //------------------------------------------------------------------ 77 /// Destructor 78 //------------------------------------------------------------------ 79 ~IRExecutionUnit(); 80 81 llvm::Module *GetModule() 82 { 83 return m_module; 84 } 85 86 llvm::Function *GetFunction() 87 { 88 if (m_module) 89 return m_module->getFunction (m_name.AsCString()); 90 else 91 return NULL; 92 } 93 94 void GetRunnableInfo(Error &error, 95 lldb::addr_t &func_addr, 96 lldb::addr_t &func_end); 97 98 //------------------------------------------------------------------ 99 /// Accessors for IRForTarget and other clients that may want binary 100 /// data placed on their behalf. The binary data is owned by the 101 /// IRExecutionUnit unless the client explicitly chooses to free it. 102 //------------------------------------------------------------------ 103 104 lldb::addr_t WriteNow(const uint8_t *bytes, 105 size_t size, 106 Error &error); 107 108 void FreeNow(lldb::addr_t allocation); 109 110private: 111 //------------------------------------------------------------------ 112 /// Look up the object in m_address_map that contains a given address, 113 /// find where it was copied to, and return the remote address at the 114 /// same offset into the copied entity 115 /// 116 /// @param[in] local_address 117 /// The address in the debugger. 118 /// 119 /// @return 120 /// The address in the target process. 121 //------------------------------------------------------------------ 122 lldb::addr_t 123 GetRemoteAddressForLocal (lldb::addr_t local_address); 124 125 //------------------------------------------------------------------ 126 /// Look up the object in m_address_map that contains a given address, 127 /// find where it was copied to, and return its address range in the 128 /// target process 129 /// 130 /// @param[in] local_address 131 /// The address in the debugger. 132 /// 133 /// @return 134 /// The range of the containing object in the target process. 135 //------------------------------------------------------------------ 136 typedef std::pair <lldb::addr_t, uintptr_t> AddrRange; 137 AddrRange 138 GetRemoteRangeForLocal (lldb::addr_t local_address); 139 140 //------------------------------------------------------------------ 141 /// Commit all allocations to the process and record where they were stored. 142 /// 143 /// @param[in] process 144 /// The process to allocate memory in. 145 /// 146 /// @return 147 /// True <=> all allocations were performed successfully. 148 /// This method will attempt to free allocated memory if the 149 /// operation fails. 150 //------------------------------------------------------------------ 151 bool 152 CommitAllocations (lldb::ProcessSP &process_sp); 153 154 //------------------------------------------------------------------ 155 /// Report all committed allocations to the execution engine. 156 /// 157 /// @param[in] engine 158 /// The execution engine to notify. 159 //------------------------------------------------------------------ 160 void 161 ReportAllocations (llvm::ExecutionEngine &engine); 162 163 //------------------------------------------------------------------ 164 /// Write the contents of all allocations to the process. 165 /// 166 /// @param[in] local_address 167 /// The process containing the allocations. 168 /// 169 /// @return 170 /// True <=> all allocations were performed successfully. 171 //------------------------------------------------------------------ 172 bool 173 WriteData (lldb::ProcessSP &process_sp); 174 175 Error 176 DisassembleFunction (Stream &stream, 177 lldb::ProcessSP &process_sp); 178 179 class MemoryManager : public llvm::JITMemoryManager 180 { 181 public: 182 MemoryManager (IRExecutionUnit &parent); 183 184 //------------------------------------------------------------------ 185 /// Passthrough interface stub 186 //------------------------------------------------------------------ 187 virtual void setMemoryWritable (); 188 189 //------------------------------------------------------------------ 190 /// Passthrough interface stub 191 //------------------------------------------------------------------ 192 virtual void setMemoryExecutable (); 193 194 //------------------------------------------------------------------ 195 /// Passthrough interface stub 196 //------------------------------------------------------------------ 197 virtual void setPoisonMemory (bool poison) 198 { 199 m_default_mm_ap->setPoisonMemory (poison); 200 } 201 202 //------------------------------------------------------------------ 203 /// Passthrough interface stub 204 //------------------------------------------------------------------ 205 virtual void AllocateGOT() 206 { 207 m_default_mm_ap->AllocateGOT(); 208 } 209 210 //------------------------------------------------------------------ 211 /// Passthrough interface stub 212 //------------------------------------------------------------------ 213 virtual uint8_t *getGOTBase() const 214 { 215 return m_default_mm_ap->getGOTBase(); 216 } 217 218 //------------------------------------------------------------------ 219 /// Passthrough interface stub 220 //------------------------------------------------------------------ 221 virtual uint8_t *startFunctionBody(const llvm::Function *F, 222 uintptr_t &ActualSize); 223 224 //------------------------------------------------------------------ 225 /// Allocate room for a dyld stub for a lazy-referenced function, 226 /// and add it to the m_stubs map 227 /// 228 /// @param[in] F 229 /// The function being referenced. 230 /// 231 /// @param[in] StubSize 232 /// The size of the stub. 233 /// 234 /// @param[in] Alignment 235 /// The required alignment of the stub. 236 /// 237 /// @return 238 /// Allocated space for the stub. 239 //------------------------------------------------------------------ 240 virtual uint8_t *allocateStub(const llvm::GlobalValue* F, 241 unsigned StubSize, 242 unsigned Alignment); 243 244 //------------------------------------------------------------------ 245 /// Complete the body of a function, and add it to the m_functions map 246 /// 247 /// @param[in] F 248 /// The function being completed. 249 /// 250 /// @param[in] FunctionStart 251 /// The first instruction of the function. 252 /// 253 /// @param[in] FunctionEnd 254 /// The last byte of the last instruction of the function. 255 //------------------------------------------------------------------ 256 virtual void endFunctionBody(const llvm::Function *F, 257 uint8_t *FunctionStart, 258 uint8_t *FunctionEnd); 259 //------------------------------------------------------------------ 260 /// Allocate space for an unspecified purpose, and add it to the 261 /// m_spaceBlocks map 262 /// 263 /// @param[in] Size 264 /// The size of the area. 265 /// 266 /// @param[in] Alignment 267 /// The required alignment of the area. 268 /// 269 /// @return 270 /// Allocated space. 271 //------------------------------------------------------------------ 272 virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment); 273 274 //------------------------------------------------------------------ 275 /// Allocate space for executable code, and add it to the 276 /// m_spaceBlocks map 277 /// 278 /// @param[in] Size 279 /// The size of the area. 280 /// 281 /// @param[in] Alignment 282 /// The required alignment of the area. 283 /// 284 /// @param[in] SectionID 285 /// A unique identifier for the section. 286 /// 287 /// @return 288 /// Allocated space. 289 //------------------------------------------------------------------ 290 virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 291 unsigned SectionID); 292 293 //------------------------------------------------------------------ 294 /// Allocate space for data, and add it to the m_spaceBlocks map 295 /// 296 /// @param[in] Size 297 /// The size of the area. 298 /// 299 /// @param[in] Alignment 300 /// The required alignment of the area. 301 /// 302 /// @param[in] SectionID 303 /// A unique identifier for the section. 304 /// 305 /// @param[in] IsReadOnly 306 /// Flag indicating the section is read-only. 307 /// 308 /// @return 309 /// Allocated space. 310 //------------------------------------------------------------------ 311 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 312 unsigned SectionID, bool IsReadOnly); 313 314 //------------------------------------------------------------------ 315 /// Allocate space for a global variable, and add it to the 316 /// m_spaceBlocks map 317 /// 318 /// @param[in] Size 319 /// The size of the variable. 320 /// 321 /// @param[in] Alignment 322 /// The required alignment of the variable. 323 /// 324 /// @return 325 /// Allocated space for the global. 326 //------------------------------------------------------------------ 327 virtual uint8_t *allocateGlobal(uintptr_t Size, 328 unsigned Alignment); 329 330 //------------------------------------------------------------------ 331 /// Called when object loading is complete and section page 332 /// permissions can be applied. Currently unimplemented for LLDB. 333 /// 334 /// @param[out] ErrMsg 335 /// The error that prevented the page protection from succeeding. 336 /// 337 /// @return 338 /// True in case of failure, false in case of success. 339 //------------------------------------------------------------------ 340 bool applyPermissions(std::string *ErrMsg) { return false; } 341 342 //------------------------------------------------------------------ 343 /// Passthrough interface stub 344 //------------------------------------------------------------------ 345 virtual void deallocateFunctionBody(void *Body); 346 347 //------------------------------------------------------------------ 348 /// Passthrough interface stub 349 //------------------------------------------------------------------ 350 virtual uint8_t* startExceptionTable(const llvm::Function* F, 351 uintptr_t &ActualSize); 352 353 //------------------------------------------------------------------ 354 /// Complete the exception table for a function, and add it to the 355 /// m_exception_tables map 356 /// 357 /// @param[in] F 358 /// The function whose exception table is being written. 359 /// 360 /// @param[in] TableStart 361 /// The first byte of the exception table. 362 /// 363 /// @param[in] TableEnd 364 /// The last byte of the exception table. 365 /// 366 /// @param[in] FrameRegister 367 /// I don't know what this does, but it's passed through. 368 //------------------------------------------------------------------ 369 virtual void endExceptionTable(const llvm::Function *F, 370 uint8_t *TableStart, 371 uint8_t *TableEnd, 372 uint8_t* FrameRegister); 373 374 //------------------------------------------------------------------ 375 /// Passthrough interface stub 376 //------------------------------------------------------------------ 377 virtual void deallocateExceptionTable(void *ET); 378 379 //------------------------------------------------------------------ 380 /// Passthrough interface stub 381 //------------------------------------------------------------------ 382 virtual size_t GetDefaultCodeSlabSize() { 383 return m_default_mm_ap->GetDefaultCodeSlabSize(); 384 } 385 386 //------------------------------------------------------------------ 387 /// Passthrough interface stub 388 //------------------------------------------------------------------ 389 virtual size_t GetDefaultDataSlabSize() { 390 return m_default_mm_ap->GetDefaultDataSlabSize(); 391 } 392 393 virtual size_t GetDefaultStubSlabSize() { 394 return m_default_mm_ap->GetDefaultStubSlabSize(); 395 } 396 397 //------------------------------------------------------------------ 398 /// Passthrough interface stub 399 //------------------------------------------------------------------ 400 virtual unsigned GetNumCodeSlabs() { 401 return m_default_mm_ap->GetNumCodeSlabs(); 402 } 403 404 //------------------------------------------------------------------ 405 /// Passthrough interface stub 406 //------------------------------------------------------------------ 407 virtual unsigned GetNumDataSlabs() { 408 return m_default_mm_ap->GetNumDataSlabs(); 409 } 410 411 //------------------------------------------------------------------ 412 /// Passthrough interface stub 413 //------------------------------------------------------------------ 414 virtual unsigned GetNumStubSlabs() { 415 return m_default_mm_ap->GetNumStubSlabs(); 416 } 417 418 virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) { 419 return m_default_mm_ap->registerEHFrames(llvm::StringRef((const char *)Addr, Size)); 420 } 421 422 //------------------------------------------------------------------ 423 /// Passthrough interface stub 424 //------------------------------------------------------------------ 425 virtual void *getPointerToNamedFunction(const std::string &Name, 426 bool AbortOnFailure = true) { 427 return m_default_mm_ap->getPointerToNamedFunction(Name, AbortOnFailure); 428 } 429 private: 430 std::unique_ptr<JITMemoryManager> m_default_mm_ap; ///< The memory allocator to use in actually creating space. All calls are passed through to it. 431 IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for. 432 }; 433 434 //---------------------------------------------------------------------- 435 /// @class JittedFunction IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h" 436 /// @brief Encapsulates a single function that has been generated by the JIT. 437 /// 438 /// Functions that have been generated by the JIT are first resident in the 439 /// local process, and then placed in the target process. JittedFunction 440 /// represents a function possibly resident in both. 441 //---------------------------------------------------------------------- 442 struct JittedFunction { 443 std::string m_name; ///< The function's name 444 lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory 445 lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory 446 447 //------------------------------------------------------------------ 448 /// Constructor 449 /// 450 /// Initializes class variabes. 451 /// 452 /// @param[in] name 453 /// The name of the function. 454 /// 455 /// @param[in] local_addr 456 /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if 457 /// it is not present in LLDB's memory. 458 /// 459 /// @param[in] remote_addr 460 /// The address of the function in the target, or LLDB_INVALID_ADDRESS 461 /// if it is not present in the target's memory. 462 //------------------------------------------------------------------ 463 JittedFunction (const char *name, 464 lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, 465 lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) : 466 m_name (name), 467 m_local_addr (local_addr), 468 m_remote_addr (remote_addr) 469 { 470 } 471 }; 472 473 static const unsigned eSectionIDInvalid = (unsigned)-1; 474 475 //---------------------------------------------------------------------- 476 /// @class AllocationRecord IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h" 477 /// @brief Enacpsulates a single allocation request made by the JIT. 478 /// 479 /// Allocations made by the JIT are first queued up and then applied in 480 /// bulk to the underlying process. 481 //---------------------------------------------------------------------- 482 struct AllocationRecord { 483 lldb::addr_t m_process_address; 484 uintptr_t m_host_address; 485 uint32_t m_permissions; 486 size_t m_size; 487 unsigned m_alignment; 488 unsigned m_section_id; 489 490 AllocationRecord (uintptr_t host_address, 491 uint32_t permissions, 492 size_t size, 493 unsigned alignment, 494 unsigned section_id = eSectionIDInvalid) : 495 m_process_address(LLDB_INVALID_ADDRESS), 496 m_host_address(host_address), 497 m_permissions(permissions), 498 m_size(size), 499 m_alignment(alignment), 500 m_section_id(section_id) 501 { 502 } 503 504 void dump (Log *log); 505 }; 506 507 typedef std::vector<AllocationRecord> RecordVector; 508 RecordVector m_records; 509 510 std::unique_ptr<llvm::LLVMContext> m_context_ap; 511 std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_ap; 512 std::unique_ptr<llvm::Module> m_module_ap; ///< Holder for the module until it's been handed off 513 llvm::Module *m_module; ///< Owned by the execution engine 514 std::vector<std::string> m_cpu_features; 515 llvm::SmallVector<JittedFunction, 1> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code 516 const ConstString m_name; 517 518 std::atomic<bool> m_did_jit; 519 520 lldb::addr_t m_function_load_addr; 521 lldb::addr_t m_function_end_load_addr; 522}; 523 524} // namespace lldb_private 525 526#endif // lldb_IRExecutionUnit_h_ 527