1094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea/* 2094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * Copyright 2012, The Android Open Source Project 3094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * 4094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * Licensed under the Apache License, Version 2.0 (the "License"); 5094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * you may not use this file except in compliance with the License. 6094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * You may obtain a copy of the License at 7094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * 8094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * http://www.apache.org/licenses/LICENSE-2.0 9094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * 10094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * Unless required by applicable law or agreed to in writing, software 11094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * distributed under the License is distributed on an "AS IS" BASIS, 12094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * See the License for the specific language governing permissions and 14094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea * limitations under the License. 15094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea */ 16094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 17094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// This file contains portions derived from LLVM, with the original copyright 18094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// header below: 19094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea//==----- GDBJITRegistrar.cpp - Notify GDB about in-memory object files ---==// 20094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// 21094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// The LLVM Compiler Infrastructure 22094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// 23094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// This file is distributed under the University of Illinois Open Source 24094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// License. See LICENSE.TXT for details. 25094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// 26094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea//===----------------------------------------------------------------------===// 27094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// 28094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// This file defines the GDBJITRegistrar object which is used by JIT engines to 29094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// register in-memory object files with GDB for debugging. 30094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// 31094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea//===----------------------------------------------------------------------===// 32094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 33c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/ExecutionEngine/GDBJITRegistrar.h" 34c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang 35c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include <llvm/ADT/DenseMap.h> 36c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include <llvm/Support/ErrorHandling.h> 37c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include <llvm/Support/Memory.h> 38c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include <llvm/Support/Mutex.h> 39c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include <llvm/Support/MutexGuard.h> 40c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang 41c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/ExecutionEngine/GDBJIT.h" 42094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 43094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#include <fstream> 44094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 45094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#ifdef ANDROID_ENGINEERING_BUILD 46094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// Path to write dump output. 47094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// It is expected that a debugger (plugin) sets this 48094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// string to a writeable directory where files (such as JITted object files, 49094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// IR dumps) are to be written. If this variable is 0, no debug dumps 50094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// are generated. 51094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleachar* gDebugDumpDirectory = 0; 52094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#endif // ANDROID_ENGINEERING_BUILD 53094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 54094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea//************************************************************************ 55094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// COPIED/ADAPTED FROM llvm/lib/ExecutionEngine/JIT/JITDebugRegisterer.cpp 56094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea//************************************************************************ 57094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// This must be kept in sync with gdb/gdb/jit.h . 58094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleaextern "C" { 59094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 60094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // We put information about the JITed function in this global, which the 61094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // debugger reads. Make sure to specify the version statically, because the 62094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // debugger checks the version before we can set it during runtime. 63094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea static struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; 64094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 65094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea} 66094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea//**************************************************************************** 67094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// END COPIED/ADAPTED FROM llvm/lib/ExecutionEngine/JIT/JITDebugRegisterer.cpp 68094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea//**************************************************************************** 69094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 70094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleanamespace { 71094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 72094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea// Buffer for an in-memory object file in executable memory 73094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleatypedef llvm::DenseMap< const ObjectBuffer*, std::pair<std::size_t, jit_code_entry*> > 74094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea RegisteredObjectBufferMap; 75094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 76094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea/// Global access point for the GDB JIT interface designed for use with a 77094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea/// singleton toolbox. Handles thread-safe registration and deregistration of 78094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea/// object files that are in executable memory managed by the client of this 79094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea/// class. 80094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleaclass GDBJITRegistrar { 81094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// A map of in-memory object files that have been registered with the GDB JIT interface. 82094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea RegisteredObjectBufferMap ObjectBufferMap; 83094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 84094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleapublic: 85094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// Instantiates the GDB JIT service. 86094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea GDBJITRegistrar() : ObjectBufferMap() {} 87094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 88094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// Unregisters each object that was previously registered with GDB, and 89094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// releases all internal resources. 90094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea ~GDBJITRegistrar(); 91094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 92094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// Creates an entry in the GDB JIT registry for the buffer @p Object, 93094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// which must contain an object file in executable memory with any 94094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// debug information for GDB. 95094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea void registerObject(const ObjectBuffer* Object, std::size_t Size); 96094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 97094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// Removes the internal registration of @p Object, and 98094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// frees associated resources. 99094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// Returns true if @p Object was found in ObjectBufferMap. 100094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea bool deregisterObject(const ObjectBuffer* Object); 101094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 102094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleaprivate: 103094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// Deregister the debug info for the given object file from the debugger 104094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// and delete any temporary copies. This private method does not remove 105094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea /// the function from Map so that it can be called while iterating over Map. 106094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea void deregisterObjectInternal(RegisteredObjectBufferMap::iterator I); 107094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea}; 108094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 109094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea/// Lock used to serialize all gdb-jit registration events, since they 110094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea/// modify global variables. 111094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleallvm::sys::Mutex JITDebugLock; 112094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 113094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea/// Acquire the lock and do the registration. 114094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleavoid NotifyGDB(jit_code_entry* JITCodeEntry) { 115094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea llvm::MutexGuard locked(JITDebugLock); 116094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; 117094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 118094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // Insert this entry at the head of the list. 119094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea JITCodeEntry->prev_entry = NULL; 120094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea jit_code_entry* NextEntry = __jit_debug_descriptor.first_entry; 121094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea JITCodeEntry->next_entry = NextEntry; 122094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea if (NextEntry != NULL) { 123094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea NextEntry->prev_entry = JITCodeEntry; 124094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 125094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea __jit_debug_descriptor.first_entry = JITCodeEntry; 126094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea __jit_debug_descriptor.relevant_entry = JITCodeEntry; 127094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea __jit_debug_register_code(); 128094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea} 129094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 130094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel MaleaGDBJITRegistrar* RegistrarSingleton() { 131094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea static GDBJITRegistrar* sRegistrar = NULL; 132094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea if (sRegistrar == NULL) { 133094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // The mutex is here so that it won't slow down access once the registrar 134094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // is instantiated 135094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea llvm::MutexGuard locked(JITDebugLock); 136094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // Check again to be sure another thread didn't create this while we waited 137094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea if (sRegistrar == NULL) { 138094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea sRegistrar = new GDBJITRegistrar; 139094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 140094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 141094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea return sRegistrar; 142094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea} 143094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 144094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel MaleaGDBJITRegistrar::~GDBJITRegistrar() { 145094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // Free all registered object files. 146094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), E = ObjectBufferMap.end(); 147094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea I != E; ++I) { 148094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // Call the private method that doesn't update the map so our iterator 149094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // doesn't break. 150094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea deregisterObjectInternal(I); 151094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 152094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea ObjectBufferMap.clear(); 153094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea} 154094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 155094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleavoid GDBJITRegistrar::registerObject(const ObjectBuffer* Object, std::size_t Size) { 156094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 157094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea assert(Object && "Attempt to register a null object with a debugger."); 158094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea assert(ObjectBufferMap.find(Object) == ObjectBufferMap.end() 159094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea && "Second attempt to perform debug registration."); 160094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 161094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea jit_code_entry* JITCodeEntry = new jit_code_entry(); 162094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 163094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea if (JITCodeEntry == 0) { 164094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea llvm::report_fatal_error("Allocation failed when registering a GDB-JIT entry!\n"); 165094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 166094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea else { 167094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea JITCodeEntry->symfile_addr = Object; 168094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea JITCodeEntry->symfile_size = Size; 169094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 170094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea ObjectBufferMap[Object] = std::make_pair(Size, JITCodeEntry); 171094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea NotifyGDB(JITCodeEntry); 172094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 173094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#ifdef ANDROID_ENGINEERING_BUILD 174094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea if (0 != gDebugDumpDirectory) { 175094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea std::string Filename(gDebugDumpDirectory); 176094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea Filename += "/jit_registered.o"; 177094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 178094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea std::ofstream outfile(Filename.c_str(), std::ofstream::binary); 179094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea outfile.write((char*)JITCodeEntry->symfile_addr, JITCodeEntry->symfile_size); 180094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea outfile.close(); 181094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 182094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea#endif 183094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 184094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea} 185094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 186094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleabool GDBJITRegistrar::deregisterObject(const ObjectBuffer *Object) { 187094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Object); 188094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 189094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea if (I != ObjectBufferMap.end()) { 190094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea deregisterObjectInternal(I); 191094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea ObjectBufferMap.erase(I); 192094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea return true; 193094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 194094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea return false; 195094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea} 196094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 197094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleavoid GDBJITRegistrar::deregisterObjectInternal( 198094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea RegisteredObjectBufferMap::iterator I) { 199094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 200094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea jit_code_entry*& JITCodeEntry = I->second.second; 201094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 202094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // Acquire the lock and do the unregistration. 203094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea { 204094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea llvm::MutexGuard locked(JITDebugLock); 205094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN; 206094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 207094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // Remove the jit_code_entry from the linked list. 208094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea jit_code_entry* PrevEntry = JITCodeEntry->prev_entry; 209094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea jit_code_entry* NextEntry = JITCodeEntry->next_entry; 210094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 211094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea if (NextEntry) { 212094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea NextEntry->prev_entry = PrevEntry; 213094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 214094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea if (PrevEntry) { 215094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea PrevEntry->next_entry = NextEntry; 216094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 217094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea else { 218094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea assert(__jit_debug_descriptor.first_entry == JITCodeEntry); 219094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea __jit_debug_descriptor.first_entry = NextEntry; 220094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 221094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 222094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea // Tell GDB which entry we removed, and unregister the code. 223094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea __jit_debug_descriptor.relevant_entry = JITCodeEntry; 224094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea __jit_debug_register_code(); 225094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 226094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 227094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea delete JITCodeEntry; 228094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea JITCodeEntry = NULL; 229094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea} 230094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 231094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea} // end namespace 232094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 233094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleavoid registerObjectWithGDB(const ObjectBuffer* Object, std::size_t Size) { 234094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea GDBJITRegistrar* Registrar = RegistrarSingleton(); 235094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea if (Registrar) { 236094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea Registrar->registerObject(Object, Size); 237094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 238094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea} 239094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea 240094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Maleavoid deregisterObjectWithGDB(const ObjectBuffer* Object) { 241094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea GDBJITRegistrar* Registrar = RegistrarSingleton(); 242094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea if (Registrar) { 243094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea Registrar->deregisterObject(Object); 244094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea } 245094881f513ab366f7ffd0b2c7778ab50281ca59eDaniel Malea} 246