This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/2] jit-reader.h: describe interface implemented by the JIT readers.


Generating ELF files in memory is usually too much work for JIT
compilers, since they usually don't have the related routines (as
opposed to a regular static compiler). One way to simplify this is to
have the JIT vendor themselves provide a shared object which is loaded
and used to parse the debug information. This patch exposes a
simplified interface for the debug info parser.

The interface is _simplified_ in the sense that it does not expose all
of GDB's functionality. The idea is that if the user wishes to use GDB
for full-on debugging of generated code, it will probably be simpler
to generate the full DWARF info.

The interface does not expose more than the minimum amount of GDB
internals; both to prevent versioning problems, and to keep writing
the debug-info reader simple. For the same reason, GDB specific
typedefs (like CORE_ADDR) have been kept out of `jit-reader.h'.

This patch adds a header file (`jit-reader.h') which can be included
and implemented in a shared object to build a working JIT
debug-reader.

gdb/ChangeLog:

	* jit-reader.h: Add (new) JIT reader interface.
	* jit.c: Include jit-reader.h in source file
	* Makefile.in: Add jit-reader.h to HFILES_NO_SRCDIR.
---
 gdb/ChangeLog    |    6 ++
 gdb/Makefile.in  |    2 +-
 gdb/jit-reader.h |  189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/jit.c        |    4 +
 4 files changed, 200 insertions(+), 1 deletions(-)
 create mode 100644 gdb/jit-reader.h

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 8ed7eaf..e067f04 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2011-07-13  Sanjoy Das  <sanjoy@playingwithpointers.com>
+
+	* jit-reader.h: Add (new) JIT reader interface.
+	* jit.c: Include jit-reader.h in source file
+	* Makefile.in: Add jit-reader.h to HFILES_NO_SRCDIR.
+
 2011-07-12  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	Code cleanup making also optimized out values lazy.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 494f24f..ca2cbcb 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -816,7 +816,7 @@ osdata.h procfs.h python/py-event.h python/py-events.h python/py-stopevent.h \
 python/python-internal.h python/python.h ravenscar-thread.h record.h \
 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
