xref: /dflybsd-src/contrib/gdb-7/gdb/cli/cli-dump.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Dump-to-file commands, for GDB, the GNU debugger.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 2002-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    Contributed by Red Hat.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This file is part of GDB.
85796c8dcSSimon Schubert 
95796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert    (at your option) any later version.
135796c8dcSSimon Schubert 
145796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175796c8dcSSimon Schubert    GNU General Public License for more details.
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert #include "defs.h"
235796c8dcSSimon Schubert #include "gdb_string.h"
245796c8dcSSimon Schubert #include "cli/cli-decode.h"
255796c8dcSSimon Schubert #include "cli/cli-cmds.h"
265796c8dcSSimon Schubert #include "value.h"
275796c8dcSSimon Schubert #include "completer.h"
285796c8dcSSimon Schubert #include "cli/cli-dump.h"
295796c8dcSSimon Schubert #include "gdb_assert.h"
305796c8dcSSimon Schubert #include <ctype.h>
315796c8dcSSimon Schubert #include "target.h"
325796c8dcSSimon Schubert #include "readline/readline.h"
335796c8dcSSimon Schubert #include "gdbcore.h"
34c50c785cSJohn Marino #include "cli/cli-utils.h"
35*ef5ccd6cSJohn Marino #include "gdb_bfd.h"
365796c8dcSSimon Schubert 
375796c8dcSSimon Schubert #define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
385796c8dcSSimon Schubert 
395796c8dcSSimon Schubert 
405796c8dcSSimon Schubert char *
scan_expression_with_cleanup(char ** cmd,const char * def)415796c8dcSSimon Schubert scan_expression_with_cleanup (char **cmd, const char *def)
425796c8dcSSimon Schubert {
435796c8dcSSimon Schubert   if ((*cmd) == NULL || (**cmd) == '\0')
445796c8dcSSimon Schubert     {
455796c8dcSSimon Schubert       char *exp = xstrdup (def);
46cf7f2e2dSJohn Marino 
475796c8dcSSimon Schubert       make_cleanup (xfree, exp);
485796c8dcSSimon Schubert       return exp;
495796c8dcSSimon Schubert     }
505796c8dcSSimon Schubert   else
515796c8dcSSimon Schubert     {
525796c8dcSSimon Schubert       char *exp;
535796c8dcSSimon Schubert       char *end;
545796c8dcSSimon Schubert 
555796c8dcSSimon Schubert       end = (*cmd) + strcspn (*cmd, " \t");
565796c8dcSSimon Schubert       exp = savestring ((*cmd), end - (*cmd));
575796c8dcSSimon Schubert       make_cleanup (xfree, exp);
585796c8dcSSimon Schubert       (*cmd) = skip_spaces (end);
595796c8dcSSimon Schubert       return exp;
605796c8dcSSimon Schubert     }
615796c8dcSSimon Schubert }
625796c8dcSSimon Schubert 
635796c8dcSSimon Schubert 
645796c8dcSSimon Schubert char *
scan_filename_with_cleanup(char ** cmd,const char * defname)655796c8dcSSimon Schubert scan_filename_with_cleanup (char **cmd, const char *defname)
665796c8dcSSimon Schubert {
675796c8dcSSimon Schubert   char *filename;
685796c8dcSSimon Schubert   char *fullname;
695796c8dcSSimon Schubert 
705796c8dcSSimon Schubert   /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere.  */
715796c8dcSSimon Schubert 
725796c8dcSSimon Schubert   /* File.  */
735796c8dcSSimon Schubert   if ((*cmd) == NULL)
745796c8dcSSimon Schubert     {
755796c8dcSSimon Schubert       if (defname == NULL)
765796c8dcSSimon Schubert 	error (_("Missing filename."));
775796c8dcSSimon Schubert       filename = xstrdup (defname);
785796c8dcSSimon Schubert       make_cleanup (xfree, filename);
795796c8dcSSimon Schubert     }
805796c8dcSSimon Schubert   else
815796c8dcSSimon Schubert     {
825796c8dcSSimon Schubert       /* FIXME: should parse a possibly quoted string.  */
835796c8dcSSimon Schubert       char *end;
845796c8dcSSimon Schubert 
855796c8dcSSimon Schubert       (*cmd) = skip_spaces (*cmd);
865796c8dcSSimon Schubert       end = *cmd + strcspn (*cmd, " \t");
875796c8dcSSimon Schubert       filename = savestring ((*cmd), end - (*cmd));
885796c8dcSSimon Schubert       make_cleanup (xfree, filename);
895796c8dcSSimon Schubert       (*cmd) = skip_spaces (end);
905796c8dcSSimon Schubert     }
915796c8dcSSimon Schubert   gdb_assert (filename != NULL);
925796c8dcSSimon Schubert 
935796c8dcSSimon Schubert   fullname = tilde_expand (filename);
945796c8dcSSimon Schubert   make_cleanup (xfree, fullname);
955796c8dcSSimon Schubert 
965796c8dcSSimon Schubert   return fullname;
975796c8dcSSimon Schubert }
985796c8dcSSimon Schubert 
995796c8dcSSimon Schubert FILE *
fopen_with_cleanup(const char * filename,const char * mode)1005796c8dcSSimon Schubert fopen_with_cleanup (const char *filename, const char *mode)
1015796c8dcSSimon Schubert {
1025796c8dcSSimon Schubert   FILE *file = fopen (filename, mode);
103cf7f2e2dSJohn Marino 
1045796c8dcSSimon Schubert   if (file == NULL)
1055796c8dcSSimon Schubert     perror_with_name (filename);
1065796c8dcSSimon Schubert   make_cleanup_fclose (file);
1075796c8dcSSimon Schubert   return file;
1085796c8dcSSimon Schubert }
1095796c8dcSSimon Schubert 
1105796c8dcSSimon Schubert static bfd *
bfd_openr_with_cleanup(const char * filename,const char * target)1115796c8dcSSimon Schubert bfd_openr_with_cleanup (const char *filename, const char *target)
1125796c8dcSSimon Schubert {
1135796c8dcSSimon Schubert   bfd *ibfd;
1145796c8dcSSimon Schubert 
115*ef5ccd6cSJohn Marino   ibfd = gdb_bfd_openr (filename, target);
1165796c8dcSSimon Schubert   if (ibfd == NULL)
1175796c8dcSSimon Schubert     error (_("Failed to open %s: %s."), filename,
1185796c8dcSSimon Schubert 	   bfd_errmsg (bfd_get_error ()));
1195796c8dcSSimon Schubert 
120*ef5ccd6cSJohn Marino   make_cleanup_bfd_unref (ibfd);
1215796c8dcSSimon Schubert   if (!bfd_check_format (ibfd, bfd_object))
1225796c8dcSSimon Schubert     error (_("'%s' is not a recognized file format."), filename);
1235796c8dcSSimon Schubert 
1245796c8dcSSimon Schubert   return ibfd;
1255796c8dcSSimon Schubert }
1265796c8dcSSimon Schubert 
1275796c8dcSSimon Schubert static bfd *
bfd_openw_with_cleanup(const char * filename,const char * target,const char * mode)1285796c8dcSSimon Schubert bfd_openw_with_cleanup (const char *filename, const char *target,
1295796c8dcSSimon Schubert 			const char *mode)
1305796c8dcSSimon Schubert {
1315796c8dcSSimon Schubert   bfd *obfd;
1325796c8dcSSimon Schubert 
1335796c8dcSSimon Schubert   if (*mode == 'w')	/* Write: create new file */
1345796c8dcSSimon Schubert     {
135*ef5ccd6cSJohn Marino       obfd = gdb_bfd_openw (filename, target);
1365796c8dcSSimon Schubert       if (obfd == NULL)
1375796c8dcSSimon Schubert 	error (_("Failed to open %s: %s."), filename,
1385796c8dcSSimon Schubert 	       bfd_errmsg (bfd_get_error ()));
139*ef5ccd6cSJohn Marino       make_cleanup_bfd_unref (obfd);
1405796c8dcSSimon Schubert       if (!bfd_set_format (obfd, bfd_object))
1415796c8dcSSimon Schubert 	error (_("bfd_openw_with_cleanup: %s."), bfd_errmsg (bfd_get_error ()));
1425796c8dcSSimon Schubert     }
143c50c785cSJohn Marino   else if (*mode == 'a')	/* Append to existing file.  */
1445796c8dcSSimon Schubert     {	/* FIXME -- doesn't work...  */
1455796c8dcSSimon Schubert       error (_("bfd_openw does not work with append."));
1465796c8dcSSimon Schubert     }
1475796c8dcSSimon Schubert   else
1485796c8dcSSimon Schubert     error (_("bfd_openw_with_cleanup: unknown mode %s."), mode);
1495796c8dcSSimon Schubert 
1505796c8dcSSimon Schubert   return obfd;
1515796c8dcSSimon Schubert }
1525796c8dcSSimon Schubert 
153*ef5ccd6cSJohn Marino static struct cmd_list_element *dump_cmdlist;
154*ef5ccd6cSJohn Marino static struct cmd_list_element *append_cmdlist;
155*ef5ccd6cSJohn Marino static struct cmd_list_element *srec_cmdlist;
156*ef5ccd6cSJohn Marino static struct cmd_list_element *ihex_cmdlist;
157*ef5ccd6cSJohn Marino static struct cmd_list_element *tekhex_cmdlist;
158*ef5ccd6cSJohn Marino static struct cmd_list_element *binary_dump_cmdlist;
159*ef5ccd6cSJohn Marino static struct cmd_list_element *binary_append_cmdlist;
1605796c8dcSSimon Schubert 
1615796c8dcSSimon Schubert static void
dump_command(char * cmd,int from_tty)1625796c8dcSSimon Schubert dump_command (char *cmd, int from_tty)
1635796c8dcSSimon Schubert {
1645796c8dcSSimon Schubert   printf_unfiltered (_("\"dump\" must be followed by a subcommand.\n\n"));
1655796c8dcSSimon Schubert   help_list (dump_cmdlist, "dump ", -1, gdb_stdout);
1665796c8dcSSimon Schubert }
1675796c8dcSSimon Schubert 
1685796c8dcSSimon Schubert static void
append_command(char * cmd,int from_tty)1695796c8dcSSimon Schubert append_command (char *cmd, int from_tty)
1705796c8dcSSimon Schubert {
1715796c8dcSSimon Schubert   printf_unfiltered (_("\"append\" must be followed by a subcommand.\n\n"));
1725796c8dcSSimon Schubert   help_list (dump_cmdlist, "append ", -1, gdb_stdout);
1735796c8dcSSimon Schubert }
1745796c8dcSSimon Schubert 
1755796c8dcSSimon Schubert static void
dump_binary_file(const char * filename,const char * mode,const bfd_byte * buf,ULONGEST len)1765796c8dcSSimon Schubert dump_binary_file (const char *filename, const char *mode,
177a45ae5f8SJohn Marino 		  const bfd_byte *buf, ULONGEST len)
1785796c8dcSSimon Schubert {
1795796c8dcSSimon Schubert   FILE *file;
1805796c8dcSSimon Schubert   int status;
1815796c8dcSSimon Schubert 
1825796c8dcSSimon Schubert   file = fopen_with_cleanup (filename, mode);
1835796c8dcSSimon Schubert   status = fwrite (buf, len, 1, file);
1845796c8dcSSimon Schubert   if (status != 1)
1855796c8dcSSimon Schubert     perror_with_name (filename);
1865796c8dcSSimon Schubert }
1875796c8dcSSimon Schubert 
1885796c8dcSSimon Schubert static void
dump_bfd_file(const char * filename,const char * mode,const char * target,CORE_ADDR vaddr,const bfd_byte * buf,ULONGEST len)1895796c8dcSSimon Schubert dump_bfd_file (const char *filename, const char *mode,
1905796c8dcSSimon Schubert 	       const char *target, CORE_ADDR vaddr,
191a45ae5f8SJohn Marino 	       const bfd_byte *buf, ULONGEST len)
1925796c8dcSSimon Schubert {
1935796c8dcSSimon Schubert   bfd *obfd;
1945796c8dcSSimon Schubert   asection *osection;
1955796c8dcSSimon Schubert 
1965796c8dcSSimon Schubert   obfd = bfd_openw_with_cleanup (filename, target, mode);
1975796c8dcSSimon Schubert   osection = bfd_make_section_anyway (obfd, ".newsec");
1985796c8dcSSimon Schubert   bfd_set_section_size (obfd, osection, len);
1995796c8dcSSimon Schubert   bfd_set_section_vma (obfd, osection, vaddr);
2005796c8dcSSimon Schubert   bfd_set_section_alignment (obfd, osection, 0);
2015796c8dcSSimon Schubert   bfd_set_section_flags (obfd, osection, (SEC_HAS_CONTENTS
2025796c8dcSSimon Schubert 					  | SEC_ALLOC
2035796c8dcSSimon Schubert 					  | SEC_LOAD));
2045796c8dcSSimon Schubert   osection->entsize = 0;
205c50c785cSJohn Marino   if (!bfd_set_section_contents (obfd, osection, buf, 0, len))
206c50c785cSJohn Marino     warning (_("writing dump file '%s' (%s)"), filename,
207c50c785cSJohn Marino 	     bfd_errmsg (bfd_get_error ()));
2085796c8dcSSimon Schubert }
2095796c8dcSSimon Schubert 
2105796c8dcSSimon Schubert static void
dump_memory_to_file(char * cmd,char * mode,char * file_format)2115796c8dcSSimon Schubert dump_memory_to_file (char *cmd, char *mode, char *file_format)
2125796c8dcSSimon Schubert {
2135796c8dcSSimon Schubert   struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
2145796c8dcSSimon Schubert   CORE_ADDR lo;
2155796c8dcSSimon Schubert   CORE_ADDR hi;
2165796c8dcSSimon Schubert   ULONGEST count;
2175796c8dcSSimon Schubert   char *filename;
2185796c8dcSSimon Schubert   void *buf;
2195796c8dcSSimon Schubert   char *lo_exp;
2205796c8dcSSimon Schubert   char *hi_exp;
2215796c8dcSSimon Schubert 
2225796c8dcSSimon Schubert   /* Open the file.  */
2235796c8dcSSimon Schubert   filename = scan_filename_with_cleanup (&cmd, NULL);
2245796c8dcSSimon Schubert 
2255796c8dcSSimon Schubert   /* Find the low address.  */
2265796c8dcSSimon Schubert   if (cmd == NULL || *cmd == '\0')
2275796c8dcSSimon Schubert     error (_("Missing start address."));
2285796c8dcSSimon Schubert   lo_exp = scan_expression_with_cleanup (&cmd, NULL);
2295796c8dcSSimon Schubert 
2305796c8dcSSimon Schubert   /* Find the second address - rest of line.  */
2315796c8dcSSimon Schubert   if (cmd == NULL || *cmd == '\0')
2325796c8dcSSimon Schubert     error (_("Missing stop address."));
2335796c8dcSSimon Schubert   hi_exp = cmd;
2345796c8dcSSimon Schubert 
2355796c8dcSSimon Schubert   lo = parse_and_eval_address (lo_exp);
2365796c8dcSSimon Schubert   hi = parse_and_eval_address (hi_exp);
2375796c8dcSSimon Schubert   if (hi <= lo)
2385796c8dcSSimon Schubert     error (_("Invalid memory address range (start >= end)."));
2395796c8dcSSimon Schubert   count = hi - lo;
2405796c8dcSSimon Schubert 
2415796c8dcSSimon Schubert   /* FIXME: Should use read_memory_partial() and a magic blocking
2425796c8dcSSimon Schubert      value.  */
2435796c8dcSSimon Schubert   buf = xmalloc (count);
2445796c8dcSSimon Schubert   make_cleanup (xfree, buf);
2455796c8dcSSimon Schubert   read_memory (lo, buf, count);
2465796c8dcSSimon Schubert 
2475796c8dcSSimon Schubert   /* Have everything.  Open/write the data.  */
2485796c8dcSSimon Schubert   if (file_format == NULL || strcmp (file_format, "binary") == 0)
2495796c8dcSSimon Schubert     {
2505796c8dcSSimon Schubert       dump_binary_file (filename, mode, buf, count);
2515796c8dcSSimon Schubert     }
2525796c8dcSSimon Schubert   else
2535796c8dcSSimon Schubert     {
2545796c8dcSSimon Schubert       dump_bfd_file (filename, mode, file_format, lo, buf, count);
2555796c8dcSSimon Schubert     }
2565796c8dcSSimon Schubert 
2575796c8dcSSimon Schubert   do_cleanups (old_cleanups);
2585796c8dcSSimon Schubert }
2595796c8dcSSimon Schubert 
2605796c8dcSSimon Schubert static void
dump_memory_command(char * cmd,char * mode)2615796c8dcSSimon Schubert dump_memory_command (char *cmd, char *mode)
2625796c8dcSSimon Schubert {
2635796c8dcSSimon Schubert   dump_memory_to_file (cmd, mode, "binary");
2645796c8dcSSimon Schubert }
2655796c8dcSSimon Schubert 
2665796c8dcSSimon Schubert static void
dump_value_to_file(char * cmd,char * mode,char * file_format)2675796c8dcSSimon Schubert dump_value_to_file (char *cmd, char *mode, char *file_format)
2685796c8dcSSimon Schubert {
2695796c8dcSSimon Schubert   struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
2705796c8dcSSimon Schubert   struct value *val;
2715796c8dcSSimon Schubert   char *filename;
2725796c8dcSSimon Schubert 
2735796c8dcSSimon Schubert   /* Open the file.  */
2745796c8dcSSimon Schubert   filename = scan_filename_with_cleanup (&cmd, NULL);
2755796c8dcSSimon Schubert 
2765796c8dcSSimon Schubert   /* Find the value.  */
2775796c8dcSSimon Schubert   if (cmd == NULL || *cmd == '\0')
2785796c8dcSSimon Schubert     error (_("No value to %s."), *mode == 'a' ? "append" : "dump");
2795796c8dcSSimon Schubert   val = parse_and_eval (cmd);
2805796c8dcSSimon Schubert   if (val == NULL)
2815796c8dcSSimon Schubert     error (_("Invalid expression."));
2825796c8dcSSimon Schubert 
2835796c8dcSSimon Schubert   /* Have everything.  Open/write the data.  */
2845796c8dcSSimon Schubert   if (file_format == NULL || strcmp (file_format, "binary") == 0)
2855796c8dcSSimon Schubert     {
2865796c8dcSSimon Schubert       dump_binary_file (filename, mode, value_contents (val),
2875796c8dcSSimon Schubert 			TYPE_LENGTH (value_type (val)));
2885796c8dcSSimon Schubert     }
2895796c8dcSSimon Schubert   else
2905796c8dcSSimon Schubert     {
2915796c8dcSSimon Schubert       CORE_ADDR vaddr;
2925796c8dcSSimon Schubert 
2935796c8dcSSimon Schubert       if (VALUE_LVAL (val))
2945796c8dcSSimon Schubert 	{
2955796c8dcSSimon Schubert 	  vaddr = value_address (val);
2965796c8dcSSimon Schubert 	}
2975796c8dcSSimon Schubert       else
2985796c8dcSSimon Schubert 	{
2995796c8dcSSimon Schubert 	  vaddr = 0;
3005796c8dcSSimon Schubert 	  warning (_("value is not an lval: address assumed to be zero"));
3015796c8dcSSimon Schubert 	}
3025796c8dcSSimon Schubert 
3035796c8dcSSimon Schubert       dump_bfd_file (filename, mode, file_format, vaddr,
3045796c8dcSSimon Schubert 		     value_contents (val),
3055796c8dcSSimon Schubert 		     TYPE_LENGTH (value_type (val)));
3065796c8dcSSimon Schubert     }
3075796c8dcSSimon Schubert 
3085796c8dcSSimon Schubert   do_cleanups (old_cleanups);
3095796c8dcSSimon Schubert }
3105796c8dcSSimon Schubert 
3115796c8dcSSimon Schubert static void
dump_value_command(char * cmd,char * mode)3125796c8dcSSimon Schubert dump_value_command (char *cmd, char *mode)
3135796c8dcSSimon Schubert {
3145796c8dcSSimon Schubert   dump_value_to_file (cmd, mode, "binary");
3155796c8dcSSimon Schubert }
3165796c8dcSSimon Schubert 
3175796c8dcSSimon Schubert static void
dump_srec_memory(char * args,int from_tty)3185796c8dcSSimon Schubert dump_srec_memory (char *args, int from_tty)
3195796c8dcSSimon Schubert {
3205796c8dcSSimon Schubert   dump_memory_to_file (args, FOPEN_WB, "srec");
3215796c8dcSSimon Schubert }
3225796c8dcSSimon Schubert 
3235796c8dcSSimon Schubert static void
dump_srec_value(char * args,int from_tty)3245796c8dcSSimon Schubert dump_srec_value (char *args, int from_tty)
3255796c8dcSSimon Schubert {
3265796c8dcSSimon Schubert   dump_value_to_file (args, FOPEN_WB, "srec");
3275796c8dcSSimon Schubert }
3285796c8dcSSimon Schubert 
3295796c8dcSSimon Schubert static void
dump_ihex_memory(char * args,int from_tty)3305796c8dcSSimon Schubert dump_ihex_memory (char *args, int from_tty)
3315796c8dcSSimon Schubert {
3325796c8dcSSimon Schubert   dump_memory_to_file (args, FOPEN_WB, "ihex");
3335796c8dcSSimon Schubert }
3345796c8dcSSimon Schubert 
3355796c8dcSSimon Schubert static void
dump_ihex_value(char * args,int from_tty)3365796c8dcSSimon Schubert dump_ihex_value (char *args, int from_tty)
3375796c8dcSSimon Schubert {
3385796c8dcSSimon Schubert   dump_value_to_file (args, FOPEN_WB, "ihex");
3395796c8dcSSimon Schubert }
3405796c8dcSSimon Schubert 
3415796c8dcSSimon Schubert static void
dump_tekhex_memory(char * args,int from_tty)3425796c8dcSSimon Schubert dump_tekhex_memory (char *args, int from_tty)
3435796c8dcSSimon Schubert {
3445796c8dcSSimon Schubert   dump_memory_to_file (args, FOPEN_WB, "tekhex");
3455796c8dcSSimon Schubert }
3465796c8dcSSimon Schubert 
3475796c8dcSSimon Schubert static void
dump_tekhex_value(char * args,int from_tty)3485796c8dcSSimon Schubert dump_tekhex_value (char *args, int from_tty)
3495796c8dcSSimon Schubert {
3505796c8dcSSimon Schubert   dump_value_to_file (args, FOPEN_WB, "tekhex");
3515796c8dcSSimon Schubert }
3525796c8dcSSimon Schubert 
3535796c8dcSSimon Schubert static void
dump_binary_memory(char * args,int from_tty)3545796c8dcSSimon Schubert dump_binary_memory (char *args, int from_tty)
3555796c8dcSSimon Schubert {
3565796c8dcSSimon Schubert   dump_memory_to_file (args, FOPEN_WB, "binary");
3575796c8dcSSimon Schubert }
3585796c8dcSSimon Schubert 
3595796c8dcSSimon Schubert static void
dump_binary_value(char * args,int from_tty)3605796c8dcSSimon Schubert dump_binary_value (char *args, int from_tty)
3615796c8dcSSimon Schubert {
3625796c8dcSSimon Schubert   dump_value_to_file (args, FOPEN_WB, "binary");
3635796c8dcSSimon Schubert }
3645796c8dcSSimon Schubert 
3655796c8dcSSimon Schubert static void
append_binary_memory(char * args,int from_tty)3665796c8dcSSimon Schubert append_binary_memory (char *args, int from_tty)
3675796c8dcSSimon Schubert {
3685796c8dcSSimon Schubert   dump_memory_to_file (args, FOPEN_AB, "binary");
3695796c8dcSSimon Schubert }
3705796c8dcSSimon Schubert 
3715796c8dcSSimon Schubert static void
append_binary_value(char * args,int from_tty)3725796c8dcSSimon Schubert append_binary_value (char *args, int from_tty)
3735796c8dcSSimon Schubert {
3745796c8dcSSimon Schubert   dump_value_to_file (args, FOPEN_AB, "binary");
3755796c8dcSSimon Schubert }
3765796c8dcSSimon Schubert 
3775796c8dcSSimon Schubert struct dump_context
3785796c8dcSSimon Schubert {
3795796c8dcSSimon Schubert   void (*func) (char *cmd, char *mode);
3805796c8dcSSimon Schubert   char *mode;
3815796c8dcSSimon Schubert };
3825796c8dcSSimon Schubert 
3835796c8dcSSimon Schubert static void
call_dump_func(struct cmd_list_element * c,char * args,int from_tty)3845796c8dcSSimon Schubert call_dump_func (struct cmd_list_element *c, char *args, int from_tty)
3855796c8dcSSimon Schubert {
3865796c8dcSSimon Schubert   struct dump_context *d = get_cmd_context (c);
387cf7f2e2dSJohn Marino 
3885796c8dcSSimon Schubert   d->func (args, d->mode);
3895796c8dcSSimon Schubert }
3905796c8dcSSimon Schubert 
3915796c8dcSSimon Schubert void
add_dump_command(char * name,void (* func)(char * args,char * mode),char * descr)3925796c8dcSSimon Schubert add_dump_command (char *name, void (*func) (char *args, char *mode),
3935796c8dcSSimon Schubert 		  char *descr)
3945796c8dcSSimon Schubert 
3955796c8dcSSimon Schubert {
3965796c8dcSSimon Schubert   struct cmd_list_element *c;
3975796c8dcSSimon Schubert   struct dump_context *d;
3985796c8dcSSimon Schubert 
3995796c8dcSSimon Schubert   c = add_cmd (name, all_commands, NULL, descr, &dump_cmdlist);
4005796c8dcSSimon Schubert   c->completer =  filename_completer;
4015796c8dcSSimon Schubert   d = XMALLOC (struct dump_context);
4025796c8dcSSimon Schubert   d->func = func;
4035796c8dcSSimon Schubert   d->mode = FOPEN_WB;
4045796c8dcSSimon Schubert   set_cmd_context (c, d);
4055796c8dcSSimon Schubert   c->func = call_dump_func;
4065796c8dcSSimon Schubert 
4075796c8dcSSimon Schubert   c = add_cmd (name, all_commands, NULL, descr, &append_cmdlist);
4085796c8dcSSimon Schubert   c->completer =  filename_completer;
4095796c8dcSSimon Schubert   d = XMALLOC (struct dump_context);
4105796c8dcSSimon Schubert   d->func = func;
4115796c8dcSSimon Schubert   d->mode = FOPEN_AB;
4125796c8dcSSimon Schubert   set_cmd_context (c, d);
4135796c8dcSSimon Schubert   c->func = call_dump_func;
4145796c8dcSSimon Schubert 
4155796c8dcSSimon Schubert   /* Replace "Dump " at start of docstring with "Append " (borrowed
4165796c8dcSSimon Schubert      from [deleted] deprecated_add_show_from_set).  */
4175796c8dcSSimon Schubert   if (   c->doc[0] == 'W'
4185796c8dcSSimon Schubert       && c->doc[1] == 'r'
4195796c8dcSSimon Schubert       && c->doc[2] == 'i'
4205796c8dcSSimon Schubert       && c->doc[3] == 't'
4215796c8dcSSimon Schubert       && c->doc[4] == 'e'
4225796c8dcSSimon Schubert       && c->doc[5] == ' ')
4235796c8dcSSimon Schubert     c->doc = concat ("Append ", c->doc + 6, (char *)NULL);
4245796c8dcSSimon Schubert }
4255796c8dcSSimon Schubert 
4265796c8dcSSimon Schubert /* Opaque data for restore_section_callback.  */
4275796c8dcSSimon Schubert struct callback_data {
4285796c8dcSSimon Schubert   CORE_ADDR load_offset;
4295796c8dcSSimon Schubert   CORE_ADDR load_start;
4305796c8dcSSimon Schubert   CORE_ADDR load_end;
4315796c8dcSSimon Schubert };
4325796c8dcSSimon Schubert 
4335796c8dcSSimon Schubert /* Function: restore_section_callback.
4345796c8dcSSimon Schubert 
4355796c8dcSSimon Schubert    Callback function for bfd_map_over_sections.
4365796c8dcSSimon Schubert    Selectively loads the sections into memory.  */
4375796c8dcSSimon Schubert 
4385796c8dcSSimon Schubert static void
restore_section_callback(bfd * ibfd,asection * isec,void * args)4395796c8dcSSimon Schubert restore_section_callback (bfd *ibfd, asection *isec, void *args)
4405796c8dcSSimon Schubert {
4415796c8dcSSimon Schubert   struct callback_data *data = args;
4425796c8dcSSimon Schubert   bfd_vma sec_start  = bfd_section_vma (ibfd, isec);
4435796c8dcSSimon Schubert   bfd_size_type size = bfd_section_size (ibfd, isec);
4445796c8dcSSimon Schubert   bfd_vma sec_end    = sec_start + size;
4455796c8dcSSimon Schubert   bfd_size_type sec_offset = 0;
4465796c8dcSSimon Schubert   bfd_size_type sec_load_count = size;
4475796c8dcSSimon Schubert   struct cleanup *old_chain;
4485796c8dcSSimon Schubert   gdb_byte *buf;
4495796c8dcSSimon Schubert   int ret;
4505796c8dcSSimon Schubert 
4515796c8dcSSimon Schubert   /* Ignore non-loadable sections, eg. from elf files.  */
4525796c8dcSSimon Schubert   if (!(bfd_get_section_flags (ibfd, isec) & SEC_LOAD))
4535796c8dcSSimon Schubert     return;
4545796c8dcSSimon Schubert 
4555796c8dcSSimon Schubert   /* Does the section overlap with the desired restore range? */
4565796c8dcSSimon Schubert   if (sec_end <= data->load_start
4575796c8dcSSimon Schubert       || (data->load_end > 0 && sec_start >= data->load_end))
4585796c8dcSSimon Schubert     {
4595796c8dcSSimon Schubert       /* No, no useable data in this section.  */
4605796c8dcSSimon Schubert       printf_filtered (_("skipping section %s...\n"),
4615796c8dcSSimon Schubert 		       bfd_section_name (ibfd, isec));
4625796c8dcSSimon Schubert       return;
4635796c8dcSSimon Schubert     }
4645796c8dcSSimon Schubert 
4655796c8dcSSimon Schubert   /* Compare section address range with user-requested
4665796c8dcSSimon Schubert      address range (if any).  Compute where the actual
4675796c8dcSSimon Schubert      transfer should start and end.  */
4685796c8dcSSimon Schubert   if (sec_start < data->load_start)
4695796c8dcSSimon Schubert     sec_offset = data->load_start - sec_start;
470c50c785cSJohn Marino   /* Size of a partial transfer.  */
4715796c8dcSSimon Schubert   sec_load_count -= sec_offset;
4725796c8dcSSimon Schubert   if (data->load_end > 0 && sec_end > data->load_end)
4735796c8dcSSimon Schubert     sec_load_count -= sec_end - data->load_end;
4745796c8dcSSimon Schubert 
4755796c8dcSSimon Schubert   /* Get the data.  */
4765796c8dcSSimon Schubert   buf = xmalloc (size);
4775796c8dcSSimon Schubert   old_chain = make_cleanup (xfree, buf);
4785796c8dcSSimon Schubert   if (!bfd_get_section_contents (ibfd, isec, buf, 0, size))
4795796c8dcSSimon Schubert     error (_("Failed to read bfd file %s: '%s'."), bfd_get_filename (ibfd),
4805796c8dcSSimon Schubert 	   bfd_errmsg (bfd_get_error ()));
4815796c8dcSSimon Schubert 
4825796c8dcSSimon Schubert   printf_filtered ("Restoring section %s (0x%lx to 0x%lx)",
4835796c8dcSSimon Schubert 		   bfd_section_name (ibfd, isec),
4845796c8dcSSimon Schubert 		   (unsigned long) sec_start,
4855796c8dcSSimon Schubert 		   (unsigned long) sec_end);
4865796c8dcSSimon Schubert 
4875796c8dcSSimon Schubert   if (data->load_offset != 0 || data->load_start != 0 || data->load_end != 0)
4885796c8dcSSimon Schubert     printf_filtered (" into memory (%s to %s)\n",
489*ef5ccd6cSJohn Marino 		     paddress (target_gdbarch (),
4905796c8dcSSimon Schubert 			       (unsigned long) sec_start
4915796c8dcSSimon Schubert 			       + sec_offset + data->load_offset),
492*ef5ccd6cSJohn Marino 		     paddress (target_gdbarch (),
4935796c8dcSSimon Schubert 			       (unsigned long) sec_start + sec_offset
4945796c8dcSSimon Schubert 				+ data->load_offset + sec_load_count));
4955796c8dcSSimon Schubert   else
4965796c8dcSSimon Schubert     puts_filtered ("\n");
4975796c8dcSSimon Schubert 
4985796c8dcSSimon Schubert   /* Write the data.  */
4995796c8dcSSimon Schubert   ret = target_write_memory (sec_start + sec_offset + data->load_offset,
5005796c8dcSSimon Schubert 			     buf + sec_offset, sec_load_count);
5015796c8dcSSimon Schubert   if (ret != 0)
5025796c8dcSSimon Schubert     warning (_("restore: memory write failed (%s)."), safe_strerror (ret));
5035796c8dcSSimon Schubert   do_cleanups (old_chain);
5045796c8dcSSimon Schubert   return;
5055796c8dcSSimon Schubert }
5065796c8dcSSimon Schubert 
5075796c8dcSSimon Schubert static void
restore_binary_file(char * filename,struct callback_data * data)5085796c8dcSSimon Schubert restore_binary_file (char *filename, struct callback_data *data)
5095796c8dcSSimon Schubert {
5105796c8dcSSimon Schubert   FILE *file = fopen_with_cleanup (filename, FOPEN_RB);
5115796c8dcSSimon Schubert   gdb_byte *buf;
5125796c8dcSSimon Schubert   long len;
5135796c8dcSSimon Schubert 
5145796c8dcSSimon Schubert   /* Get the file size for reading.  */
5155796c8dcSSimon Schubert   if (fseek (file, 0, SEEK_END) == 0)
516c50c785cSJohn Marino     {
5175796c8dcSSimon Schubert       len = ftell (file);
518c50c785cSJohn Marino       if (len < 0)
519c50c785cSJohn Marino 	perror_with_name (filename);
520c50c785cSJohn Marino     }
5215796c8dcSSimon Schubert   else
5225796c8dcSSimon Schubert     perror_with_name (filename);
5235796c8dcSSimon Schubert 
5245796c8dcSSimon Schubert   if (len <= data->load_start)
5255796c8dcSSimon Schubert     error (_("Start address is greater than length of binary file %s."),
5265796c8dcSSimon Schubert 	   filename);
5275796c8dcSSimon Schubert 
5285796c8dcSSimon Schubert   /* Chop off "len" if it exceeds the requested load_end addr.  */
5295796c8dcSSimon Schubert   if (data->load_end != 0 && data->load_end < len)
5305796c8dcSSimon Schubert     len = data->load_end;
5315796c8dcSSimon Schubert   /* Chop off "len" if the requested load_start addr skips some bytes.  */
5325796c8dcSSimon Schubert   if (data->load_start > 0)
5335796c8dcSSimon Schubert     len -= data->load_start;
5345796c8dcSSimon Schubert 
5355796c8dcSSimon Schubert   printf_filtered
5365796c8dcSSimon Schubert     ("Restoring binary file %s into memory (0x%lx to 0x%lx)\n",
5375796c8dcSSimon Schubert      filename,
5385796c8dcSSimon Schubert      (unsigned long) (data->load_start + data->load_offset),
5395796c8dcSSimon Schubert      (unsigned long) (data->load_start + data->load_offset + len));
5405796c8dcSSimon Schubert 
5415796c8dcSSimon Schubert   /* Now set the file pos to the requested load start pos.  */
5425796c8dcSSimon Schubert   if (fseek (file, data->load_start, SEEK_SET) != 0)
5435796c8dcSSimon Schubert     perror_with_name (filename);
5445796c8dcSSimon Schubert 
5455796c8dcSSimon Schubert   /* Now allocate a buffer and read the file contents.  */
5465796c8dcSSimon Schubert   buf = xmalloc (len);
5475796c8dcSSimon Schubert   make_cleanup (xfree, buf);
5485796c8dcSSimon Schubert   if (fread (buf, 1, len, file) != len)
5495796c8dcSSimon Schubert     perror_with_name (filename);
5505796c8dcSSimon Schubert 
5515796c8dcSSimon Schubert   /* Now write the buffer into target memory.  */
5525796c8dcSSimon Schubert   len = target_write_memory (data->load_start + data->load_offset, buf, len);
5535796c8dcSSimon Schubert   if (len != 0)
5545796c8dcSSimon Schubert     warning (_("restore: memory write failed (%s)."), safe_strerror (len));
5555796c8dcSSimon Schubert   return;
5565796c8dcSSimon Schubert }
5575796c8dcSSimon Schubert 
5585796c8dcSSimon Schubert static void
restore_command(char * args,int from_tty)5595796c8dcSSimon Schubert restore_command (char *args, int from_tty)
5605796c8dcSSimon Schubert {
5615796c8dcSSimon Schubert   char *filename;
5625796c8dcSSimon Schubert   struct callback_data data;
5635796c8dcSSimon Schubert   bfd *ibfd;
5645796c8dcSSimon Schubert   int binary_flag = 0;
5655796c8dcSSimon Schubert 
5665796c8dcSSimon Schubert   if (!target_has_execution)
5675796c8dcSSimon Schubert     noprocess ();
5685796c8dcSSimon Schubert 
5695796c8dcSSimon Schubert   data.load_offset = 0;
5705796c8dcSSimon Schubert   data.load_start  = 0;
5715796c8dcSSimon Schubert   data.load_end    = 0;
5725796c8dcSSimon Schubert 
5735796c8dcSSimon Schubert   /* Parse the input arguments.  First is filename (required).  */
5745796c8dcSSimon Schubert   filename = scan_filename_with_cleanup (&args, NULL);
5755796c8dcSSimon Schubert   if (args != NULL && *args != '\0')
5765796c8dcSSimon Schubert     {
5775796c8dcSSimon Schubert       char *binary_string = "binary";
5785796c8dcSSimon Schubert 
5795796c8dcSSimon Schubert       /* Look for optional "binary" flag.  */
5805796c8dcSSimon Schubert       if (strncmp (args, binary_string, strlen (binary_string)) == 0)
5815796c8dcSSimon Schubert 	{
5825796c8dcSSimon Schubert 	  binary_flag = 1;
5835796c8dcSSimon Schubert 	  args += strlen (binary_string);
5845796c8dcSSimon Schubert 	  args = skip_spaces (args);
5855796c8dcSSimon Schubert 	}
5865796c8dcSSimon Schubert       /* Parse offset (optional).  */
5875796c8dcSSimon Schubert       if (args != NULL && *args != '\0')
5885796c8dcSSimon Schubert       data.load_offset =
5895796c8dcSSimon Schubert 	parse_and_eval_address (scan_expression_with_cleanup (&args, NULL));
5905796c8dcSSimon Schubert       if (args != NULL && *args != '\0')
5915796c8dcSSimon Schubert 	{
5925796c8dcSSimon Schubert 	  /* Parse start address (optional).  */
5935796c8dcSSimon Schubert 	  data.load_start =
5945796c8dcSSimon Schubert 	    parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
5955796c8dcSSimon Schubert 	  if (args != NULL && *args != '\0')
5965796c8dcSSimon Schubert 	    {
5975796c8dcSSimon Schubert 	      /* Parse end address (optional).  */
5985796c8dcSSimon Schubert 	      data.load_end = parse_and_eval_long (args);
5995796c8dcSSimon Schubert 	      if (data.load_end <= data.load_start)
6005796c8dcSSimon Schubert 		error (_("Start must be less than end."));
6015796c8dcSSimon Schubert 	    }
6025796c8dcSSimon Schubert 	}
6035796c8dcSSimon Schubert     }
6045796c8dcSSimon Schubert 
6055796c8dcSSimon Schubert   if (info_verbose)
6065796c8dcSSimon Schubert     printf_filtered ("Restore file %s offset 0x%lx start 0x%lx end 0x%lx\n",
6075796c8dcSSimon Schubert 		     filename, (unsigned long) data.load_offset,
6085796c8dcSSimon Schubert 		     (unsigned long) data.load_start,
6095796c8dcSSimon Schubert 		     (unsigned long) data.load_end);
6105796c8dcSSimon Schubert 
6115796c8dcSSimon Schubert   if (binary_flag)
6125796c8dcSSimon Schubert     {
6135796c8dcSSimon Schubert       restore_binary_file (filename, &data);
6145796c8dcSSimon Schubert     }
6155796c8dcSSimon Schubert   else
6165796c8dcSSimon Schubert     {
6175796c8dcSSimon Schubert       /* Open the file for loading.  */
6185796c8dcSSimon Schubert       ibfd = bfd_openr_with_cleanup (filename, NULL);
6195796c8dcSSimon Schubert 
6205796c8dcSSimon Schubert       /* Process the sections.  */
6215796c8dcSSimon Schubert       bfd_map_over_sections (ibfd, restore_section_callback, &data);
6225796c8dcSSimon Schubert     }
6235796c8dcSSimon Schubert   return;
6245796c8dcSSimon Schubert }
6255796c8dcSSimon Schubert 
6265796c8dcSSimon Schubert static void
srec_dump_command(char * cmd,int from_tty)6275796c8dcSSimon Schubert srec_dump_command (char *cmd, int from_tty)
6285796c8dcSSimon Schubert {
6295796c8dcSSimon Schubert   printf_unfiltered ("\"dump srec\" must be followed by a subcommand.\n");
6305796c8dcSSimon Schubert   help_list (srec_cmdlist, "dump srec ", -1, gdb_stdout);
6315796c8dcSSimon Schubert }
6325796c8dcSSimon Schubert 
6335796c8dcSSimon Schubert static void
ihex_dump_command(char * cmd,int from_tty)6345796c8dcSSimon Schubert ihex_dump_command (char *cmd, int from_tty)
6355796c8dcSSimon Schubert {
6365796c8dcSSimon Schubert   printf_unfiltered ("\"dump ihex\" must be followed by a subcommand.\n");
6375796c8dcSSimon Schubert   help_list (ihex_cmdlist, "dump ihex ", -1, gdb_stdout);
6385796c8dcSSimon Schubert }
6395796c8dcSSimon Schubert 
6405796c8dcSSimon Schubert static void
tekhex_dump_command(char * cmd,int from_tty)6415796c8dcSSimon Schubert tekhex_dump_command (char *cmd, int from_tty)
6425796c8dcSSimon Schubert {
6435796c8dcSSimon Schubert   printf_unfiltered ("\"dump tekhex\" must be followed by a subcommand.\n");
6445796c8dcSSimon Schubert   help_list (tekhex_cmdlist, "dump tekhex ", -1, gdb_stdout);
6455796c8dcSSimon Schubert }
6465796c8dcSSimon Schubert 
6475796c8dcSSimon Schubert static void
binary_dump_command(char * cmd,int from_tty)6485796c8dcSSimon Schubert binary_dump_command (char *cmd, int from_tty)
6495796c8dcSSimon Schubert {
6505796c8dcSSimon Schubert   printf_unfiltered ("\"dump binary\" must be followed by a subcommand.\n");
6515796c8dcSSimon Schubert   help_list (binary_dump_cmdlist, "dump binary ", -1, gdb_stdout);
6525796c8dcSSimon Schubert }
6535796c8dcSSimon Schubert 
6545796c8dcSSimon Schubert static void
binary_append_command(char * cmd,int from_tty)6555796c8dcSSimon Schubert binary_append_command (char *cmd, int from_tty)
6565796c8dcSSimon Schubert {
6575796c8dcSSimon Schubert   printf_unfiltered ("\"append binary\" must be followed by a subcommand.\n");
6585796c8dcSSimon Schubert   help_list (binary_append_cmdlist, "append binary ", -1, gdb_stdout);
6595796c8dcSSimon Schubert }
6605796c8dcSSimon Schubert 
6615796c8dcSSimon Schubert extern initialize_file_ftype _initialize_cli_dump; /* -Wmissing-prototypes */
6625796c8dcSSimon Schubert 
6635796c8dcSSimon Schubert void
_initialize_cli_dump(void)6645796c8dcSSimon Schubert _initialize_cli_dump (void)
6655796c8dcSSimon Schubert {
6665796c8dcSSimon Schubert   struct cmd_list_element *c;
667cf7f2e2dSJohn Marino 
668c50c785cSJohn Marino   add_prefix_cmd ("dump", class_vars, dump_command,
669c50c785cSJohn Marino 		  _("Dump target code/data to a local file."),
6705796c8dcSSimon Schubert 		  &dump_cmdlist, "dump ",
6715796c8dcSSimon Schubert 		  0/*allow-unknown*/,
6725796c8dcSSimon Schubert 		  &cmdlist);
673c50c785cSJohn Marino   add_prefix_cmd ("append", class_vars, append_command,
674c50c785cSJohn Marino 		  _("Append target code/data to a local file."),
6755796c8dcSSimon Schubert 		  &append_cmdlist, "append ",
6765796c8dcSSimon Schubert 		  0/*allow-unknown*/,
6775796c8dcSSimon Schubert 		  &cmdlist);
6785796c8dcSSimon Schubert 
6795796c8dcSSimon Schubert   add_dump_command ("memory", dump_memory_command, "\
6805796c8dcSSimon Schubert Write contents of memory to a raw binary file.\n\
6815796c8dcSSimon Schubert Arguments are FILE START STOP.  Writes the contents of memory within the\n\
682a45ae5f8SJohn Marino range [START .. STOP) to the specified FILE in raw target ordered bytes.");
6835796c8dcSSimon Schubert 
6845796c8dcSSimon Schubert   add_dump_command ("value", dump_value_command, "\
6855796c8dcSSimon Schubert Write the value of an expression to a raw binary file.\n\
6865796c8dcSSimon Schubert Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION to\n\
6875796c8dcSSimon Schubert the specified FILE in raw target ordered bytes.");
6885796c8dcSSimon Schubert 
689c50c785cSJohn Marino   add_prefix_cmd ("srec", all_commands, srec_dump_command,
690c50c785cSJohn Marino 		  _("Write target code/data to an srec file."),
6915796c8dcSSimon Schubert 		  &srec_cmdlist, "dump srec ",
6925796c8dcSSimon Schubert 		  0 /*allow-unknown*/,
6935796c8dcSSimon Schubert 		  &dump_cmdlist);
6945796c8dcSSimon Schubert 
695c50c785cSJohn Marino   add_prefix_cmd ("ihex", all_commands, ihex_dump_command,
696c50c785cSJohn Marino 		  _("Write target code/data to an intel hex file."),
6975796c8dcSSimon Schubert 		  &ihex_cmdlist, "dump ihex ",
6985796c8dcSSimon Schubert 		  0 /*allow-unknown*/,
6995796c8dcSSimon Schubert 		  &dump_cmdlist);
7005796c8dcSSimon Schubert 
701c50c785cSJohn Marino   add_prefix_cmd ("tekhex", all_commands, tekhex_dump_command,
702c50c785cSJohn Marino 		  _("Write target code/data to a tekhex file."),
7035796c8dcSSimon Schubert 		  &tekhex_cmdlist, "dump tekhex ",
7045796c8dcSSimon Schubert 		  0 /*allow-unknown*/,
7055796c8dcSSimon Schubert 		  &dump_cmdlist);
7065796c8dcSSimon Schubert 
707c50c785cSJohn Marino   add_prefix_cmd ("binary", all_commands, binary_dump_command,
708c50c785cSJohn Marino 		  _("Write target code/data to a raw binary file."),
7095796c8dcSSimon Schubert 		  &binary_dump_cmdlist, "dump binary ",
7105796c8dcSSimon Schubert 		  0 /*allow-unknown*/,
7115796c8dcSSimon Schubert 		  &dump_cmdlist);
7125796c8dcSSimon Schubert 
713c50c785cSJohn Marino   add_prefix_cmd ("binary", all_commands, binary_append_command,
714c50c785cSJohn Marino 		  _("Append target code/data to a raw binary file."),
7155796c8dcSSimon Schubert 		  &binary_append_cmdlist, "append binary ",
7165796c8dcSSimon Schubert 		  0 /*allow-unknown*/,
7175796c8dcSSimon Schubert 		  &append_cmdlist);
7185796c8dcSSimon Schubert 
7195796c8dcSSimon Schubert   add_cmd ("memory", all_commands, dump_srec_memory, _("\
7205796c8dcSSimon Schubert Write contents of memory to an srec file.\n\
7215796c8dcSSimon Schubert Arguments are FILE START STOP.  Writes the contents of memory\n\
722a45ae5f8SJohn Marino within the range [START .. STOP) to the specified FILE in srec format."),
7235796c8dcSSimon Schubert 	   &srec_cmdlist);
7245796c8dcSSimon Schubert 
7255796c8dcSSimon Schubert   add_cmd ("value", all_commands, dump_srec_value, _("\
7265796c8dcSSimon Schubert Write the value of an expression to an srec file.\n\
7275796c8dcSSimon Schubert Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
7285796c8dcSSimon Schubert to the specified FILE in srec format."),
7295796c8dcSSimon Schubert 	   &srec_cmdlist);
7305796c8dcSSimon Schubert 
7315796c8dcSSimon Schubert   add_cmd ("memory", all_commands, dump_ihex_memory, _("\
7325796c8dcSSimon Schubert Write contents of memory to an ihex file.\n\
7335796c8dcSSimon Schubert Arguments are FILE START STOP.  Writes the contents of memory within\n\
734a45ae5f8SJohn Marino the range [START .. STOP) to the specified FILE in intel hex format."),
7355796c8dcSSimon Schubert 	   &ihex_cmdlist);
7365796c8dcSSimon Schubert 
7375796c8dcSSimon Schubert   add_cmd ("value", all_commands, dump_ihex_value, _("\
7385796c8dcSSimon Schubert Write the value of an expression to an ihex file.\n\
7395796c8dcSSimon Schubert Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
7405796c8dcSSimon Schubert to the specified FILE in intel hex format."),
7415796c8dcSSimon Schubert 	   &ihex_cmdlist);
7425796c8dcSSimon Schubert 
7435796c8dcSSimon Schubert   add_cmd ("memory", all_commands, dump_tekhex_memory, _("\
7445796c8dcSSimon Schubert Write contents of memory to a tekhex file.\n\
7455796c8dcSSimon Schubert Arguments are FILE START STOP.  Writes the contents of memory\n\
746a45ae5f8SJohn Marino within the range [START .. STOP) to the specified FILE in tekhex format."),
7475796c8dcSSimon Schubert 	   &tekhex_cmdlist);
7485796c8dcSSimon Schubert 
7495796c8dcSSimon Schubert   add_cmd ("value", all_commands, dump_tekhex_value, _("\
7505796c8dcSSimon Schubert Write the value of an expression to a tekhex file.\n\
7515796c8dcSSimon Schubert Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
7525796c8dcSSimon Schubert to the specified FILE in tekhex format."),
7535796c8dcSSimon Schubert 	   &tekhex_cmdlist);
7545796c8dcSSimon Schubert 
7555796c8dcSSimon Schubert   add_cmd ("memory", all_commands, dump_binary_memory, _("\
7565796c8dcSSimon Schubert Write contents of memory to a raw binary file.\n\
7575796c8dcSSimon Schubert Arguments are FILE START STOP.  Writes the contents of memory\n\
758a45ae5f8SJohn Marino within the range [START .. STOP) to the specified FILE in binary format."),
7595796c8dcSSimon Schubert 	   &binary_dump_cmdlist);
7605796c8dcSSimon Schubert 
7615796c8dcSSimon Schubert   add_cmd ("value", all_commands, dump_binary_value, _("\
7625796c8dcSSimon Schubert Write the value of an expression to a raw binary file.\n\
7635796c8dcSSimon Schubert Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
7645796c8dcSSimon Schubert to the specified FILE in raw target ordered bytes."),
7655796c8dcSSimon Schubert 	   &binary_dump_cmdlist);
7665796c8dcSSimon Schubert 
7675796c8dcSSimon Schubert   add_cmd ("memory", all_commands, append_binary_memory, _("\
7685796c8dcSSimon Schubert Append contents of memory to a raw binary file.\n\
7695796c8dcSSimon Schubert Arguments are FILE START STOP.  Writes the contents of memory within the\n\
770a45ae5f8SJohn Marino range [START .. STOP) to the specified FILE in raw target ordered bytes."),
7715796c8dcSSimon Schubert 	   &binary_append_cmdlist);
7725796c8dcSSimon Schubert 
7735796c8dcSSimon Schubert   add_cmd ("value", all_commands, append_binary_value, _("\
7745796c8dcSSimon Schubert Append the value of an expression to a raw binary file.\n\
7755796c8dcSSimon Schubert Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
7765796c8dcSSimon Schubert to the specified FILE in raw target ordered bytes."),
7775796c8dcSSimon Schubert 	   &binary_append_cmdlist);
7785796c8dcSSimon Schubert 
7795796c8dcSSimon Schubert   c = add_com ("restore", class_vars, restore_command, _("\
7805796c8dcSSimon Schubert Restore the contents of FILE to target memory.\n\
7815796c8dcSSimon Schubert Arguments are FILE OFFSET START END where all except FILE are optional.\n\
7825796c8dcSSimon Schubert OFFSET will be added to the base address of the file (default zero).\n\
7835796c8dcSSimon Schubert If START and END are given, only the file contents within that range\n\
7845796c8dcSSimon Schubert (file relative) will be restored to target memory."));
7855796c8dcSSimon Schubert   c->completer = filename_completer;
7865796c8dcSSimon Schubert   /* FIXME: completers for other commands.  */
7875796c8dcSSimon Schubert }
788