Re: [PATCH] Allow spaces in filenames to load command

Andrew STUBBS
2005-12-07T17:54:48Z

[-- Attachment #1: Type: text/plain, Size: 64 bytes --]

I forgot to update the Makefile dependencies.

Update attached.

[-- Attachment #2: load-2.patch --]
[-- Type: text/plain, Size: 8299 bytes --]

2005-12-07 Andrew Stubbs <andrew.stubbs@st.com>

* symfile.c (generic_load): Use buildargv() and tilde_expand()
to parse file names with quoting, spaces and tildes properly.
(load_command): Quote all special characters before calling
target_load() such that buildargv() doesn't break file names.
(_initialize_symfile): Mention the load offset in the help for
the load command.
* remote-sim.c: Include readline.h.
(gdbsim_load): Use buildargv and tilde_expand() to parse file
names with quoting, spaces and tildes properly.
* target.h (target_load): Comment the parameters better.
* Makefile.in (remote_sim.o): Add readline.h dependency.

Index: src/gdb/symfile.c
===================================================================
--- src.orig/gdb/symfile.c 2005-12-02 16:15:22.000000000 +0000
+++ src/gdb/symfile.c 2005-12-07 16:41:26.000000000 +0000
@@ -1468,7 +1468,42 @@ static void
load_command (char *arg, int from_tty)
{
if (arg == NULL)
- arg = get_exec_file (1);
+ {
+ char *parg;
+ int count = 0;
+
+ parg = arg = get_exec_file (1);
+
+ /* Count how many \ " ' tab space there are in the name. */
+ while ((parg = strpbrk (parg, "\\\"'\t ")))
+ {
+ parg++;
+ count++;
+ }
+
+ if (count)
+ {
+ /* We need to quote this string so buildargv can pull it apart. */
+ char *temp = xmalloc (strlen (arg) + count + 1 );
+ char *ptemp = temp;
+ char *prev;
+
+ make_cleanup (xfree, temp);
+
+ prev = parg = arg;
+ while ((parg = strpbrk (parg, "\\\"'\t ")))
+ {
+ strncpy (ptemp, prev, parg - prev);
+ ptemp += parg - prev;
+ prev = parg++;
+ *ptemp++ = '\\';
+ }
+ strcpy (ptemp, prev);
+
+ arg = temp;
+ }
+ }
+
target_load (arg, from_tty);

/* After re-loading the executable, we don't really know which
@@ -1615,33 +1650,40 @@ generic_load (char *args, int from_tty)
bfd *loadfile_bfd;
struct timeval start_time, end_time;
char *filename;
- struct cleanup *old_cleanups;
- char *offptr;
+ struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
struct load_section_data cbdata;
CORE_ADDR entry;
+ char **argv;

cbdata.load_offset = 0; /* Offset to add to vma for each section. */
cbdata.write_count = 0; /* Number of writes needed. */
cbdata.data_count = 0; /* Number of bytes written to target memory. */
cbdata.total_size = 0; /* Total size of all bfd sectors. */

- /* Parse the input argument - the user can specify a load offset as
- a second argument. */
- filename = xmalloc (strlen (args) + 1);
- old_cleanups = make_cleanup (xfree, filename);
- strcpy (filename, args);
- offptr = strchr (filename, ' ');
- if (offptr != NULL)
+ argv = buildargv (args);
+
+ if (argv == NULL)
+ nomem(0);
+
+ make_cleanup_freeargv (argv);
+
+ filename = tilde_expand (argv[0]);
+ make_cleanup (xfree, filename);
+
+ if (argv[1] != NULL)
{
char *endptr;

- cbdata.load_offset = strtoul (offptr, &endptr, 0);
- if (offptr == endptr)
- error (_("Invalid download offset:%s."), offptr);
- *offptr = '\0';
+ cbdata.load_offset = strtoul (argv[1], &endptr, 0);
+
+ /* If the last word was not a valid number then
+ treat it as a file name with spaces in. */
+ if (argv[1] == endptr)
+ error (_("Invalid download offset:%s."), argv[1]);
+
+ if (argv[2] != NULL)
+ error (_("Too many parameters."));
}
- else
- cbdata.load_offset = 0;

/* Open the file for loading. */
loadfile_bfd = bfd_openr (filename, gnutarget);
@@ -3716,7 +3758,8 @@ Load the symbols from shared objects in

c = add_cmd ("load", class_files, load_command, _("\
Dynamically load FILE into the running program, and record its symbols\n\
-for access from GDB."), &cmdlist);
+for access from GDB.\n\
+A load OFFSET may also be given."), &cmdlist);
set_cmd_completer (c, filename_completer);

add_setshow_boolean_cmd ("symbol-reloading", class_support,
Index: src/gdb/remote-sim.c
===================================================================
--- src.orig/gdb/remote-sim.c 2005-11-29 10:51:01.000000000 +0000
+++ src/gdb/remote-sim.c 2005-12-07 17:32:55.000000000 +0000
@@ -43,6 +43,7 @@
#include "gdb_assert.h"
#include "sim-regno.h"
#include "arch-utils.h"
+#include "readline/readline.h"

/* Prototypes */

@@ -391,8 +392,21 @@ gdbsim_kill (void)
GDB's symbol tables to match. */

static void
-gdbsim_load (char *prog, int fromtty)
+gdbsim_load (char *args, int fromtty)
{
+ char **argv = buildargv (args);
+ char *prog;
+
+ if (argv == NULL)
+ nomem (0);
+
+ make_cleanup_freeargv (argv);
+
+ prog = tilde_expand (argv[0]);
+
+ if (argv[1] != NULL)
+ error (_("GDB sim does not yet support a load offset."));
+
if (sr_get_debug ())
printf_filtered ("gdbsim_load: prog \"%s\"\n", prog);

Index: src/gdb/target.h
===================================================================
--- src.orig/gdb/target.h 2005-09-04 17:18:20.000000000 +0100
+++ src/gdb/target.h 2005-12-07 14:18:05.000000000 +0000
@@ -679,7 +679,14 @@ extern void print_section_info (struct t

/* Load an executable file into the target process. This is expected
to not only bring new code into the target process, but also to
- update GDB's symbol tables to match. */
+ update GDB's symbol tables to match.
+
+ ARG contains command-line arguments, to be broken down with
+ buildargv (). The first non-switch argument is the filename to
+ load, FILE; the second is a number (as parsed by strtoul (..., ...,
+ 0)), which is an offset to apply to the load addresses of FILE's
+ sections. The target may define switches, or other non-switch
+ arguments, as it pleases. */

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

Index: src/gdb/testsuite/gdb.base/help.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/help.exp 2005-12-07 14:15:01.000000000 +0000
+++ src/gdb/testsuite/gdb.base/help.exp 2005-12-07 17:24:55.000000000 +0000
@@ -277,7 +277,7 @@ gdb_test "help l" "List specified functi
# test help list
gdb_test "help list" "List specified function or line\.\[\r\n\]+With no argument, lists ten more lines after or around previous listing\.\[\r\n\]+\"list -\" lists the ten lines before a previous ten-line listing\.\[\r\n\]+One argument specifies a line, and ten lines are listed around that line\.\[\r\n\]+Two arguments with comma between specify starting and ending lines to list\.\[\r\n\]+Lines can be specified in these ways:\[\r\n\]+ LINENUM, to list around that line in current file,\[\r\n\]+ FILE:LINENUM, to list around that line in that file,\[\r\n\]+ FUNCTION, to list around beginning of that function,\[\r\n\]+ FILE:FUNCTION, to distinguish among like-named static functions\.\[\r\n\]+ \[*\]ADDRESS, to list around the line containing that address\.\[\r\n\]+With two args if one is empty it stands for ten lines away from the other arg\." "help list"
# test help load
-gdb_test "help load" "Dynamically load FILE into the running program, and record its symbols\[\r\n\]+for access from GDB\." "help load"
+gdb_test "help load" "Dynamically load FILE into the running program, and record its symbols\[\r\n\]+for access from GDB\.\[\r\n\]+A load OFFSET may also be given\." "help load"
# test help make
gdb_test "help make" "Run the ``make'' program using the rest of the line as arguments\." "help make"
# test help next "n" abbreviation
Index: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in 2005-12-02 16:15:21.000000000 +0000
+++ src/gdb/Makefile.in 2005-12-07 17:51:41.000000000 +0000
@@ -2465,7 +2465,8 @@ remote-sds.o: remote-sds.c $(defs_h) $(g
remote-sim.o: remote-sim.c $(defs_h) $(inferior_h) $(value_h) \
$(gdb_string_h) $(terminal_h) $(target_h) $(gdbcore_h) \
$(gdb_callback_h) $(gdb_remote_sim_h) $(remote_utils_h) $(command_h) \
- $(regcache_h) $(gdb_assert_h) $(sim_regno_h) $(arch_utils_h)
+ $(regcache_h) $(gdb_assert_h) $(sim_regno_h) $(arch_utils_h) \
+ $(readline_h)
remote-st.o: remote-st.c $(defs_h) $(gdbcore_h) $(target_h) $(gdb_string_h) \
$(serial_h) $(regcache_h)
remote-utils.o: remote-utils.c $(defs_h) $(gdb_string_h) $(gdbcmd_h) \