dce506bbfefd904985bc6f03862b20702ba6eca7
[oota-llvm.git] / lib / ExecutionEngine / JIT / JITDebugRegisterer.h
1 //===-- JITDebugRegisterer.h - Register debug symbols for JIT -------------===//
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 // This file defines a JITDebugRegisterer object that is used by the JIT to
11 // register debug info with debuggers like GDB.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_EXECUTION_ENGINE_JIT_DEBUGREGISTERER_H
16 #define LLVM_EXECUTION_ENGINE_JIT_DEBUGREGISTERER_H
17
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/Support/DataTypes.h"
20 #include <string>
21
22 // This must be kept in sync with gdb/gdb/jit.h .
23 extern "C" {
24
25   typedef enum {
26     JIT_NOACTION = 0,
27     JIT_REGISTER_FN,
28     JIT_UNREGISTER_FN
29   } jit_actions_t;
30
31   struct jit_code_entry {
32     struct jit_code_entry *next_entry;
33     struct jit_code_entry *prev_entry;
34     const char *symfile_addr;
35     uint64_t symfile_size;
36   };
37
38   struct jit_descriptor {
39     uint32_t version;
40     // This should be jit_actions_t, but we want to be specific about the
41     // bit-width.
42     uint32_t action_flag;
43     struct jit_code_entry *relevant_entry;
44     struct jit_code_entry *first_entry;
45   };
46
47 }
48
49 namespace llvm {
50
51 class ELFSection;
52 class Function;
53 class TargetMachine;
54
55
56 /// This class encapsulates information we want to send to the debugger.
57 ///
58 struct DebugInfo {
59   uint8_t *FnStart;
60   uint8_t *FnEnd;
61   uint8_t *EhStart;
62   uint8_t *EhEnd;
63
64   DebugInfo() : FnStart(0), FnEnd(0), EhStart(0), EhEnd(0) {}
65 };
66
67 typedef DenseMap< const Function*, std::pair<std::string, jit_code_entry*> >
68   RegisteredFunctionsMap;
69
70 /// This class registers debug info for JITed code with an attached debugger.
71 /// Without proper debug info, GDB can't do things like source level debugging
72 /// or even produce a proper stack trace on linux-x86_64.  To use this class,
73 /// whenever a function is JITed, create a DebugInfo struct and pass it to the
74 /// RegisterFunction method.  The method will then do whatever is necessary to
75 /// inform the debugger about the JITed function.
76 class JITDebugRegisterer {
77
78   TargetMachine &TM;
79
80   /// FnMap - A map of functions that have been registered to the associated
81   /// temporary files.  Used for cleanup.
82   RegisteredFunctionsMap FnMap;
83
84   /// MakeELF - Builds the ELF file in memory and returns a std::string that
85   /// contains the ELF.
86   std::string MakeELF(const Function *F, DebugInfo &I);
87
88 public:
89   JITDebugRegisterer(TargetMachine &tm);
90
91   /// ~JITDebugRegisterer - Unregisters all code and frees symbol files.
92   ///
93   ~JITDebugRegisterer();
94
95   /// RegisterFunction - Register debug info for the given function with an
96   /// attached debugger.  Clients must call UnregisterFunction on all
97   /// registered functions before deleting them to free the associated symbol
98   /// file and unregister it from the debugger.
99   void RegisterFunction(const Function *F, DebugInfo &I);
100
101   /// UnregisterFunction - Unregister the debug info for the given function
102   /// from the debugger and free associated memory.
103   void UnregisterFunction(const Function *F);
104
105 private:
106   /// UnregisterFunctionInternal - Unregister the debug info for the given
107   /// function from the debugger and delete any temporary files.  The private
108   /// version of this method does not remove the function from FnMap so that it
109   /// can be called while iterating over FnMap.
110   void UnregisterFunctionInternal(RegisteredFunctionsMap::iterator I);
111
112 };
113
114 } // end namespace llvm
115
116 #endif // LLVM_EXECUTION_ENGINE_JIT_DEBUGREGISTERER_H