* [PATCH v12 4/5] Function is_elf_target.
2013-07-17 16:28 [PATCH v12 0/5] remove-symbol-file & add-symbol-file Nicolas Blanc
@ 2013-07-17 16:27 ` Nicolas Blanc
2013-07-17 18:43 ` Mark Kettenis
2013-07-17 16:27 ` [PATCH v12 2/5] Documentation for the remove-symbol-file command Nicolas Blanc
` (3 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Nicolas Blanc @ 2013-07-17 16:27 UTC (permalink / raw)
To: gdb-patches, dje; +Cc: nicolas.blanc
2013-17-07 Nicolas Blanc <nicolas.blanc@intel.com>
gdb/testsuite
* lib/gdb.exp (is_elf_target): New function.
Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
---
gdb/testsuite/lib/gdb.exp | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 376aacc..8c5cdb5 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -1782,6 +1782,21 @@ proc supports_reverse {} {
return 0
}
+# Return 1 if target supports ELF.
+proc is_elf_target {} {
+
+ if { [istarget "*-*-linux*"]
+ || [istarget "*-*-gnu*"]
+ || [istarget "*-*-elf*"]
+ || [istarget "arm*-*-eabi*"]
+ || [istarget "arm*-*-symbianelf*"]
+ || [istarget "powerpc-*-eabi*"] } {
+ return 1
+ }
+
+ return 0
+}
+
# Return 1 if target is ILP32.
# This cannot be decided simply from looking at the target string,
# as it might depend on externally passed compiler options like -m64.
--
1.7.6.5
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v12 4/5] Function is_elf_target.
2013-07-17 16:27 ` [PATCH v12 4/5] Function is_elf_target Nicolas Blanc
@ 2013-07-17 18:43 ` Mark Kettenis
2013-07-17 19:47 ` Doug Evans
0 siblings, 1 reply; 14+ messages in thread
From: Mark Kettenis @ 2013-07-17 18:43 UTC (permalink / raw)
To: nicolas.blanc; +Cc: gdb-patches, dje, nicolas.blanc
> From: Nicolas Blanc <nicolas.blanc@intel.com>
> Date: Wed, 17 Jul 2013 18:27:34 +0200
>
> 2013-17-07 Nicolas Blanc <nicolas.blanc@intel.com>
>
> gdb/testsuite
> * lib/gdb.exp (is_elf_target): New function.
>
> Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
That's a very incomplete list.
I think a better solution is needed. Instead of whitelisting targets
for what is basically the default, blacklisting targets that aren't
ELF would be a better approach.
> ---
> gdb/testsuite/lib/gdb.exp | 15 +++++++++++++++
> 1 files changed, 15 insertions(+), 0 deletions(-)
>
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 376aacc..8c5cdb5 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -1782,6 +1782,21 @@ proc supports_reverse {} {
> return 0
> }
>
> +# Return 1 if target supports ELF.
> +proc is_elf_target {} {
> +
> + if { [istarget "*-*-linux*"]
> + || [istarget "*-*-gnu*"]
> + || [istarget "*-*-elf*"]
> + || [istarget "arm*-*-eabi*"]
> + || [istarget "arm*-*-symbianelf*"]
> + || [istarget "powerpc-*-eabi*"] } {
> + return 1
> + }
> +
> + return 0
> +}
> +
> # Return 1 if target is ILP32.
> # This cannot be decided simply from looking at the target string,
> # as it might depend on externally passed compiler options like -m64.
> --
> 1.7.6.5
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v12 4/5] Function is_elf_target.
2013-07-17 18:43 ` Mark Kettenis
@ 2013-07-17 19:47 ` Doug Evans
0 siblings, 0 replies; 14+ messages in thread
From: Doug Evans @ 2013-07-17 19:47 UTC (permalink / raw)
To: Mark Kettenis; +Cc: Nicolas Blanc, gdb-patches
On Wed, Jul 17, 2013 at 11:43 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>> From: Nicolas Blanc <nicolas.blanc@intel.com>
>> Date: Wed, 17 Jul 2013 18:27:34 +0200
>>
>> 2013-17-07 Nicolas Blanc <nicolas.blanc@intel.com>
>>
>> gdb/testsuite
>> * lib/gdb.exp (is_elf_target): New function.
>>
>> Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
>
> That's a very incomplete list.
>
> I think a better solution is needed. Instead of whitelisting targets
> for what is basically the default, blacklisting targets that aren't
> ELF would be a better approach.
There are plenty of places in the testsuite that don't do an
exhaustive check for whether the system is elf.
Instead, they just cover enough cases that we care about.
Consider testsuite/lib/dwarf.exp:dwarf2_support
ortestsuite/lib/gdb.exp:skip_shlib_tests.
[I realize there's also some blacklist-using functions, e.g. skip_cplus_tests.
But for the task at hand, I'm ok with the whitelist since that is what
the testsuite uses today,
except that it replicates this list every time, with some apparent drift.
E.g., gdb.base/dup-sect.exp and gdb.python/py-section-script.exp.]
How about renaming the function to is_known_elf_target?
[Though for consistency's sake one might then want to rename
dwarf_support to known_dwarf_support.
Thus I prefer is_elf_target, but if necessary is_known_elf_target works too.]
One thing one could wish is requiring all places that currently
hardcode this list to be updated to use this function.
grepping for "istarget.*-elf" doesn't have that many hits and the spu
hits can be ignored.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v12 2/5] Documentation for the remove-symbol-file command.
2013-07-17 16:28 [PATCH v12 0/5] remove-symbol-file & add-symbol-file Nicolas Blanc
2013-07-17 16:27 ` [PATCH v12 4/5] Function is_elf_target Nicolas Blanc
@ 2013-07-17 16:27 ` Nicolas Blanc
2013-07-17 17:02 ` Eli Zaretskii
2013-07-17 16:27 ` [PATCH v12 1/5] New " Nicolas Blanc
` (2 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Nicolas Blanc @ 2013-07-17 16:27 UTC (permalink / raw)
To: gdb-patches, dje; +Cc: nicolas.blanc
2013-04-05 Nicolas Blanc <nicolas.blanc@intel.com>
* NEWS: Add description of the remove-symbol-file command.
gdb/doc
* gdb.texinfo (Commands to Specify Files): Add description
of the remove-symbol-file command.
Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
---
gdb/NEWS | 6 ++++++
gdb/doc/gdb.texinfo | 26 ++++++++++++++++++++++++--
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/gdb/NEWS b/gdb/NEWS
index e469f1e..b8a1a68 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -32,6 +32,12 @@ maint set|show per-command time
maint set|show per-command symtab
Enable display of per-command gdb resource usage.
+remove-symbol-file FILENAME
+remove-symbol-file -a ADDRESS
+ Remove a symbol file added via add-symbol-file. The file to remove
+ can be identified by its filename or by an address that lies within
+ the boundaries of this symbol file in memory.
+
* New options
set remote trace-status-packet
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index fae54e4..b4f08bc 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -16513,8 +16513,9 @@ section name and base address for that section. You can specify any
The symbol table of the file @var{filename} is added to the symbol table
originally read with the @code{symbol-file} command. You can use the
@code{add-symbol-file} command any number of times; the new symbol data
-thus read keeps adding to the old. To discard all old symbol data
-instead, use the @code{symbol-file} command without any arguments.
+thus read is kept in addition to the old.
+
+Changes can be reverted using the command @code{remove-symbol-file}.
@cindex relocatable object files, reading symbols from
@cindex object files, relocatable, reading symbols from
@@ -16552,6 +16553,27 @@ way.
@code{add-symbol-file} does not repeat if you press @key{RET} after using it.
+@kindex remove-symbol-file
+@item remove-symbol-file @var{filename}
+@item remove-symbol-file -a @var{address}
+Remove a symbol file added via the @code{add-symbol-file} command. The
+file to remove can be identified by its @var{filename} or by an @var{address}
+that lies within the boundaries of this symbol file in memory. Example:
+
+@smallexample
+(gdb) add-symbol-file /home/user/gdb/mylib.so 0x7ffff7ff9480
+add symbol table from file "/home/user/gdb/mylib.so" at
+ .text_addr = 0x7ffff7ff9480
+(y or n) y
+Reading symbols from /home/user/gdb/mylib.so...done.
+(gdb) remove-symbol-file -a 0x7ffff7ff9480
+Remove symbol table from file "/home/user/gdb/mylib.so"? (y or n) y
+(gdb)
+@end smallexample
+
+
+@code{remove-symbol-file} does not repeat if you press @key{RET} after using it.
+
@kindex add-symbol-file-from-memory
@cindex @code{syscall DSO}
@cindex load symbols from memory
--
1.7.6.5
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v12 2/5] Documentation for the remove-symbol-file command.
2013-07-17 16:27 ` [PATCH v12 2/5] Documentation for the remove-symbol-file command Nicolas Blanc
@ 2013-07-17 17:02 ` Eli Zaretskii
0 siblings, 0 replies; 14+ messages in thread
From: Eli Zaretskii @ 2013-07-17 17:02 UTC (permalink / raw)
To: Nicolas Blanc; +Cc: gdb-patches, dje, nicolas.blanc
> From: Nicolas Blanc <nicolas.blanc@intel.com>
> Cc: nicolas.blanc@intel.com
> Date: Wed, 17 Jul 2013 18:27:32 +0200
>
> 2013-04-05 Nicolas Blanc <nicolas.blanc@intel.com>
>
> * NEWS: Add description of the remove-symbol-file command.
> gdb/doc
> * gdb.texinfo (Commands to Specify Files): Add description
> of the remove-symbol-file command.
>
> Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
Thanks, but didn't I review this already?
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v12 1/5] New remove-symbol-file command.
2013-07-17 16:28 [PATCH v12 0/5] remove-symbol-file & add-symbol-file Nicolas Blanc
2013-07-17 16:27 ` [PATCH v12 4/5] Function is_elf_target Nicolas Blanc
2013-07-17 16:27 ` [PATCH v12 2/5] Documentation for the remove-symbol-file command Nicolas Blanc
@ 2013-07-17 16:27 ` Nicolas Blanc
2013-07-17 16:28 ` [PATCH v12 5/5] Test adding and removing a symbol file at runtime Nicolas Blanc
2013-07-17 16:28 ` [PATCH v12 3/5] 'add-symbol-file' should update the current target sections Nicolas Blanc
4 siblings, 0 replies; 14+ messages in thread
From: Nicolas Blanc @ 2013-07-17 16:27 UTC (permalink / raw)
To: gdb-patches, dje; +Cc: nicolas.blanc
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 | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 206 insertions(+), 9 deletions(-)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 4d09b30..3542775 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -7412,9 +7412,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)
@@ -7466,6 +7466,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
@@ -15921,6 +15981,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 759159c..4863a4f 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);
@@ -1461,6 +1464,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 84167e0..7233807 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 addr, const struct objfile *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..f21ba21 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
+ all references 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 5129105..dbcccd3 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -2326,6 +2326,79 @@ add_symbol_file_command (char *args, int from_tty)
}
\f
+/* 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 (_("remove-symbol-file FILENAME\nremove-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);
@@ -3740,6 +3813,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
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v12 5/5] Test adding and removing a symbol file at runtime.
2013-07-17 16:28 [PATCH v12 0/5] remove-symbol-file & add-symbol-file Nicolas Blanc
` (2 preceding siblings ...)
2013-07-17 16:27 ` [PATCH v12 1/5] New " Nicolas Blanc
@ 2013-07-17 16:28 ` Nicolas Blanc
2013-07-17 18:53 ` Mark Kettenis
2013-07-17 16:28 ` [PATCH v12 3/5] 'add-symbol-file' should update the current target sections Nicolas Blanc
4 siblings, 1 reply; 14+ messages in thread
From: Nicolas Blanc @ 2013-07-17 16:28 UTC (permalink / raw)
To: gdb-patches, dje; +Cc: nicolas.blanc
This test exercises the commands 'add-symbol-file'
and 'remove-symbol-file'.
2013-04-04 Nicolas Blanc <nicolas.blanc@intel.com>
gdb/testsuite
* gdb.base/sym-file-lib.c: New file.
* gdb.base/sym-file-loader.c: New file.
* gdb.base/sym-file-loader.h: New file.
* gdb.base/sym-file-main.c: New file.
* gdb.base/sym-file.exp: New file.
Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
---
gdb/testsuite/gdb.base/sym-file-lib.c | 26 +++
gdb/testsuite/gdb.base/sym-file-loader.c | 348 ++++++++++++++++++++++++++++++
gdb/testsuite/gdb.base/sym-file-loader.h | 83 +++++++
gdb/testsuite/gdb.base/sym-file-main.c | 78 +++++++
gdb/testsuite/gdb.base/sym-file.exp | 160 ++++++++++++++
5 files changed, 695 insertions(+), 0 deletions(-)
create mode 100644 gdb/testsuite/gdb.base/sym-file-lib.c
create mode 100644 gdb/testsuite/gdb.base/sym-file-loader.c
create mode 100644 gdb/testsuite/gdb.base/sym-file-loader.h
create mode 100644 gdb/testsuite/gdb.base/sym-file-main.c
create mode 100644 gdb/testsuite/gdb.base/sym-file.exp
diff --git a/gdb/testsuite/gdb.base/sym-file-lib.c b/gdb/testsuite/gdb.base/sym-file-lib.c
new file mode 100644
index 0000000..586215d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sym-file-lib.c
@@ -0,0 +1,26 @@
+/* Copyright 2013 Free Software Foundation, Inc.
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+extern int
+bar ()
+{
+ return 1; /* gdb break at bar */
+}
+
+extern int
+foo (int a)
+{
+ return a; /* gdb break at foo */
+}
diff --git a/gdb/testsuite/gdb.base/sym-file-loader.c b/gdb/testsuite/gdb.base/sym-file-loader.c
new file mode 100644
index 0000000..58975cb
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sym-file-loader.c
@@ -0,0 +1,348 @@
+/* Copyright 2013 Free Software Foundation, Inc.
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include "sym-file-loader.h"
+
+#ifdef TARGET_LP64
+
+unsigned char
+elf_st_type (unsigned char st_info)
+{
+ return ELF64_ST_TYPE (st_info);
+}
+
+#elif defined TARGET_ILP32
+
+unsigned char
+elf_st_type (unsigned char st_info)
+{
+ return ELF32_ST_TYPE (st_info);
+}
+
+#endif
+
+/* Load a program segment. */
+
+static struct segment *
+load (char *addr, Elf_Phdr *phdr, struct segment *tail_seg)
+{
+ struct segment *seg = NULL;
+ char *mapped_addr = NULL;
+ void *from = NULL;
+ void *to = NULL;
+
+ /* For the sake of simplicity all operations are permitted. */
+ unsigned perm = PROT_READ | PROT_WRITE | PROT_EXEC;
+
+ mapped_addr = (char *) mmap ((void *) phdr->p_vaddr,
+ phdr->p_memsz, perm,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+
+ from = (void *) (addr + phdr->p_offset);
+ to = (void *) mapped_addr;
+
+ memcpy (to, from, phdr->p_filesz);
+
+ seg = (struct segment *) malloc (sizeof (struct segment));
+
+ if (seg == 0)
+ return 0;
+
+ seg->mapped_addr = mapped_addr;
+ seg->phdr = phdr;
+ seg->next = 0;
+
+ if (tail_seg != 0)
+ tail_seg->next = seg;
+
+ return seg;
+}
+
+/* Mini shared library loader. No reallocation
+ is performed for the sake of simplicity. */
+
+int
+load_shlib (const char *file, Elf_Ehdr **ehdr_out, struct segment **seg_out)
+{
+ unsigned i = 0;
+ int fd = -1;
+ off_t fsize = -1;
+ char *addr = NULL;
+ Elf_Ehdr *ehdr = NULL;
+ Elf_Phdr *phdr = NULL;
+ struct segment *head_seg = NULL;
+ struct segment *tail_seg = NULL;
+
+ /* Map the lib in memory for reading. */
+ fd = open (file, O_RDONLY);
+ if (fd < 0)
+ {
+ perror ("fopen failed.");
+ return -1;
+ }
+
+ fsize = lseek (fd, 0, SEEK_END);
+
+ if (fsize < 0)
+ {
+ perror ("lseek failed.");
+ return -1;
+ }
+
+ addr = (char *) mmap (NULL, fsize, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (addr == (char *) -1)
+ {
+ perror ("mmap failed.");
+ return -1;
+ }
+
+ /* Check if the lib is an ELF file. */
+ ehdr = (Elf_Ehdr *) addr;
+ if (ehdr->e_ident[EI_MAG0] != ELFMAG0
+ || ehdr->e_ident[EI_MAG1] != ELFMAG1
+ || ehdr->e_ident[EI_MAG2] != ELFMAG2
+ || ehdr->e_ident[EI_MAG3] != ELFMAG3)
+ {
+ printf ("Not an ELF file: %x\n", ehdr->e_ident[EI_MAG0]);
+ return -1;
+ }
+
+ if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
+ {
+ if (sizeof (int *) != 4)
+ {
+ printf ("Architecture mismatch.");
+ return -1;
+ }
+ }
+ else if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+ {
+ if (sizeof (int *) != 8)
+ {
+ printf ("Architecture mismatch.");
+ return -1;
+ }
+ }
+
+ /* Load the program segments. For the sake of simplicity
+ assume that no reallocation is needed. */
+ phdr = (Elf_Phdr *) (addr + ehdr->e_phoff);
+ for (i = 0; i < ehdr->e_phnum; i++, phdr++)
+ {
+ if (phdr->p_type == PT_LOAD)
+ {
+ struct segment *next_seg = load (addr, phdr, tail_seg);
+ if (next_seg == 0)
+ continue;
+ tail_seg = next_seg;
+ if (head_seg == 0)
+ head_seg = next_seg;
+ }
+ }
+ *ehdr_out = ehdr;
+ *seg_out = head_seg;
+ return 0;
+}
+
+/* Return the section-header table. */
+
+Elf_Shdr *
+find_shdrtab (Elf_Ehdr *ehdr)
+{
+ return (Elf_Shdr *) (((char *) ehdr) + ehdr->e_shoff);
+}
+
+/* Return the string table of the section headers. */
+
+const char *
+find_shstrtab (Elf_Ehdr *ehdr, unsigned *size)
+{
+ const Elf_Shdr *shdr = NULL;
+ const Elf_Shdr *shstr = NULL;
+
+ if (ehdr->e_shnum <= ehdr->e_shstrndx)
+ {
+ printf ("The index of the string table is corrupt.");
+ return NULL;
+ }
+
+ shdr = find_shdrtab (ehdr);
+
+ shstr = &shdr[ehdr->e_shstrndx];
+ *size = shstr->sh_size;
+ return ((const char *) ehdr) + shstr->sh_offset;
+}
+
+/* Return the string table named SECTION. */
+
+const char *
+find_strtab (Elf_Ehdr *ehdr,
+ const char *section, unsigned *strtab_size)
+{
+ unsigned shstrtab_size = 0;
+ const char *shstrtab = NULL;
+ unsigned i = 0;
+ const Elf_Shdr *shdr = find_shdrtab (ehdr);
+
+ /* Get the string table of the section headers. */
+ shstrtab = find_shstrtab (ehdr, &shstrtab_size);
+ if (shstrtab == NULL)
+ return NULL;
+
+ for (i = 0; i < ehdr->e_shnum; i++)
+ {
+ Elf_Word name = shdr[i].sh_name;
+ if (shdr[i].sh_type == SHT_STRTAB && name <= shstrtab_size
+ && strcmp ((const char *) &shstrtab[name], section) == 0)
+ {
+ *strtab_size = shdr[i].sh_size;
+ return ((const char *) ehdr) + shdr[i].sh_offset;
+ }
+
+ }
+ return NULL;
+}
+
+/* Return the section header named SECTION. */
+
+Elf_Shdr *
+find_shdr (Elf_Ehdr *ehdr, const char *section)
+{
+ unsigned shstrtab_size = 0;
+ const char *shstrtab = NULL;
+ unsigned i = 0;
+
+ /* Get the string table of the section headers. */
+ shstrtab = find_shstrtab (ehdr, &shstrtab_size);
+ if (shstrtab == NULL)
+ return NULL;
+
+ Elf_Shdr *shdr = find_shdrtab (ehdr);
+ for (i = 0; i < ehdr->e_shnum; i++)
+ {
+ Elf_Word name = shdr[i].sh_name;
+ if (name <= shstrtab_size)
+ {
+ if (strcmp ((const char *) &shstrtab[name], section) == 0)
+ return &shdr[i];
+ }
+
+ }
+ return NULL;
+}
+
+/* Return the symbol table. */
+
+Elf_Sym *
+find_symtab (Elf_Ehdr *ehdr, unsigned *symtab_size)
+{
+ unsigned i = 0;
+ const Elf_Shdr *shdr = find_shdrtab (ehdr);
+ for (i = 0; i < ehdr->e_shnum; i++)
+ {
+ if (shdr[i].sh_type == SHT_SYMTAB)
+ {
+ *symtab_size = shdr[i].sh_size / sizeof (Elf_Sym);
+ return (Elf_Sym *) (((const char *) ehdr) + shdr[i].sh_offset);
+ }
+ }
+ return NULL;
+}
+
+/* Translate a file offset to an address in a loaded segment. */
+
+int
+translate_offset (Elf_Word file_offset, struct segment *seg, void **addr)
+{
+ while (seg)
+ {
+ Elf_Word p_from = 0, p_to = 0;
+ Elf_Phdr *phdr = seg->phdr;
+
+ if (phdr == NULL)
+ {
+ seg = seg->next;
+ continue;
+ }
+
+ p_from = phdr->p_offset;
+ p_to = p_from + phdr->p_filesz;
+ if (p_from <= file_offset && file_offset < p_to)
+ {
+ *addr = (void *) (seg->mapped_addr + (file_offset - p_from));
+ return 0;
+ }
+ seg = seg->next;
+ }
+
+ return -1;
+}
+
+/* Lookup the address of FUNC. */
+
+int
+lookup_function (const char *func,
+ Elf_Ehdr *ehdr, struct segment *seg, void **addr)
+{
+ const char *strtab = NULL;
+ unsigned strtab_size = 0;
+ Elf_Sym *symtab = NULL;
+ unsigned symtab_size = 0;
+ unsigned i = 0;
+
+ /* Get the string table for the symbols. */
+ strtab = find_strtab (ehdr, ".strtab", &strtab_size);
+ if (strtab == NULL)
+ {
+ printf (".strtab not found.");
+ return -1;
+ }
+
+ /* Get the symbol table. */
+ symtab = find_symtab (ehdr, &symtab_size);
+ if (symtab == NULL)
+ {
+ printf ("symbol table not found.");
+ return -1;
+ }
+
+ for (i = 0; i < symtab_size; i++)
+ {
+ Elf_Sym *sym = &symtab[i];
+
+ if (elf_st_type (sym->st_info) != STT_FUNC)
+ continue;
+
+ if (sym->st_name < strtab_size)
+ {
+ const char *name = &strtab[sym->st_name];
+ if (strcmp (name, func) == 0)
+ {
+
+ unsigned offset = (unsigned) sym->st_value;
+ return translate_offset (offset, seg, addr);
+ }
+ }
+ }
+
+ return -1;
+}
diff --git a/gdb/testsuite/gdb.base/sym-file-loader.h b/gdb/testsuite/gdb.base/sym-file-loader.h
new file mode 100644
index 0000000..573726b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sym-file-loader.h
@@ -0,0 +1,83 @@
+/* Copyright 2013 Free Software Foundation, Inc.
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __SYM_FILE_LOADER__
+#define __SYM_FILE_LOADER__
+
+#include <elf.h>
+
+#ifdef TARGET_LP64
+
+typedef Elf64_Phdr Elf_Phdr;
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Shdr Elf_Shdr;
+typedef Elf64_Sym Elf_Sym;
+typedef Elf64_Word Elf_Word;
+
+#elif defined TARGET_ILP32
+
+typedef Elf32_Phdr Elf_Phdr;
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Sym Elf_Sym;
+typedef Elf32_Word Elf_Word;
+
+#endif
+
+struct segment
+{
+ char *mapped_addr;
+ Elf_Phdr *phdr;
+ struct segment *next;
+};
+
+/* Mini shared library loader. No reallocation is performed
+ for the sake of simplicity. */
+
+int
+load_shlib (const char *file, Elf_Ehdr **ehdr_out, struct segment **seg_out);
+
+/* Return the section-header table. */
+
+Elf_Shdr *find_shdrtab (Elf_Ehdr *ehdr);
+
+/* Return the string table of the section headers. */
+
+const char *find_shstrtab (Elf_Ehdr *ehdr, unsigned *size);
+
+/* Return the string table named SECTION. */
+
+const char *find_strtab (Elf_Ehdr *ehdr,
+ const char *section, unsigned *strtab_size);
+
+/* Return the section header named SECTION. */
+
+Elf_Shdr *find_shdr (Elf_Ehdr *ehdr, const char *section);
+
+/* Return the symbol table. */
+
+Elf_Sym *find_symtab (Elf_Ehdr *ehdr, unsigned *symtab_size);
+
+/* Translate a file offset to an address in a loaded segment. */
+
+int translate_offset (Elf_Word file_offset, struct segment *seg, void **addr);
+
+/* Lookup the address of FUNC. */
+
+int
+lookup_function (const char *func, Elf_Ehdr* ehdr,
+ struct segment *seg, void **addr);
+
+#endif
diff --git a/gdb/testsuite/gdb.base/sym-file-main.c b/gdb/testsuite/gdb.base/sym-file-main.c
new file mode 100644
index 0000000..e1b0044
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sym-file-main.c
@@ -0,0 +1,78 @@
+/* Copyright 2013 Free Software Foundation, Inc.
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "sym-file-loader.h"
+
+void
+gdb_add_symbol_file (void *addr, const char *file)
+{
+ return;
+}
+
+void
+gdb_remove_symbol_file (void *addr)
+{
+ return;
+}
+
+/* Load a shared library without relying on the standard
+ loader to test GDB's commands for adding and removing
+ symbol files at runtime. */
+
+int
+main (int argc, const char *argv[])
+{
+ const char *file = SHLIB_NAME;
+ Elf_Ehdr *ehdr = NULL;
+ struct segment *head_seg = NULL;
+ Elf_Shdr *text = NULL;
+ char *text_addr = NULL;
+ int (*pbar) () = NULL;
+ int (*pfoo) (int) = NULL;
+
+ if (load_shlib (file, &ehdr, &head_seg) != 0)
+ return -1;
+
+ /* Get the text section. */
+ text = find_shdr (ehdr, ".text");
+ if (text == NULL)
+ return -1;
+
+ /* Notify GDB to add the symbol file. */
+ if (translate_offset (text->sh_offset, head_seg, (void **) &text_addr) != 0)
+ return -1;
+
+ gdb_add_symbol_file (text_addr, file);
+
+ /* Call bar from SHLIB_NAME. */
+ if (lookup_function ("bar", ehdr, head_seg, (void *) &pbar) != 0)
+ return -1;
+
+ (*pbar) ();
+
+ /* Call foo from SHLIB_NAME. */
+ if (lookup_function ("foo", ehdr, head_seg, (void *) &pfoo) != 0)
+ return -1;
+
+ (*pfoo) (2);
+
+ /* Notify GDB to remove the symbol file. */
+ gdb_remove_symbol_file (text_addr);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/sym-file.exp b/gdb/testsuite/gdb.base/sym-file.exp
new file mode 100644
index 0000000..fee93f4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sym-file.exp
@@ -0,0 +1,160 @@
+# Copyright 2013 Free Software Foundation, Inc.
+
+# 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 <http://www.gnu.org/licenses/>. */
+
+# Test adding and removing a symbol file dynamically:
+# 1) Run to gdb_add_symbol_file in $mainfile.
+# 2) Set a pending breakpoint at bar in $libsrc.
+# 3) Load $shlib_name using 'add-symbol-file'.
+# 4) 'info files' must display $libname.
+# 5) Continue to bar in $libsrc.
+# 6) Set a breakpoint at foo in $librc.
+# 7) Continue to foo in $libsrc.
+# 8) Set a breakpoint at gdb_remove_symbol_file.
+# 9) Continue to gdb_remove_symbol_file in $mainfile.
+# 10) Remove $shlib_name using 'remove-symbol-file'.
+# 11) 'info files' must not display $libname, anymore.
+# 12) Check that the breakpoints at foo and bar are pending.
+# 13) Check that the execution can continue without error.
+
+if { ![is_elf_target] } {
+ return 0
+}
+
+if [skip_shlib_tests] {
+ return 0
+}
+
+if [is_remote target] {
+ return 0
+}
+
+set target_size TARGET_UNKNOWN
+if [is_lp64_target] {
+ set target_size TARGET_LP64
+} elseif [is_ilp32_target] {
+ set target_size TARGET_ILP32
+} else {
+ return 0
+}
+
+set testfile sym-file.exp
+set mainfile sym-file-main
+set loaderfile sym-file-loader
+set libfile sym-file-lib
+set srcfiles "${mainfile}.c ${loaderfile}.c"
+set libsrc "${srcdir}/${subdir}/${libfile}.c"
+set libname "${libfile}.so"
+set shlib_name "${objdir}/${subdir}/${libname}"
+set libobj "${objdir}/${subdir}/${libname}"
+set exec_opts [list debug "additional_flags=-D$target_size\
+ -DSHLIB_NAME\\=\"$shlib_name\""]
+
+if [get_compiler_info] {
+ return -1
+}
+
+if { [gdb_compile_shlib $libsrc $libobj {debug}] != "" } {
+ untested ${testfile}
+ return
+}
+
+if { [prepare_for_testing ${testfile} ${mainfile} ${srcfiles} $exec_opts] } {
+ return
+}
+
+# 1) Run to GDB_ADD_SYMBOl_FILE in $mainfile for adding
+# $shlib_name.
+set result [runto gdb_add_symbol_file]
+if { !$result } then {
+ return
+}
+
+# 2) Set a pending breakpoint at bar in $libsrc.
+set result [gdb_breakpoint bar allow-pending]
+if { !$result } then {
+ return
+}
+
+# 3) Add $shlib_name using 'add-symbol-file'.
+set result [gdb_test "add-symbol-file ${shlib_name} addr" \
+ "Reading symbols from .*${shlib_name}\\.\\.\\.done\\." \
+ "add-symbol-file ${shlib_name} addr" \
+ "add symbol table from file \".*${shlib_name}\"\
+ at.*\\(y or n\\) " \
+ "y"]
+if { $result != 0 } then {
+ return
+}
+
+# 4) 'info files' must display $libname.
+gdb_test "info files" \
+ "^(?=(.*${libname})).*" \
+ "info files must display $libname"
+
+# 5) Continue to bar in $libsrc to ensure that the breakpoint
+# was bound correctly after adding $shilb_name.
+set lnum_bar [gdb_get_line_number "break at bar" ${libfile}.c]
+gdb_continue_to_breakpoint bar ".*$libfile\\.c:$lnum_bar.*"
+
+# 6) Set a breakpoint at foo in $libsrc.
+set result [gdb_breakpoint foo]
+if { !$result } then {
+ return
+}
+
+# 7) Continue to foo in $libsrc to ensure that the breakpoint
+# was bound correctly.
+set lnum_foo [gdb_get_line_number "break at foo" ${libfile}.c]
+gdb_continue_to_breakpoint foo ".*$libfile\\.c:$lnum_foo.*"
+
+# 8) Set a breakpoint at gdb_remove_symbol_file in $mainfile for
+# removing $shlib_name.
+set result [gdb_breakpoint gdb_remove_symbol_file]
+if { !$result } then {
+ return
+}
+
+# 9) Continue to gdb_remove_symbol_file in $mainfile.
+gdb_continue_to_breakpoint gdb_remove_symbol_file
+
+# 10) Remove $shlib_name using 'remove-symbol-file'.
+set result [gdb_test "remove-symbol-file -a addr" \
+ ""\
+ "remove-symbol-file -a addr" \
+ "Remove symbol table from file \".*${shlib_name}\"\\?\
+.*\\(y or n\\) " \
+ "y"]
+if { $result != 0 } then {
+ return
+}
+
+# 11) 'info files' must not display $libname, anymore.
+gdb_test "info files" \
+ "^(?!(.*${libname})).*" \
+ "info files must not display ${libname}"
+
+# 12) Check that the breakpoints at foo and bar are pending after removing
+# $shlib_name.
+gdb_test "info breakpoints 2" \
+ ".*PENDING.*" \
+ "check if Breakpoint 2 is pending."
+
+gdb_test "info breakpoints 3" \
+ ".*PENDING.*" \
+ "check if Breakpoint 3 is pending."
+
+# 13) Check that the execution can continue without error.
+gdb_continue_to_end
+
--
1.7.6.5
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v12 5/5] Test adding and removing a symbol file at runtime.
2013-07-17 16:28 ` [PATCH v12 5/5] Test adding and removing a symbol file at runtime Nicolas Blanc
@ 2013-07-17 18:53 ` Mark Kettenis
2013-07-18 12:52 ` Blanc, Nicolas
0 siblings, 1 reply; 14+ messages in thread
From: Mark Kettenis @ 2013-07-17 18:53 UTC (permalink / raw)
To: nicolas.blanc; +Cc: gdb-patches, dje, nicolas.blanc
> From: Nicolas Blanc <nicolas.blanc@intel.com>
> Date: Wed, 17 Jul 2013 18:27:35 +0200
>
> +#include <elf.h>
The <elf.h> header isn't standardized at all. So this testcase
probably only compile on systems that use glibc as their C library.
Might not even work on a significant fraction of systems that use a
Linux kernel.
Perhaps it is possible to use the headers from include/elf in the src
tree instead?
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH v12 5/5] Test adding and removing a symbol file at runtime.
2013-07-17 18:53 ` Mark Kettenis
@ 2013-07-18 12:52 ` Blanc, Nicolas
2013-07-18 13:28 ` Mark Kettenis
0 siblings, 1 reply; 14+ messages in thread
From: Blanc, Nicolas @ 2013-07-18 12:52 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches, dje
>> +#include <elf.h>
>
>The <elf.h> header isn't standardized at all. So this testcase probably only compile on systems that use glibc as their C library.
>Might not even work on a significant fraction of systems that use a Linux kernel.
>
>Perhaps it is possible to use the headers from include/elf in the src tree instead?
Thanks Mark of looking into this patch. I can change the include, no big deal, but <elf.h> looks
more portable to me than </usr/include/elf.h> for the following reasons:
* The man pages for Linux and FreeBSD both mention <elf.h> but not </usr/include/elf.h>:
http://man7.org/linux/man-pages/man5/elf.5.html
http://www.freebsd.org/cgi/man.cgi?query=elf&sektion=5&apropos=0&manpath=FreeBSD+9.1-RELEASE
I could compile the test on following distros: Fedora 15, Red Hat 6.2, Ubuntu 12.4, and SUSE 11.1. And <elf.h> is even available on Cygwin.
* My understanding is that <elf.h> provides at least the definitions that are relevant for the target system, which is what matter here, and does not
hardcode any path.
* The following GDB tests include <elf.h>:
./gdb.arch/ppc-dfp.c:#include <elf.h>
./gdb.base/jit-main.c:#include <elf.h>
There is not test including any other elf header.
Can you comment on this?
Thank you,
Nicolas
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v12 5/5] Test adding and removing a symbol file at runtime.
2013-07-18 12:52 ` Blanc, Nicolas
@ 2013-07-18 13:28 ` Mark Kettenis
2013-07-18 16:05 ` Blanc, Nicolas
0 siblings, 1 reply; 14+ messages in thread
From: Mark Kettenis @ 2013-07-18 13:28 UTC (permalink / raw)
To: nicolas.blanc; +Cc: mark.kettenis, gdb-patches, dje
> From: "Blanc, Nicolas" <nicolas.blanc@intel.com>
> Date: Thu, 18 Jul 2013 12:51:48 +0000
>
> >> +#include <elf.h>
> >
> >The <elf.h> header isn't standardized at all. So this testcase
> >probably only compile on systems that use glibc as their C library.
> >Might not even work on a significant fraction of systems that use a
> >Linux kernel.
> >
> >Perhaps it is possible to use the headers from include/elf in the
> >src tree instead?
>
> Thanks Mark of looking into this patch. I can change the include, no
> big deal, but <elf.h> looks more portable to me than
> </usr/include/elf.h> for the following reasons:
I wasn't suggesting to use /usr/include/elf.h, but rather the header
files in $(srcdir)/../include/elf.
> * The man pages for Linux and FreeBSD both mention <elf.h> but not
> * </usr/include/elf.h>:
> http://man7.org/linux/man-pages/man5/elf.5.html
> http://www.freebsd.org/cgi/man.cgi?query=elf&sektion=5&apropos=0&manpath=FreeBSD+9.1-RELEASE
>
> I could compile the test on following distros: Fedora 15, Red Hat
> 6.2, Ubuntu 12.4, and SUSE 11.1. And <elf.h> is even available on
> Cygwin.
It's not available on OpenBSD and NetBSD, although we have a somewhat
similar header called <elf_abi.h> on OpenBSD (and probably on NetBSD
too). But even on the platforms that do have <elf.h> its contents
aren't completely standardized. So you'll need to be very careful
with what defenitions you use. That's why I'm suggesting to use a
header provided by gdb (or rather BFD) itself as.
> * The following GDB tests include <elf.h>:
> ./gdb.arch/ppc-dfp.c:#include <elf.h>
> ./gdb.base/jit-main.c:#include <elf.h>
Didn't catch the ppc-dfp.c test yet, since it runs only on PowerPC.
The problems with jit-main.c is the reason why I pointed this out to
you ;).
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH v12 5/5] Test adding and removing a symbol file at runtime.
2013-07-18 13:28 ` Mark Kettenis
@ 2013-07-18 16:05 ` Blanc, Nicolas
0 siblings, 0 replies; 14+ messages in thread
From: Blanc, Nicolas @ 2013-07-18 16:05 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches, dje
> I wasn't suggesting to use /usr/include/elf.h, but rather the header files in $(srcdir)/../include/elf.
Thanks for the clarification. I'll rewrite the code using the headers from there.
Regards,
Nicolas
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v12 3/5] 'add-symbol-file' should update the current target sections.
2013-07-17 16:28 [PATCH v12 0/5] remove-symbol-file & add-symbol-file Nicolas Blanc
` (3 preceding siblings ...)
2013-07-17 16:28 ` [PATCH v12 5/5] Test adding and removing a symbol file at runtime Nicolas Blanc
@ 2013-07-17 16:28 ` Nicolas Blanc
2013-07-26 19:10 ` Luis Machado
4 siblings, 1 reply; 14+ messages in thread
From: Nicolas Blanc @ 2013-07-17 16:28 UTC (permalink / raw)
To: gdb-patches, dje; +Cc: nicolas.blanc
2013-17-06 Nicolas Blanc <nicolas.blanc@intel.com>
* symfile.c (add_target_sections_of_objfile): New function.
(add_symbol_file_command): Update the current target sections.
(symfile_free_objfile): New function.
(_initialize_symfile): Attach observer for free_objfile.
Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
---
gdb/symfile.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/gdb/symfile.c b/gdb/symfile.c
index dbcccd3..96d9cdc 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -57,6 +57,7 @@
#include "stack.h"
#include "gdb_bfd.h"
#include "cli/cli-utils.h"
+#include "target.h"
#include <sys/types.h>
#include <fcntl.h>
@@ -2158,6 +2159,51 @@ print_transfer_performance (struct ui_file *stream,
ui_out_text (uiout, ".\n");
}
+/* Add the sections of OBJFILE to the current set of target sections. */
+
+static void
+add_target_sections_of_objfile (struct objfile *objfile)
+{
+ struct target_section_table *table = current_target_sections;
+ struct obj_section *osect;
+ int space;
+ unsigned count = 0;
+ struct target_section *ts;
+
+ if (objfile == NULL)
+ return;
+
+ /* Compute the number of sections to add. */
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ {
+ if (bfd_get_section_size (osect->the_bfd_section) == 0)
+ continue;
+ count++;
+ }
+
+ if (count == 0)
+ return;
+
+ space = resize_section_table (table, count);
+
+ ts = table->sections + space;
+
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ {
+ if (bfd_get_section_size (osect->the_bfd_section) == 0)
+ continue;
+
+ gdb_assert (ts < table->sections + space + count);
+
+ ts->addr = obj_section_addr (osect);
+ ts->endaddr = obj_section_endaddr (osect);
+ ts->the_bfd_section = osect->the_bfd_section;
+ ts->key = (void *) objfile;
+
+ ts++;
+ }
+}
+
/* This function allows the addition of incrementally linked object files.
It does not modify any state in the target, only in the debugger. */
/* Note: ezannoni 2000-04-13 This function/command used to have a
@@ -2181,6 +2227,7 @@ add_symbol_file_command (char *args, int from_tty)
int expecting_sec_name = 0;
int expecting_sec_addr = 0;
char **argv;
+ struct objfile *objf;
struct sect_opt
{
@@ -2316,8 +2363,10 @@ add_symbol_file_command (char *args, int from_tty)
if (from_tty && (!query ("%s", "")))
error (_("Not confirmed."));
- symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
- section_addrs, flags);
+ objf = symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
+ section_addrs, flags);
+
+ add_target_sections_of_objfile (objf);
/* Getting new symbols may change our opinion about what is
frameless. */
@@ -3792,11 +3841,26 @@ symfile_find_segment_sections (struct objfile *objfile)
free_symfile_segment_data (data);
}
+/* Listen for free_objfile events. */
+
+static void
+symfile_free_objfile (struct objfile *objfile)
+{
+ if (objfile == NULL)
+ return;
+
+ /* Remove the target sections of user-added objfiles. */
+ if (objfile->flags & OBJF_USERLOADED && objfile->obfd)
+ remove_target_sections ((void*)objfile, objfile->obfd);
+}
+
void
_initialize_symfile (void)
{
struct cmd_list_element *c;
+ observer_attach_free_objfile (symfile_free_objfile);
+
c = add_cmd ("symbol-file", class_files, symbol_file_command, _("\
Load symbol table from executable file FILE.\n\
The `file' command can also load symbol tables, as well as setting the file\n\
--
1.7.6.5
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v12 3/5] 'add-symbol-file' should update the current target sections.
2013-07-17 16:28 ` [PATCH v12 3/5] 'add-symbol-file' should update the current target sections Nicolas Blanc
@ 2013-07-26 19:10 ` Luis Machado
0 siblings, 0 replies; 14+ messages in thread
From: Luis Machado @ 2013-07-26 19:10 UTC (permalink / raw)
To: Nicolas Blanc; +Cc: gdb-patches, dje
Hi Nicolas,
On 07/17/2013 01:27 PM, Nicolas Blanc wrote:
> diff --git a/gdb/symfile.c b/gdb/symfile.c
> index dbcccd3..96d9cdc 100644
> --- a/gdb/symfile.c
> +++ b/gdb/symfile.c
> @@ -57,6 +57,7 @@
> #include "stack.h"
> #include "gdb_bfd.h"
> #include "cli/cli-utils.h"
> +#include "target.h"
>
> #include <sys/types.h>
> #include <fcntl.h>
> @@ -2158,6 +2159,51 @@ print_transfer_performance (struct ui_file *stream,
> ui_out_text (uiout, ".\n");
> }
>
> +/* Add the sections of OBJFILE to the current set of target sections. */
> +
> +static void
> +add_target_sections_of_objfile (struct objfile *objfile)
> +{
> + struct target_section_table *table = current_target_sections;
> + struct obj_section *osect;
> + int space;
> + unsigned count = 0;
> + struct target_section *ts;
> +
> + if (objfile == NULL)
> + return;
> +
> + /* Compute the number of sections to add. */
> + ALL_OBJFILE_OSECTIONS (objfile, osect)
> + {
> + if (bfd_get_section_size (osect->the_bfd_section) == 0)
> + continue;
> + count++;
> + }
> +
> + if (count == 0)
> + return;
> +
> + space = resize_section_table (table, count);
> +
> + ts = table->sections + space;
> +
> + ALL_OBJFILE_OSECTIONS (objfile, osect)
> + {
> + if (bfd_get_section_size (osect->the_bfd_section) == 0)
> + continue;
> +
> + gdb_assert (ts < table->sections + space + count);
> +
> + ts->addr = obj_section_addr (osect);
> + ts->endaddr = obj_section_endaddr (osect);
> + ts->the_bfd_section = osect->the_bfd_section;
> + ts->key = (void *) objfile;
> +
> + ts++;
> + }
> +}
> +
This hunk needs to be updated because of this change:
2013-07-22 Doug Evans <dje@google.com>
* exec.h (remove_target_sections): Delete arg abfd.
* exec.c (exec_close): Update call to remove_target_sections.
(remove_target_sections): Delete arg abfd.
* solib.c (update_solib_list): Ditto.
(reload_shared_libraries_1): Ditto.
(clear_solib): Ditto, and unconditionally call
remove_target_sections.
* target.h (struct target_section): Rename key to owner.
All uses updated.
ts->key should be ts->owner now.
> /* This function allows the addition of incrementally linked object files.
> It does not modify any state in the target, only in the debugger. */
> /* Note: ezannoni 2000-04-13 This function/command used to have a
> @@ -2181,6 +2227,7 @@ add_symbol_file_command (char *args, int from_tty)
> int expecting_sec_name = 0;
> int expecting_sec_addr = 0;
> char **argv;
> + struct objfile *objf;
>
> struct sect_opt
> {
> @@ -2316,8 +2363,10 @@ add_symbol_file_command (char *args, int from_tty)
> if (from_tty && (!query ("%s", "")))
> error (_("Not confirmed."));
>
> - symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
> - section_addrs, flags);
> + objf = symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
> + section_addrs, flags);
> +
> + add_target_sections_of_objfile (objf);
>
> /* Getting new symbols may change our opinion about what is
> frameless. */
> @@ -3792,11 +3841,26 @@ symfile_find_segment_sections (struct objfile *objfile)
> free_symfile_segment_data (data);
> }
>
> +/* Listen for free_objfile events. */
> +
> +static void
> +symfile_free_objfile (struct objfile *objfile)
> +{
> + if (objfile == NULL)
> + return;
> +
> + /* Remove the target sections of user-added objfiles. */
> + if (objfile->flags & OBJF_USERLOADED && objfile->obfd)
> + remove_target_sections ((void*)objfile, objfile->obfd);
> +}
> +
This hunk as well. The same change removed the second parameter of
remove_target_sections.
With those changes i can build it cleanly.
Luis
^ permalink raw reply [flat|nested] 14+ messages in thread