void JITDebugRegisterer::UnregisterFunctionInternal( RegisteredFunctionsMap::iterator I) { jit_code_entry *&JITCodeEntry = I->second.second; // Acquire the lock and do the unregistration. { MutexGuard locked(JITDebugLock); __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN; // Remove the jit_code_entry from the linked list. jit_code_entry *PrevEntry = JITCodeEntry->prev_entry; jit_code_entry *NextEntry = JITCodeEntry->next_entry; if (NextEntry) { NextEntry->prev_entry = PrevEntry; } if (PrevEntry) { PrevEntry->next_entry = NextEntry; } else { assert(__jit_debug_descriptor.first_entry == JITCodeEntry); __jit_debug_descriptor.first_entry = NextEntry; } // Tell GDB which entry we removed, and unregister the code. __jit_debug_descriptor.relevant_entry = JITCodeEntry; __jit_debug_register_code(); } delete JITCodeEntry; JITCodeEntry = NULL; // Free the ELF file in memory. std::string &Buffer = I->second.first; Buffer.clear(); }
void JITDebugRegisterer::RegisterFunction(const Function *F, DebugInfo &I) { // TODO: Support non-ELF platforms. if (!TM.getELFWriterInfo()) return; std::string Buffer = MakeELF(F, I); jit_code_entry *JITCodeEntry = new jit_code_entry(); JITCodeEntry->symfile_addr = Buffer.c_str(); JITCodeEntry->symfile_size = Buffer.size(); // Add a mapping from F to the entry and buffer, so we can delete this // info later. FnMap[F] = std::make_pair<std::string, jit_code_entry*>(Buffer, JITCodeEntry); // Acquire the lock and do the registration. { MutexGuard locked(JITDebugLock); __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; // Insert this entry at the head of the list. JITCodeEntry->prev_entry = NULL; jit_code_entry *NextEntry = __jit_debug_descriptor.first_entry; JITCodeEntry->next_entry = NextEntry; if (NextEntry != NULL) { NextEntry->prev_entry = JITCodeEntry; } __jit_debug_descriptor.first_entry = JITCodeEntry; __jit_debug_descriptor.relevant_entry = JITCodeEntry; __jit_debug_register_code(); } }
int main (int argc, char **argv) { struct jithost_abi *symfile; char *code = mmap (NULL, getpagesize (), PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); jit_function_t *function = (jit_function_t *) code; memcpy (code, jit_function_00_code, sizeof (jit_function_00_code)); symfile = malloc (sizeof (struct jithost_abi)); symfile->begin = code; symfile->end = code + sizeof (jit_function_00_code); only_entry.symfile_addr = symfile; only_entry.symfile_size = sizeof (struct jithost_abi); __jit_debug_descriptor.first_entry = &only_entry; __jit_debug_descriptor.relevant_entry = &only_entry; __jit_debug_descriptor.action_flag = JIT_REGISTER; __jit_debug_descriptor.version = 1; __jit_debug_register_code (); function (); return 0; }
static void xdebug_end_emit (MonoImageWriter *w, MonoDwarfWriter *dw, MonoMethod *method) { guint8 *img; guint32 img_size; struct jit_code_entry *entry; guint64 *psize; il_file_line_index = mono_dwarf_writer_get_il_file_line_index (dw); mono_dwarf_writer_close (dw); img_writer_emit_writeout (w); img = img_writer_get_output (w, &img_size); img_writer_destroy (w); if (FALSE) { /* Save the symbol files to help debugging */ FILE *fp; char *file_name; static int file_counter; file_counter ++; file_name = g_strdup_printf ("xdb-%d.o", file_counter); printf ("%s %p %d\n", file_name, img, img_size); fp = fopen (file_name, "w"); fwrite (img, img_size, 1, fp); fclose (fp); g_free (file_name); } /* Register the image with GDB */ entry = g_malloc0 (sizeof (struct jit_code_entry)); entry->symfile_addr = (const char*)img; psize = (guint64*)&entry->symfile_size1; *psize = img_size; entry->next_entry = __jit_debug_descriptor.first_entry; if (__jit_debug_descriptor.first_entry) __jit_debug_descriptor.first_entry->prev_entry = entry; __jit_debug_descriptor.first_entry = entry; __jit_debug_descriptor.relevant_entry = entry; __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; __jit_debug_register_code (); }