#include "jit.h"
#include "breakpoint.h"
+#include "command.h"
+#include "gdbcmd.h"
#include "gdbcore.h"
#include "observer.h"
#include "objfiles.h"
static int registering_code = 0;
+/* Non-zero if we want to see trace of jit level stuff. */
+
+static int jit_debug = 0;
+
+static void
+show_jit_debug (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("JIT debugging is %s.\n"), value);
+}
+
/* Helper cleanup function to clear an integer flag like the one above. */
static void
struct target_buffer
{
CORE_ADDR base;
- size_t size;
+ ULONGEST size;
};
/* Openning the file is a no-op. */
/* Open a BFD from the target's memory. */
static struct bfd *
-bfd_open_from_target_memory (CORE_ADDR addr, size_t size, char *target)
+bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, char *target)
{
const char *filename = xstrdup ("<in-memory>");
struct target_buffer *buffer = xmalloc (sizeof (struct target_buffer));
mem_bfd_iovec_stat);
}
-/* Helper function for reading the global JIT descriptor from remote memory. */
+/* Helper function for reading the global JIT descriptor from remote
+ memory. */
static void
jit_read_descriptor (struct gdbarch *gdbarch,
const struct bfd_arch_info *b;
CORE_ADDR *entry_addr_ptr;
+ if (jit_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "jit_register_code, symfile_addr = %s, "
+ "symfile_size = %s\n",
+ paddress (gdbarch, code_entry->symfile_addr),
+ pulongest (code_entry->symfile_size));
+
nbfd = bfd_open_from_target_memory (code_entry->symfile_addr,
code_entry->symfile_size, gnutarget);
old_cleanups = make_cleanup_bfd_close (nbfd);
discard_cleanups (old_cleanups);
}
-/* This function unregisters JITed code and frees the corresponding objfile. */
+/* This function unregisters JITed code and frees the corresponding
+ objfile. */
static void
jit_unregister_code (struct objfile *objfile)
struct jit_code_entry cur_entry;
CORE_ADDR cur_entry_addr;
+ if (jit_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "jit_inferior_init, registering_code = %d\n",
+ registering_code);
+
/* When we register code, GDB resets its breakpoints in case symbols have
changed. That in turn calls this handler, which makes us look for new
code again. To avoid being re-entered, we check this flag. */
if (reg_addr == 0)
return;
+ if (jit_debug)
+ fprintf_unfiltered (gdb_stdlog, "jit_inferior_init, reg_addr = %s\n",
+ paddress (gdbarch, reg_addr));
+
/* Lookup the descriptor symbol and cache the addr. If it is missing, we
assume we are not attached to a JIT and return early. */
desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, NULL);
if (jit_descriptor_addr == 0)
return;
- /* Read the descriptor so we can check the version number and load any already
- JITed functions. */
+ if (jit_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "jit_inferior_init, jit_descriptor_addr = %s\n",
+ paddress (gdbarch, jit_descriptor_addr));
+
+ /* Read the descriptor so we can check the version number and load
+ any already JITed functions. */
jit_read_descriptor (gdbarch, &descriptor);
/* Check that the version number agrees with that we support. */
/* Put a breakpoint in the registration symbol. */
create_jit_event_breakpoint (gdbarch, reg_addr);
- /* If we've attached to a running program, we need to check the descriptor to
- register any functions that were already generated. */
+ /* If we've attached to a running program, we need to check the descriptor
+ to register any functions that were already generated. */
for (cur_entry_addr = descriptor.first_entry;
cur_entry_addr != 0;
cur_entry_addr = cur_entry.next_entry)
jit_inferior_init (target_gdbarch);
}
-/* This function cleans up any code entries left over when the inferior exits.
- We get left over code when the inferior exits without unregistering its code,
- for example when it crashes. */
+/* This function cleans up any code entries left over when the
+ inferior exits. We get left over code when the inferior exits
+ without unregistering its code, for example when it crashes. */
static void
jit_inferior_exit_hook (struct inferior *inf)
jit_read_descriptor (gdbarch, &descriptor);
entry_addr = descriptor.relevant_entry;
- /* Do the corresponding action. */
+ /* Do the corresponding action. */
switch (descriptor.action_flag)
{
case JIT_NOACTION:
case JIT_UNREGISTER:
objf = jit_find_objf_with_entry_addr (entry_addr);
if (objf == NULL)
- printf_unfiltered (_("Unable to find JITed code entry at address: %s\n"),
+ printf_unfiltered (_("Unable to find JITed code "
+ "entry at address: %s\n"),
paddress (gdbarch, entry_addr));
else
jit_unregister_code (objf);
void
_initialize_jit (void)
{
+ add_setshow_zinteger_cmd ("jit", class_maintenance, &jit_debug,
+ _("Set JIT debugging."),
+ _("Show JIT debugging."),
+ _("When non-zero, JIT debugging is enabled."),
+ NULL,
+ show_jit_debug,
+ &setdebuglist, &showdebuglist);
+
observer_attach_inferior_created (jit_inferior_created_observer);
observer_attach_inferior_exit (jit_inferior_exit_hook);
jit_objfile_data = register_objfile_data ();