* [PATCH 4/7] Use the loaded reader.
2011-08-09 15:21 [PATCH] JIT debug info Reader Sanjoy Das
2011-08-09 15:21 ` [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
2011-08-15 20:21 ` Tom Tromey
2011-08-09 15:21 ` [PATCH 3/7] New commands for loading and unloading a reader 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
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
` (4 preceding siblings ...)
2011-08-09 15:21 ` [PATCH 5/7] Add a proxy unwinder 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
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 3/7] New commands for loading and unloading a reader Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
2011-08-09 15:51 ` Eli Zaretskii
2011-08-09 15:21 ` [PATCH 5/7] Add a proxy unwinder 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
` (3 preceding siblings ...)
2011-08-09 15:21 ` [PATCH 7/7] Add documentation Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
2011-08-15 20:38 ` Tom Tromey
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
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
@ 2011-08-09 15:21 ` Sanjoy Das
2011-08-09 15:40 ` Eli Zaretskii
2011-08-10 20:57 ` Tom Tromey
2011-08-09 15:21 ` [PATCH 4/7] Use the loaded reader Sanjoy Das
` (5 subsequent siblings)
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 1/7] Introduce header (jit-reader.h.in) and modify build system 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
2011-08-09 15:21 ` [PATCH 1/7] Introduce header (jit-reader.h.in) and modify build system Sanjoy Das
2011-08-09 15:21 ` [PATCH 4/7] Use the loaded reader Sanjoy Das
@ 2011-08-09 15:21 ` Sanjoy Das
2011-08-12 20:58 ` 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
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
` (5 preceding siblings ...)
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
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, µblaze_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 proxy unwinder 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 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
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 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 7/7] Add documentation Sanjoy Das
2011-08-09 15:51 ` Eli Zaretskii
2011-08-09 15:21 ` [PATCH 5/7] Add a proxy unwinder Sanjoy Das
2011-08-15 20:38 ` Tom Tromey
2011-08-20 6:26 ` 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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox