Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH 4/7] Use the loaded reader.
  2011-08-09 15:21 [PATCH] JIT debug info Reader Sanjoy Das
                   ` (4 preceding siblings ...)
  2011-08-09 15:21 ` [PATCH 3/7] New commands for loading and unloading a reader Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
  2011-08-15 20:21   ` Tom Tromey
  2011-08-09 15:21 ` [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system Sanjoy Das
  6 siblings, 1 reply; 23+ messages in thread
From: Sanjoy Das @ 2011-08-09 15:21 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanjoy Das

Invoke the loaded JIT debug info reader to parse the registered symbol
files.
---
 gdb/ChangeLog |   12 ++
 gdb/jit.c     |  428 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 410 insertions(+), 30 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 884b51a..bd63356 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,17 @@
 2011-08-09  Sanjoy Das  <sdas@igalia.com>
 
+	* jit.c (add_objfile_entry, jit_target_read_impl)
+	(jit_object_open_impl, jit_symtab_open_impl, compare_block)
+	(jit_block_open_impl, jit_block_open_impl)
+	(jit_symtab_line_mapping_impl, jit_symtab_close_impl)
+	(finalize_symtab, jit_object_close_impl)
+	(jit_reader_try_read_symtab, jit_bfd_try_read_symtab): New
+	functions.
+	(jit_register_code): Try using the loaded jit reader before
+	resorting to BFD.
+
+2011-08-09  Sanjoy Das  <sdas@igalia.com>
+
 	* jit.c (_initialize_jit): Add commands load-jit-reader and
 	unload-jit-reader.
 	(jit_reader_load): New function.
diff --git a/gdb/jit.c b/gdb/jit.c
index 3f83065..e81a386 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -21,8 +21,11 @@
 
 #include "jit.h"
 #include "jit-reader.h"
+#include "block.h"
 #include "breakpoint.h"
 #include "command.h"
+#include "dictionary.h"
+#include "frame-unwind.h"
 #include "gdbcmd.h"
 #include "gdbcore.h"
 #include "inferior.h"
@@ -236,9 +239,19 @@ struct jit_inferior_data
 {
   CORE_ADDR breakpoint_addr;  /* &__jit_debug_register_code()  */
   CORE_ADDR descriptor_addr;  /* &__jit_debug_descriptor  */
-  struct objfile *jit_objfile; /* All the JIT symbols will be added to this. */
 };
 
+/* Remember a mapping from entry_addr to objfile.  */
+static void
+add_objfile_entry (struct objfile *objfile, CORE_ADDR entry)
+{
+  CORE_ADDR *entry_addr_ptr;
+
+  entry_addr_ptr = xmalloc (sizeof (CORE_ADDR));
+  *entry_addr_ptr = entry;
+  set_objfile_data (objfile, jit_objfile_data, entry_addr_ptr);
+}
+
 /* Return jit_inferior_data for current inferior.  Allocate if not already
    present.  */
 
@@ -335,37 +348,369 @@ jit_read_code_entry (struct gdbarch *gdbarch,
       extract_unsigned_integer (&entry_buf[3 * ptr_size], 8, byte_order);
 }
 
-/* This function registers code associated with a JIT code entry.  It uses the
-   pointer and size pair in the entry to read the symbol file from the remote
-   and then calls symbol_file_add_from_local_memory to add it as though it were
-   a symbol file added by the user.  */
+/* Proxy object for building a block. */
+struct gdb_block
+{
+  /* gdb_blocks are linked into a tree structure. Next points to the
+     next node at the same depth as this block and parent to the
+     parent gdb_block. */
+  struct gdb_block *next, *parent;
+  struct block *real_block;
+
+  /* The first and last code address corresponding to this block */
+  CORE_ADDR begin, end;
+  /* The name of this block (if any).  If this is non-NULL, the
+     FUNCTION symbol symbol is set to this value. */
+  const char *name;
+};
+
+/* Proxy object for building a symtab. */
+struct gdb_symtab
+{
+  /* The list of blocks in this symtab. These will eventually be
+     converted to real blocks. */
+  struct gdb_block *blocks;
+  /* The number of blocks inserted. */
+  int nblocks;
+  /* A mapping between line numbers to PC. */
+  struct linetable *linetable;
+  /* The source file for this symtab. */
+  const char *file_name;
+  struct gdb_symtab *next;
+};
+
+/* Proxy object for building an object. */
+struct gdb_object
+{
+  struct gdb_symtab *symtabs;
+};
+
+/* The type of the `private' data passed around by the callback
+   functions. */
+struct jit_dbg_reader_data
+{
+  CORE_ADDR entry_address;
+};
+
+/* The reader calls into this function to read data off the targets
+   address space. */
+static enum gdb_status
+jit_target_read_impl (GDB_CORE_ADDR target_mem, void *gdb_buf, int len)
+{
+  int result = target_read_memory ((CORE_ADDR) target_mem, gdb_buf, len);
+  if (result == 0)
+    return GDB_SUCCESS;
+  else
+    return GDB_FAIL;
+}
+
+static struct gdb_object *
+jit_object_open_impl (struct gdb_symbol_callbacks *cb)
+{
+  return XZALLOC (struct gdb_object);
+}
+
+static struct gdb_symtab *
+jit_symtab_open_impl (struct gdb_symbol_callbacks *cb,
+                      struct gdb_object *object,
+                      const char *file_name)
+{
+  struct gdb_symtab *ret = XZALLOC (struct gdb_symtab);
+  ret->file_name = file_name ? xstrdup (file_name) : xstrdup ("");
+  ret->next = object->symtabs;
+  object->symtabs = ret;
+  return ret;
+}
+
+/* Returns true if the block corrensponding to old should be placed
+   before the block corresponding to new in the final blockvector. */
+static int
+compare_block (struct gdb_block *old, struct gdb_block *new)
+{
+  if (old == NULL)
+    return 1;
+  if (old->begin < new->begin)
+    return 1;
+  else if (old->begin == new->begin)
+    {
+      if (old->end > new->end)
+        return 1;
+      else
+        return 0;
+    }
+  else
+    return 0;
+}
+
+static struct gdb_block *
+jit_block_open_impl (struct gdb_symbol_callbacks *cb, struct gdb_symtab *symtab,
+                     struct gdb_block *parent, GDB_CORE_ADDR begin,
+                     GDB_CORE_ADDR end, const char *name)
+{
+  struct gdb_block *block = XZALLOC (struct gdb_block);
+
+  block->next = symtab->blocks;
+  block->begin = (CORE_ADDR) begin;
+  block->end = (CORE_ADDR) end;
+  block->name = name ? xstrdup (name) : NULL;
+  block->parent = parent;
+
+  /* Ensure that the blocks are inserted in the correct (reverse of
+     the order expected by blockvector). */
+  if (compare_block (symtab->blocks, block))
+    {
+      symtab->blocks = block;
+    }
+  else
+    {
+      struct gdb_block *i = symtab->blocks;
+
+      for (;; i = i->next)
+        {
+          /* Guaranteed to terminate, since compare_block (NULL, _)
+             returns 1 */
+          if (compare_block (i->next, block))
+            {
+              block->next = i->next;
+              i->next = block;
+              break;
+            }
+        }
+    }
+  symtab->nblocks++;
+
+  return block;
+}
 
 static void
-jit_register_code (struct gdbarch *gdbarch,
-		   CORE_ADDR entry_addr, struct jit_code_entry *code_entry)
+jit_symtab_line_mapping_add_impl (struct gdb_symbol_callbacks *cb,
+                                  struct gdb_symtab *stab, int nlines,
+                                  struct gdb_line_mapping *map)
+{
+  int i;
+  if (!nlines)
+    return;
+
+  stab->linetable = xmalloc (sizeof (struct linetable) + (nlines - 1) *
+                             sizeof (struct linetable_entry));
+  stab->linetable->nitems = nlines;
+  for (i = 0; i < nlines; i++)
+    {
+      stab->linetable->item [i].pc = (CORE_ADDR) map[i].pc;
+      stab->linetable->item [i].line = map[i].line;
+    }
+}
+
+static void
+jit_symtab_close_impl (struct gdb_symbol_callbacks *cb, struct gdb_symtab *stab)
+{
+}
+
+/* Transform STAB to a proper symtab, and add it it OBJFILE. */
+static void
+finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile)
 {
+  struct symtab *symtab;
+  struct gdb_block *gdb_block_iter, *gdb_block_iter_tmp;
+  struct block *block_iter;
+  int actual_nblocks = FIRST_LOCAL_BLOCK + stab->nblocks, i, blockvector_size;
+  CORE_ADDR begin, end;
+
+  symtab = allocate_symtab (stab->file_name, objfile);
+  symtab->dirname = NULL; /* JIT compilers compile in memory */
+
+  /* Copy over the linetable entry if one was provided. */
+  if (stab->linetable)
+    {
+      int size = (stab->linetable->nitems - 1) *
+        sizeof (struct linetable_entry) + sizeof (struct linetable);
+      LINETABLE (symtab) = obstack_alloc (&objfile->objfile_obstack, size);
+      memcpy (LINETABLE (symtab), stab->linetable, size);
+    }
+  else
+    {
+      LINETABLE (symtab) = NULL;
+    }
+
+  blockvector_size = (sizeof (struct blockvector) +
+                      (actual_nblocks - 1) * sizeof (struct block *));
+  symtab->blockvector = obstack_alloc (&objfile->objfile_obstack,
+                                       blockvector_size);
+
+  /* (begin, end) will contain the PC range this entire blockvector spans. */
+  symtab->primary = 1;
+  BLOCKVECTOR_MAP (symtab->blockvector) = NULL;
+  begin = stab->blocks->begin;
+  end = stab->blocks->end;
+  BLOCKVECTOR_NBLOCKS (symtab->blockvector) = actual_nblocks;
+
+  /* First run over all the gdb_block objects, creating a real block
+     object for each. Simultaneously, keep setting the real_block
+     fields. */
+  for (i = (actual_nblocks - 1), gdb_block_iter = stab->blocks;
+       i >= FIRST_LOCAL_BLOCK; i--, gdb_block_iter = gdb_block_iter->next)
+    {
+      struct block *new_block = allocate_block (&objfile->objfile_obstack);
+      struct symbol *block_name = obstack_alloc (&objfile->objfile_obstack,
+                                                 sizeof (struct symbol));
+
+      BLOCK_DICT (new_block) = dict_create_linear (&objfile->objfile_obstack,
+                                                   NULL);
+      /* The address range. */
+      BLOCK_START (new_block) = (CORE_ADDR) gdb_block_iter->begin;
+      BLOCK_END (new_block) = (CORE_ADDR) gdb_block_iter->end;
+
+      /* The name. */
+      memset (block_name, 0, sizeof (struct symbol));
+      SYMBOL_DOMAIN (block_name) = VAR_DOMAIN;
+      SYMBOL_CLASS (block_name) = LOC_BLOCK;
+      block_name->symtab = symtab;
+      SYMBOL_BLOCK_VALUE (block_name) = new_block;
+      block_name->ginfo.name = obstack_alloc (&objfile->objfile_obstack, 1 +
+                                              strlen (gdb_block_iter->name));
+      strcpy (block_name->ginfo.name, gdb_block_iter->name);
+      BLOCK_FUNCTION (new_block) = block_name;
+
+      BLOCKVECTOR_BLOCK (symtab->blockvector, i) = new_block;
+      if (begin > BLOCK_START (new_block))
+        begin = BLOCK_START (new_block);
+      if (end < BLOCK_END (new_block))
+        end = BLOCK_END (new_block);
+
+      gdb_block_iter->real_block = new_block;
+    }
+
+  /* Now add the special blocks. */
+  block_iter = NULL;
+  for (i = 0; i < FIRST_LOCAL_BLOCK; i++)
+    {
+      struct block *new_block = allocate_block (&objfile->objfile_obstack);
+      BLOCK_DICT (new_block) = dict_create_linear (&objfile->objfile_obstack,
+                                                   NULL);
+      BLOCK_SUPERBLOCK (new_block) = block_iter;
+      block_iter = new_block;
+
+      BLOCK_START (new_block) = (CORE_ADDR) begin;
+      BLOCK_END (new_block) = (CORE_ADDR) end;
+
+      BLOCKVECTOR_BLOCK (symtab->blockvector, i) = new_block;
+    }
+
+  /* Fill up the superblock fields for the real blocks, using the
+     real_block fields populated earlier. */
+  for (gdb_block_iter = stab->blocks; gdb_block_iter;
+       gdb_block_iter = gdb_block_iter->next)
+    {
+      if (gdb_block_iter->parent != NULL)
+        BLOCK_SUPERBLOCK (gdb_block_iter->real_block) =
+          gdb_block_iter->parent->real_block;
+    }
+
+  /* Free memory. */
+  gdb_block_iter = stab->blocks;
+  for (gdb_block_iter = stab->blocks, gdb_block_iter_tmp = gdb_block_iter->next;
+       gdb_block_iter; gdb_block_iter = gdb_block_iter_tmp)
+    {
+      xfree ((void *) gdb_block_iter->name);
+      xfree (gdb_block_iter);
+    }
+  xfree (stab->linetable);
+  xfree ((char *) stab->file_name);
+  xfree (stab);
+}
+
+/* Convert OBJ to a proper objfile. */
+static void
+jit_object_close_impl (struct gdb_symbol_callbacks *cb, struct gdb_object *obj)
+{
+  struct gdb_symtab *i, *j = NULL;
+  struct objfile *objfile = allocate_objfile (NULL, 0);
+  struct jit_dbg_reader_data *priv_data = cb->priv_data;
+
+  objfile->gdbarch = target_gdbarch;
+  objfile->msymbols = obstack_alloc (&objfile->objfile_obstack,
+                                     sizeof (struct minimal_symbol));
+  objfile->msymbols[0].ginfo.name = NULL;
+  objfile->msymbols[0].ginfo.value.address = 0;
+  objfile->name = xstrdup ("JIT");
+
+  for (i = obj->symtabs; i; i = j)
+    {
+      j = i->next;
+      finalize_symtab (i, objfile);
+    }
+  add_objfile_entry (objfile, priv_data->entry_address);
+  xfree (obj);
+}
+
+/* Try to read CODE_ENTRY using the loaded jit reader (if any). */
+static int
+jit_reader_try_read_symtab (struct jit_code_entry *code_entry)
+{
+  void *gdb_mem;
+  int status = 0;
+  struct jit_dbg_reader *i;
+  struct jit_dbg_reader_data priv_data;
+  struct gdb_reader_funcs *funcs;
+  struct gdb_symbol_callbacks callbacks =
+    {
+      jit_object_open_impl,
+      jit_symtab_open_impl,
+      jit_block_open_impl,
+      jit_symtab_close_impl,
+      jit_object_close_impl,
+
+      jit_symtab_line_mapping_add_impl,
+      jit_target_read_impl,
+
+      &priv_data
+    };
+
+  priv_data.entry_address = code_entry->symfile_addr;
+
+  if (!loaded_jit_reader)
+    return 0;
+
+  gdb_mem = xmalloc (code_entry->symfile_size);
+  if (target_read_memory (code_entry->symfile_addr, gdb_mem,
+                          code_entry->symfile_size))
+    {
+      status = 0;
+      goto cleanup;
+    }
+
+  funcs = loaded_jit_reader->functions;
+  if (funcs->read (funcs, &callbacks, gdb_mem, code_entry->symfile_size)
+      == GDB_SUCCESS)
+    {
+      status = 1;
+      goto cleanup;
+    }
+
+ cleanup:
+  xfree (gdb_mem);
+  return status;
+}
+
+/* Try to read CODE_ENTRY using BFD. */
+static void
+jit_bfd_try_read_symtab (struct jit_code_entry *code_entry,
+                         struct gdbarch *gdbarch)
+{
+  struct cleanup *old_cleanups;
+  struct objfile *objfile;
   bfd *nbfd;
   struct section_addr_info *sai;
   struct bfd_section *sec;
-  struct objfile *objfile;
-  struct cleanup *old_cleanups, *my_cleanups;
-  int i;
   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));