+gnulib/stddef.in.h inline-frame.h jit-reader.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
diff --git a/gdb/jit-reader.h b/gdb/jit-reader.h
new file mode 100644
index 0000000..15980bd
--- /dev/null
+++ b/gdb/jit-reader.h
@@ -0,0 +1,189 @@
+/* Interface for JIT debug-info readers.
+
+   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
+
+/* Versioning: for the SO to be correctly recognized and loaded, put the macro
+   GDB_JIT_DECLARE_API_VERSION in a source file. */
+
+#define GDB_JIT_INTERFACE_VERSION  1
+#define GDB_JIT_DECLARE_API_VERSION             \
+  extern int __gdbjit_so_api_version (void)     \
+  {                                             \
+    return GDB_JIT_INTERFACE_VERSION;           \
+  }
+
+#define GDB_JIT_SUCCESS          1
+#define GDB_JIT_FAIL             0
+#define GDBJIT_MAX_REGISTER_SIZE 64 /* Mirrors the internal GDB definition. */
+
+struct gdbjit_symtab;
+struct gdbjit_block;
+struct gdbjit_symbol;
+struct gdbjit_symtab_callbacks;
+
+#ifndef __GDB__INTERNAL /* Only defined when being compiled in GDB. */
+typedef long long CORE_ADDR;
+#endif
+
+struct gdbjit_line_mapping
+{
+  int line;
+  CORE_ADDR pc;
+};
+
+typedef struct gdbjit_symtab *(gdbjit_symtab_open)
+  (struct gdbjit_symtab_callbacks *callbacks,
+   const char *file_name);
+
+typedef struct gdbjit_block *(gdbjit_new_block)
+  (struct gdbjit_symtab_callbacks *callbacks, struct gdbjit_symtab *symtab,
+   struct gdbjit_block *parent, CORE_ADDR begin_addr, CORE_ADDR end_addr,
+   const char *name);
+
+typedef void (gdbjit_symtab_close) (struct gdbjit_symtab_callbacks *callbacks,
+                                    struct gdbjit_symtab *symtab);
+
+typedef void (gdbjit_symtab_add_line_mapping)
+(struct gdbjit_symtab_callbacks * callbacks, struct gdbjit_symtab *symtab,
+ int nlines, struct gdbjit_line_mapping *lines);
+
+typedef int (gdbjit_target_read) (CORE_ADDR target_mem, void *gdb_buf, int len);
+
+struct gdbjit_symtab_callbacks {
+  /* Create a new symbol table. A symbol table consists of a forest of block
+     hierachies. Blocks are added by a call to new_block. This needs to be
+     paired with a call to symtab_close.
+
+     An optional FILE_NAME can be passed, which will be associated with the
+     symbol table as the source file from which this code was compiled.
+
+     Returns a new struct gdbjit_symtab which can be further passed to
+     new_block and symtab_close. */
+  gdbjit_symtab_open *symtab_open;
+
+  /* Creates a new block. A block is an optionally named contiguous block of
+     code in memory. Creating a new block automatically adds it to the symbol
+     table in which it is created.
+
+     SYMTAB is the symbol table this block is added to. Each block may have an
+     optionally non-NULL PARENT. BEGIN_ADDR and END_ADDR are the first and last
+     addresses spanned by this piece of compiled code. This block may have an
+     optional NAME, in case it corresponds to a function.
+
+     Returns a gdbjit_block instance, which, at this point, is useless. */
+  gdbjit_new_block *new_block;
+
+  /* Adds PC <-> line number mapping for the symbol table SYMTAB. Pass an array
+     of NLINES gdbjit_line_mapping s in LINES. */
+  gdbjit_symtab_add_line_mapping *add_line_mapping;
+
+  /* Reads LEN bytes of memory from the target's address space, beginning from
+     TARGET_MEM into the buffer GDB_BUF points to. */
+  gdbjit_target_read *target_read;
+
+  /* Closes the symbol table SYMTAB, and add it to the internal GDB list. */
+  gdbjit_symtab_close *symtab_close;
+
+  /* For internal use. */
+  void *private;
+};
+
+/* Denotes a register value. */
+struct gdbjit_reg_value
+{
+  /* Set to non-zero if this register has a valid value. Otherwise 0. */
+  int defined;
+  /* The actual value of the register (this is considered valid only if defined
+     is non-zero). */
+  unsigned char value[GDBJIT_MAX_REGISTER_SIZE];
+};
+
+/* Unique frame identifier. This should remain constant throughout the lifetime
+   of the frame concerned. */
+struct gdbjit_frame_id
+{
+  CORE_ADDR code_address;
+  CORE_ADDR stack_address;
+};
+
+struct gdbjit_unwind_callbacks;
+
+typedef struct gdbjit_reg_value (gdbjit_unwind_reg_get)
+  (struct gdbjit_unwind_callbacks *callback, int regnum);
+
+typedef void (gdbjit_unwind_reg_set) (struct gdbjit_unwind_callbacks *callback,
+                                      int regnum, struct gdbjit_reg_value val);
+
+struct gdbjit_unwind_callbacks
+{
+  /* Gets the current value for the register REGNUM (DWARF numbering). */
+  gdbjit_unwind_reg_get *reg_get;
+
+  /* Sets the previous value of the REGNUM register (i.e. its value in the
+     previous frame) to VAL. */
+  gdbjit_unwind_reg_set *reg_set;
+
+  /* Function to read memory off the inferior process being debugged, as
+     documented in gdbjit_symtab_callbacks. */
+  gdbjit_target_read *target_read;
+
+  /* For internal use. */
+  void *private;
+};
+
+/* Called once for each new inferior program. It should also initialize the
+   private pointer (to which a pointer is passed here) if the it needs one.
+
+   return: GDB_SUCCESS on success, or GDB_JIT_FAIL on error,
+   in which this plugin will be discarded (gdbjit_destroy_reader will not be
+   called in such a case). */
+extern int gdbjit_init_reader (void **private);
+
+/* Called to have the reader try to read a block of memory. PRIVATE is the
+   private pointer, (possibly) initialized by gdbjit_init_reader.
+
+   The function is expected to use CALLBACKS (documented above) to build a
+   symbol table for this particular block of memory (pointed to by MEMORY,
+   already copied from the target address space to GDB's address space).
+   MEMORY_SZ is the size of the block of memory.
+
+   Should return GDB_JIT_SUCESS on success and GDB_JIT_FAIL on error. */
+extern int gdbjit_read_debug_info (void *private,
+                                   struct gdbjit_symtab_callbacks *callbacks,
+                                   CORE_ADDR memory, long memory_sz);
+
+/* Called to unwind one frame. PRIVATE is the private pointer. Expected to use
+   CALLBACKS to unwind the registers to the older frame.
+
+   Should return GDB_JIT_SUCESS for success, GDB_JIT_FAIL for fail. */
+extern int gdbjit_unwind_frame (void *private,
+                                struct gdbjit_unwind_callbacks *callbacks);
+
+/* Called to get a unique identifier for the current stack frame (as reported by
+   callbacks). */
+struct gdbjit_frame_id gdbjit_get_frame_id (void *private, struct
+                                            gdbjit_unwind_callbacks *callbacks);
+
+/* Called once the inferior process exits. */
+extern void gdbjit_destroy_reader (void *private);
+
+#endif
diff --git a/gdb/jit.c b/gdb/jit.c
index eb1bcc7..6c07a57 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -19,7 +19,11 @@
 
 #include "defs.h"
 
+/* To stop jit-reader.h from re-defining CORE_ADDR */
+#define __GDB__INTERNAL
+
 #include "jit.h"
+#include "jit-reader.h"
 #include "breakpoint.h"
 #include "command.h"
 #include "gdbcmd.h"
-- 
1.7.5.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]