From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7380 invoked by alias); 29 May 2013 09:13:46 -0000 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 Received: (qmail 7261 invoked by uid 89); 29 May 2013 09:13:45 -0000 X-Spam-SWARE-Status: No, score=-6.4 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,RP_MATCHES_RCVD,TW_BJ autolearn=ham version=3.3.1 Received: from mga09.intel.com (HELO mga09.intel.com) (134.134.136.24) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 29 May 2013 09:13:43 +0000 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 29 May 2013 02:11:32 -0700 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga001.jf.intel.com with ESMTP; 29 May 2013 02:13:37 -0700 Received: from ulslx001.iul.intel.com (ulslx001.iul.intel.com [172.28.207.63]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id r4T9DZIa011436; Wed, 29 May 2013 10:13:36 +0100 Received: from ulslx001.iul.intel.com (localhost [127.0.0.1]) by ulslx001.iul.intel.com with ESMTP id r4T9DZ2T014335; Wed, 29 May 2013 11:13:35 +0200 Received: (from nblanc@localhost) by ulslx001.iul.intel.com with id r4T9DZap014331; Wed, 29 May 2013 11:13:35 +0200 From: Nicolas Blanc To: gdb-patches@sourceware.org, palves@redhat.com, tromey@redhat.com, eliz@gnu.org, yao@codesourcery.com Cc: nicolas.blanc@intel.com Subject: [patch v4 1/3] Create remove-symbol-file command. Date: Wed, 29 May 2013 09:13:00 -0000 Message-Id: <1369818805-14288-2-git-send-email-nicolas.blanc@intel.com> In-Reply-To: <1369818805-14288-1-git-send-email-nicolas.blanc@intel.com> References: <1369818805-14288-1-git-send-email-nicolas.blanc@intel.com> X-SW-Source: 2013-05/txt/msg00981.txt.bz2 Create remove-symbol-file command for removing symbol files added via the add-symbol-file command. 2013-18-03 Nicolas Blanc * breakpoint.c (is_addr_in_objfile): Create static helper function. (disable_breakpoints_in_freed_objfile): Create function for disabling breakpoints in objfiles upon free_objfile notifications. * objfiles.c (free_objfile): Notify free_objfile. * objfiles.h (struct objfile): Add comment for low_addr. * printcmd.c (clear_dangling_display_expressions): Act upon free_objfile events instead of solib_unloaded events. (_initialize_printcmd): Register observer for free_objfile instead of solib_unloaded notifications. * solib.c (remove_user_added_objfile): Create function for removing dangling references upon notification of free_objfile. * symfile.c (add_symbol_file_command): Set OBJFILE->LOW_ADDR. (remove_symbol_file_command): Create command for removing symbol files. (_initialize_symfile): Add remove-symbol-file. gdb/doc * observer.texi: Created free_objfile event. Signed-off-by: Nicolas Blanc --- gdb/breakpoint.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++-- gdb/doc/observer.texi | 4 ++ gdb/objfiles.c | 3 ++ gdb/objfiles.h | 4 ++ gdb/printcmd.c | 15 +++++--- gdb/solib.c | 23 ++++++++++++++ gdb/symfile.c | 55 ++++++++++++++++++++++++++++++++- 7 files changed, 176 insertions(+), 10 deletions(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index b4d2f27..e42b32d 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -7417,9 +7417,9 @@ disable_breakpoints_in_shlibs (void) } } -/* Disable any breakpoints and tracepoints that are in an unloaded shared - library. Only apply to enabled breakpoints, disabled ones can just stay - disabled. */ +/* Disable any breakpoints and tracepoints that are in SOLIB upon + notification of unloaded_shlib. Only apply to enabled breakpoints, + disabled ones can just stay disabled. */ static void disable_breakpoints_in_unloaded_shlib (struct so_list *solib) @@ -7471,6 +7471,81 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib) } } +/* Return 1 if ADDR maps in one of the sections of OBJFILE and 0 + otherwise. OBJFILE must be valid. */ + +static inline int +is_addr_in_objfile (CORE_ADDR addr, const struct objfile * objfile) +{ + struct obj_section *osect; + ALL_OBJFILE_OSECTIONS (objfile, osect) + { + if (obj_section_addr (osect) <= addr + && addr < obj_section_endaddr (osect)) + return 1; + } + return 0; +} + +/* Disable any breakpoints and tracepoints in OBJFILE upon + notification of free_objfile. Only apply to enabled breakpoints, + disabled ones can just stay disabled. */ + +static void +disable_breakpoints_in_freed_objfile (struct objfile * objfile) +{ + struct breakpoint *b; + + if (objfile == NULL) + return; + + /* If the file is a shared library not loaded by the user then + solib_unloaded was notified and disable_breakpoints_in_unloaded_shlib + was called. In that case there is no need to take action again. */ + if ((objfile->flags & OBJF_SHARED) && !(objfile->flags & OBJF_USERLOADED)) + return; + + ALL_BREAKPOINTS (b) + { + struct bp_location *loc; + int bp_modified = 0; + int is_no_tracepoint = !is_tracepoint (b); + + if (is_no_tracepoint + && b->type != bp_breakpoint + && b->type != bp_jit_event + && b->type != bp_hardware_breakpoint) + continue; + + for (loc = b->loc; loc != NULL; loc = loc->next) + { + CORE_ADDR loc_addr = loc->address; + + if (is_no_tracepoint + && loc->loc_type != bp_loc_hardware_breakpoint + && loc->loc_type != bp_loc_software_breakpoint) + continue; + + if (loc->shlib_disabled != 0) + continue; + + if (objfile->pspace != loc->pspace) + continue; + + if (is_addr_in_objfile (loc_addr, objfile)) + { + loc->shlib_disabled = 1; + loc->inserted = 0; + bp_modified = 1; + } + } + + if (bp_modified) + observer_notify_breakpoint_modified (b); + } + +} + /* FORK & VFORK catchpoints. */ /* An instance of this type is used to represent a fork or vfork @@ -15875,6 +15950,7 @@ _initialize_breakpoint (void) initialize_breakpoint_ops (); observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib); + observer_attach_free_objfile (disable_breakpoints_in_freed_objfile); observer_attach_inferior_exit (clear_syscall_counts); observer_attach_memory_changed (invalidate_bp_value_on_memory_change); diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi index adb7085..f753965 100644 --- a/gdb/doc/observer.texi +++ b/gdb/doc/observer.texi @@ -138,6 +138,10 @@ Called with @var{objfile} equal to @code{NULL} to indicate previously loaded symbol table data has now been invalidated. @end deftypefun +@deftypefun void free_objfile (struct objfile *@var{objfile}) +The object file specified by @var{objfile} is about to be freed. +@end deftypefun + @deftypefun void new_thread (struct thread_info *@var{t}) The thread specified by @var{t} has been created. @end deftypefun diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 3e49ea2..c70a5a2 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -530,6 +530,9 @@ free_objfile_separate_debug (struct objfile *objfile) void free_objfile (struct objfile *objfile) { + /* First notify observers that this objfile is about to be freed. */ + observer_notify_free_objfile (objfile); + /* Free all separate debug objfiles. */ free_objfile_separate_debug (objfile); diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 93149e2..644e780 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -204,6 +204,10 @@ struct objfile char *name; + /* The base address of the object file, which is often assumed to be + the address of the text section. The remove-symbol-file command + uses this field to identify the object file to remove. */ + CORE_ADDR addr_low; /* Some flag bits for this objfile. diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 2cc33d0..bd4bd42 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1928,21 +1928,24 @@ disable_display_command (char *args, int from_tty) an item by re-parsing .exp_string field in the new execution context. */ static void -clear_dangling_display_expressions (struct so_list *solib) +clear_dangling_display_expressions (struct objfile *objfile) { - struct objfile *objfile = solib->objfile; struct display *d; + struct program_space *pspace; /* With no symbol file we cannot have a block or expression from it. */ if (objfile == NULL) return; + pspace = objfile->pspace; if (objfile->separate_debug_objfile_backlink) - objfile = objfile->separate_debug_objfile_backlink; - gdb_assert (objfile->pspace == solib->pspace); + { + objfile = objfile->separate_debug_objfile_backlink; + gdb_assert (objfile->pspace == pspace); + } for (d = display_chain; d != NULL; d = d->next) { - if (d->pspace != solib->pspace) + if (d->pspace != pspace) continue; if (lookup_objfile_from_block (d->block) == objfile @@ -2474,7 +2477,7 @@ _initialize_printcmd (void) current_display_number = -1; - observer_attach_solib_unloaded (clear_dangling_display_expressions); + observer_attach_free_objfile (clear_dangling_display_expressions); add_info ("address", address_info, _("Describe where symbol SYM is stored.")); diff --git a/gdb/solib.c b/gdb/solib.c index a3479c5..a897777 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -1446,6 +1446,27 @@ gdb_bfd_lookup_symbol (bfd *abfd, return symaddr; } +/* SO_LIST_HEAD may contain user-loaded object files that can be removed + out-of-band by the user. So upon notification of free_objfile remove + any reference to any user-loaded file that is about to be freed. */ + +static void +remove_user_added_objfile (struct objfile *objfile) +{ + struct so_list *so; + + if (!objfile) + return; + + if (objfile->flags & OBJF_USERLOADED) + { + for (so = so_list_head; so != NULL; so = so->next) + if (so->objfile == objfile) + so->objfile = NULL; + } +} + + extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */ void @@ -1453,6 +1474,8 @@ _initialize_solib (void) { solib_data = gdbarch_data_register_pre_init (solib_init); + observer_attach_free_objfile (remove_user_added_objfile); + add_com ("sharedlibrary", class_files, sharedlibrary_command, _("Load shared object library symbols for files matching REGEXP.")); add_info ("sharedlibrary", info_sharedlibrary_command, diff --git a/gdb/symfile.c b/gdb/symfile.c index e9609b2..7c5989c 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -2175,6 +2175,8 @@ add_symbol_file_command (char *args, int from_tty) int expecting_sec_name = 0; int expecting_sec_addr = 0; char **argv; + struct objfile *objf; + CORE_ADDR addr_low; struct sect_opt { @@ -2307,12 +2309,17 @@ add_symbol_file_command (char *args, int from_tty) } section_addrs->num_sections = sec_num; + addr_low = section_addrs->other[0].addr; + if (from_tty && (!query ("%s", ""))) error (_("Not confirmed.")); - symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0, + objf = symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0, section_addrs, flags); + /* Set the low address of the object for identification. */ + objf->addr_low = addr_low; + /* Getting new symbols may change our opinion about what is frameless. */ reinit_frame_cache (); @@ -2320,6 +2327,46 @@ add_symbol_file_command (char *args, int from_tty) } + +/* This function removes a symbol file that was added via add-symbol-file. */ + +static void +remove_symbol_file_command (char *args, int from_tty) +{ + CORE_ADDR addr = 0; + struct objfile* objf; + struct gdbarch *gdbarch = get_current_arch (); + + dont_repeat (); + + if (args == NULL) + error (_("USAGE: remove-symbol-file ")); + + addr = parse_and_eval_address (args); + + ALL_OBJFILES (objf) + { + if (objf->flags & OBJF_USERLOADED && objf->addr_low == addr) + break; + } + + if (objf == NULL) + error (_("no user-added symbol file for .text_addr = 0x%s"), + phex_nz (addr, sizeof (addr))); + + printf_unfiltered (_("Remove symbol table from file \"%s\"\ + at .text_addr = %s\n"), + objf->name, paddress (gdbarch, addr)); + + if (from_tty && (!query ("%s", ""))) + error (_("Not confirmed.")); + + free_objfile (objf); + clear_symtab_users (0); + +} + + typedef struct objfile *objfilep; DEF_VEC_P (objfilep); @@ -3734,6 +3781,12 @@ with the text. SECT is a section name to be loaded at SECT_ADDR."), &cmdlist); set_cmd_completer (c, filename_completer); + c = add_cmd ("remove-symbol-file", class_files, + remove_symbol_file_command, _("\ +Remove a symbol file loaded via the add-symbol-file command.\n\ +Usage: remove-symbol-file ADDR.\nADDR is the starting address of the\ + text section of the file to remove."), &cmdlist); + c = add_cmd ("load", class_files, load_command, _("\ Dynamically load FILE into the running program, and record its symbols\n\ for access from GDB.\n\ -- 1.7.6.5