+  int i;
 
   nbfd = bfd_open_from_target_memory (code_entry->symfile_addr,
                                       code_entry->symfile_size, gnutarget);
   old_cleanups = make_cleanup_bfd_close (nbfd);
 
-  /* Check the format.  NOTE: This initializes important data that GDB uses!
-     We would segfault later without this line.  */
+  /* Check the format.  NOTE: This initializes important data that GDB
+     uses!  We would segfault later without this line.  */
   if (!bfd_check_format (nbfd, bfd_object))
     {
       printf_unfiltered (_("\
@@ -381,17 +726,17 @@ JITed symbol file is not an object file, ignoring it.\n"));
                "with target architecture %s."), bfd_get_arch_info
              (nbfd)->printable_name, b->printable_name);
 
-  /* Read the section address information out of the symbol file.  Since the
-     file is generated by the JIT at runtime, it should all of the absolute
-     addresses that we care about.  */
+  /* Read the section address information out of the symbol file.
+     Since the file is generated by the JIT at runtime, it should all
+     of the absolute addresses that we care about.  */
   sai = alloc_section_addr_info (bfd_count_sections (nbfd));
   make_cleanup_free_section_addr_info (sai);
   i = 0;
   for (sec = nbfd->sections; sec != NULL; sec = sec->next)
     if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
       {
-        /* We assume that these virtual addresses are absolute, and do not
-           treat them as offsets.  */
+        /* We assume that these virtual addresses are absolute, and do
+           not treat them as offsets.  */
         sai->other[i].addr = bfd_get_section_vma (nbfd, sec);
         sai->other[i].name = xstrdup (bfd_get_section_name (nbfd, sec));
         sai->other[i].sectindex = sec->index;
@@ -401,12 +746,34 @@ JITed symbol file is not an object file, ignoring it.\n"));
   /* This call takes ownership of sai.  */
   objfile = symbol_file_add_from_bfd (nbfd, 0, sai, OBJF_SHARED, NULL);
 
-  /* Remember a mapping from entry_addr to objfile.  */
-  entry_addr_ptr = xmalloc (sizeof (CORE_ADDR));
-  *entry_addr_ptr = entry_addr;
-  set_objfile_data (objfile, jit_objfile_data, entry_addr_ptr);
-
   discard_cleanups (old_cleanups);
+  add_objfile_entry (objfile, code_entry->symfile_addr);
+}
+
+/* This function registers code associated with a JIT code entry.  It uses the
+   pointer and size pair in the entry to read the symbol file from the remote
+   and then calls symbol_file_add_from_local_memory to add it as though it were
+   a symbol file added by the user.  */
+
+static void
+jit_register_code (struct gdbarch *gdbarch,
+                   CORE_ADDR entry_addr, struct jit_code_entry *code_entry)
+{
+  int i, success;
+  const struct bfd_arch_info *b;
+  struct jit_inferior_data *inf_data = get_jit_inferior_data ();
+
+  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));
+
+  success = jit_reader_try_read_symtab (code_entry);
+
+  if (!success)
+    jit_bfd_try_read_symtab (code_entry, gdbarch);
 }
 
 /* This function unregisters JITed code and frees the corresponding
@@ -415,6 +782,7 @@ JITed symbol file is not an object file, ignoring it.\n"));
 static void
 jit_unregister_code (struct objfile *objfile)
 {
+  xfree (objfile_data (objfile, jit_objfile_data));
   free_objfile (objfile);
 }
 
-- 
1.7.5.4


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/7] Add platform agnostic dynamic loading code.
  2011-08-09 15:21 [PATCH] JIT debug info Reader Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
  2011-08-10 21:01   ` Tom Tromey
  2011-08-09 15:21 ` [PATCH 6/7] Register the proxy unwinder Sanjoy Das
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 23+ messages in thread
From: Sanjoy Das @ 2011-08-09 15:21 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanjoy Das

gdb-dlfcn.h and gdb-dlfcn.c are added, which implement the (cross
platform) functions gdb_dlopen, gdb_dlsym and gdb_dlclose. They should
work correctly on POSIX and windows systems.

gdb/ChangeLog
	* gdb-dlfcn.h, gdb-dlfcn.c: New.
	* Makefile.in: Add gdb_dlcfn.c and gdb_dlcfn.h to the build system.
	* configure.ac, config.in: Check for -ldl and accordingly define HAVE_LIBDL.
---
 gdb/ChangeLog   |    6 ++++++
 gdb/Makefile.in |    6 +++---
 gdb/gdb-dlfcn.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/gdb-dlfcn.h |   27 +++++++++++++++++++++++++++
 4 files changed, 85 insertions(+), 3 deletions(-)
 create mode 100644 gdb/gdb-dlfcn.c
 create mode 100644 gdb/gdb-dlfcn.h

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e7844b8..639f1f7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2011-08-09  Sanjoy Das  <sdas@igalia.com>
+
+	* gdb-dlfcn.h, gdb-dlfcn.c: New.
+    	* Makefile.in: Add gdb_dlcfn.c and gdb_dlcfn.h to the build
+	system.
+
 2011-08-09  Sanjoy Das	<sdas@igalia.com>
 
 	* Makefile.in: Add jit-reader.h.in to HFILES_WITH_SRCDIR,
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 1ace7b8..f614204 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -739,7 +739,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
 	annotate.c common/signals.c copying.c dfp.c gdb.c inf-child.c \
 	regset.c sol-thread.c windows-termcap.c \
 	common/common-utils.c common/xml-utils.c \
-	common/ptid.c common/buffer.c
+	common/ptid.c common/buffer.c gdb-dlfcn.c
 
 LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
 
@@ -820,7 +820,7 @@ solib-darwin.h solib-ia64-hpux.h solib-spu.h windows-nat.h xcoffread.h \
 gnulib/extra/arg-nonnull.h gnulib/extra/c++defs.h gnulib/extra/warn-on-use.h \
 gnulib/stddef.in.h inline-frame.h \
 common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
-common/linux-osdata.h
+common/linux-osdata.h gdb-dlfcn.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -907,7 +907,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
 	target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
 	inferior.o osdata.o gdb_usleep.o record.o gcore.o \
 	jit.o progspace.o \
-	common-utils.o buffer.o ptid.o
+	common-utils.o buffer.o ptid.o gdb-dlfcn.o
 
 TSOBS = inflow.o
 
diff --git a/gdb/gdb-dlfcn.c b/gdb/gdb-dlfcn.c
new file mode 100644
index 0000000..91e8a22
--- /dev/null
+++ b/gdb/gdb-dlfcn.c
@@ -0,0 +1,49 @@
+#include "gdb-dlfcn.h"
+
+#include "config.h"
+
+#ifdef HAVE_LIBDL
+#include <dlfcn.h>
+#elif __MINGW32__
+#include <windows.h>
+#else
+/* Unsupported configuration.  See Eg. gdb_dlopen for details.  */
+#error API to load shared library missing (Eg. libdl)
+#endif
+
+/* Load the dynamic library file named FILENAME, and return a handle
+   for that dynamic library.  Return NULL if the loading fails for
+   any reason.  */
+
+void *
+gdb_dlopen (const char *filename)
+{
+#ifdef HAVE_LIBDL
+  return dlopen (filename, RTLD_NOW);
+#elif __MINGW32__
+  return (void *) LoadLibrary (filename);
+#endif
+}
+
+/* Return the address of the symbol named SYMBOL inside the shared library
+   whose handle is HANDLE.  Return NULL when the symbol could not be found.  */
+
+void *
+gdb_dlsym (void *handle, const char *symbol)
+{
+#ifdef HAVE_LIBDL
+  return dlsym (handle, symbol);
+#elif __MINGW32__
+  return (void *) GetProcAddress (handle, symbol);
+#endif
+}
+
+int
+gdb_dlclose (void *handle)
+{
+#ifdef HAVE_LIBDL
+  return dlclose (handle);
+#elif __MINGW32__
+  return (int) FreeLibrary (handle);
+#endif
+}
diff --git a/gdb/gdb-dlfcn.h b/gdb/gdb-dlfcn.h
new file mode 100644
index 0000000..0d7b111
--- /dev/null
+++ b/gdb/gdb-dlfcn.h
@@ -0,0 +1,27 @@
+/* JIT declarations for GDB, the GNU Debugger.
+
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_DLFCN_H
+#define GDB_DLFCN_H
+
+void *gdb_dlopen (const char *filename);
+void *gdb_dlsym (void *handle, const char *symbol);
+int gdb_dlclose (void *handle);
+
+#endif /* GDB_DLFCN_H */
-- 
1.7.5.4


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 7/7] Add documentation.
  2011-08-09 15:21 [PATCH] JIT debug info Reader Sanjoy Das
                   ` (2 preceding siblings ...)
  2011-08-09 15:21 ` [PATCH 5/7] Add a " Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
  2011-08-09 15:51   ` Eli Zaretskii
  2011-08-09 15:21 ` [PATCH 3/7] New commands for loading and unloading a reader Sanjoy Das
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 23+ messages in thread
From: Sanjoy Das @ 2011-08-09 15:21 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanjoy Das

Adds some basic documentation to gdb.texinfo about the new JIT reader
functionality. Most of the actual documentation is still in
jit-reader.h.
---
 gdb/ChangeLog       |    5 +++
 gdb/doc/gdb.texinfo |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2b3dc1a..5fa54bc 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2011-08-09  Sanjoy Das  <sdas@igalia.com>
 
