From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25442 invoked by alias); 9 Aug 2011 15:21:32 -0000 Received: (qmail 25369 invoked by uid 22791); 9 Aug 2011 15:21:31 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_SOFTFAIL,TW_BJ X-Spam-Check-By: sourceware.org Received: from mail-gw0-f41.google.com (HELO mail-gw0-f41.google.com) (74.125.83.41) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 09 Aug 2011 15:21:16 +0000 Received: by gwaa20 with SMTP id a20so84089gwa.0 for ; Tue, 09 Aug 2011 08:21:16 -0700 (PDT) Received: by 10.143.66.11 with SMTP id t11mr6863152wfk.91.1312903275582; Tue, 09 Aug 2011 08:21:15 -0700 (PDT) Received: from localhost.localdomain ([203.110.240.178]) by mx.google.com with ESMTPS id s9sm46202pbk.66.2011.08.09.08.21.11 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 09 Aug 2011 08:21:15 -0700 (PDT) From: Sanjoy Das To: gdb-patches@sourceware.org Cc: Sanjoy Das Subject: [PATCH 3/7] New commands for loading and unloading a reader. Date: Tue, 09 Aug 2011 15:21:00 -0000 Message-Id: <1312903509-25132-4-git-send-email-sanjoy@playingwithpointers.com> In-Reply-To: <1312903509-25132-1-git-send-email-sanjoy@playingwithpointers.com> References: <1312903509-25132-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-08/txt/msg00187.txt.bz2 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 + * jit.c (_initialize_jit): Add commands load-jit-reader and + unload-jit-reader. + (jit_reader_load): New function. + +2011-08-09 Sanjoy Das + * 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