llvm.org GIT mirror llvm / 482f878
Add files which were not included by commit 154868. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154872 91177308-0d34-0410-b5e6-96231b3b80d8 Preston Gurd 8 years ago
3 changed file(s) with 316 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===-- GDBRegistrar.cpp - Registers objects with GDB ---------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "JITRegistrar.h"
10 #include "llvm/ADT/DenseMap.h"
11 #include "llvm/Support/MutexGuard.h"
12 #include "llvm/Support/Mutex.h"
13 #include "llvm/Support/ErrorHandling.h"
14 #include "llvm/Support/Compiler.h"
15
16 using namespace llvm;
17
18 // This must be kept in sync with gdb/gdb/jit.h .
19 extern "C" {
20
21 typedef enum {
22 JIT_NOACTION = 0,
23 JIT_REGISTER_FN,
24 JIT_UNREGISTER_FN
25 } jit_actions_t;
26
27 struct jit_code_entry {
28 struct jit_code_entry *next_entry;
29 struct jit_code_entry *prev_entry;
30 const char *symfile_addr;
31 uint64_t symfile_size;
32 };
33
34 struct jit_descriptor {
35 uint32_t version;
36 // This should be jit_actions_t, but we want to be specific about the
37 // bit-width.
38 uint32_t action_flag;
39 struct jit_code_entry *relevant_entry;
40 struct jit_code_entry *first_entry;
41 };
42
43 // We put information about the JITed function in this global, which the
44 // debugger reads. Make sure to specify the version statically, because the
45 // debugger checks the version before we can set it during runtime.
46 static struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
47
48 // Debuggers puts a breakpoint in this function.
49 LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() { }
50
51 }
52
53 namespace {
54
55 // Buffer for an in-memory object file in executable memory
56 typedef llvm::DenseMap< const char*,
57 std::pair >
58 RegisteredObjectBufferMap;
59
60 /// Global access point for the JIT debugging interface designed for use with a
61 /// singleton toolbox. Handles thread-safe registration and deregistration of
62 /// object files that are in executable memory managed by the client of this
63 /// class.
64 class GDBJITRegistrar : public JITRegistrar {
65 /// A map of in-memory object files that have been registered with the
66 /// JIT interface.
67 RegisteredObjectBufferMap ObjectBufferMap;
68
69 public:
70 /// Instantiates the JIT service.
71 GDBJITRegistrar() : ObjectBufferMap() {}
72
73 /// Unregisters each object that was previously registered and releases all
74 /// internal resources.
75 virtual ~GDBJITRegistrar();
76
77 /// Creates an entry in the JIT registry for the buffer @p Object,
78 /// which must contain an object file in executable memory with any
79 /// debug information for the debugger.
80 void registerObject(const MemoryBuffer &Object);
81
82 /// Removes the internal registration of @p Object, and
83 /// frees associated resources.
84 /// Returns true if @p Object was found in ObjectBufferMap.
85 bool deregisterObject(const MemoryBuffer &Object);
86
87 private:
88 /// Deregister the debug info for the given object file from the debugger
89 /// and delete any temporary copies. This private method does not remove
90 /// the function from Map so that it can be called while iterating over Map.
91 void deregisterObjectInternal(RegisteredObjectBufferMap::iterator I);
92 };
93
94 /// Lock used to serialize all jit registration events, since they
95 /// modify global variables.
96 llvm::sys::Mutex JITDebugLock;
97
98 /// Acquire the lock and do the registration.
99 void NotifyDebugger(jit_code_entry* JITCodeEntry) {
100 llvm::MutexGuard locked(JITDebugLock);
101 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
102
103 // Insert this entry at the head of the list.
104 JITCodeEntry->prev_entry = NULL;
105 jit_code_entry* NextEntry = __jit_debug_descriptor.first_entry;
106 JITCodeEntry->next_entry = NextEntry;
107 if (NextEntry != NULL) {
108 NextEntry->prev_entry = JITCodeEntry;
109 }
110 __jit_debug_descriptor.first_entry = JITCodeEntry;
111 __jit_debug_descriptor.relevant_entry = JITCodeEntry;
112 __jit_debug_register_code();
113 }
114
115 GDBJITRegistrar::~GDBJITRegistrar() {
116 // Free all registered object files.
117 for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), E = ObjectBufferMap.end();
118 I != E; ++I) {
119 // Call the private method that doesn't update the map so our iterator
120 // doesn't break.
121 deregisterObjectInternal(I);
122 }
123 ObjectBufferMap.clear();
124 }
125
126 void GDBJITRegistrar::registerObject(const MemoryBuffer &Object) {
127
128 const char *Buffer = Object.getBufferStart();
129 size_t Size = Object.getBufferSize();
130
131 assert(Buffer && "Attempt to register a null object with a debugger.");
132 assert(ObjectBufferMap.find(Buffer) == ObjectBufferMap.end() &&
133 "Second attempt to perform debug registration.");
134 jit_code_entry* JITCodeEntry = new jit_code_entry();
135
136 if (JITCodeEntry == 0) {
137 llvm::report_fatal_error(
138 "Allocation failed when registering a JIT entry!\n");
139 }
140 else {
141 JITCodeEntry->symfile_addr = Buffer;
142 JITCodeEntry->symfile_size = Size;
143
144 ObjectBufferMap[Buffer] = std::make_pair(Size, JITCodeEntry);
145 NotifyDebugger(JITCodeEntry);
146 }
147 }
148
149 bool GDBJITRegistrar::deregisterObject(const MemoryBuffer& Object) {
150 const char *Buffer = Object.getBufferStart();
151 RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Buffer);
152
153 if (I != ObjectBufferMap.end()) {
154 deregisterObjectInternal(I);
155 ObjectBufferMap.erase(I);
156 return true;
157 }
158 return false;
159 }
160
161 void GDBJITRegistrar::deregisterObjectInternal(
162 RegisteredObjectBufferMap::iterator I) {
163
164 jit_code_entry*& JITCodeEntry = I->second.second;
165
166 // Acquire the lock and do the unregistration.
167 {
168 llvm::MutexGuard locked(JITDebugLock);
169 __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
170
171 // Remove the jit_code_entry from the linked list.
172 jit_code_entry* PrevEntry = JITCodeEntry->prev_entry;
173 jit_code_entry* NextEntry = JITCodeEntry->next_entry;
174
175 if (NextEntry) {
176 NextEntry->prev_entry = PrevEntry;
177 }
178 if (PrevEntry) {
179 PrevEntry->next_entry = NextEntry;
180 }
181 else {
182 assert(__jit_debug_descriptor.first_entry == JITCodeEntry);
183 __jit_debug_descriptor.first_entry = NextEntry;
184 }
185
186 // Tell the debugger which entry we removed, and unregister the code.
187 __jit_debug_descriptor.relevant_entry = JITCodeEntry;
188 __jit_debug_register_code();
189 }
190
191 delete JITCodeEntry;
192 JITCodeEntry = NULL;
193 }
194
195 } // end namespace
196
197 namespace llvm {
198
199 JITRegistrar& JITRegistrar::getGDBRegistrar() {
200 static GDBJITRegistrar* sRegistrar = NULL;
201 if (sRegistrar == NULL) {
202 // The mutex is here so that it won't slow down access once the registrar
203 // is instantiated
204 llvm::MutexGuard locked(JITDebugLock);
205 // Check again to be sure another thread didn't create this while we waited
206 if (sRegistrar == NULL) {
207 sRegistrar = new GDBJITRegistrar;
208 }
209 }
210 return *sRegistrar;
211 }
212
213 } // namespace llvm
0 //===-- JITRegistrar.h - Registers objects with a debugger ----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_EXECUTION_ENGINE_JIT_REGISTRAR_H
10 #define LLVM_EXECUTION_ENGINE_JIT_REGISTRAR_H
11
12 #include "llvm/Support/MemoryBuffer.h"
13
14 namespace llvm {
15
16 /// Global access point for the JIT debugging interface.
17 class JITRegistrar {
18 public:
19 /// Instantiates the JIT service.
20 JITRegistrar() {}
21
22 /// Unregisters each object that was previously registered and releases all
23 /// internal resources.
24 virtual ~JITRegistrar() {}
25
26 /// Creates an entry in the JIT registry for the buffer @p Object,
27 /// which must contain an object file in executable memory with any
28 /// debug information for the debugger.
29 virtual void registerObject(const MemoryBuffer &Object) = 0;
30
31 /// Removes the internal registration of @p Object, and
32 /// frees associated resources.
33 /// Returns true if @p Object was previously registered.
34 virtual bool deregisterObject(const MemoryBuffer &Object) = 0;
35
36 /// Returns a reference to a GDB JIT registrar singleton
37 static JITRegistrar& getGDBRegistrar();
38 };
39
40 } // end namespace llvm
41
42 #endif // LLVM_EXECUTION_ENGINE_JIT_REGISTRAR_H
0 //===---- ObjectImage.h - Format independent executuable object image -----===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares a file format independent ObjectImage class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
14 #define LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
15
16 #include "llvm/Object/ObjectFile.h"
17
18 namespace llvm {
19
20 class ObjectImage {
21 ObjectImage(); // = delete
22 ObjectImage(const ObjectImage &other); // = delete
23 protected:
24 object::ObjectFile *ObjFile;
25
26 public:
27 ObjectImage(object::ObjectFile *Obj) { ObjFile = Obj; }
28 virtual ~ObjectImage() {}
29
30 virtual object::symbol_iterator begin_symbols() const
31 { return ObjFile->begin_symbols(); }
32 virtual object::symbol_iterator end_symbols() const
33 { return ObjFile->end_symbols(); }
34
35 virtual object::section_iterator begin_sections() const
36 { return ObjFile->begin_sections(); }
37 virtual object::section_iterator end_sections() const
38 { return ObjFile->end_sections(); }
39
40 virtual /* Triple::ArchType */ unsigned getArch() const
41 { return ObjFile->getArch(); }
42
43 // Subclasses can override these methods to update the image with loaded
44 // addresses for sections and common symbols
45 virtual void updateSectionAddress(const object::SectionRef &Sec,
46 uint64_t Addr) {}
47 virtual void updateSymbolAddress(const object::SymbolRef &Sym, uint64_t Addr)
48 {}
49
50 // Subclasses can override this method to provide JIT debugging support
51 virtual void registerWithDebugger() {}
52 virtual void deregisterWithDebugger() {}
53 };
54
55 } // end namespace llvm
56
57 #endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
58