+	* doc/gdb.texinfo (JIT Interface): Added node `Custom Debug Info'.
+	(Custom Debug Info, Using Readers, Writing Readers): New nodes.
+
+2011-08-09  Sanjoy Das  <sdas@igalia.com>
+
 	* alpha-tdep.c (alpha_dwarf2_init_abi): Call jit_prepend_unwinder.
 	* arm-tdep.c (arm_gdbarch_init): Likewise.
 	* bfin-tdep.c (bfin_gdbarch_init): Likewise.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 35fa075..e9de85b 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -30850,6 +30850,7 @@ out about additional code.
 * Declarations::                Relevant C struct declarations
 * Registering Code::            Steps to register code
 * Unregistering Code::          Steps to unregister code
+* Custom Debug Info::           Emit debug information in a custom format
 @end menu
 
 @node Declarations
@@ -30946,6 +30947,99 @@ Set @code{action_flag} to @code{JIT_UNREGISTER} and call
 If the JIT frees or recompiles code without unregistering it, then @value{GDBN}
 and the JIT will leak the memory used for the associated symbol files.
 
+@node Custom Debug Info
+@section Custom Debug Info
+
+Generating debug information in platform-native file formats (like ELF
+or COFF) may be an overkill for JIT compilers; especially if all the
+debug info is used for is displaying a meaningful backtrace.  The
+issue can be resolved by having the JIT writers decide on a debug info
+format and provide a third-party reader that parses the debug info
+generated by the JIT compiler.  This section gives a brief overview on
+writing such a parser.  More specific details can be found in the file
+@file{gdb/jit-reader.h.in}.
+
+The reader is implemented as a shared object.  Two new @value{GDBN}
+commands, @code{load-jit-reader} and @code{unload-jit-reader} are
+added, to be used to load and unload the readers from a preconfigured
+directory.  Once a correct shared object is loaded, @value{GDBN} tries
+to use it to parse the debug information registered by the JIT and to
+unwind stack frames.
+
+@menu
+* Using Readers::       How to use supplied readers correctly
+* Writing Readers::     Creating a debug-info reader
+@end menu
+
+@node Using Readers
+@subsection Using Readers
+
+A mentioned, readers can be loaded using the @code{load-jit-reader}
+command.  Executing @code{load-jit-reader foo} will have @value{GDBN}
+try to load @code{foo.so} from @code{$libdir/gdb} where @code{libdir}
+is the library directory for the system (usually something like
+@code{/usr/local/lib}).  Once a reader is loaded correctly
+(@value{GDBN} will prompt otherwise if this is not the case), no
+further interaction is required from the user's side.  The current
+reader can be unloaded by executing @code{unload-jit-reader}, after
+which a new reader may be loaded, using @code{load-jit-reader} as
+usual.
+
+@node Writing Readers
+@subsection Writing Readers
+
+As mentioned, a reader is essentially a shared object conforming to a
+certain ABI.  This ABI is described in @file{jit-reader.h}.
+
+@file{jit-reader.h} defines the structures, macros and functions
+required to write a reader.  It is installed (along with
+@value{GDBN}), in @code{$includedir/gdb} where @code{$includedir} is
+the system include directory.
+
+Readers need to be released under a GPL compatible license.  A reader
+can be declared released under such a license by placing the macro
+@code{GDB_DECLARE_GPL_COMPATIBLE_READER} in a source file.
+
+The entry point for readers is the symbol @code{gdb_init_reader},
+which is expected to be a function with the prototype
+
+@smallexample
+extern struct gdb_reader_funcs *gdb_init_reader (void);
+@end smallexample
+
+@code{struct gdb_reader_funcs} contains a set of pointers to callback
+functions.  These functions are executed to read debug info generated
+by the JIT compiler (@code{read}), to unwind stack frames
+(@code{unwind}) and to create canonical frame IDs
+(@code{get_Frame_id}).  It also has a callback that is called when the
+reader is being unloaded (@code{destroy}). The struct looks like this
+
+@smallexample
+struct gdb_reader_funcs
+@{
+  gdb_read_debug_info *read;
+  gdb_unwind_frame *unwind;
+  gdb_get_frame_id *get_frame_id;
+  gdb_destroy_reader *destroy;
+  /* Must be set to GDB_READER_INTERFACE_VERSION */
+  int reader_version;
+
+  /* For use by the reader. */
+  void *priv_data;
+@};
+@end smallexample
+
+The callbacks are provided with another set of callbacks by
+@value{GDBN} to do their job.  For @code{read}, these callbacks are
+passed in a @code{struct gdb_symbol_callbacks} and for @code{unwind}
+and @code{get_frame_id}, in a @code{struct
+gdb_unwind_callbacks}.  @code{struct gdb_symbol_callbacks} has
+callbacks to create new object files and new symbol tables inside
+those object files. @code{struct gdb_unwind_callbacks} has callbacks
+to read registers off the current frame and to write out the values of
+the registers in the previous frame. Both have a callback
+(@code{target_read}) to read bytes off the target's address space.
+
 @node GDB Bugs
 @chapter Reporting Bugs in @value{GDBN}
 @cindex bugs in @value{GDBN}
-- 
1.7.5.4


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 5/7] Add a proxy unwinder.
  2011-08-09 15:21 [PATCH] JIT debug info Reader Sanjoy Das
  2011-08-09 15:21 ` [PATCH 2/7] Add platform agnostic dynamic loading code Sanjoy Das
  2011-08-09 15:21 ` [PATCH 6/7] Register the proxy unwinder Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
  2011-08-15 20:38   ` Tom Tromey
  2011-08-09 15:21 ` [PATCH 7/7] Add documentation Sanjoy Das
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 23+ messages in thread
From: Sanjoy Das @ 2011-08-09 15:21 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanjoy Das

Have the proxy unwinder pass down all calls to the functions the JIT
reader provides.
---
 gdb/ChangeLog |    9 +++
 gdb/jit.c     |  191 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/jit.h     |    6 ++
 3 files changed, 206 insertions(+), 0 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bd63356..2556be7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,14 @@
 2011-08-09  Sanjoy Das  <sdas@igalia.com>
 
+	* jit.c (jut_unwind_reg_set_impl, free_reg_value_impl)
+	(jit_unwind_reg_get_impl, jit_frame_sniffer)
+	(jit_frame_unwind_stop_reason, jit_frame_this_id)
+	(jit_frame_prev_register, jit_dealloc_cache)
+	(jit_prepend_unwinder): New functions
+	* jit.h (jit_prepend_unwinder): New function
+
+2011-08-09  Sanjoy Das  <sdas@igalia.com>
+
 	* jit.c (add_objfile_entry, jit_target_read_impl)
 	(jit_object_open_impl, jit_symtab_open_impl, compare_block)
 	(jit_block_open_impl, jit_block_open_impl)
diff --git a/gdb/jit.c b/gdb/jit.c
index e81a386..58c3149 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -31,6 +31,7 @@
 #include "inferior.h"
 #include "observer.h"
 #include "objfiles.h"
+#include "regcache.h"
 #include "symfile.h"
 #include "symtab.h"
 #include "target.h"
@@ -843,6 +844,190 @@ jit_breakpoint_re_set_internal (struct gdbarch *gdbarch,
   return 0;
 }
 
+/* The private data passed around in the frame unwind callback
+   functions. */
+struct jit_unwind_private
+{
+  /* Cached register values. See jit_frame_sniffer to see how this
+     works. */
+  struct gdb_reg_value **registers;
+  /* The frame being unwound. */
+  struct frame_info *this_frame;
+};
+
+static void
+jit_unwind_reg_set_impl (struct gdb_unwind_callbacks *cb, int regnum,
+                         struct gdb_reg_value *value)
+{
+  struct jit_unwind_private *priv = cb->priv_data;
+  int gdb_reg = gdbarch_dwarf2_reg_to_regnum (target_gdbarch, regnum);
+  gdb_assert (priv->registers);
+  priv->registers[gdb_reg] = value;
+}
+
+static void
+free_reg_value_impl (struct gdb_reg_value *reg_value)
+{
+  free (reg_value);
+}
+
+static struct gdb_reg_value *
+jit_unwind_reg_get_impl (struct gdb_unwind_callbacks *cb, int regnum)
+{
+  struct jit_unwind_private *priv = cb->priv_data;
+  int gdb_reg = gdbarch_dwarf2_reg_to_regnum (target_gdbarch, regnum);
+  int size = register_size (target_gdbarch, gdb_reg);
+  struct gdb_reg_value *value = malloc (sizeof (struct gdb_reg_value) +
+                                        size - 1);
+  value->defined = frame_register_read (priv->this_frame, gdb_reg,
+                                        value->value);
+  value->size = size;
+  value->free = free_reg_value_impl;
+  return value;
+}
+
+/* The frame sniffer for the pseudo unwinder.
+
+   While this is nominally a frame sniffer, in the case where the JIT
+   reader actually recognizes the frame, it does a lot more work -- it
+   unwinds the frame and saves the corresponding register values in
+   the cache. jit_frame_prev_register simply returns the saved
+   register values. */
+static int
+jit_frame_sniffer (const struct frame_unwind *self,
+                   struct frame_info *this_frame, void **cache)
+{
+  struct jit_inferior_data *inf_data = get_jit_inferior_data ();
+  struct jit_unwind_private *priv_data;
+  struct jit_dbg_reader *iter;
+  struct gdb_unwind_callbacks callbacks =
+    {
+      jit_unwind_reg_get_impl,
+      jit_unwind_reg_set_impl,
+      jit_target_read_impl
+    };
+  struct gdb_reader_funcs *funcs;
+
+  if (loaded_jit_reader == NULL)
+    return 0;
+  funcs = loaded_jit_reader->functions;
+
+  if (!*cache)
+    {
+      *cache = XZALLOC (struct jit_unwind_private);
+      priv_data = *cache;
+      priv_data->registers = XCALLOC (gdbarch_num_regs (target_gdbarch),
+                                      struct gdb_reg_value *);
+      priv_data->this_frame = this_frame;
+    }
+  else
+    {
+      priv_data = *cache;
+      priv_data->this_frame = this_frame;
+    }
+
+  callbacks.priv_data = priv_data;
+
+  /* Try to coax the provided unwinder to unwind the stack */
+  if (funcs->unwind (funcs, &callbacks) == GDB_SUCCESS)
+    {
+      if (jit_debug)
+        fprintf_unfiltered (gdb_stdlog, "Successfully unwound frame using "
+                            "JIT reader.\n");
+      return 1;
+    }
+  if (jit_debug)
+    fprintf_unfiltered (gdb_stdlog, "Could not unwind frame using "
+                        "JIT reader.\n");
+
+  xfree (priv_data->registers);
+  xfree (priv_data);
+  *cache = NULL;
+
+  return 0;
+}
+
+static enum unwind_stop_reason
+jit_frame_unwind_stop_reason (struct frame_info *this_frame, void **cache)
+{
+  return UNWIND_NO_REASON;
+}
+
+static void
+jit_frame_this_id (struct frame_info *this_frame, void **cache,
+                   struct frame_id *this_id)
+{
+  struct jit_unwind_private private =
+    {
+      NULL,
+      this_frame
+    };
+  struct gdb_frame_id frame_id;
+  struct gdb_reader_funcs *funcs;
+  struct gdb_unwind_callbacks callbacks =
+    {
+      jit_unwind_reg_get_impl,
+      NULL,
+      jit_target_read_impl,
+
+      &private
+    };
+
+  gdb_assert (loaded_jit_reader);
+  funcs = loaded_jit_reader->functions;
+
+  frame_id = funcs->get_frame_id (funcs, &callbacks);
+  *this_id = frame_id_build (frame_id.stack_address, frame_id.code_address);
+}
+
+static struct value *
+jit_frame_prev_register (struct frame_info *this_frame, void **cache, int reg)
+{
+  struct jit_unwind_private *priv = *cache;
+  struct gdb_reg_value *value;
+
+  if (priv == NULL)
+    return frame_unwind_got_optimized (this_frame, reg);
+
+  gdb_assert (priv->registers);
+  value = priv->registers[reg];
+  if (value && value->defined)
+    return frame_unwind_got_bytes (this_frame, reg, value->value);
+  else
+    return frame_unwind_got_optimized (this_frame, reg);
+}
+
+/* gdb_reg_value has a free function, which must be called on each
+   saved register value. */
+static void
+jit_dealloc_cache (struct frame_info *this_frame, void *cache)
+{
+  struct jit_unwind_private *priv_data = cache;
+  int i;
+
+  gdb_assert (priv_data->registers);
+
+  for (i = 0; i < gdbarch_num_regs (target_gdbarch); i++)
+    if (priv_data->registers[i] && priv_data->registers[i]->free)
+      priv_data->registers[i]->free (priv_data->registers[i]);
+
+  xfree (priv_data->registers);
+  xfree (priv_data);
+}
+
+/* Simply relays everything back to the unwinder registered by the JIT
+   debug info reader.*/
+static const struct frame_unwind jit_frame_unwind =
+{
+  NORMAL_FRAME,
+  jit_frame_unwind_stop_reason,
+  jit_frame_this_id,
+  jit_frame_prev_register,
+  NULL,
+  jit_frame_sniffer,
+  jit_dealloc_cache
+};
+
 /* Register any already created translations.  */
 
 static void
@@ -1010,6 +1195,12 @@ jit_event_handler (struct gdbarch *gdbarch)
     }
 }
 
+void
+jit_prepend_unwinder (struct gdbarch *gdbarch)
+{
+  frame_unwind_prepend_unwinder (gdbarch, &jit_frame_unwind);
+}
+
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 
 extern void _initialize_jit (void);
diff --git a/gdb/jit.h b/gdb/jit.h
index 73a1414..29cd10d 100644
--- a/gdb/jit.h
+++ b/gdb/jit.h
@@ -80,4 +80,10 @@ extern void jit_breakpoint_re_set (void);
 
 extern void jit_event_handler (struct gdbarch *gdbarch);
 
+/* Prepend the JIT unwinder GDBARCH's. Prepending adds negligible
+   overhead since this unwinder quickly fails if no JIT reader is
+   loaded. This also prevents other unwinders which depend on the BFD
+   field not being NULL from tripping. */
+extern void jit_prepend_unwinder (struct gdbarch *gdbarch);
+
 #endif /* JIT_H */
-- 
1.7.5.4


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system.
  2011-08-09 15:21 [PATCH] JIT debug info Reader Sanjoy Das
                   ` (5 preceding siblings ...)
  2011-08-09 15:21 ` [PATCH 4/7] Use the loaded reader Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
  2011-08-09 15:40   ` Eli Zaretskii
  2011-08-10 20:57   ` Tom Tromey
  6 siblings, 2 replies; 23+ messages in thread
From: Sanjoy Das @ 2011-08-09 15:21 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanjoy Das

jit-reader.h.in will host the interface to be implemented and the API
to be used by the reader. The file needs to be processed by
./configure to produce `jit.reader.h'; so that GDB_CORE_ADDR is
defined correctly.

