/* Dump-to-file commands, for GDB, the GNU debugger.
- Copyright (c) 2002, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Red Hat.
#include <ctype.h>
#include "target.h"
#include "readline/readline.h"
+#include "gdbcore.h"
+#include "cli/cli-utils.h"
+#include "gdb_bfd.h"
+#include "filestuff.h"
#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
char *
-skip_spaces (char *chp)
-{
- if (chp == NULL)
- return NULL;
- while (isspace (*chp))
- chp++;
- return chp;
-}
-
-char *
scan_expression_with_cleanup (char **cmd, const char *def)
{
if ((*cmd) == NULL || (**cmd) == '\0')
{
char *exp = xstrdup (def);
+
make_cleanup (xfree, exp);
return exp;
}
FILE *
fopen_with_cleanup (const char *filename, const char *mode)
{
- FILE *file = fopen (filename, mode);
+ FILE *file = gdb_fopen_cloexec (filename, mode);
+
if (file == NULL)
perror_with_name (filename);
make_cleanup_fclose (file);
{
bfd *ibfd;
- ibfd = bfd_openr (filename, target);
+ ibfd = gdb_bfd_openr (filename, target);
if (ibfd == NULL)
error (_("Failed to open %s: %s."), filename,
bfd_errmsg (bfd_get_error ()));
- make_cleanup_bfd_close (ibfd);
+ make_cleanup_bfd_unref (ibfd);
if (!bfd_check_format (ibfd, bfd_object))
error (_("'%s' is not a recognized file format."), filename);
if (*mode == 'w') /* Write: create new file */
{
- obfd = bfd_openw (filename, target);
+ obfd = gdb_bfd_openw (filename, target);
if (obfd == NULL)
error (_("Failed to open %s: %s."), filename,
bfd_errmsg (bfd_get_error ()));
- make_cleanup_bfd_close (obfd);
+ make_cleanup_bfd_unref (obfd);
if (!bfd_set_format (obfd, bfd_object))
error (_("bfd_openw_with_cleanup: %s."), bfd_errmsg (bfd_get_error ()));
}
- else if (*mode == 'a') /* Append to existing file */
- { /* FIXME -- doesn't work... */
+ else if (*mode == 'a') /* Append to existing file. */
+ { /* FIXME -- doesn't work... */
error (_("bfd_openw does not work with append."));
}
else
return obfd;
}
-struct cmd_list_element *dump_cmdlist;
-struct cmd_list_element *append_cmdlist;
-struct cmd_list_element *srec_cmdlist;
-struct cmd_list_element *ihex_cmdlist;
-struct cmd_list_element *tekhex_cmdlist;
-struct cmd_list_element *binary_dump_cmdlist;
-struct cmd_list_element *binary_append_cmdlist;
+static struct cmd_list_element *dump_cmdlist;
+static struct cmd_list_element *append_cmdlist;
+static struct cmd_list_element *srec_cmdlist;
+static struct cmd_list_element *ihex_cmdlist;
+static struct cmd_list_element *tekhex_cmdlist;
+static struct cmd_list_element *binary_dump_cmdlist;
+static struct cmd_list_element *binary_append_cmdlist;
static void
dump_command (char *cmd, int from_tty)
static void
dump_binary_file (const char *filename, const char *mode,
- const bfd_byte *buf, int len)
+ const bfd_byte *buf, ULONGEST len)
{
FILE *file;
int status;
static void
dump_bfd_file (const char *filename, const char *mode,
const char *target, CORE_ADDR vaddr,
- const bfd_byte *buf, int len)
+ const bfd_byte *buf, ULONGEST len)
{
bfd *obfd;
asection *osection;
| SEC_ALLOC
| SEC_LOAD));
osection->entsize = 0;
- bfd_set_section_contents (obfd, osection, buf, 0, len);
+ if (!bfd_set_section_contents (obfd, osection, buf, 0, len))
+ warning (_("writing dump file '%s' (%s)"), filename,
+ bfd_errmsg (bfd_get_error ()));
}
static void
void *buf;
char *lo_exp;
char *hi_exp;
- int len;
/* Open the file. */
filename = scan_filename_with_cleanup (&cmd, NULL);
value. */
buf = xmalloc (count);
make_cleanup (xfree, buf);
- target_read_memory (lo, buf, count);
+ read_memory (lo, buf, count);
/* Have everything. Open/write the data. */
if (file_format == NULL || strcmp (file_format, "binary") == 0)
if (VALUE_LVAL (val))
{
- vaddr = VALUE_ADDRESS (val);
+ vaddr = value_address (val);
}
else
{
call_dump_func (struct cmd_list_element *c, char *args, int from_tty)
{
struct dump_context *d = get_cmd_context (c);
+
d->func (args, d->mode);
}
c->doc = concat ("Append ", c->doc + 6, (char *)NULL);
}
-/* Opaque data for restore_section_callback. */
+/* Opaque data for restore_section_callback. */
struct callback_data {
- long load_offset;
+ CORE_ADDR load_offset;
CORE_ADDR load_start;
CORE_ADDR load_end;
};
gdb_byte *buf;
int ret;
- /* Ignore non-loadable sections, eg. from elf files. */
+ /* Ignore non-loadable sections, eg. from elf files. */
if (!(bfd_get_section_flags (ibfd, isec) & SEC_LOAD))
return;
if (sec_end <= data->load_start
|| (data->load_end > 0 && sec_start >= data->load_end))
{
- /* No, no useable data in this section. */
+ /* No, no useable data in this section. */
printf_filtered (_("skipping section %s...\n"),
bfd_section_name (ibfd, isec));
return;
transfer should start and end. */
if (sec_start < data->load_start)
sec_offset = data->load_start - sec_start;
- /* Size of a partial transfer: */
+ /* Size of a partial transfer. */
sec_load_count -= sec_offset;
if (data->load_end > 0 && sec_end > data->load_end)
sec_load_count -= sec_end - data->load_end;
(unsigned long) sec_end);
if (data->load_offset != 0 || data->load_start != 0 || data->load_end != 0)
- printf_filtered (" into memory (0x%s to 0x%s)\n",
- paddr_nz ((unsigned long) sec_start
+ printf_filtered (" into memory (%s to %s)\n",
+ paddress (target_gdbarch (),
+ (unsigned long) sec_start
+ sec_offset + data->load_offset),
- paddr_nz ((unsigned long) sec_start + sec_offset
- + data->load_offset + sec_load_count));
+ paddress (target_gdbarch (),
+ (unsigned long) sec_start + sec_offset
+ + data->load_offset + sec_load_count));
else
puts_filtered ("\n");
restore_binary_file (char *filename, struct callback_data *data)
{
FILE *file = fopen_with_cleanup (filename, FOPEN_RB);
- int status;
gdb_byte *buf;
long len;
/* Get the file size for reading. */
if (fseek (file, 0, SEEK_END) == 0)
- len = ftell (file);
+ {
+ len = ftell (file);
+ if (len < 0)
+ perror_with_name (filename);
+ }
else
perror_with_name (filename);
error (_("Start address is greater than length of binary file %s."),
filename);
- /* Chop off "len" if it exceeds the requested load_end addr. */
+ /* Chop off "len" if it exceeds the requested load_end addr. */
if (data->load_end != 0 && data->load_end < len)
len = data->load_end;
- /* Chop off "len" if the requested load_start addr skips some bytes. */
+ /* Chop off "len" if the requested load_start addr skips some bytes. */
if (data->load_start > 0)
len -= data->load_start;
printf_filtered
("Restoring binary file %s into memory (0x%lx to 0x%lx)\n",
filename,
- (unsigned long) data->load_start + data->load_offset,
- (unsigned long) data->load_start + data->load_offset + len);
+ (unsigned long) (data->load_start + data->load_offset),
+ (unsigned long) (data->load_start + data->load_offset + len));
/* Now set the file pos to the requested load start pos. */
if (fseek (file, data->load_start, SEEK_SET) != 0)
if (fread (buf, 1, len, file) != len)
perror_with_name (filename);
- /* Now write the buffer into target memory. */
+ /* Now write the buffer into target memory. */
len = target_write_memory (data->load_start + data->load_offset, buf, len);
if (len != 0)
warning (_("restore: memory write failed (%s)."), safe_strerror (len));
data.load_start = 0;
data.load_end = 0;
- /* Parse the input arguments. First is filename (required). */
+ /* Parse the input arguments. First is filename (required). */
filename = scan_filename_with_cleanup (&args, NULL);
if (args != NULL && *args != '\0')
{
args += strlen (binary_string);
args = skip_spaces (args);
}
- /* Parse offset (optional). */
+ /* Parse offset (optional). */
if (args != NULL && *args != '\0')
data.load_offset =
- parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
+ parse_and_eval_address (scan_expression_with_cleanup (&args, NULL));
if (args != NULL && *args != '\0')
{
- /* Parse start address (optional). */
+ /* Parse start address (optional). */
data.load_start =
parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
if (args != NULL && *args != '\0')
{
- /* Parse end address (optional). */
+ /* Parse end address (optional). */
data.load_end = parse_and_eval_long (args);
if (data.load_end <= data.load_start)
error (_("Start must be less than end."));
}
else
{
- /* Open the file for loading. */
+ /* Open the file for loading. */
ibfd = bfd_openr_with_cleanup (filename, NULL);
- /* Process the sections. */
+ /* Process the sections. */
bfd_map_over_sections (ibfd, restore_section_callback, &data);
}
return;
_initialize_cli_dump (void)
{
struct cmd_list_element *c;
- add_prefix_cmd ("dump", class_vars, dump_command, _("\
-Dump target code/data to a local file."),
+
+ add_prefix_cmd ("dump", class_vars, dump_command,
+ _("Dump target code/data to a local file."),
&dump_cmdlist, "dump ",
0/*allow-unknown*/,
&cmdlist);
- add_prefix_cmd ("append", class_vars, append_command, _("\
-Append target code/data to a local file."),
+ add_prefix_cmd ("append", class_vars, append_command,
+ _("Append target code/data to a local file."),
&append_cmdlist, "append ",
0/*allow-unknown*/,
&cmdlist);
add_dump_command ("memory", dump_memory_command, "\
Write contents of memory to a raw binary file.\n\
Arguments are FILE START STOP. Writes the contents of memory within the\n\
-range [START .. STOP) to the specifed FILE in raw target ordered bytes.");
+range [START .. STOP) to the specified FILE in raw target ordered bytes.");
add_dump_command ("value", dump_value_command, "\
Write the value of an expression to a raw binary file.\n\
Arguments are FILE EXPRESSION. Writes the value of EXPRESSION to\n\
the specified FILE in raw target ordered bytes.");
- add_prefix_cmd ("srec", all_commands, srec_dump_command, _("\
-Write target code/data to an srec file."),
+ add_prefix_cmd ("srec", all_commands, srec_dump_command,
+ _("Write target code/data to an srec file."),
&srec_cmdlist, "dump srec ",
0 /*allow-unknown*/,
&dump_cmdlist);
- add_prefix_cmd ("ihex", all_commands, ihex_dump_command, _("\
-Write target code/data to an intel hex file."),
+ add_prefix_cmd ("ihex", all_commands, ihex_dump_command,
+ _("Write target code/data to an intel hex file."),
&ihex_cmdlist, "dump ihex ",
0 /*allow-unknown*/,
&dump_cmdlist);
- add_prefix_cmd ("tekhex", all_commands, tekhex_dump_command, _("\
-Write target code/data to a tekhex file."),
+ add_prefix_cmd ("tekhex", all_commands, tekhex_dump_command,
+ _("Write target code/data to a tekhex file."),
&tekhex_cmdlist, "dump tekhex ",
0 /*allow-unknown*/,
&dump_cmdlist);
- add_prefix_cmd ("binary", all_commands, binary_dump_command, _("\
-Write target code/data to a raw binary file."),
+ add_prefix_cmd ("binary", all_commands, binary_dump_command,
+ _("Write target code/data to a raw binary file."),
&binary_dump_cmdlist, "dump binary ",
0 /*allow-unknown*/,
&dump_cmdlist);
- add_prefix_cmd ("binary", all_commands, binary_append_command, _("\
-Append target code/data to a raw binary file."),
+ add_prefix_cmd ("binary", all_commands, binary_append_command,
+ _("Append target code/data to a raw binary file."),
&binary_append_cmdlist, "append binary ",
0 /*allow-unknown*/,
&append_cmdlist);
add_cmd ("memory", all_commands, dump_srec_memory, _("\
Write contents of memory to an srec file.\n\
Arguments are FILE START STOP. Writes the contents of memory\n\
-within the range [START .. STOP) to the specifed FILE in srec format."),
+within the range [START .. STOP) to the specified FILE in srec format."),
&srec_cmdlist);
add_cmd ("value", all_commands, dump_srec_value, _("\
add_cmd ("memory", all_commands, dump_ihex_memory, _("\
Write contents of memory to an ihex file.\n\
Arguments are FILE START STOP. Writes the contents of memory within\n\
-the range [START .. STOP) to the specifed FILE in intel hex format."),
+the range [START .. STOP) to the specified FILE in intel hex format."),
&ihex_cmdlist);
add_cmd ("value", all_commands, dump_ihex_value, _("\
add_cmd ("memory", all_commands, dump_tekhex_memory, _("\
Write contents of memory to a tekhex file.\n\
Arguments are FILE START STOP. Writes the contents of memory\n\
-within the range [START .. STOP) to the specifed FILE in tekhex format."),
+within the range [START .. STOP) to the specified FILE in tekhex format."),
&tekhex_cmdlist);
add_cmd ("value", all_commands, dump_tekhex_value, _("\
add_cmd ("memory", all_commands, dump_binary_memory, _("\
Write contents of memory to a raw binary file.\n\
Arguments are FILE START STOP. Writes the contents of memory\n\
-within the range [START .. STOP) to the specifed FILE in binary format."),
+within the range [START .. STOP) to the specified FILE in binary format."),
&binary_dump_cmdlist);
add_cmd ("value", all_commands, dump_binary_value, _("\
add_cmd ("memory", all_commands, append_binary_memory, _("\
Append contents of memory to a raw binary file.\n\
Arguments are FILE START STOP. Writes the contents of memory within the\n\
-range [START .. STOP) to the specifed FILE in raw target ordered bytes."),
+range [START .. STOP) to the specified FILE in raw target ordered bytes."),
&binary_append_cmdlist);
add_cmd ("value", all_commands, append_binary_value, _("\
If START and END are given, only the file contents within that range\n\
(file relative) will be restored to target memory."));
c->completer = filename_completer;
- /* FIXME: completers for other commands. */
+ /* FIXME: completers for other commands. */
}