[PATCH 04/18] add new "unload" command (symetry of existing "load" command)

Joel Brobecker
2011-02-24T17:50:46Z

As the title suggests, this patch adds a new "unload" command which
is expected to do the opposite of the load command, on the targets
that support it. VxWorks targets allow us to unload modules, and
thus this target method will be used there.

gdb/ChangeLog:

* target.h (struct target_ops): Add "to_unload" field.
(target_unload): Add declaration.
* target.c (debug_to_unload, target_unload): New functions.
(update_current_target): Add support for to_unload method.
(setup_target_debug): Set current_target.to_unload.
* symfile.c (unload_command): New function.
(_initialize_symfile): Add "unload" command.

gdb/doc/ChangeLog:

* gdb.texinfo (Target Commands): Document new "unload" command.
---
gdb/doc/gdb.texinfo | 13 +++++++++++++
gdb/symfile.c | 18 ++++++++++++++++++
gdb/target.c | 22 ++++++++++++++++++++++
gdb/target.h | 10 ++++++++++
4 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index c727dc8..32454c3 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -15842,6 +15842,19 @@ Depending on the remote side capabilities, @value{GDBN} may be able to
load programs into flash memory.

@code{load} does not repeat if you press @key{RET} again after using it.
+
+@item unload @var{filename}
+@kindex unload @var{filename}
+@cindex unload object file from target
+Depending on what remote debugging facilities are configured into
+@value{GDBN}, the @code{unload} command may be available. Where it exists,
+it does the opposite of the @code{load} command.
+
+If your @value{GDBN} does not have an @code{unload} command, attempting
+to execute it triggers the error message ``@code{You can't do that when
+your target is @dots{}}''
+
+@code{unload} does not repeat if you press @key{RET} again after using it.
@end table

@node Byte Order
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 579aaa4..2e43e83 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1788,6 +1788,20 @@ load_command (char *arg, int from_tty)
overlay_cache_invalid = 1;
}

+/* Implement the "unload" command. */
+
+static void
+unload_command (char *arg, int from_tty)
+{
+ dont_repeat ();
+
+ target_unload (arg, from_tty);
+
+ /* After unloading some object files, we don't really know which
+ overlays are mapped any more. */
+ overlay_cache_invalid = 1;
+}
+
/* This version of "load" should be usable for any target. Currently
it is just used for remote targets, not inftarg.c or core files,
on the theory that only in that case is it useful.
@@ -3672,6 +3686,10 @@ for access from GDB.\n\
A load OFFSET may also be given."), &cmdlist);
set_cmd_completer (c, filename_completer);

+ c = add_cmd ("unload", class_files, unload_command, _("\
+Unload FILE from the target."), &cmdlist);
+ set_cmd_completer (c, filename_completer);
+
add_setshow_boolean_cmd ("symbol-reloading", class_support,
&symbol_reloading, _("\
Set dynamic symbol table reloading multiple times in one run."), _("\
diff --git a/gdb/target.c b/gdb/target.c
index a4e2ae9..959e5ff 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -149,6 +149,8 @@ static void debug_to_terminal_info (char *, int);

static void debug_to_load (char *, int);

+static void debug_to_unload (char *, int);
+
static int debug_to_lookup_symbol (char *, CORE_ADDR *);

static int debug_to_can_run (void);
@@ -468,6 +470,13 @@ target_load (char *arg, int from_tty)
}

void
+target_unload (char *arg, int from_tty)
+{
+ target_dcache_invalidate ();
+ (*current_target.to_unload) (arg, from_tty);
+}
+
+void
target_create_inferior (char *exec_file, char *args,
char **env, int from_tty)
{
@@ -615,6 +624,7 @@ update_current_target (void)
INHERIT (to_terminal_info, t);
/* Do not inherit to_kill. */
INHERIT (to_load, t);
+ INHERIT (to_unload, t);
INHERIT (to_lookup_symbol, t);
/* Do no inherit to_create_inferior. */
INHERIT (to_post_startup_inferior, t);
@@ -768,6 +778,9 @@ update_current_target (void)
de_fault (to_load,
(void (*) (char *, int))
tcomplain);
+ de_fault (to_unload,
+ (void (*) (char *, int))
+ tcomplain);
de_fault (to_lookup_symbol,
(int (*) (char *, CORE_ADDR *))
nosymbol);
@@ -3788,6 +3801,14 @@ debug_to_load (char *args, int from_tty)
fprintf_unfiltered (gdb_stdlog, "target_load (%s, %d)\n", args, from_tty);
}

+static void
+debug_to_unload (char *args, int from_tty)
+{
+ debug_target.to_unload (args, from_tty);
+
+ fprintf_unfiltered (gdb_stdlog, "target_unload (%s, %d)\n", args, from_tty);
+}
+
static int
debug_to_lookup_symbol (char *name, CORE_ADDR *addrp)
{
@@ -3999,6 +4020,7 @@ setup_target_debug (void)
current_target.to_terminal_save_ours = debug_to_terminal_save_ours;
current_target.to_terminal_info = debug_to_terminal_info;
current_target.to_load = debug_to_load;
+ current_target.to_unload = debug_to_unload;
current_target.to_lookup_symbol = debug_to_lookup_symbol;
current_target.to_post_startup_inferior = debug_to_post_startup_inferior;
current_target.to_insert_fork_catchpoint = debug_to_insert_fork_catchpoint;
diff --git a/gdb/target.h b/gdb/target.h
index e856dde..78fccd3 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -479,6 +479,7 @@ struct target_ops
void (*to_terminal_info) (char *, int);
void (*to_kill) (struct target_ops *);
void (*to_load) (char *, int);
+ void (*to_unload) (char *, int);
int (*to_lookup_symbol) (char *, CORE_ADDR *);
void (*to_create_inferior) (struct target_ops *,
char *, char *, char **, int);
@@ -1016,6 +1017,15 @@ extern void target_kill (void);

extern void target_load (char *arg, int from_tty);

+/* Unload an object file.
+
+ ARG contains command-line arguments, to be broken down with buildargv.
+ The first non-switch argument is the object filename to be unloaded.
+ The target may define switches, or other non-switch arguments, as
+ it pleases. */
+
+extern void target_unload (char *arg, int from_tty);
+
/* Look up a symbol in the target's symbol table. NAME is the symbol
name. ADDRP is a CORE_ADDR * pointing to where the value of the
symbol should be returned. The result is 0 if successful, nonzero
--
1.7.0.4