This commit arranges for `jit-reader.h' to be installed in the global
include directory.

It also adds libdir as a define (to GDB_CFLAGS) since the value is
needed to determine the location from where the shared objects
(readers) are to be lifted.
---
 gdb/ChangeLog       |   11 ++
 gdb/Makefile.in     |   15 ++-
 gdb/config.in       |    3 +
 gdb/configure       |  169 +++++++++++++++++++++++++++++
 gdb/configure.ac    |   23 ++++
 gdb/jit-reader.h.in |  300 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/jit.c           |    1 +
 7 files changed, 517 insertions(+), 5 deletions(-)
 create mode 100644 gdb/jit-reader.h.in

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e21006e..e7844b8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2011-08-09  Sanjoy Das	<sdas@igalia.com>
+
+	* Makefile.in: Add jit-reader.h.in to HFILES_WITH_SRCDIR,
+	generated_files and install-only.  Add -DLIBDIR to GDB_CFLAGS.
+	* config.in: Add HAVE_LIBDL.
+	* configure.ac: Add TARGET_PTR, check for libdl and add
+	jit-reader.h.in.
+	* configure: (Autogenerated)
+	* jit-reader.h.in: New
+	* jit.c: Include jit-reader.h.
+
 2011-08-08  Tom Tromey  <tromey@redhat.com>
 
 	* breakpoint.c (clean_up_filters): Remove.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index bd00644..1ace7b8 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -419,7 +419,7 @@ CONFIG_UNINSTALL = @CONFIG_UNINSTALL@
 # should be according to Posix).
 DEFS = @DEFS@
 GDB_CFLAGS = -I. -I$(srcdir) -I$(srcdir)/common -I$(srcdir)/config \
-	-DLOCALEDIR="\"$(localedir)\"" $(DEFS)
+	-DLOCALEDIR="\"$(localedir)\"" $(DEFS) -DLIBDIR="\"@libdir@\""
 
 # MH_CFLAGS, if defined, has host-dependent CFLAGS from the config directory.
 GLOBAL_CFLAGS = $(MH_CFLAGS)
@@ -824,7 +824,7 @@ common/linux-osdata.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
-HFILES_WITH_SRCDIR = ../bfd/bfd.h
+HFILES_WITH_SRCDIR = ../bfd/bfd.h jit-reader.h
 
 
 # GDB "info" files, which should be included in their entirety
@@ -941,7 +941,7 @@ DISTSTUFF = $(YYFILES)
 
 
 # All generated files which can be included by another file.
-generated_files = config.h observer.h observer.inc ada-lex.c \
+generated_files = config.h observer.h observer.inc ada-lex.c jit-reader.h \
 	$(GNULIB_H) $(NAT_GENERATED_FILES)
 
 .c.o:
@@ -1026,7 +1026,9 @@ install-only: $(CONFIG_INSTALL)
 		$(SHELL) $(srcdir)/../mkinstalldirs \
 			$(DESTDIR)$(man1dir) ; \
 		$(INSTALL_DATA) $(srcdir)/gdb.1 \
-			$(DESTDIR)$(man1dir)/$$transformed_name.1
+			$(DESTDIR)$(man1dir)/$$transformed_name.1 ; \
+		$(SHELL) $(srcdir)/../mkinstalldirs $(includedir)/gdb ; \
+		$(INSTALL_DATA) jit-reader.h $(includedir)/gdb/jit-reader.h
 	@$(MAKE) DO=install "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do
 .PHONY: install-tui
 install-tui:
@@ -1254,7 +1256,7 @@ distclean: clean
 	rm -f gdbserver/config.status gdbserver/config.log
 	rm -f gdbserver/tm.h gdbserver/xm.h gdbserver/nm.h
 	rm -f gdbserver/Makefile gdbserver/config.cache
-	rm -f nm.h config.status config.h stamp-h .gdbinit
+	rm -f nm.h config.status config.h stamp-h .gdbinit jit-reader.h
 	rm -f y.output yacc.acts yacc.tmp y.tab.h
 	rm -f config.log config.cache
 	rm -f Makefile
@@ -1320,6 +1322,9 @@ data-directory/Makefile: data-directory/Makefile.in config.status @frags@
 	  CONFIG_LINKS= \
 	  $(SHELL) config.status
 
+jit-reader.h: $(srcdir)/jit-reader.h.in
+	$(SHELL) config.status $@
+
 config.h: stamp-h ; @true
 stamp-h: $(srcdir)/config.in config.status
 	CONFIG_HEADERS=config.h:config.in \
diff --git a/gdb/config.in b/gdb/config.in
index c1d7c68..8b3f0cf 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -982,3 +982,6 @@
 
 /* Define as `fork' if `vfork' does not work. */
 #undef vfork
+
+/* Define if -ldl will work. */
+#undef HAVE_LIBDL
diff --git a/gdb/configure b/gdb/configure
index ac143e4..c9345c2 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -666,6 +666,7 @@ python_prog_path
 LTLIBEXPAT
 LIBEXPAT
 HAVE_LIBEXPAT
+TARGET_PTR
 READLINE_TEXI_INCFLAG
 READLINE_CFLAGS
 READLINE_DEPS
@@ -9807,6 +9808,173 @@ fi
 
 
 
+# Generate jit-reader.h
+
+# This is typedeffed to GDB_CORE_ADDR in jit-reader.h
+TARGET_PTR=
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5
+$as_echo_n "checking size of unsigned long long... " >&6; }
+if test "${ac_cv_sizeof_unsigned_long_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_unsigned_long_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (unsigned long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_unsigned_long_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5
+$as_echo_n "checking size of unsigned long... " >&6; }
+if test "${ac_cv_sizeof_unsigned_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_unsigned_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (unsigned long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_unsigned_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned __int128" >&5
+$as_echo_n "checking size of unsigned __int128... " >&6; }
+if test "${ac_cv_sizeof_unsigned___int128+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned __int128))" "ac_cv_sizeof_unsigned___int128"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_unsigned___int128" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (unsigned __int128)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_unsigned___int128=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned___int128" >&5
+$as_echo "$ac_cv_sizeof_unsigned___int128" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED___INT128 $ac_cv_sizeof_unsigned___int128
+_ACEOF
+
+
+
+if test "x${ac_cv_sizeof_unsigned_long}" = "x8"; then
+  TARGET_PTR="unsigned long"
+elif test "x${ac_cv_sizeof_unsigned_long_long}" = "x8"; then
+  TARGET_PTR="unsigned long long"
+elif test "x${ac_cv_sizeof_unsigned___int128}" = "x16"; then
+  TARGET_PTR="unsigned __int128"
+else
+  TARGET_PTR="unsigned long"
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDL 1
+_ACEOF
+
+  LIBS="-ldl $LIBS"
+
+fi
+
+ac_config_files="$ac_config_files jit-reader.h:jit-reader.h.in"
+
+
 
 # Check whether --with-expat was given.
 if test "${with_expat+set}" = set; then :
@@ -16717,6 +16885,7 @@ do
     "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;;
     "depdir") CONFIG_COMMANDS="$CONFIG_COMMANDS depdir" ;;
     "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "jit-reader.h") CONFIG_FILES="$CONFIG_FILES jit-reader.h:jit-reader.h.in" ;;
     "$ac_config_links_1") CONFIG_LINKS="$CONFIG_LINKS $ac_config_links_1" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     ".gdbinit") CONFIG_FILES="$CONFIG_FILES .gdbinit:gdbinit.in" ;;
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 8c12a44..bd957e1 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -573,6 +573,29 @@ AC_SUBST(READLINE_DEPS)
 AC_SUBST(READLINE_CFLAGS)
 AC_SUBST(READLINE_TEXI_INCFLAG)
 
+# Generate jit-reader.h
+
+# This is typedeffed to GDB_CORE_ADDR in jit-reader.h
+TARGET_PTR=
+
+AC_CHECK_SIZEOF(unsigned long long)
+AC_CHECK_SIZEOF(unsigned long)
+AC_CHECK_SIZEOF(unsigned __int128)
+
+if test "x${ac_cv_sizeof_unsigned_long}" = "x8"; then
+  TARGET_PTR="unsigned long"
+elif test "x${ac_cv_sizeof_unsigned_long_long}" = "x8"; then
+  TARGET_PTR="unsigned long long"
+elif test "x${ac_cv_sizeof_unsigned___int128}" = "x16"; then
+  TARGET_PTR="unsigned __int128"
+else
+  TARGET_PTR="unsigned long"
+fi
+
+AC_SUBST(TARGET_PTR)
+AC_CHECK_LIB([dl], [dlopen], [], [], [])
+AC_CONFIG_FILES([jit-reader.h:jit-reader.h.in])
+
 AC_ARG_WITH(expat,
   AS_HELP_STRING([--with-expat], [include expat support (auto/yes/no)]),
   [], [with_expat=auto])
diff --git a/gdb/jit-reader.h.in b/gdb/jit-reader.h.in
new file mode 100644
index 0000000..38d4c94
--- /dev/null
+++ b/gdb/jit-reader.h.in
@@ -0,0 +1,300 @@
+/* JIT declarations for GDB, the GNU Debugger.
+
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_JIT_READER_H
+#define GDB_JIT_READER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Versioning information. See gdb_reader_funcs */
+#define GDB_READER_INTERFACE_VERSION 1
+
+/* Readers must be released under a GPL compatible license. To declare
+   that the reader is indeed released under a GPL compatible license,
+   invoke the macro GDB_DECLARE_GPL_COMPATIBLE in a source file. */
+#define GDB_DECLARE_GPL_COMPATIBLE_READER       \
+  extern "C" {                                  \
+  extern int plugin_is_GPL_compatible (void)    \
+  {                                             \
+    return 0;                                   \
+  }                                             \
+  }
+
+/* Represents an address on the target system. */
+typedef @TARGET_PTR@ GDB_CORE_ADDR;
+
+/* Return status codes. */
+enum gdb_status {
+  GDB_FAIL = 0,
+  GDB_SUCCESS = 1
+};
+
+struct gdb_object;
+struct gdb_symtab;
+struct gdb_block;
+struct gdb_symbol_callbacks;
+
+/* An array of these are used to represent a map from code addresses to line
+   numbers in the source file. */
+struct gdb_line_mapping
+{
+  int line;
+  GDB_CORE_ADDR pc;
+};
+
+/* Create a new GDB code object. Each code object can have one or more
+   symbol tables, each representing a compiled source file. */
+typedef struct gdb_object *(gdb_object_open) (struct gdb_symbol_callbacks *cb);
+
+/* The callback used to create new symbol table.  CB is the
+   gdb_symbol_callbacks which the structure is part of.  FILE_NAME is
+   an (optionally NULL) file name to associate with this new symbol
+   table.
+
+   Returns a new instance to gdb_symtab that can later be passed to
+   gdb_block_new, gdb_symtab_add_line_mapping and gdb_symtab_close.
+*/
+typedef struct gdb_symtab *(gdb_symtab_open) (struct gdb_symbol_callbacks *cb,
+                                              struct gdb_object *obj,
+                                              const char *file_name);
+
+/* Creates a new block in a given symbol table. A symbol table is a
+   forest of blocks, each block representing an code address range and
+   a corresponding (optionally NULL) NAME. In case the block
+   corresponds to a function, the NAME passed should be the name of
+   the function.
+
+   If the new block to be created is a child of (i.e. is nested in)
+   another block, the parent block can be passed in PARENT. SYMTAB is
+   the symbol table the new block is to belong in. BEGIN, END is the
+   code address range the block corresponds to.
+
+   Returns a new instance of gdb_block, which, as of now, has no
+   use. Note that the gdb_block returned must not be freed by the
+   caller. */
+typedef struct gdb_block *(gdb_block_open) (struct gdb_symbol_callbacks *cb,
+                                            struct gdb_symtab *symtab,
+                                            struct gdb_block *parent,
+                                            GDB_CORE_ADDR begin,
+                                            GDB_CORE_ADDR end,
+                                            const char *name);
+
+/* Adds a PC to line number mapping for the symbol table
+   SYMTAB. NLINES is the number of elements in LINES, each element
+   corresponding to one (PC, line) pair. */
+typedef void (gdb_symtab_add_line_mapping) (struct gdb_symbol_callbacks *cb,
+                                            struct gdb_symtab *symtab,
+                                            int nlines,
+                                            struct gdb_line_mapping *lines);
+
+/* Close the symtab SYMTAB. This signals to GDB that no more blocks
+   will be opened on this symtab. */
+typedef void (gdb_symtab_close) (struct gdb_symbol_callbacks *cb,
+                                 struct gdb_symtab *symtab);
+
+
+/* Closes the gdb_object OBJ and adds the emitted information into
+   GDB's internal structures. Once this is done, the debug information
+   will be picked up and used; this will usually be the last operation
+   in gdb_read_debug_info. */
+typedef void (gdb_object_close) (struct gdb_symbol_callbacks *cb,
+                                 struct gdb_object *obj);
+
+/* Reads LEN bytes from TARGET_MEM in the target's virtual address
+   space into GDB_BUF.
+
+   Returns GDB_FAIL on failure, and GDB_SUCCESS on success. */
+typedef enum gdb_status (gdb_target_read) (GDB_CORE_ADDR target_mem,
+                                           void *gdb_buf, int len);
+
+/* The list of callbacks that are passed to read. These callbacks are
+   to be used to construct the symbol table. The functions have been
+   described above. */
+struct gdb_symbol_callbacks
+{
+  gdb_object_open *object_open;
+  gdb_symtab_open *symtab_open;
+  gdb_block_open *block_open;
+  gdb_symtab_close *symtab_close;
+  gdb_object_close *object_close;
+
+  gdb_symtab_add_line_mapping *line_mapping_add;
+  gdb_target_read *target_read;
+
+  /* For internal use by GDB. */
+  void *priv_data;
+};
+
+/* Forward declaration. */
+struct gdb_reg_value;
+
+typedef void (gdb_reg_value_free) (struct gdb_reg_value *);
+
+/* Denotes the value of a register. */
+struct gdb_reg_value
+{
+  /* The size of the register in bytes. The reader need not set this
+     field. This will be set for (defined) register values being read
+     from GDB using reg_get. */
+  int size;
+  /* Set to non-zero if the value for the register is known. The
+     registers for which the reader does not call reg_set are also
+     assumed to be undefined */
+  int defined;
+
+  /* Since gdb_reg_value is a variable sized structure, it will
+     usually be allocated on the heap. This function is expected to
+     contain the corresponding "free" function.
+
+     When a pointer to gdb_reg_value is being sent from GDB to the
+     reader (via gdb_unwind_reg_get), the reader is expected to call
+     this function (with the same gdb_reg_value as argument) once it
+     is done with the value.
+
+     When the function sends the a gdb_reg_value to GDB (via
+     gdb_unwind_reg_set), it is expected to set this field to point to
+     an appropriate cleanup routine (or to NULL if no cleanup is
+     required). */
+  gdb_reg_value_free *free;
+
+  /* The value of the register. */
+  unsigned char value[1];
+};
+
+/* get_frame_id in gdb_reader_funcs is to return a gdb_frame_id
+   corresponding to the current frame. The registers corresponding to
+   the current frame can be read using reg_get. Calling get_frame_id
+   on a particular frame should return the same gdb_frame_id
+   throughout its lifetime (i.e. till before it gets unwound). One way
+   to do this is by having the CODE_ADDRESS point to the function's
+   first instruction and STACK_ADDRESS point to the value of the stack
+   pointer when entering the function. */
+struct gdb_frame_id
+{
+  GDB_CORE_ADDR code_address;
+  GDB_CORE_ADDR stack_address;
+};
+
+/* Forward declaration. */
+struct gdb_unwind_callbacks;
+
+/* Returns the value of a particular register in the current
+   frame. The current frame is the frame that needs to be unwound into
+   the outer (earlier) frame.
+
+   CB is the struct gdb_unwind_callbacks * the callback belongs
+   to. REGNUM is the DWARF register number of the register that needs
+   to be unwound.
+
+   Returns the gdb_reg_value corresponding to the register
+   requested. In case the value of the register has been optimized
+   away or otherwise unavailable, the defined flag in the returned
+   gdb_reg_value will be zero. */
+typedef struct gdb_reg_value *(gdb_unwind_reg_get)
+                              (struct gdb_unwind_callbacks *cb, int regnum);
+
+/* Sets the previous value of a particular register. REGNUM is the
+   (DWARF) register number whose value is to be set. VAL is the value
+   the register is to be set to.
+
+   VAL is *not* copied, so the memory allocated to it cannot be
+   reused. Once GDB no longer needs the value, it is deallocated using
+   the FREE function (see gdb_reg_value).
+
+   A register can also be "set" to an undefined value by setting the
+   defined in VAL to zero. */
+typedef void (gdb_unwind_reg_set) (struct gdb_unwind_callbacks *cb, int regnum,
+                                   struct gdb_reg_value *val);
+
+/* This struct is passed to unwind in gdb_reader_funcs, and is to be
+   used to unwind the current frame (current being the frame whose
+   registers can be read using reg_get) into the earlier frame. The
+   functions have been described above. */
+struct gdb_unwind_callbacks
+{
+  gdb_unwind_reg_get *reg_get;
+  gdb_unwind_reg_set *reg_set;
+  gdb_target_read *target_read;
+
+  /* For internal use by GDB. */
+  void *priv_data;
+};
+
+/* Forward declaration. */
+struct gdb_reader_funcs;
+
+/* Parse the debug info off a block of memory, pointed to by MEMORY
+   (already copied to GDB's address space) and MEMORY_SZ bytes long.
+   The implementation has to use the functions in CB to actually emit
+   the parsed data into GDB. SELF is the same structure returned by
+   gdb_init_reader.
+
+   Return GDB_FAIL on failure and GDB_SUCCESS on success. */
+typedef enum gdb_status (gdb_read_debug_info) (struct gdb_reader_funcs *self,
+                                               struct gdb_symbol_callbacks *cb,
+                                               void *memory, long memory_sz);
+
+/* Unwind the current frame, CB is the set of unwind callbacks that
+   are to be used to do this.
+
+   Return GDB_FAIL on failure and GDB_SUCCESS on success. */
+typedef enum gdb_status (gdb_unwind_frame) (struct gdb_reader_funcs *self,
+                                            struct gdb_unwind_callbacks *cb);
+
+/* Return the frame ID corresponding to the current frame, using C to
+   read the current register values. See the comment on struct
+   gdb_frame_id. */
+typedef struct gdb_frame_id (gdb_get_frame_id) (struct gdb_reader_funcs *self,
+                                                struct gdb_unwind_callbacks *c);
+
+/* Called when a reader is being unloaded. This function should also
+   free SELF, if required. */
+typedef void (gdb_destroy_reader) (struct gdb_reader_funcs *self);
+
+/* Called when the reader is loaded. Must either return a properly
+   populated gdb_reader_funcs or NULL. The memory allocated for the
+   gdb_reader_funcs is to be managed by the reader itself (i.e. if it
+   is allocated from the heap, it must also be freed in
+   gdb_destroy_reader).  */
+extern struct gdb_reader_funcs *gdb_init_reader (void);
+
+/* Pointer to the functions which implement the reader's
+   functionality. The individual functions have been documented above.
+
+   None of the fields are optional. */
+struct gdb_reader_funcs
+{
+  gdb_read_debug_info *read;
+  gdb_unwind_frame *unwind;
+  gdb_get_frame_id *get_frame_id;
+  gdb_destroy_reader *destroy;
+  /* Must be set to GDB_READER_INTERFACE_VERSION */
+  int reader_version;
+
+  /* For use by the reader. */
+  void *priv_data;
+};
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/gdb/jit.c b/gdb/jit.c
index eb1bcc7..e3bb81a 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -20,6 +20,7 @@
 #include "defs.h"
 
 #include "jit.h"
