This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch v4 1/3] Create remove-symbol-file command.
- From: Nicolas Blanc <nicolas dot blanc at intel dot com>
- To: gdb-patches at sourceware dot org, palves at redhat dot com, tromey at redhat dot com, eliz at gnu dot org, yao at codesourcery dot com
- Cc: nicolas dot blanc at intel dot com
- Date: Wed, 29 May 2013 11:13:23 +0200
- Subject: [patch v4 1/3] Create remove-symbol-file command.
- References: <1369818805-14288-1-git-send-email-nicolas dot blanc at intel dot com>
Create remove-symbol-file command for removing
symbol files added via the add-symbol-file command.
2013-18-03 Nicolas Blanc <nicolas.blanc@intel.com>
* 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 <nicolas.blanc@intel.com>
---
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 <text_address>"));
+
+ 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