1 /* Dump-to-file commands, for GDB, the GNU debugger.
3 Copyright 2002, 2005 Free Software Foundation, Inc.
5 Contributed by Red Hat.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
25 #include "gdb_string.h"
26 #include "cli/cli-decode.h"
27 #include "cli/cli-cmds.h"
29 #include "completer.h"
30 #include "cli/cli-dump.h"
31 #include "gdb_assert.h"
34 #include "readline/readline.h"
36 #define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
40 skip_spaces (char *chp)
44 while (isspace (*chp))
50 scan_expression_with_cleanup (char **cmd, const char *def)
52 if ((*cmd) == NULL || (**cmd) == '\0')
54 char *exp = xstrdup (def);
55 make_cleanup (xfree, exp);
63 end = (*cmd) + strcspn (*cmd, " \t");
64 exp = savestring ((*cmd), end - (*cmd));
65 make_cleanup (xfree, exp);
66 (*cmd) = skip_spaces (end);
73 do_fclose_cleanup (void *arg)
79 static struct cleanup *
80 make_cleanup_fclose (FILE *file)
82 return make_cleanup (do_fclose_cleanup, file);
86 scan_filename_with_cleanup (char **cmd, const char *defname)
91 /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere. */
97 error (_("Missing filename."));
98 filename = xstrdup (defname);
99 make_cleanup (xfree, filename);
103 /* FIXME: should parse a possibly quoted string. */
106 (*cmd) = skip_spaces (*cmd);
107 end = *cmd + strcspn (*cmd, " \t");
108 filename = savestring ((*cmd), end - (*cmd));
109 make_cleanup (xfree, filename);
110 (*cmd) = skip_spaces (end);
112 gdb_assert (filename != NULL);
114 fullname = tilde_expand (filename);
115 make_cleanup (xfree, fullname);
121 fopen_with_cleanup (const char *filename, const char *mode)
123 FILE *file = fopen (filename, mode);
125 perror_with_name (filename);
126 make_cleanup_fclose (file);
131 bfd_openr_with_cleanup (const char *filename, const char *target)
135 ibfd = bfd_openr (filename, target);
137 error (_("Failed to open %s: %s."), filename,
138 bfd_errmsg (bfd_get_error ()));
140 make_cleanup_bfd_close (ibfd);
141 if (!bfd_check_format (ibfd, bfd_object))
142 error (_("'%s' is not a recognized file format."), filename);
148 bfd_openw_with_cleanup (const char *filename, const char *target,
153 if (*mode == 'w') /* Write: create new file */
155 obfd = bfd_openw (filename, target);
157 error (_("Failed to open %s: %s."), filename,
158 bfd_errmsg (bfd_get_error ()));
159 make_cleanup_bfd_close (obfd);
160 if (!bfd_set_format (obfd, bfd_object))
161 error (_("bfd_openw_with_cleanup: %s."), bfd_errmsg (bfd_get_error ()));
163 else if (*mode == 'a') /* Append to existing file */
164 { /* FIXME -- doesn't work... */
165 error (_("bfd_openw does not work with append."));
168 error (_("bfd_openw_with_cleanup: unknown mode %s."), mode);
173 struct cmd_list_element *dump_cmdlist;
174 struct cmd_list_element *append_cmdlist;
175 struct cmd_list_element *srec_cmdlist;
176 struct cmd_list_element *ihex_cmdlist;
177 struct cmd_list_element *tekhex_cmdlist;
178 struct cmd_list_element *binary_dump_cmdlist;
179 struct cmd_list_element *binary_append_cmdlist;
182 dump_command (char *cmd, int from_tty)
184 printf_unfiltered (_("\"dump\" must be followed by a subcommand.\n\n"));
185 help_list (dump_cmdlist, "dump ", -1, gdb_stdout);
189 append_command (char *cmd, int from_tty)
191 printf_unfiltered (_("\"append\" must be followed by a subcommand.\n\n"));
192 help_list (dump_cmdlist, "append ", -1, gdb_stdout);
196 dump_binary_file (const char *filename, const char *mode,
197 const bfd_byte *buf, int len)
202 file = fopen_with_cleanup (filename, mode);
203 status = fwrite (buf, len, 1, file);
205 perror_with_name (filename);
209 dump_bfd_file (const char *filename, const char *mode,
210 const char *target, CORE_ADDR vaddr,
211 const bfd_byte *buf, int len)
216 obfd = bfd_openw_with_cleanup (filename, target, mode);
217 osection = bfd_make_section_anyway (obfd, ".newsec");
218 bfd_set_section_size (obfd, osection, len);
219 bfd_set_section_vma (obfd, osection, vaddr);
220 bfd_set_section_alignment (obfd, osection, 0);
221 bfd_set_section_flags (obfd, osection, (SEC_HAS_CONTENTS
224 osection->entsize = 0;
225 bfd_set_section_contents (obfd, osection, buf, 0, len);
229 dump_memory_to_file (char *cmd, char *mode, char *file_format)
231 struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
242 filename = scan_filename_with_cleanup (&cmd, NULL);
244 /* Find the low address. */
245 if (cmd == NULL || *cmd == '\0')
246 error (_("Missing start address."));
247 lo_exp = scan_expression_with_cleanup (&cmd, NULL);
249 /* Find the second address - rest of line. */
250 if (cmd == NULL || *cmd == '\0')
251 error (_("Missing stop address."));
254 lo = parse_and_eval_address (lo_exp);
255 hi = parse_and_eval_address (hi_exp);
257 error (_("Invalid memory address range (start >= end)."));
260 /* FIXME: Should use read_memory_partial() and a magic blocking
262 buf = xmalloc (count);
263 make_cleanup (xfree, buf);
264 target_read_memory (lo, buf, count);
266 /* Have everything. Open/write the data. */
267 if (file_format == NULL || strcmp (file_format, "binary") == 0)
269 dump_binary_file (filename, mode, buf, count);
273 dump_bfd_file (filename, mode, file_format, lo, buf, count);
276 do_cleanups (old_cleanups);
280 dump_memory_command (char *cmd, char *mode)
282 dump_memory_to_file (cmd, mode, "binary");
286 dump_value_to_file (char *cmd, char *mode, char *file_format)
288 struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
293 filename = scan_filename_with_cleanup (&cmd, NULL);
295 /* Find the value. */
296 if (cmd == NULL || *cmd == '\0')
297 error (_("No value to %s."), *mode == 'a' ? "append" : "dump");
298 val = parse_and_eval (cmd);
300 error (_("Invalid expression."));
302 /* Have everything. Open/write the data. */
303 if (file_format == NULL || strcmp (file_format, "binary") == 0)
305 dump_binary_file (filename, mode, value_contents (val),
306 TYPE_LENGTH (value_type (val)));
312 if (VALUE_LVAL (val))
314 vaddr = VALUE_ADDRESS (val);
319 warning (_("value is not an lval: address assumed to be zero"));
322 dump_bfd_file (filename, mode, file_format, vaddr,
323 value_contents (val),
324 TYPE_LENGTH (value_type (val)));
327 do_cleanups (old_cleanups);
331 dump_value_command (char *cmd, char *mode)
333 dump_value_to_file (cmd, mode, "binary");
337 dump_srec_memory (char *args, int from_tty)
339 dump_memory_to_file (args, FOPEN_WB, "srec");
343 dump_srec_value (char *args, int from_tty)
345 dump_value_to_file (args, FOPEN_WB, "srec");
349 dump_ihex_memory (char *args, int from_tty)
351 dump_memory_to_file (args, FOPEN_WB, "ihex");
355 dump_ihex_value (char *args, int from_tty)
357 dump_value_to_file (args, FOPEN_WB, "ihex");
361 dump_tekhex_memory (char *args, int from_tty)
363 dump_memory_to_file (args, FOPEN_WB, "tekhex");
367 dump_tekhex_value (char *args, int from_tty)
369 dump_value_to_file (args, FOPEN_WB, "tekhex");
373 dump_binary_memory (char *args, int from_tty)
375 dump_memory_to_file (args, FOPEN_WB, "binary");
379 dump_binary_value (char *args, int from_tty)
381 dump_value_to_file (args, FOPEN_WB, "binary");
385 append_binary_memory (char *args, int from_tty)
387 dump_memory_to_file (args, FOPEN_AB, "binary");
391 append_binary_value (char *args, int from_tty)
393 dump_value_to_file (args, FOPEN_AB, "binary");
398 void (*func) (char *cmd, char *mode);
403 call_dump_func (struct cmd_list_element *c, char *args, int from_tty)
405 struct dump_context *d = get_cmd_context (c);
406 d->func (args, d->mode);
410 add_dump_command (char *name, void (*func) (char *args, char *mode),
414 struct cmd_list_element *c;
415 struct dump_context *d;
417 c = add_cmd (name, all_commands, NULL, descr, &dump_cmdlist);
418 c->completer = filename_completer;
419 d = XMALLOC (struct dump_context);
422 set_cmd_context (c, d);
423 c->func = call_dump_func;
425 c = add_cmd (name, all_commands, NULL, descr, &append_cmdlist);
426 c->completer = filename_completer;
427 d = XMALLOC (struct dump_context);
430 set_cmd_context (c, d);
431 c->func = call_dump_func;
433 /* Replace "Dump " at start of docstring with "Append " (borrowed
434 from [deleted] deprecated_add_show_from_set). */
435 if ( c->doc[0] == 'W'
441 c->doc = concat ("Append ", c->doc + 6, NULL);
444 /* Opaque data for restore_section_callback. */
445 struct callback_data {
446 unsigned long load_offset;
447 CORE_ADDR load_start;
451 /* Function: restore_section_callback.
453 Callback function for bfd_map_over_sections.
454 Selectively loads the sections into memory. */
457 restore_section_callback (bfd *ibfd, asection *isec, void *args)
459 struct callback_data *data = args;
460 bfd_vma sec_start = bfd_section_vma (ibfd, isec);
461 bfd_size_type size = bfd_section_size (ibfd, isec);
462 bfd_vma sec_end = sec_start + size;
463 bfd_size_type sec_offset = 0;
464 bfd_size_type sec_load_count = size;
465 struct cleanup *old_chain;
469 /* Ignore non-loadable sections, eg. from elf files. */
470 if (!(bfd_get_section_flags (ibfd, isec) & SEC_LOAD))
473 /* Does the section overlap with the desired restore range? */
474 if (sec_end <= data->load_start
475 || (data->load_end > 0 && sec_start >= data->load_end))
477 /* No, no useable data in this section. */
478 printf_filtered (_("skipping section %s...\n"),
479 bfd_section_name (ibfd, isec));
483 /* Compare section address range with user-requested
484 address range (if any). Compute where the actual
485 transfer should start and end. */
486 if (sec_start < data->load_start)
487 sec_offset = data->load_start - sec_start;
488 /* Size of a partial transfer: */
489 sec_load_count -= sec_offset;
490 if (data->load_end > 0 && sec_end > data->load_end)
491 sec_load_count -= sec_end - data->load_end;
494 buf = xmalloc (size);
495 old_chain = make_cleanup (xfree, buf);
496 if (!bfd_get_section_contents (ibfd, isec, buf, 0, size))
497 error (_("Failed to read bfd file %s: '%s'."), bfd_get_filename (ibfd),
498 bfd_errmsg (bfd_get_error ()));
500 printf_filtered ("Restoring section %s (0x%lx to 0x%lx)",
501 bfd_section_name (ibfd, isec),
502 (unsigned long) sec_start,
503 (unsigned long) sec_end);
505 if (data->load_offset != 0 || data->load_start != 0 || data->load_end != 0)
506 printf_filtered (" into memory (0x%s to 0x%s)\n",
507 paddr_nz ((unsigned long) sec_start
508 + sec_offset + data->load_offset),
509 paddr_nz ((unsigned long) sec_start + sec_offset
510 + data->load_offset + sec_load_count));
512 puts_filtered ("\n");
514 /* Write the data. */
515 ret = target_write_memory (sec_start + sec_offset + data->load_offset,
516 buf + sec_offset, sec_load_count);
518 warning (_("restore: memory write failed (%s)."), safe_strerror (ret));
519 do_cleanups (old_chain);
524 restore_binary_file (char *filename, struct callback_data *data)
526 FILE *file = fopen_with_cleanup (filename, FOPEN_RB);
531 /* Get the file size for reading. */
532 if (fseek (file, 0, SEEK_END) == 0)
535 perror_with_name (filename);
537 if (len <= data->load_start)
538 error (_("Start address is greater than length of binary file %s."),
541 /* Chop off "len" if it exceeds the requested load_end addr. */
542 if (data->load_end != 0 && data->load_end < len)
543 len = data->load_end;
544 /* Chop off "len" if the requested load_start addr skips some bytes. */
545 if (data->load_start > 0)
546 len -= data->load_start;
549 ("Restoring binary file %s into memory (0x%lx to 0x%lx)\n",
551 (unsigned long) data->load_start + data->load_offset,
552 (unsigned long) data->load_start + data->load_offset + len);
554 /* Now set the file pos to the requested load start pos. */
555 if (fseek (file, data->load_start, SEEK_SET) != 0)
556 perror_with_name (filename);
558 /* Now allocate a buffer and read the file contents. */
560 make_cleanup (xfree, buf);
561 if (fread (buf, 1, len, file) != len)
562 perror_with_name (filename);
564 /* Now write the buffer into target memory. */
565 len = target_write_memory (data->load_start + data->load_offset, buf, len);
567 warning (_("restore: memory write failed (%s)."), safe_strerror (len));
572 restore_command (char *args, int from_tty)
575 struct callback_data data;
579 if (!target_has_execution)
582 data.load_offset = 0;
586 /* Parse the input arguments. First is filename (required). */
587 filename = scan_filename_with_cleanup (&args, NULL);
588 if (args != NULL && *args != '\0')
590 char *binary_string = "binary";
592 /* Look for optional "binary" flag. */
593 if (strncmp (args, binary_string, strlen (binary_string)) == 0)
596 args += strlen (binary_string);
597 args = skip_spaces (args);
599 /* Parse offset (optional). */
600 if (args != NULL && *args != '\0')
602 parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
603 if (args != NULL && *args != '\0')
605 /* Parse start address (optional). */
607 parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
608 if (args != NULL && *args != '\0')
610 /* Parse end address (optional). */
611 data.load_end = parse_and_eval_long (args);
612 if (data.load_end <= data.load_start)
613 error (_("Start must be less than end."));
619 printf_filtered ("Restore file %s offset 0x%lx start 0x%lx end 0x%lx\n",
620 filename, (unsigned long) data.load_offset,
621 (unsigned long) data.load_start,
622 (unsigned long) data.load_end);
626 restore_binary_file (filename, &data);
630 /* Open the file for loading. */
631 ibfd = bfd_openr_with_cleanup (filename, NULL);
633 /* Process the sections. */
634 bfd_map_over_sections (ibfd, restore_section_callback, &data);
640 srec_dump_command (char *cmd, int from_tty)
642 printf_unfiltered ("\"dump srec\" must be followed by a subcommand.\n");
643 help_list (srec_cmdlist, "dump srec ", -1, gdb_stdout);
647 ihex_dump_command (char *cmd, int from_tty)
649 printf_unfiltered ("\"dump ihex\" must be followed by a subcommand.\n");
650 help_list (ihex_cmdlist, "dump ihex ", -1, gdb_stdout);
654 tekhex_dump_command (char *cmd, int from_tty)
656 printf_unfiltered ("\"dump tekhex\" must be followed by a subcommand.\n");
657 help_list (tekhex_cmdlist, "dump tekhex ", -1, gdb_stdout);
661 binary_dump_command (char *cmd, int from_tty)
663 printf_unfiltered ("\"dump binary\" must be followed by a subcommand.\n");
664 help_list (binary_dump_cmdlist, "dump binary ", -1, gdb_stdout);
668 binary_append_command (char *cmd, int from_tty)
670 printf_unfiltered ("\"append binary\" must be followed by a subcommand.\n");
671 help_list (binary_append_cmdlist, "append binary ", -1, gdb_stdout);
674 extern initialize_file_ftype _initialize_cli_dump; /* -Wmissing-prototypes */
677 _initialize_cli_dump (void)
679 struct cmd_list_element *c;
680 add_prefix_cmd ("dump", class_vars, dump_command, _("\
681 Dump target code/data to a local file."),
682 &dump_cmdlist, "dump ",
685 add_prefix_cmd ("append", class_vars, append_command, _("\
686 Append target code/data to a local file."),
687 &append_cmdlist, "append ",
691 add_dump_command ("memory", dump_memory_command, "\
692 Write contents of memory to a raw binary file.\n\
693 Arguments are FILE START STOP. Writes the contents of memory within the\n\
694 range [START .. STOP) to the specifed FILE in raw target ordered bytes.");
696 add_dump_command ("value", dump_value_command, "\
697 Write the value of an expression to a raw binary file.\n\
698 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION to\n\
699 the specified FILE in raw target ordered bytes.");
701 add_prefix_cmd ("srec", all_commands, srec_dump_command, _("\
702 Write target code/data to an srec file."),
703 &srec_cmdlist, "dump srec ",
707 add_prefix_cmd ("ihex", all_commands, ihex_dump_command, _("\
708 Write target code/data to an intel hex file."),
709 &ihex_cmdlist, "dump ihex ",
713 add_prefix_cmd ("tekhex", all_commands, tekhex_dump_command, _("\
714 Write target code/data to a tekhex file."),
715 &tekhex_cmdlist, "dump tekhex ",
719 add_prefix_cmd ("binary", all_commands, binary_dump_command, _("\
720 Write target code/data to a raw binary file."),
721 &binary_dump_cmdlist, "dump binary ",
725 add_prefix_cmd ("binary", all_commands, binary_append_command, _("\
726 Append target code/data to a raw binary file."),
727 &binary_append_cmdlist, "append binary ",
731 add_cmd ("memory", all_commands, dump_srec_memory, _("\
732 Write contents of memory to an srec file.\n\
733 Arguments are FILE START STOP. Writes the contents of memory\n\
734 within the range [START .. STOP) to the specifed FILE in srec format."),
737 add_cmd ("value", all_commands, dump_srec_value, _("\
738 Write the value of an expression to an srec file.\n\
739 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
740 to the specified FILE in srec format."),
743 add_cmd ("memory", all_commands, dump_ihex_memory, _("\
744 Write contents of memory to an ihex file.\n\
745 Arguments are FILE START STOP. Writes the contents of memory within\n\
746 the range [START .. STOP) to the specifed FILE in intel hex format."),
749 add_cmd ("value", all_commands, dump_ihex_value, _("\
750 Write the value of an expression to an ihex file.\n\
751 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
752 to the specified FILE in intel hex format."),
755 add_cmd ("memory", all_commands, dump_tekhex_memory, _("\
756 Write contents of memory to a tekhex file.\n\
757 Arguments are FILE START STOP. Writes the contents of memory\n\
758 within the range [START .. STOP) to the specifed FILE in tekhex format."),
761 add_cmd ("value", all_commands, dump_tekhex_value, _("\
762 Write the value of an expression to a tekhex file.\n\
763 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
764 to the specified FILE in tekhex format."),
767 add_cmd ("memory", all_commands, dump_binary_memory, _("\
768 Write contents of memory to a raw binary file.\n\
769 Arguments are FILE START STOP. Writes the contents of memory\n\
770 within the range [START .. STOP) to the specifed FILE in binary format."),
771 &binary_dump_cmdlist);
773 add_cmd ("value", all_commands, dump_binary_value, _("\
774 Write the value of an expression to a raw binary file.\n\
775 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
776 to the specified FILE in raw target ordered bytes."),
777 &binary_dump_cmdlist);
779 add_cmd ("memory", all_commands, append_binary_memory, _("\
780 Append contents of memory to a raw binary file.\n\
781 Arguments are FILE START STOP. Writes the contents of memory within the\n\
782 range [START .. STOP) to the specifed FILE in raw target ordered bytes."),
783 &binary_append_cmdlist);
785 add_cmd ("value", all_commands, append_binary_value, _("\
786 Append the value of an expression to a raw binary file.\n\
787 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
788 to the specified FILE in raw target ordered bytes."),
789 &binary_append_cmdlist);
791 c = add_com ("restore", class_vars, restore_command, _("\
792 Restore the contents of FILE to target memory.\n\
793 Arguments are FILE OFFSET START END where all except FILE are optional.\n\
794 OFFSET will be added to the base address of the file (default zero).\n\
795 If START and END are given, only the file contents within that range\n\
796 (file relative) will be restored to target memory."));
797 c->completer = filename_completer;
798 /* FIXME: completers for other commands. */