+#include "jit-reader.h"
 #include "breakpoint.h"
 #include "command.h"
 #include "gdbcmd.h"
-- 
1.7.5.4


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH] JIT debug info Reader
@ 2011-08-09 15:21 Sanjoy Das
  2011-08-09 15:21 ` [PATCH 2/7] Add platform agnostic dynamic loading code Sanjoy Das
                   ` (6 more replies)
  0 siblings, 7 replies; 23+ messages in thread
From: Sanjoy Das @ 2011-08-09 15:21 UTC (permalink / raw)
  To: gdb-patches

Re-roll of the previous patch-set.

[PATCH 1/7] Introduce header (jit-reader.h.in) and modify build
[PATCH 2/7] Add platform agnostic dynamic loading code.
[PATCH 3/7] New commands for loading and unloading a reader.
[PATCH 4/7] Use the loaded reader.
[PATCH 5/7] Add a proxy unwinder.
[PATCH 6/7] Register the proxy unwinder.
[PATCH 7/7] Add documentation.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 3/7] New commands for loading and unloading a reader.
  2011-08-09 15:21 [PATCH] JIT debug info Reader Sanjoy Das
                   ` (3 preceding siblings ...)
  2011-08-09 15:21 ` [PATCH 7/7] Add documentation Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
  2011-08-12 20:58   ` Tom Tromey
  2011-08-09 15:21 ` [PATCH 4/7] Use the loaded reader Sanjoy Das
  2011-08-09 15:21 ` [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system Sanjoy Das
  6 siblings, 1 reply; 23+ messages in thread
From: Sanjoy Das @ 2011-08-09 15:21 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanjoy Das

Introduces two new GDB commands - `load-jit-reader' and
`unload-jit-reader'.
---
 gdb/ChangeLog |    6 +++
 gdb/jit.c     |  130 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 125 insertions(+), 11 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 639f1f7..884b51a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
 2011-08-09  Sanjoy Das  <sdas@igalia.com>
 
+	* jit.c (_initialize_jit): Add commands load-jit-reader and
+	unload-jit-reader.
+	(jit_reader_load): New function.
+
+2011-08-09  Sanjoy Das  <sdas@igalia.com>
+
 	* gdb-dlfcn.h, gdb-dlfcn.c: New.
     	* Makefile.in: Add gdb_dlcfn.c and gdb_dlcfn.h to the build
 	system.
diff --git a/gdb/jit.c b/gdb/jit.c
index e3bb81a..3f83065 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -31,8 +31,11 @@
 #include "symfile.h"
 #include "symtab.h"
 #include "target.h"
+#include "gdb-dlfcn.h"
 #include "gdb_stat.h"
 
+#define GDB_READER_DIR (LIBDIR "/gdb/")
+
 static const struct objfile_data *jit_objfile_data;
 
 static const char *const jit_break_name = "__jit_debug_register_code";
@@ -113,6 +116,102 @@ mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
   return 0;
 }
 
+/* One reader that has been loaded successfully, and can potentially be used to
+   parse debug info. */
+struct jit_reader
+{
+  struct gdb_reader_funcs *functions;
+} *loaded_jit_reader = NULL;
+
+typedef struct gdb_reader_funcs * (reader_init_fn_type) (void);
+const char *reader_init_fn_sym = "gdb_init_reader";
+
+/* Try to load FILE_NAME as a JIT debug info reader. Set ERROR_STRING
+   in case of an error (and return NULL), else return a correcly
+   formed struct jit_reader. */
+static struct jit_reader *
+jit_reader_load (const char *file_name, char **error_string)
+{
+  void *so;
+  reader_init_fn_type *init_fn;
+  struct jit_reader *new_reader = NULL;
+  struct gdb_reader_funcs *funcs = NULL;
+
+  if (jit_debug)
+    fprintf_unfiltered (gdb_stdlog, "Opening shared object %s.\n", file_name);
+  so = gdb_dlopen (file_name);
+
+  if (!so)
+    {
+      *error_string = _("could not open reader file");
+      return NULL;
+    }
+
+  init_fn = gdb_dlsym (so, reader_init_fn_sym);
+  if (!init_fn)
+    {
+      *error_string = _("could not locate initialization routine");
+      goto error;
+    }
+
+  if (gdb_dlsym (so, "plugin_is_GPL_compatible") == NULL)
+    {
+      *error_string = _("reader not GPL compatible");
+      goto error;
+    }
+
+  funcs = init_fn ();
+  if (funcs->reader_version != GDB_READER_INTERFACE_VERSION)
+    {
+      *error_string = _("incorrect module version");
+      goto error;
+    }
+
+  new_reader = XZALLOC (struct jit_reader);
+  new_reader->functions = funcs;
+  return new_reader;
+
+ error:
+  if (so)
+    gdb_dlclose(so);
+  return NULL;
+}
+
+/* Provides the load-jit-reader command. */
+static void
+load_jit_reader_command (char *args, int from_tty)
+{
+  char so_name[PATH_MAX] = GDB_READER_DIR;
+  char *error_string;
+
+  if (args == NULL)
+    {
+      error (_("No reader name provided."));
+      return;
+    }
+
+  strncat (so_name, args, PATH_MAX - sizeof(GDB_READER_DIR) - 4);
+  strcat (so_name, ".so");
+
+  loaded_jit_reader = jit_reader_load (so_name, &error_string);
+  if (loaded_jit_reader == NULL)
+    error(_("Unable to load reader: %s."), error_string);
+}
+
+/* Provides the unload-jit-reader command. */
+static void
+unload_jit_reader_command (char *args, int from_tty)
+{
+  if (!loaded_jit_reader)
+    {
+      error(_("No JIT reader loaded."));
+      return;
+    }
+  loaded_jit_reader->functions->destroy (loaded_jit_reader->functions);
+  free (loaded_jit_reader);
+  loaded_jit_reader = NULL;
+}
+
 /* Open a BFD from the target's memory.  */
 
 static struct bfd *
@@ -137,6 +236,7 @@ struct jit_inferior_data
 {
   CORE_ADDR breakpoint_addr;  /* &__jit_debug_register_code()  */
   CORE_ADDR descriptor_addr;  /* &__jit_debug_descriptor  */
+  struct objfile *jit_objfile; /* All the JIT symbols will be added to this. */
 };
 
 /* Return jit_inferior_data for current inferior.  Allocate if not already
@@ -510,10 +610,10 @@ jit_event_handler (struct gdbarch *gdbarch)
   struct jit_code_entry code_entry;
   CORE_ADDR entry_addr;
   struct objfile *objf;
+  struct jit_inferior_data *inf_data = get_jit_inferior_data ();
 
   /* Read the descriptor from remote memory.  */
-  jit_read_descriptor (gdbarch, &descriptor,
-		       get_jit_inferior_data ()->descriptor_addr);
+  jit_read_descriptor (gdbarch, &descriptor, inf_data->descriptor_addr);
   entry_addr = descriptor.relevant_entry;
 
   /* Do the corresponding action.  */
@@ -526,15 +626,16 @@ jit_event_handler (struct gdbarch *gdbarch)
       jit_register_code (gdbarch, entry_addr, &code_entry);
       break;
     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"),
-			   paddress (gdbarch, entry_addr));
-      else
-        jit_unregister_code (objf);
-
-      break;
+      {
+        objf = jit_find_objf_with_entry_addr (entry_addr);
+        if (objf == NULL)
+          printf_unfiltered (_("Unable to find JITed code "
+                               "entry at address: %s\n"),
+                             paddress (gdbarch, entry_addr));
+        else
+          jit_unregister_code (objf);
+        break;
+      }
     default:
       error (_("Unknown action_flag value in JIT descriptor!"));
       break;
@@ -562,4 +663,11 @@ _initialize_jit (void)
   jit_objfile_data = register_objfile_data ();
   jit_inferior_data =
     register_inferior_data_with_cleanup (jit_inferior_data_cleanup);
+  add_com ("load-jit-reader", no_class, load_jit_reader_command, _("\
+Try to load file FILE as a debug info reader (and unwinder) for\n\
+JIT compiled code from " LIBDIR "/gdb\n\
+Usage is `load-jit-reader FILE`."));
+  add_com ("unload-jit-reader", no_class, unload_jit_reader_command, _("\
+Unload the currently loaded JIT reader (loaded using load-jit-reader)\n\
+Usage is simply `unload-jit-reader`."));
 }
-- 
1.7.5.4


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 6/7] Register the proxy unwinder.
  2011-08-09 15:21 [PATCH] JIT debug info Reader Sanjoy Das
  2011-08-09 15:21 ` [PATCH 2/7] Add platform agnostic dynamic loading code Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
  2011-08-12 21:07   ` Tom Tromey
  2011-08-09 15:21 ` [PATCH 5/7] Add a " Sanjoy Das
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 23+ messages in thread
From: Sanjoy Das @ 2011-08-09 15:21 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanjoy Das

Register the proxy unwinder introduced in the previous commit so that
it actually gets picked up and used.
---
 gdb/ChangeLog            |   25 +++++++++++++++++++++++++
 gdb/alpha-tdep.c         |    2 ++
 gdb/arm-tdep.c           |    2 ++
 gdb/bfin-tdep.c          |    2 ++
 gdb/cris-tdep.c          |    2 ++
 gdb/h8300-tdep.c         |    2 ++
 gdb/i386-tdep.c          |    2 ++
 gdb/iq2000-tdep.c        |    2 ++
 gdb/m68hc11-tdep.c       |    2 ++
 gdb/microblaze-tdep.c    |    2 ++
 gdb/mips-tdep.c          |    2 ++
 gdb/mn10300-tdep.c       |    2 ++
 gdb/mt-tdep.c            |    2 ++
 gdb/rs6000-tdep.c        |    2 ++
 gdb/rx-tdep.c            |    2 ++
 gdb/s390-tdep.c          |    3 +++
 gdb/score-tdep.c         |    2 ++
 gdb/sh64-tdep.c          |    2 ++
 gdb/sparc-linux-tdep.c   |    2 ++
 gdb/sparc64-linux-tdep.c |    2 ++
 gdb/v850-tdep.c          |    2 ++
 gdb/xstormy16-tdep.c     |    2 ++
 gdb/xtensa-tdep.c        |    2 ++
 23 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2556be7..2b3dc1a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,30 @@
 2011-08-09  Sanjoy Das  <sdas@igalia.com>
 
