This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch v8 1/3] New remove-symbol-file command.
- From: Nicolas Blanc <nicolas dot blanc at intel dot com>
- To: gdb-patches at sourceware dot org, Hafiz_Abid at mentor dot com
- Cc: palves at redhat dot com, tromey at redhat dot com, eliz at gnu dot org, yao at codesourcery dot com, lgustavo at codesourcery dot com, dje at google dot com, nicolas dot blanc at intel dot com
- Date: Tue, 11 Jun 2013 15:57:19 +0200
- Subject: [patch v8 1/3] New remove-symbol-file command.
- References: <1370959041-12236-1-git-send-email-nicolas dot blanc at intel dot com>
New command for removing symbol files added via
the add-symbol-file command.
2013-18-03 Nicolas Blanc <nicolas.blanc@intel.com>
* breakpoint.c (disable_breakpoints_in_freed_objfile): New function.
* objfiles.c (free_objfile): Notify free_objfile.
(is_addr_in_objfile): New function.
* objfiles.h (is_addr_in_objfile): New declaration.
* 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): New function.
* symfile.c (remove_symbol_file_command): New command.
(_initialize_symfile): Add remove-symbol-file.
gdb/doc
* observer.texi: New free_objfile event.
Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
---
gdb/breakpoint.c | 67 +++++++++++++++++++++++++++++++++++++--
gdb/doc/observer.texi | 4 ++
gdb/objfiles.c | 23 +++++++++++++
gdb/objfiles.h | 2 +
gdb/printcmd.c | 15 +++++---
gdb/solib.c | 22 +++++++++++++
gdb/symfile.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 208 insertions(+), 9 deletions(-)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index d4ccc81..50284a0 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -7403,9 +7403,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)
@@ -7457,6 +7457,66 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
}
}
+/* 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;
+
+ if (!is_breakpoint (b) && !is_tracepoint (b))
+ continue;
+
+ for (loc = b->loc; loc != NULL; loc = loc->next)
+ {
+ CORE_ADDR loc_addr = loc->address;
+
+ if (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 (loc->loc_type != bp_loc_hardware_breakpoint
+ && loc->loc_type != bp_loc_software_breakpoint)
+ continue;
+
+ if (is_addr_in_objfile (loc_addr, objfile))
+ {
+ loc->shlib_disabled = 1;
+ loc->inserted = 0;
+
+ mark_breakpoint_location_modified (loc);
+
+ 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
@@ -15861,6 +15921,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 1e1b7bc..6411380 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -539,6 +539,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);
@@ -1463,6 +1466,26 @@ resume_section_map_updates_cleanup (void *arg)
resume_section_map_updates (arg);
}
+/* Return 1 if ADDR maps into one of the sections of OBJFILE and 0
+ otherwise. */
+
+int
+is_addr_in_objfile (CORE_ADDR addr, const struct objfile * objfile)
+{
+ struct obj_section *osect;
+
+ if (objfile == NULL)
+ return 0;
+
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ {
+ if (obj_section_addr (osect) <= addr
+ && addr < obj_section_endaddr (osect))
+ return 1;
+ }
+ return 0;
+}
+
/* The default implementation for the "iterate_over_objfiles_in_search_order"
gdbarch method. It is equivalent to use the ALL_OBJFILES macro,
searching the objfiles in the order they are stored internally,
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index adb1ef8..b25afb1 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -482,6 +482,8 @@ extern int have_full_symbols (void);
extern void objfiles_changed (void);
+extern int is_addr_in_objfile (CORE_ADDR, const struct objfile *);
+
/* This operation deletes all objfile entries that represent solibs that
weren't explicitly loaded by the user, via e.g., the add-symbol-file
command. */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 99d4dba..1234135 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1936,21 +1936,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
@@ -2482,7 +2485,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 c987fe5..7ceef29 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1478,6 +1478,26 @@ 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 == NULL)
+ 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
@@ -1485,6 +1505,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 c2ad797..f7ad268 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -2330,6 +2330,81 @@ 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)
+{
+ char **argv;
+ struct objfile* objf = NULL;
+ struct cleanup *my_cleanups;
+ struct program_space *pspace = current_program_space;
+ struct gdbarch *gdbarch = get_current_arch ();
+
+ dont_repeat ();
+
+ if (args == NULL)
+ error (_("USAGE: remove-symbol-file FILENAME\n\
+ remove-symbol-file -a ADDRESS"));
+
+ my_cleanups = make_cleanup (null_cleanup, NULL);
+
+ argv = gdb_buildargv (args);
+
+ if (strcmp (argv[0], "-a") == 0)
+ {
+ /* Interpret the next argument as an address. */
+ CORE_ADDR addr;
+
+ if (argv[1] == NULL)
+ error (_("Missing address argument"));
+
+ if (argv[2] != NULL)
+ error (_("Junk after %s"), argv[1]);
+
+ addr = parse_and_eval_address (argv[1]);
+
+ ALL_OBJFILES (objf)
+ {
+ if (objf->flags & OBJF_USERLOADED
+ && objf->pspace == pspace
+ && is_addr_in_objfile (addr, objf))
+ break;
+ }
+ }
+ else if (argv[0] != NULL)
+ {
+ /* Interpret the current argument as a file name. */
+ char *filename;
+
+ if (argv[1] != NULL)
+ error (_("Junk after %s"), argv[0]);
+
+ filename = tilde_expand (argv[0]);
+ make_cleanup (xfree, filename);
+
+ ALL_OBJFILES (objf)
+ {
+ if (objf->flags & OBJF_USERLOADED
+ && objf->pspace == pspace
+ && filename_cmp (filename, objf->name) == 0)
+ break;
+ }
+ }
+
+ if (objf == NULL)
+ error (_("No symbol file found"));
+
+ if (from_tty
+ && !query (_("Remove symbol table from file \"%s\"? "), objf->name))
+ error (_("Not confirmed."));
+
+ free_objfile (objf);
+ clear_symtab_users (0);
+
+ do_cleanups (my_cleanups);
+}
+
typedef struct objfile *objfilep;
DEF_VEC_P (objfilep);
@@ -3744,6 +3819,15 @@ 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 added via the add-symbol-file command.\n\
+Usage: remove-symbol-file FILENAME\n\
+ remove-symbol-file -a ADDRESS\n\
+The file to remove can be identified by its filename or by an address\n\
+that lies within the boundaries of this symbol file in memory."),
+ &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