From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26727 invoked by alias); 13 Jul 2011 20:23:56 -0000 Received: (qmail 26413 invoked by uid 22791); 13 Jul 2011 20:23:52 -0000 X-SWARE-Spam-Status: No, hits=-0.2 required=5.0 tests=AWL,BAYES_60,RCVD_IN_DNSWL_LOW,SPF_SOFTFAIL,TW_DB X-Spam-Check-By: sourceware.org Received: from mail-pv0-f169.google.com (HELO mail-pv0-f169.google.com) (74.125.83.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 13 Jul 2011 20:23:23 +0000 Received: by pvc12 with SMTP id 12so5976194pvc.0 for ; Wed, 13 Jul 2011 13:23:23 -0700 (PDT) Received: by 10.68.20.201 with SMTP id p9mr1925844pbe.327.1310588603236; Wed, 13 Jul 2011 13:23:23 -0700 (PDT) Received: from localhost.localdomain ([203.110.240.178]) by mx.google.com with ESMTPS id e6sm9387727pbm.39.2011.07.13.13.23.20 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 13 Jul 2011 13:23:22 -0700 (PDT) From: Sanjoy Das To: gdb-patches@sourceware.org Cc: Sanjoy Das Subject: [PATCH 1/4] jit-reader.h: describe interface implemented by the JIT readers. Date: Wed, 13 Jul 2011 20:24:00 -0000 Message-Id: <1310588850-10967-1-git-send-email-sanjoy@playingwithpointers.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-07/txt/msg00358.txt.bz2 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. 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 + + * 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 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 . */ + +#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