+	* alpha-tdep.c (alpha_dwarf2_init_abi): Call jit_prepend_unwinder.
+	* arm-tdep.c (arm_gdbarch_init): Likewise.
+	* bfin-tdep.c (bfin_gdbarch_init): Likewise.
+	* cris-tdep.c (cris_gdbarch_init): Likewise.
+	* h8300-tdep.c (h8300_gdbarch_init): Likewise.
+	* i386-tdep.c (i386_gdbarch_init): Likewise.
+	* iq2000-tdep.c (iq2000_gdbarch_init): Likewise.
+	* m68hc11-tdep.c (m68hc11_gdbarch_init): Likewise.
+	* microblaze-tdep.c (microblaze_gdbarch_init): Likewise.
+	* mips-tdep.c (mips_gdbarch_init): Likewise.
+	* mn10300-tdep.c (mn10300_gdbarch_init): Likewise.
+	* mt-tdep.c (mt_gdbarch_init): Likewise.
+	* rs6000-tdep.c (rs6000_gdbarch_init): Likewise.
+	* rx-tdep.c (rx_gdbarch_init): Likewise.
+	* s390-tdep.c (s390_gdbarch_init): Likewise.
+	* score-tdep.c (score_gdbarch_init): Likewise.
+	* sh64-tdep.c (sh64_gdbarch_init): Likewise.
+	* sparc-linux-tdep.c (sparc_linux_init_abi): Likewise.
+	* sparc64-linux-tdep.c (sparc64_linux_init_abi): Likewise.
+	* v850-tdep.c (v858_gdbarch_init): Likewise.
+	* xstormy16-tdep.c (xstormy16_gdbarch_init): Likewise.
+	* xtensa-tdep.c (xtensa_gdbarch_init): Likewise.
+
+2011-08-09  Sanjoy Das  <sdas@igalia.com>
+
 	* jit.c (jut_unwind_reg_set_impl, free_reg_value_impl)
 	(jit_unwind_reg_get_impl, jit_frame_sniffer)
 	(jit_frame_unwind_stop_reason, jit_frame_this_id)
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 77782e8..818449e 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -42,6 +42,7 @@
 #include "block.h"
 #include "infcall.h"
 #include "trad-frame.h"
+#include "jit.h"
 
 #include "elf-bfd.h"
 
@@ -1770,6 +1771,7 @@ void
 alpha_dwarf2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
 }
 
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 1a75af1..19e0e57 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -44,6 +44,7 @@
 #include "target-descriptions.h"
 #include "user-regs.h"
 #include "observer.h"
+#include "jit.h"
 
 #include "arm-tdep.h"
 #include "gdb/sim-arm.h"
@@ -8687,6 +8688,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Add some default predicates.  */
   frame_unwind_append_unwinder (gdbarch, &arm_stub_unwind);
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &arm_exidx_unwind);
   frame_unwind_append_unwinder (gdbarch, &arm_prologue_unwind);
 
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
index 5522c5b..977f62f 100644
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -42,6 +42,7 @@
 #include "infcall.h"
 #include "xml-syscall.h"
 #include "bfin-tdep.h"
+#include "jit.h"
 
 /* Macros used by prologue functions.  */
 #define P_LINKAGE			0xE800
@@ -853,6 +854,7 @@ bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   gdbarch_init_osabi (info, gdbarch);
 
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
 
   frame_base_set_default (gdbarch, &bfin_frame_base);
 
diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c
index f79e84c..a88afed 100644
--- a/gdb/cris-tdep.c
+++ b/gdb/cris-tdep.c
@@ -38,6 +38,7 @@
 #include "arch-utils.h"
 #include "regcache.h"
 #include "gdb_assert.h"
+#include "jit.h"
 
 #include "objfiles.h"
 
@@ -4228,6 +4229,7 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   frame_unwind_append_unwinder (gdbarch, &cris_frame_unwind);
   frame_base_set_default (gdbarch, &cris_frame_base);
+  jit_prepend_unwinder (gdbarch);
 
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
index fa39dee..a1052be 100644
--- a/gdb/h8300-tdep.c
+++ b/gdb/h8300-tdep.c
@@ -35,6 +35,7 @@
 #include "dwarf2-frame.h"
 #include "frame-base.h"
 #include "frame-unwind.h"
+#include "jit.h"
 
 enum gdb_regnum
 {
@@ -1355,6 +1356,7 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Hook in the DWARF CFI frame unwinder.  */
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &h8300_frame_unwind);
 
   return gdbarch;
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 5fb2efb..f4fbc43 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -48,6 +48,7 @@
 #include "exceptions.h"
 #include "gdb_assert.h"
 #include "gdb_string.h"
+#include "jit.h"
 
 #include "i386-tdep.h"
 #include "i387-tdep.h"
@@ -7357,6 +7358,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      to the list before the prologue-based unwinders, so that DWARF
      CFI info will be used if it is available.  */
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
 
   frame_base_set_default (gdbarch, &i386_frame_base);
 
diff --git a/gdb/iq2000-tdep.c b/gdb/iq2000-tdep.c
index 1926da6..e0b17e7 100644
--- a/gdb/iq2000-tdep.c
+++ b/gdb/iq2000-tdep.c
@@ -34,6 +34,7 @@
 #include "regcache.h"
 #include "osabi.h"
 #include "gdbcore.h"
+#include "jit.h"
 
 enum gdb_regnum
 {
@@ -851,6 +852,7 @@ iq2000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   gdbarch_init_osabi (info, gdbarch);
 
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &iq2000_frame_unwind);
 
   return gdbarch;
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index b789ce7..333f867 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -40,6 +40,7 @@
 #include "arch-utils.h"
 #include "regcache.h"
 #include "reggroups.h"
+#include "jit.h"
 
 #include "target.h"
 #include "opcode/m68hc11.h"
@@ -1534,6 +1535,7 @@ m68hc11_gdbarch_init (struct gdbarch_info info,
 
   /* Hook in the DWARF CFI frame unwinder.  */
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
 
   frame_unwind_append_unwinder (gdbarch, &m68hc11_frame_unwind);
   frame_base_set_default (gdbarch, &m68hc11_frame_base);
diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
index 2482c87..9a04dcc 100644
--- a/gdb/microblaze-tdep.c
+++ b/gdb/microblaze-tdep.c
@@ -34,6 +34,7 @@
 #include "frame-unwind.h"
 #include "dwarf2-frame.h"
 #include "osabi.h"
+#include "jit.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -724,6 +725,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Unwind the frame.  */
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &microblaze_frame_unwind);
   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
 
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 47d9182..4f30eb3 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -59,6 +59,7 @@
 #include "user-regs.h"
 #include "valprint.h"
 #include "ax.h"
+#include "jit.h"
 
 static const struct objfile_data *mips_pdr_data;
 
@@ -6303,6 +6304,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Unwind the frame.  */
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &mips_stub_frame_unwind);
   frame_unwind_append_unwinder (gdbarch, &mips_insn16_frame_unwind);
   frame_unwind_append_unwinder (gdbarch, &mips_insn32_frame_unwind);
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index e949b40..de14a59 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -37,6 +37,7 @@
 #include "infcall.h"
 #include "prologue-value.h"
 #include "target.h"
+#include "jit.h"
 
 #include "mn10300-tdep.h"
 
@@ -1203,6 +1204,7 @@ static void
 mn10300_frame_unwind_init (struct gdbarch *gdbarch)
 {
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &mn10300_frame_unwind);
   set_gdbarch_dummy_id (gdbarch, mn10300_dummy_id);
   set_gdbarch_unwind_pc (gdbarch, mn10300_unwind_pc);
diff --git a/gdb/mt-tdep.c b/gdb/mt-tdep.c
index ee98d3d..99e19ea 100644
--- a/gdb/mt-tdep.c
+++ b/gdb/mt-tdep.c
@@ -39,6 +39,7 @@
 #include "gdb_assert.h"
 #include "language.h"
 #include "valprint.h"
+#include "jit.h"
 
 enum mt_arch_constants
 {
@@ -1191,6 +1192,7 @@ mt_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Register the DWARF 2 sniffer first, and then the traditional prologue
      based sniffer.  */
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &mt_frame_unwind);
   frame_base_set_default (gdbarch, &mt_frame_base);
 
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 6539644..ad6eaed 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -41,6 +41,7 @@
 #include "dwarf2-frame.h"
 #include "target-descriptions.h"
 #include "user-regs.h"
+#include "jit.h"
 
 #include "libbfd.h"		/* for bfd_default_set_arch_mach */
 #include "coff/internal.h"	/* for libcoff.h */
@@ -4081,6 +4082,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Hook in the DWARF CFI frame unwinder.  */
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   dwarf2_frame_set_adjust_regnum (gdbarch, rs6000_adjust_frame_regnum);
 
   /* Frame handling.  */
diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c
index 16637b0..185e38a 100644
--- a/gdb/rx-tdep.c
+++ b/gdb/rx-tdep.c
@@ -33,6 +33,7 @@
 #include "value.h"
 #include "gdbcore.h"
 #include "dwarf2-frame.h"
+#include "jit.h"
 
 #include "elf/rx.h"
 #include "elf-bfd.h"
@@ -844,6 +845,7 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      so it's turned off for now.  */
   dwarf2_append_unwinders (gdbarch);
 #endif
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &rx_frame_unwind);
 
   /* Methods for saving / extracting a dummy frame's ID.
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index ca7ecc7..ea117aa 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -45,6 +45,7 @@
 #include "prologue-value.h"
 #include "linux-tdep.h"
 #include "s390-tdep.h"
+#include "jit.h"
 
 #include "features/s390-linux32.c"
 #include "features/s390-linux64.c"
@@ -2915,6 +2916,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   dwarf2_frame_set_init_reg (gdbarch, s390_dwarf2_frame_init_reg);
   dwarf2_frame_set_adjust_regnum (gdbarch, s390_adjust_frame_regnum);
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
+
   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
   frame_unwind_append_unwinder (gdbarch, &s390_stub_frame_unwind);
   frame_unwind_append_unwinder (gdbarch, &s390_sigtramp_frame_unwind);
diff --git a/gdb/score-tdep.c b/gdb/score-tdep.c
index 4ddcd27..4364acd 100644
--- a/gdb/score-tdep.c
+++ b/gdb/score-tdep.c
@@ -38,6 +38,7 @@
 #include "trad-frame.h"
 #include "dwarf2-frame.h"
 #include "score-tdep.h"
+#include "jit.h"
 
 #define G_FLD(_i,_ms,_ls) \
     ((unsigned)((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
@@ -1543,6 +1544,7 @@ score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Normal frame hooks.  */
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
   frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
   frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index a4da7a4..01b9540 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -40,6 +40,7 @@
 #include "regcache.h"
 #include "osabi.h"
 #include "valprint.h"
+#include "jit.h"
 
 #include "elf-bfd.h"
 
@@ -2567,6 +2568,7 @@ sh64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   gdbarch_init_osabi (info, gdbarch);
 
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &sh64_frame_unwind);
 
   return gdbarch;
diff --git a/gdb/sparc-linux-tdep.c b/gdb/sparc-linux-tdep.c
index b21b7a8..c5abf3c 100644
--- a/gdb/sparc-linux-tdep.c
+++ b/gdb/sparc-linux-tdep.c
@@ -34,6 +34,7 @@
 #include "tramp-frame.h"
 #include "xml-syscall.h"
 #include "linux-tdep.h"
+#include "jit.h"
 
 /* The syscall's XML filename for sparc 32-bit.  */
 #define XML_SYSCALL_FILENAME_SPARC32 "syscalls/sparc-linux.xml"
@@ -307,6 +308,7 @@ sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Hook in the DWARF CFI frame unwinder.  */
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
 
   set_gdbarch_write_pc (gdbarch, sparc_linux_write_pc);
 
diff --git a/gdb/sparc64-linux-tdep.c b/gdb/sparc64-linux-tdep.c
index 87e7285..ff71256 100644
--- a/gdb/sparc64-linux-tdep.c
+++ b/gdb/sparc64-linux-tdep.c
@@ -33,6 +33,7 @@
 #include "tramp-frame.h"
 #include "xml-syscall.h"
 #include "linux-tdep.h"
+#include "jit.h"
 
 /* The syscall's XML filename for sparc 64-bit.  */
 #define XML_SYSCALL_FILENAME_SPARC64 "syscalls/sparc64-linux.xml"
@@ -254,6 +255,7 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Hook in the DWARF CFI frame unwinder.  */
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
 
   sparc64_init_abi (info, gdbarch);
 
diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c
index ac5d83f..1beac57 100644
--- a/gdb/v850-tdep.c
+++ b/gdb/v850-tdep.c
@@ -33,6 +33,7 @@
 #include "regcache.h"
 #include "dis-asm.h"
 #include "osabi.h"
+#include "jit.h"
 
 enum
   {
@@ -1041,6 +1042,7 @@ v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   gdbarch_init_osabi (info, gdbarch);
 
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &v850_frame_unwind);
 
   return gdbarch;
diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c
index bf32cbd..6e6cbc0 100644
--- a/gdb/xstormy16-tdep.c
+++ b/gdb/xstormy16-tdep.c
@@ -38,6 +38,7 @@
 #include "doublest.h"
 #include "osabi.h"
 #include "objfiles.h"
+#include "jit.h"
 
 enum gdb_regnum
 {
@@ -849,6 +850,7 @@ xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   gdbarch_init_osabi (info, gdbarch);
 
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &xstormy16_frame_unwind);
 
   return gdbarch;
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 518b77b..515ece9 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -33,6 +33,7 @@
 #include "regcache.h"
 #include "reggroups.h"
 #include "regset.h"
+#include "jit.h"
 
 #include "dummy-frame.h"
 #include "dwarf2.h"
@@ -3277,6 +3278,7 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   frame_base_set_default (gdbarch, &xtensa_frame_base);
   frame_unwind_append_unwinder (gdbarch, &xtensa_unwind);
   dwarf2_append_unwinders (gdbarch);
