//===-- JITDebugRegisterer.h - Register debug symbols for JIT -------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines a JITDebugRegisterer object that is used by the JIT to // register debug info with debuggers like GDB. // //===----------------------------------------------------------------------===// #ifndef LLVM_EXECUTION_ENGINE_JIT_DEBUGREGISTERER_H #define LLVM_EXECUTION_ENGINE_JIT_DEBUGREGISTERER_H #include "llvm/ADT/DenseMap.h" #include "llvm/System/DataTypes.h" #include // This must be kept in sync with gdb/gdb/jit.h . extern "C" { typedef enum { JIT_NOACTION = 0, JIT_REGISTER_FN, JIT_UNREGISTER_FN } jit_actions_t; struct jit_code_entry { struct jit_code_entry *next_entry; struct jit_code_entry *prev_entry; const char *symfile_addr; uint64_t symfile_size; }; struct jit_descriptor { uint32_t version; // This should be jit_actions_t, but we want to be specific about the // bit-width. uint32_t action_flag; struct jit_code_entry *relevant_entry; struct jit_code_entry *first_entry; }; } namespace llvm { class ELFSection; class Function; class TargetMachine; /// This class encapsulates information we want to send to the debugger. /// struct DebugInfo { uint8_t *FnStart; uint8_t *FnEnd; uint8_t *EhStart; uint8_t *EhEnd; DebugInfo() : FnStart(0), FnEnd(0), EhStart(0), EhEnd(0) {} }; typedef DenseMap< const Function*, std::pair > RegisteredFunctionsMap; /// This class registers debug info for JITed code with an attached debugger. /// Without proper debug info, GDB can't do things like source level debugging /// or even produce a proper stack trace on linux-x86_64. To use this class, /// whenever a function is JITed, create a DebugInfo struct and pass it to the /// RegisterFunction method. The method will then do whatever is necessary to /// inform the debugger about the JITed function. class JITDebugRegisterer { TargetMachine &TM; /// FnMap - A map of functions that have been registered to the associated /// temporary files. Used for cleanup. RegisteredFunctionsMap FnMap; /// MakeELF - Builds the ELF file in memory and returns a std::string that /// contains the ELF. std::string MakeELF(const Function *F, DebugInfo &I); public: JITDebugRegisterer(TargetMachine &tm); /// ~JITDebugRegisterer - Unregisters all code and frees symbol files. /// ~JITDebugRegisterer(); /// RegisterFunction - Register debug info for the given function with an /// attached debugger. Clients must call UnregisterFunction on all /// registered functions before deleting them to free the associated symbol /// file and unregister it from the debugger. void RegisterFunction(const Function *F, DebugInfo &I); /// UnregisterFunction - Unregister the debug info for the given function /// from the debugger and free associated memory. void UnregisterFunction(const Function *F); private: /// UnregisterFunctionInternal - Unregister the debug info for the given /// function from the debugger and delete any temporary files. The private /// version of this method does not remove the function from FnMap so that it /// can be called while iterating over FnMap. void UnregisterFunctionInternal(RegisteredFunctionsMap::iterator I); }; } // end namespace llvm #endif // LLVM_EXECUTION_ENGINE_JIT_DEBUGREGISTERER_H