+  jit_prepend_unwinder (gdbarch);
 
   set_gdbarch_print_insn (gdbarch, print_insn_xtensa);
 
-- 
1.7.5.4


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system.
  2011-08-09 15:21 ` [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system Sanjoy Das
@ 2011-08-09 15:40   ` Eli Zaretskii
  2011-08-09 15:43     ` Sanjoy Das
  2011-08-20 17:17     ` Jan Kratochvil
  2011-08-10 20:57   ` Tom Tromey
  1 sibling, 2 replies; 23+ messages in thread
From: Eli Zaretskii @ 2011-08-09 15:40 UTC (permalink / raw)
  To: Sanjoy Das; +Cc: gdb-patches, sanjoy

> From: Sanjoy Das <sanjoy@playingwithpointers.com>
> Cc: Sanjoy Das <sanjoy@playingwithpointers.com>
> Date: Tue,  9 Aug 2011 20:55:03 +0530
> 
> jit-reader.h.in will host the interface to be implemented and the API
> to be used by the reader. The file needs to be processed by
> ./configure to produce `jit.reader.h'; so that GDB_CORE_ADDR is
> defined correctly.

I understand that jit.c will be compiled unconditionally on the x86
architectures, is that right?  If so, would it be possible to rename
jit-header.h.in to jit-header.in, or some other name that doesn't
violate the file-naming restrictions on 8+3 (a.k.a. DOS) filesystems?
Handling such files that need to be used while compiling the DJGPP
port of GDB is a nuisance.

TIA


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system.
  2011-08-09 15:40   ` Eli Zaretskii
@ 2011-08-09 15:43     ` Sanjoy Das
  2011-08-09 15:53       ` Eli Zaretskii
  2011-08-20 17:17     ` Jan Kratochvil
  1 sibling, 1 reply; 23+ messages in thread
From: Sanjoy Das @ 2011-08-09 15:43 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

Hi!

> I understand that jit.c will be compiled unconditionally on the x86
> architectures, is that right?  If so, would it be possible to rename
> jit-header.h.in to jit-header.in, or some other name that doesn't
> violate the file-naming restrictions on 8+3 (a.k.a. DOS) filesystems?
> Handling such files that need to be used while compiling the DJGPP
> port of GDB is a nuisance.

Shouldn't be a problem, I'll correct this in the next iteration.

-- 
Sanjoy Das
http://playingwithpointers.com


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 7/7] Add documentation.
  2011-08-09 15:21 ` [PATCH 7/7] Add documentation Sanjoy Das
@ 2011-08-09 15:51   ` Eli Zaretskii
  0 siblings, 0 replies; 23+ messages in thread
From: Eli Zaretskii @ 2011-08-09 15:51 UTC (permalink / raw)
  To: Sanjoy Das; +Cc: gdb-patches

> From: Sanjoy Das <sanjoy@playingwithpointers.com>
> Cc: Sanjoy Das <sanjoy@playingwithpointers.com>
> Date: Tue,  9 Aug 2011 20:55:09 +0530
> 
> +@node Custom Debug Info
> +@section Custom Debug Info

Please add a couple of @cindex entries here for the subjects of this
section.

> +A mentioned

Probably meant "as mentioned" here.

>                readers can be loaded using the @code{load-jit-reader}
> +command.  Executing @code{load-jit-reader foo} will have @value{GDBN}
> +try to load @code{foo.so}

@file{foo.so}

Btw, is the .so extension hard-coded?  That is, does this feature
support only Posix-style shared libraries, or Windows-style as well?

> from @code{$libdir/gdb} where @code{libdir}

@file{@var{libdir}/gdb}

"libdir" is a place-holder, so it should be in @var.

> +is the library directory for the system (usually something like
> +@code{/usr/local/lib}).

@file{/usr/local/lib}

> +further interaction is required from the user's side.  The current
> +reader can be unloaded by executing @code{unload-jit-reader},

Please describe the commands in the format we use for all the other
commands, including @kindex entries etc.

>                                                              after
> +which a new reader may be loaded, using @code{load-jit-reader} as
> +usual.

Does this mean only one reader can be loaded at any given time?  If
so, this should be said explicitly.  What happens if I try to load
another one without unloading first?

> +As mentioned, a reader is essentially a shared object conforming to a
> +certain ABI.  This ABI is described in @file{jit-reader.h}.

jit-reader.h or jit-reader.h.in?  The previous section used the
latter.

> +@value{GDBN}), in @code{$includedir/gdb} where @code{$includedir} is
> +the system include directory.

@file{@var{includedir}/gdb} and @var{includedir}

> +Readers need to be released under a GPL compatible license.  A reader
> +can be declared released under such a license by placing the macro
          ^^^^^^^^^^^^^^^^^
"declared as released", probably.

> +those object files. @code{struct gdb_unwind_callbacks} has callbacks
                     ^^
Need two spaces here.

> +to read registers off the current frame and to write out the values of
> +the registers in the previous frame. Both have a callback
                                      ^^
Likewise.

Thanks.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system.
  2011-08-09 15:43     ` Sanjoy Das
@ 2011-08-09 15:53       ` Eli Zaretskii
  0 siblings, 0 replies; 23+ messages in thread
From: Eli Zaretskii @ 2011-08-09 15:53 UTC (permalink / raw)
  To: Sanjoy Das; +Cc: gdb-patches

> Date: Tue, 09 Aug 2011 21:17:29 +0530
> From: Sanjoy Das <sanjoy@playingwithpointers.com>
> CC: gdb-patches@sourceware.org
> 
> Hi!
> 
> > I understand that jit.c will be compiled unconditionally on the x86
> > architectures, is that right?  If so, would it be possible to rename
> > jit-header.h.in to jit-header.in, or some other name that doesn't
> > violate the file-naming restrictions on 8+3 (a.k.a. DOS) filesystems?
> > Handling such files that need to be used while compiling the DJGPP
> > port of GDB is a nuisance.
> 
> Shouldn't be a problem, I'll correct this in the next iteration.

Thank you.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system.
  2011-08-09 15:21 ` [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system Sanjoy Das
  2011-08-09 15:40   ` Eli Zaretskii
@ 2011-08-10 20:57   ` Tom Tromey
  1 sibling, 0 replies; 23+ messages in thread
From: Tom Tromey @ 2011-08-10 20:57 UTC (permalink / raw)
  To: Sanjoy Das; +Cc: gdb-patches

>>>>> "Sanjoy" == Sanjoy Das <sanjoy@playingwithpointers.com> writes:

Sanjoy> jit-reader.h.in will host the interface to be implemented and the API
Sanjoy> to be used by the reader. The file needs to be processed by
Sanjoy> ./configure to produce `jit.reader.h'; so that GDB_CORE_ADDR is
Sanjoy> defined correctly.

This looks pretty good.

Sanjoy> +	-DLOCALEDIR="\"$(localedir)\"" $(DEFS) -DLIBDIR="\"@libdir@\""

I want to note that LIBDIR should be relocated at runtime.

Sanjoy> +#define GDB_DECLARE_GPL_COMPATIBLE_READER       \
Sanjoy> +  extern "C" {                                  \
Sanjoy> +  extern int plugin_is_GPL_compatible (void)    \
Sanjoy> +  {                                             \
Sanjoy> +    return 0;                                   \
Sanjoy> +  }                                             \
Sanjoy> +  }

This define isn't ok, because the including source code might be C.
You can just make two separate defines, one for C and one for C++.

Sanjoy> +struct gdb_reader_funcs
Sanjoy> +{
Sanjoy> +  gdb_read_debug_info *read;
Sanjoy> +  gdb_unwind_frame *unwind;
Sanjoy> +  gdb_get_frame_id *get_frame_id;
Sanjoy> +  gdb_destroy_reader *destroy;
Sanjoy> +  /* Must be set to GDB_READER_INTERFACE_VERSION */
Sanjoy> +  int reader_version;

Put the version first.  That gives maximum freedom for rearranging the
structure in future versions.

Tom


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/7] Add platform agnostic dynamic loading code.
  2011-08-09 15:21 ` [PATCH 2/7] Add platform agnostic dynamic loading code Sanjoy Das
@ 2011-08-10 21:01   ` Tom Tromey
  0 siblings, 0 replies; 23+ messages in thread
From: Tom Tromey @ 2011-08-10 21:01 UTC (permalink / raw)
  To: Sanjoy Das; +Cc: gdb-patches

>>>>> "Sanjoy" == Sanjoy Das <sanjoy@playingwithpointers.com> writes:

Sanjoy> 	* gdb-dlfcn.h, gdb-dlfcn.c: New.
Sanjoy> 	* Makefile.in: Add gdb_dlcfn.c and gdb_dlcfn.h to the build system.
Sanjoy> 	* configure.ac, config.in: Check for -ldl and accordingly define HAVE_LIBDL.

Looks pretty good.

Sanjoy> diff --git a/gdb/gdb-dlfcn.c b/gdb/gdb-dlfcn.c
Sanjoy> new file mode 100644
Sanjoy> index 0000000..91e8a22
Sanjoy> --- /dev/null
Sanjoy> +++ b/gdb/gdb-dlfcn.c
Sanjoy> @@ -0,0 +1,49 @@
Sanjoy> +#include "gdb-dlfcn.h"
Sanjoy> +
Sanjoy> +#include "config.h"

This file needs a copyright header.
Instead of config.h, include defs.h first thing.

Sanjoy> +int
Sanjoy> +gdb_dlclose (void *handle)

Needs a comment describing the return value.

For a new self-contained module like this, I'd rather the comments be in
the header than in the implementation.

Tom


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 3/7] New commands for loading and unloading a reader.
  2011-08-09 15:21 ` [PATCH 3/7] New commands for loading and unloading a reader Sanjoy Das
@ 2011-08-12 20:58   ` Tom Tromey
  0 siblings, 0 replies; 23+ messages in thread
From: Tom Tromey @ 2011-08-12 20:58 UTC (permalink / raw)
  To: Sanjoy Das; +Cc: gdb-patches

>>>>> "Sanjoy" == Sanjoy Das <sanjoy@playingwithpointers.com> writes:

Sanjoy> Introduces two new GDB commands - `load-jit-reader' and
Sanjoy> `unload-jit-reader'.

I am not that fond of these command names.
I'm not sure what else I would propose... maybe a "jit" prefix command,
with "load" and "unload" subcommands?

Do we actually need the ability to unload?

Sanjoy> +#define GDB_READER_DIR (LIBDIR "/gdb/")

This should go through the relocation process done for other
directories.  See main.c.

Sanjoy> +/* One reader that has been loaded successfully, and can potentially be used to
Sanjoy> +   parse debug info. */
Sanjoy> +struct jit_reader
Sanjoy> +{
Sanjoy> +  struct gdb_reader_funcs *functions;
Sanjoy> +} *loaded_jit_reader = NULL;

Can this be static?

Sanjoy> +typedef struct gdb_reader_funcs * (reader_init_fn_type) (void);
Sanjoy> +const char *reader_init_fn_sym = "gdb_init_reader";

Likewise.

Sanjoy> +/* Try to load FILE_NAME as a JIT debug info reader. Set ERROR_STRING
Sanjoy> +   in case of an error (and return NULL), else return a correcly
Sanjoy> +   formed struct jit_reader. */
Sanjoy> +static struct jit_reader *
Sanjoy> +jit_reader_load (const char *file_name, char **error_string)

It is more normal in gdb to simply call error when an error occurs.
Then you don't need to worry about the return value, or passing in the
error_string pointer.

Sanjoy> +  so = gdb_dlopen (file_name);
Sanjoy> +
Sanjoy> +  if (!so)
Sanjoy> +    {
Sanjoy> +      *error_string = _("could not open reader file");
Sanjoy> +      return NULL;
Sanjoy> +    }

It might be nicer if gdb_dlopen called error, so that the different
ports could give better error messages, say via dlerror.

Sanjoy> +  if (so)
Sanjoy> +    gdb_dlclose(so);

With the error approach, you would install a cleanup that calls
gdb_dlclose, then discard_cleanups at the point of normal return.

Sanjoy> +  strncat (so_name, args, PATH_MAX - sizeof(GDB_READER_DIR) - 4);
Sanjoy> +  strcat (so_name, ".so");

It seems to me that you want a directory separator in here.

Sanjoy> +  free (loaded_jit_reader);

xfree.

Sanjoy> @@ -510,10 +610,10 @@ jit_event_handler (struct gdbarch *gdbarch)
Sanjoy>    struct jit_code_entry code_entry;
Sanjoy>    CORE_ADDR entry_addr;
Sanjoy>    struct objfile *objf;
Sanjoy> +  struct jit_inferior_data *inf_data = get_jit_inferior_data ();
 
Sanjoy>    /* Read the descriptor from remote memory.  */
Sanjoy> -  jit_read_descriptor (gdbarch, &descriptor,
Sanjoy> -		       get_jit_inferior_data ()->descriptor_addr);
Sanjoy> +  jit_read_descriptor (gdbarch, &descriptor, inf_data->descriptor_addr);
Sanjoy>    entry_addr = descriptor.relevant_entry;
 
Sanjoy>    /* Do the corresponding action.  */
Sanjoy> @@ -526,15 +626,16 @@ jit_event_handler (struct gdbarch *gdbarch)
Sanjoy>        jit_register_code (gdbarch, entry_addr, &code_entry);
Sanjoy>        break;
Sanjoy>      case JIT_UNREGISTER:
Sanjoy> -      objf = jit_find_objf_with_entry_addr (entry_addr);
Sanjoy> -      if (objf == NULL)
Sanjoy> -	printf_unfiltered (_("Unable to find JITed code "
Sanjoy> -			     "entry at address: %s\n"),
Sanjoy> -			   paddress (gdbarch, entry_addr));
Sanjoy> -      else
Sanjoy> -        jit_unregister_code (objf);
Sanjoy> -
Sanjoy> -      break;
Sanjoy> +      {
Sanjoy> +        objf = jit_find_objf_with_entry_addr (entry_addr);
Sanjoy> +        if (objf == NULL)
Sanjoy> +          printf_unfiltered (_("Unable to find JITed code "
Sanjoy> +                               "entry at address: %s\n"),
Sanjoy> +                             paddress (gdbarch, entry_addr));
Sanjoy> +        else
Sanjoy> +          jit_unregister_code (objf);
Sanjoy> +        break;
Sanjoy> +      }

These hunks seem to be just formatting changes.
Please drop.

Tom


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 6/7] Register the proxy unwinder.
  2011-08-09 15:21 ` [PATCH 6/7] Register the proxy unwinder Sanjoy Das
@ 2011-08-12 21:07   ` Tom Tromey
  0 siblings, 0 replies; 23+ messages in thread
From: Tom Tromey @ 2011-08-12 21:07 UTC (permalink / raw)
  To: Sanjoy Das; +Cc: gdb-patches

>>>>> "Sanjoy" == Sanjoy Das <sanjoy@playingwithpointers.com> writes:

Sanjoy> Register the proxy unwinder introduced in the previous commit so that
Sanjoy> it actually gets picked up and used.

It seems to me that we'd always want the JIT unwinder available, and
we'd always want it first on the list -- so we could add it in a single
generic place instead of modifying all the *-tdep.c files.  What do you
think of that?

Tom


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 4/7] Use the loaded reader.
  2011-08-09 15:21 ` [PATCH 4/7] Use the loaded reader Sanjoy Das
@ 2011-08-15 20:21   ` Tom Tromey
  0 siblings, 0 replies; 23+ messages in thread
From: Tom Tromey @ 2011-08-15 20:21 UTC (permalink / raw)
  To: Sanjoy Das; +Cc: gdb-patches

>>>>> "Sanjoy" == Sanjoy Das <sanjoy@playingwithpointers.com> writes:

Sanjoy> Invoke the loaded JIT debug info reader to parse the registered symbol
Sanjoy> files.

Thanks.

Sanjoy> +/* Remember a mapping from entry_addr to objfile.  */
Sanjoy> +static void
Sanjoy> +add_objfile_entry (struct objfile *objfile, CORE_ADDR entry)
Sanjoy> +{
Sanjoy> +  CORE_ADDR *entry_addr_ptr;
Sanjoy> +
Sanjoy> +  entry_addr_ptr = xmalloc (sizeof (CORE_ADDR));
Sanjoy> +  *entry_addr_ptr = entry;
Sanjoy> +  set_objfile_data (objfile, jit_objfile_data, entry_addr_ptr);
Sanjoy> +}

Sanjoy> +/* Returns true if the block corrensponding to old should be placed

Typo, "corresponding".

Sanjoy> +static struct gdb_block *
Sanjoy> +jit_block_open_impl (struct gdb_symbol_callbacks *cb, struct gdb_symtab *symtab,

This line is too long.

Every new function should have some kind of introductory comment.  There
should be a blank line between the comment and the start of the
function.

Sanjoy>  static void
Sanjoy> -jit_register_code (struct gdbarch *gdbarch,
Sanjoy> -		   CORE_ADDR entry_addr, struct jit_code_entry *code_entry)
Sanjoy> +jit_symtab_line_mapping_add_impl (struct gdb_symbol_callbacks *cb,
Sanjoy> +                                  struct gdb_symtab *stab, int nlines,
Sanjoy> +                                  struct gdb_line_mapping *map)
Sanjoy> +{
Sanjoy> +  int i;
Sanjoy> +  if (!nlines)

Blank line between declarations and code.

For safety this check should probably be 'if (nlines < 1)'.

Sanjoy> +  stab->linetable = xmalloc (sizeof (struct linetable) + (nlines - 1) *
Sanjoy> +                             sizeof (struct linetable_entry));

Break before "*", not after it.  This is a GNU style thing.

Personally I'd prefer a break before the "+" instead.

Sanjoy> +static void
Sanjoy> +jit_symtab_close_impl (struct gdb_symbol_callbacks *cb, struct gdb_symtab *stab)

Line too long.

Sanjoy> +  int actual_nblocks = FIRST_LOCAL_BLOCK + stab->nblocks, i, blockvector_size;

Line too long.

Sanjoy> +      int size = (stab->linetable->nitems - 1) *
Sanjoy> +        sizeof (struct linetable_entry) + sizeof (struct linetable);

Line breaks before operators.

According to GNU style you have to parenthesize the RHS here, and
further indent the second line.

Sanjoy> +  blockvector_size = (sizeof (struct blockvector) +
Sanjoy> +                      (actual_nblocks - 1) * sizeof (struct block *));

... like this :-)

Sanjoy> +      block_name->symtab = symtab;

You can use SYMBOL_SYMTAB here.

Sanjoy> +      block_name->ginfo.name = obstack_alloc (&objfile->objfile_obstack, 1 +
Sanjoy> +                                              strlen (gdb_block_iter->name));

I think it needs to be strlen() + 1 -- but you can just use obsavestring
instead.

Sanjoy> +/* Convert OBJ to a proper objfile. */
Sanjoy> +static void
Sanjoy> +jit_object_close_impl (struct gdb_symbol_callbacks *cb, struct gdb_object *obj)

Line too long.

Sanjoy> +  objfile->msymbols = obstack_alloc (&objfile->objfile_obstack,
Sanjoy> +                                     sizeof (struct minimal_symbol));
Sanjoy> +  objfile->msymbols[0].ginfo.name = NULL;
Sanjoy> +  objfile->msymbols[0].ginfo.value.address = 0;

A little surprising maybe, but I guess it is ok.

Sanjoy> +  objfile->name = xstrdup ("JIT");

You have to xfree the old name first.

Sanjoy>  static void
Sanjoy>  jit_unregister_code (struct objfile *objfile)
Sanjoy>  {
Sanjoy> +  xfree (objfile_data (objfile, jit_objfile_data));
Sanjoy>    free_objfile (objfile);
Sanjoy>  }

I think a better fix for this problem would be to change the
initialization of jit_objfile_data to use register_objfile_data_with_cleanup.

Tom


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 5/7] Add a proxy unwinder.
  2011-08-09 15:21 ` [PATCH 5/7] Add a " Sanjoy Das
@ 2011-08-15 20:38   ` Tom Tromey
  2011-08-20  6:26     ` Sanjoy Das
  0 siblings, 1 reply; 23+ messages in thread
From: Tom Tromey @ 2011-08-15 20:38 UTC (permalink / raw)
  To: Sanjoy Das; +Cc: gdb-patches

>>>>> "Sanjoy" == Sanjoy Das <sanjoy@playingwithpointers.com> writes:

Sanjoy> Have the proxy unwinder pass down all calls to the functions the JIT
Sanjoy> reader provides.

Thank you.

Sanjoy> +static void
Sanjoy> +free_reg_value_impl (struct gdb_reg_value *reg_value)
Sanjoy> +{
Sanjoy> +  free (reg_value);

xfree.

Sanjoy> +static struct gdb_reg_value *
Sanjoy> +jit_unwind_reg_get_impl (struct gdb_unwind_callbacks *cb, int regnum)
Sanjoy> +{
Sanjoy> +  struct jit_unwind_private *priv = cb->priv_data;
Sanjoy> +  int gdb_reg = gdbarch_dwarf2_reg_to_regnum (target_gdbarch, regnum);
Sanjoy> +  int size = register_size (target_gdbarch, gdb_reg);
Sanjoy> +  struct gdb_reg_value *value = malloc (sizeof (struct gdb_reg_value) +
Sanjoy> +                                        size - 1);

xmalloc.

Sanjoy> +   While this is nominally a frame sniffer, in the case where the JIT
Sanjoy> +   reader actually recognizes the frame, it does a lot more work -- it
Sanjoy> +   unwinds the frame and saves the corresponding register values in
Sanjoy> +   the cache. jit_frame_prev_register simply returns the saved
Sanjoy> +   register values. */

I'm curious why you approached it this way.

Sanjoy> +jit_frame_unwind_stop_reason (struct frame_info *this_frame, void **cache)

Line too long.

Tom


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 5/7] Add a proxy unwinder.
  2011-08-15 20:38   ` Tom Tromey
@ 2011-08-20  6:26     ` Sanjoy Das
  0 siblings, 0 replies; 23+ messages in thread
From: Sanjoy Das @ 2011-08-20  6:26 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

> 
> I'm curious why you approached it this way.
> 

It seemed to me that it'll make writing a reader easier, turning


  if (reg == RAX) {
     /* Calculate and set RAX */
  } else if (reg == RBX) {
     /* Set `undefined' */
  } /* ... and so on, for every register */

into

  /* Calculate and set RAX */
  /* Calculate and set RSP */
  /*  ... */
  /* (No need to bother about the rest of the register file) */

-- 
Sanjoy Das
http://playingwithpointers.com


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system.
  2011-08-09 15:40   ` Eli Zaretskii
  2011-08-09 15:43     ` Sanjoy Das
@ 2011-08-20 17:17     ` Jan Kratochvil
  2011-08-20 17:31       ` Eli Zaretskii
  1 sibling, 1 reply; 23+ messages in thread
From: Jan Kratochvil @ 2011-08-20 17:17 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Sanjoy Das, gdb-patches

On Tue, 09 Aug 2011 17:39:11 +0200, Eli Zaretskii wrote:
> I understand that jit.c will be compiled unconditionally on the x86
> architectures, is that right?  If so, would it be possible to rename
> jit-header.h.in to jit-header.in, or some other name that doesn't
> violate the file-naming restrictions on 8+3 (a.k.a. DOS) filesystems?

Do you have some recent successful build of DJGPP on such 8+3 platform?
jit-header.h.in is the only right name to substitute for jit-header.h so it
would make sense to break the naming for some real portability.  But the last
statement from you
	Re: [RFC] DJGPP: fnchange.lst removal attempt
	http://sourceware.org/ml/gdb-patches/2010-04/msg00389.html

said the last build you done was gdb-7.0 and I was not successful myself on
FreeDOS in that mail thread.


Thanks,
Jan


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system.
  2011-08-20 17:17     ` Jan Kratochvil
@ 2011-08-20 17:31       ` Eli Zaretskii
  2011-08-20 17:42         ` Jan Kratochvil
  0 siblings, 1 reply; 23+ messages in thread
From: Eli Zaretskii @ 2011-08-20 17:31 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: sanjoy, gdb-patches

> Date: Sat, 20 Aug 2011 19:17:28 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: Sanjoy Das <sanjoy@playingwithpointers.com>, gdb-patches@sourceware.org
> 
> On Tue, 09 Aug 2011 17:39:11 +0200, Eli Zaretskii wrote:
> > I understand that jit.c will be compiled unconditionally on the x86
> > architectures, is that right?  If so, would it be possible to rename
> > jit-header.h.in to jit-header.in, or some other name that doesn't
> > violate the file-naming restrictions on 8+3 (a.k.a. DOS) filesystems?
> 
> Do you have some recent successful build of DJGPP on such 8+3 platform?

I don't want to break that possibility if we can avoid that.

> jit-header.h.in is the only right name to substitute for
> jit-header.h

How about jit-header.in?  Emacs uses config.in to produce config.h.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system.
  2011-08-20 17:31       ` Eli Zaretskii
@ 2011-08-20 17:42         ` Jan Kratochvil
  2011-08-20 17:52           ` Eli Zaretskii
  0 siblings, 1 reply; 23+ messages in thread
From: Jan Kratochvil @ 2011-08-20 17:42 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: sanjoy, gdb-patches

On Sat, 20 Aug 2011 19:31:37 +0200, Eli Zaretskii wrote:
> > Do you have some recent successful build of DJGPP on such 8+3 platform?
> 
> I don't want to break that possibility if we can avoid that.

I am not happy to make filenames unclear because of a possibly unsupported
platform but OK, if you want it that way.


> How about jit-header.in?  Emacs uses config.in to produce config.h.

Emacs probably stays DOS compatible so I find Emacs irrelevant.


Thanks,
Jan


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system.
  2011-08-20 17:42         ` Jan Kratochvil
@ 2011-08-20 17:52           ` Eli Zaretskii
  0 siblings, 0 replies; 23+ messages in thread
From: Eli Zaretskii @ 2011-08-20 17:52 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: sanjoy, gdb-patches

> Date: Sat, 20 Aug 2011 19:42:19 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: sanjoy@playingwithpointers.com, gdb-patches@sourceware.org
> 
> On Sat, 20 Aug 2011 19:31:37 +0200, Eli Zaretskii wrote:
> > > Do you have some recent successful build of DJGPP on such 8+3 platform?
> > 
> > I don't want to break that possibility if we can avoid that.
> 
> I am not happy to make filenames unclear because of a possibly unsupported
> platform but OK, if you want it that way.

Thank you.


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2011-08-20 17:52 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-09 15:21 [PATCH] JIT debug info Reader Sanjoy Das
2011-08-09 15:21 ` [PATCH 2/7] Add platform agnostic dynamic loading code Sanjoy Das
2011-08-10 21:01   ` Tom Tromey
2011-08-09 15:21 ` [PATCH 6/7] Register the proxy unwinder Sanjoy Das
2011-08-12 21:07   ` Tom Tromey
2011-08-09 15:21 ` [PATCH 5/7] Add a " Sanjoy Das
2011-08-15 20:38   ` Tom Tromey
2011-08-20  6:26     ` Sanjoy Das
2011-08-09 15:21 ` [PATCH 7/7] Add documentation Sanjoy Das
2011-08-09 15:51   ` Eli Zaretskii
2011-08-09 15:21 ` [PATCH 3/7] New commands for loading and unloading a reader Sanjoy Das
2011-08-12 20:58   ` Tom Tromey
2011-08-09 15:21 ` [PATCH 4/7] Use the loaded reader Sanjoy Das
2011-08-15 20:21   ` Tom Tromey
2011-08-09 15:21 ` [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system Sanjoy Das
2011-08-09 15:40   ` Eli Zaretskii
2011-08-09 15:43     ` Sanjoy Das
2011-08-09 15:53       ` Eli Zaretskii
2011-08-20 17:17     ` Jan Kratochvil
2011-08-20 17:31       ` Eli Zaretskii
2011-08-20 17:42         ` Jan Kratochvil
2011-08-20 17:52           ` Eli Zaretskii
2011-08-10 20:57   ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox