eb7f69d4a2573e4b3a92a6745bf7a750aef74e17
[external/binutils.git] / gdb / cli / cli-dump.c
1 /* Dump-to-file commands, for GDB, the GNU debugger.
2
3    Copyright (C) 2002-2016 Free Software Foundation, Inc.
4
5    Contributed by Red Hat.
6
7    This file is part of GDB.
8
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 3 of the License, or
12    (at your option) any later version.
13
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.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22 #include "defs.h"
23 #include "cli/cli-decode.h"
24 #include "cli/cli-cmds.h"
25 #include "value.h"
26 #include "completer.h"
27 #include <ctype.h>
28 #include "target.h"
29 #include "readline/readline.h"
30 #include "gdbcore.h"
31 #include "cli/cli-utils.h"
32 #include "gdb_bfd.h"
33 #include "filestuff.h"
34
35
36 static const char *
37 scan_expression_with_cleanup (const char **cmd, const char *def)
38 {
39   if ((*cmd) == NULL || (**cmd) == '\0')
40     {
41       char *exp = xstrdup (def);
42
43       make_cleanup (xfree, exp);
44       return exp;
45     }
46   else
47     {
48       char *exp;
49       const char *end;
50
51       end = (*cmd) + strcspn (*cmd, " \t");
52       exp = savestring ((*cmd), end - (*cmd));
53       make_cleanup (xfree, exp);
54       (*cmd) = skip_spaces_const (end);
55       return exp;
56     }
57 }
58
59
60 static char *
61 scan_filename_with_cleanup (const char **cmd, const char *defname)
62 {
63   char *filename;
64   char *fullname;
65
66   /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere.  */
67
68   /* File.  */
69   if ((*cmd) == NULL)
70     {
71       if (defname == NULL)
72         error (_("Missing filename."));
73       filename = xstrdup (defname);
74       make_cleanup (xfree, filename);
75     }
76   else
77     {
78       /* FIXME: should parse a possibly quoted string.  */
79       const char *end;
80
81       (*cmd) = skip_spaces_const (*cmd);
82       end = *cmd + strcspn (*cmd, " \t");
83       filename = savestring ((*cmd), end - (*cmd));
84       make_cleanup (xfree, filename);
85       (*cmd) = skip_spaces_const (end);
86     }
87   gdb_assert (filename != NULL);
88
89   fullname = tilde_expand (filename);
90   make_cleanup (xfree, fullname);
91   
92   return fullname;
93 }
94
95 static FILE *
96 fopen_with_cleanup (const char *filename, const char *mode)
97 {
98   FILE *file = gdb_fopen_cloexec (filename, mode);
99
100   if (file == NULL)
101     perror_with_name (filename);
102   make_cleanup_fclose (file);
103   return file;
104 }
105
106 static bfd *
107 bfd_openr_with_cleanup (const char *filename, const char *target)
108 {
109   bfd *ibfd;
110
111   ibfd = gdb_bfd_openr (filename, target);
112   if (ibfd == NULL)
113     error (_("Failed to open %s: %s."), filename, 
114            bfd_errmsg (bfd_get_error ()));
115
116   make_cleanup_bfd_unref (ibfd);
117   if (!bfd_check_format (ibfd, bfd_object))
118     error (_("'%s' is not a recognized file format."), filename);
119
120   return ibfd;
121 }
122
123 static bfd *
124 bfd_openw_with_cleanup (const char *filename, const char *target,
125                         const char *mode)
126 {
127   bfd *obfd;
128
129   if (*mode == 'w')     /* Write: create new file */
130     {
131       obfd = gdb_bfd_openw (filename, target);
132       if (obfd == NULL)
133         error (_("Failed to open %s: %s."), filename, 
134                bfd_errmsg (bfd_get_error ()));
135       make_cleanup_bfd_unref (obfd);
136       if (!bfd_set_format (obfd, bfd_object))
137         error (_("bfd_openw_with_cleanup: %s."), bfd_errmsg (bfd_get_error ()));
138     }
139   else if (*mode == 'a')        /* Append to existing file.  */
140     {   /* FIXME -- doesn't work...  */
141       error (_("bfd_openw does not work with append."));
142     }
143   else
144     error (_("bfd_openw_with_cleanup: unknown mode %s."), mode);
145
146   return obfd;
147 }
148
149 static struct cmd_list_element *dump_cmdlist;
150 static struct cmd_list_element *append_cmdlist;
151 static struct cmd_list_element *srec_cmdlist;
152 static struct cmd_list_element *ihex_cmdlist;
153 static struct cmd_list_element *verilog_cmdlist;
154 static struct cmd_list_element *tekhex_cmdlist;
155 static struct cmd_list_element *binary_dump_cmdlist;
156 static struct cmd_list_element *binary_append_cmdlist;
157
158 static void
159 dump_command (char *cmd, int from_tty)
160 {
161   printf_unfiltered (_("\"dump\" must be followed by a subcommand.\n\n"));
162   help_list (dump_cmdlist, "dump ", all_commands, gdb_stdout);
163 }
164
165 static void
166 append_command (char *cmd, int from_tty)
167 {
168   printf_unfiltered (_("\"append\" must be followed by a subcommand.\n\n"));
169   help_list (dump_cmdlist, "append ", all_commands, gdb_stdout);
170 }
171
172 static void
173 dump_binary_file (const char *filename, const char *mode, 
174                   const bfd_byte *buf, ULONGEST len)
175 {
176   FILE *file;
177   int status;
178
179   file = fopen_with_cleanup (filename, mode);
180   status = fwrite (buf, len, 1, file);
181   if (status != 1)
182     perror_with_name (filename);
183 }
184
185 static void
186 dump_bfd_file (const char *filename, const char *mode, 
187                const char *target, CORE_ADDR vaddr, 
188                const bfd_byte *buf, ULONGEST len)
189 {
190   bfd *obfd;
191   asection *osection;
192
193   obfd = bfd_openw_with_cleanup (filename, target, mode);
194   osection = bfd_make_section_anyway (obfd, ".newsec");
195   bfd_set_section_size (obfd, osection, len);
196   bfd_set_section_vma (obfd, osection, vaddr);
197   bfd_set_section_alignment (obfd, osection, 0);
198   bfd_set_section_flags (obfd, osection, (SEC_HAS_CONTENTS
199                                           | SEC_ALLOC
200                                           | SEC_LOAD));
201   osection->entsize = 0;
202   if (!bfd_set_section_contents (obfd, osection, buf, 0, len))
203     warning (_("writing dump file '%s' (%s)"), filename, 
204              bfd_errmsg (bfd_get_error ()));
205 }
206
207 static void
208 dump_memory_to_file (const char *cmd, const char *mode, const char *file_format)
209 {
210   struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
211   CORE_ADDR lo;
212   CORE_ADDR hi;
213   ULONGEST count;
214   const char *filename;
215   const char *lo_exp;
216   const char *hi_exp;
217
218   /* Open the file.  */
219   filename = scan_filename_with_cleanup (&cmd, NULL);
220
221   /* Find the low address.  */
222   if (cmd == NULL || *cmd == '\0')
223     error (_("Missing start address."));
224   lo_exp = scan_expression_with_cleanup (&cmd, NULL);
225
226   /* Find the second address - rest of line.  */
227   if (cmd == NULL || *cmd == '\0')
228     error (_("Missing stop address."));
229   hi_exp = cmd;
230
231   lo = parse_and_eval_address (lo_exp);
232   hi = parse_and_eval_address (hi_exp);
233   if (hi <= lo)
234     error (_("Invalid memory address range (start >= end)."));
235   count = hi - lo;
236
237   /* FIXME: Should use read_memory_partial() and a magic blocking
238      value.  */
239   gdb::unique_ptr<gdb_byte[]> buf (new gdb_byte[count]);
240   read_memory (lo, buf.get (), count);
241   
242   /* Have everything.  Open/write the data.  */
243   if (file_format == NULL || strcmp (file_format, "binary") == 0)
244     {
245       dump_binary_file (filename, mode, buf.get (), count);
246     }
247   else
248     {
249       dump_bfd_file (filename, mode, file_format, lo, buf.get (), count);
250     }
251
252   do_cleanups (old_cleanups);
253 }
254
255 static void
256 dump_memory_command (char *cmd, char *mode)
257 {
258   dump_memory_to_file (cmd, mode, "binary");
259 }
260
261 static void
262 dump_value_to_file (const char *cmd, const char *mode, const char *file_format)
263 {
264   struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
265   struct value *val;
266   const char *filename;
267
268   /* Open the file.  */
269   filename = scan_filename_with_cleanup (&cmd, NULL);
270
271   /* Find the value.  */
272   if (cmd == NULL || *cmd == '\0')
273     error (_("No value to %s."), *mode == 'a' ? "append" : "dump");
274   val = parse_and_eval (cmd);
275   if (val == NULL)
276     error (_("Invalid expression."));
277
278   /* Have everything.  Open/write the data.  */
279   if (file_format == NULL || strcmp (file_format, "binary") == 0)
280     {
281       dump_binary_file (filename, mode, value_contents (val), 
282                         TYPE_LENGTH (value_type (val)));
283     }
284   else
285     {
286       CORE_ADDR vaddr;
287
288       if (VALUE_LVAL (val))
289         {
290           vaddr = value_address (val);
291         }
292       else
293         {
294           vaddr = 0;
295           warning (_("value is not an lval: address assumed to be zero"));
296         }
297
298       dump_bfd_file (filename, mode, file_format, vaddr, 
299                      value_contents (val), 
300                      TYPE_LENGTH (value_type (val)));
301     }
302
303   do_cleanups (old_cleanups);
304 }
305
306 static void
307 dump_value_command (char *cmd, char *mode)
308 {
309   dump_value_to_file (cmd, mode, "binary");
310 }
311
312 static void
313 dump_srec_memory (char *args, int from_tty)
314 {
315   dump_memory_to_file (args, FOPEN_WB, "srec");
316 }
317
318 static void
319 dump_srec_value (char *args, int from_tty)
320 {
321   dump_value_to_file (args, FOPEN_WB, "srec");
322 }
323
324 static void
325 dump_ihex_memory (char *args, int from_tty)
326 {
327   dump_memory_to_file (args, FOPEN_WB, "ihex");
328 }
329
330 static void
331 dump_ihex_value (char *args, int from_tty)
332 {
333   dump_value_to_file (args, FOPEN_WB, "ihex");
334 }
335
336 static void
337 dump_verilog_memory (char *args, int from_tty)
338 {
339   dump_memory_to_file (args, FOPEN_WB, "verilog");
340 }
341
342 static void
343 dump_verilog_value (char *args, int from_tty)
344 {
345   dump_value_to_file (args, FOPEN_WB, "verilog");
346 }
347
348 static void
349 dump_tekhex_memory (char *args, int from_tty)
350 {
351   dump_memory_to_file (args, FOPEN_WB, "tekhex");
352 }
353
354 static void
355 dump_tekhex_value (char *args, int from_tty)
356 {
357   dump_value_to_file (args, FOPEN_WB, "tekhex");
358 }
359
360 static void
361 dump_binary_memory (char *args, int from_tty)
362 {
363   dump_memory_to_file (args, FOPEN_WB, "binary");
364 }
365
366 static void
367 dump_binary_value (char *args, int from_tty)
368 {
369   dump_value_to_file (args, FOPEN_WB, "binary");
370 }
371
372 static void
373 append_binary_memory (char *args, int from_tty)
374 {
375   dump_memory_to_file (args, FOPEN_AB, "binary");
376 }
377
378 static void
379 append_binary_value (char *args, int from_tty)
380 {
381   dump_value_to_file (args, FOPEN_AB, "binary");
382 }
383
384 struct dump_context
385 {
386   void (*func) (char *cmd, char *mode);
387   char *mode;
388 };
389
390 static void
391 call_dump_func (struct cmd_list_element *c, char *args, int from_tty)
392 {
393   struct dump_context *d = (struct dump_context *) get_cmd_context (c);
394
395   d->func (args, d->mode);
396 }
397
398 static void
399 add_dump_command (char *name, void (*func) (char *args, char *mode),
400                   char *descr)
401
402 {
403   struct cmd_list_element *c;
404   struct dump_context *d;
405
406   c = add_cmd (name, all_commands, NULL, descr, &dump_cmdlist);
407   c->completer =  filename_completer;
408   d = XNEW (struct dump_context);
409   d->func = func;
410   d->mode = FOPEN_WB;
411   set_cmd_context (c, d);
412   c->func = call_dump_func;
413
414   c = add_cmd (name, all_commands, NULL, descr, &append_cmdlist);
415   c->completer =  filename_completer;
416   d = XNEW (struct dump_context);
417   d->func = func;
418   d->mode = FOPEN_AB;
419   set_cmd_context (c, d);
420   c->func = call_dump_func;
421
422   /* Replace "Dump " at start of docstring with "Append " (borrowed
423      from [deleted] deprecated_add_show_from_set).  */
424   if (   c->doc[0] == 'W' 
425       && c->doc[1] == 'r' 
426       && c->doc[2] == 'i'
427       && c->doc[3] == 't' 
428       && c->doc[4] == 'e'
429       && c->doc[5] == ' ')
430     c->doc = concat ("Append ", c->doc + 6, (char *)NULL);
431 }
432
433 /* Opaque data for restore_section_callback.  */
434 struct callback_data {
435   CORE_ADDR load_offset;
436   CORE_ADDR load_start;
437   CORE_ADDR load_end;
438 };
439
440 /* Function: restore_section_callback.
441
442    Callback function for bfd_map_over_sections.
443    Selectively loads the sections into memory.  */
444
445 static void
446 restore_section_callback (bfd *ibfd, asection *isec, void *args)
447 {
448   struct callback_data *data = (struct callback_data *) args;
449   bfd_vma sec_start  = bfd_section_vma (ibfd, isec);
450   bfd_size_type size = bfd_section_size (ibfd, isec);
451   bfd_vma sec_end    = sec_start + size;
452   bfd_size_type sec_offset = 0;
453   bfd_size_type sec_load_count = size;
454   struct cleanup *old_chain;
455   gdb_byte *buf;
456   int ret;
457
458   /* Ignore non-loadable sections, eg. from elf files.  */
459   if (!(bfd_get_section_flags (ibfd, isec) & SEC_LOAD))
460     return;
461
462   /* Does the section overlap with the desired restore range? */
463   if (sec_end <= data->load_start 
464       || (data->load_end > 0 && sec_start >= data->load_end))
465     {
466       /* No, no useable data in this section.  */
467       printf_filtered (_("skipping section %s...\n"), 
468                        bfd_section_name (ibfd, isec));
469       return;
470     }
471
472   /* Compare section address range with user-requested
473      address range (if any).  Compute where the actual
474      transfer should start and end.  */
475   if (sec_start < data->load_start)
476     sec_offset = data->load_start - sec_start;
477   /* Size of a partial transfer.  */
478   sec_load_count -= sec_offset;
479   if (data->load_end > 0 && sec_end > data->load_end)
480     sec_load_count -= sec_end - data->load_end;
481
482   /* Get the data.  */
483   buf = (gdb_byte *) xmalloc (size);
484   old_chain = make_cleanup (xfree, buf);
485   if (!bfd_get_section_contents (ibfd, isec, buf, 0, size))
486     error (_("Failed to read bfd file %s: '%s'."), bfd_get_filename (ibfd), 
487            bfd_errmsg (bfd_get_error ()));
488
489   printf_filtered ("Restoring section %s (0x%lx to 0x%lx)",
490                    bfd_section_name (ibfd, isec), 
491                    (unsigned long) sec_start, 
492                    (unsigned long) sec_end);
493
494   if (data->load_offset != 0 || data->load_start != 0 || data->load_end != 0)
495     printf_filtered (" into memory (%s to %s)\n",
496                      paddress (target_gdbarch (),
497                                (unsigned long) sec_start
498                                + sec_offset + data->load_offset), 
499                      paddress (target_gdbarch (),
500                                (unsigned long) sec_start + sec_offset
501                                 + data->load_offset + sec_load_count));
502   else
503     puts_filtered ("\n");
504
505   /* Write the data.  */
506   ret = target_write_memory (sec_start + sec_offset + data->load_offset, 
507                              buf + sec_offset, sec_load_count);
508   if (ret != 0)
509     warning (_("restore: memory write failed (%s)."), safe_strerror (ret));
510   do_cleanups (old_chain);
511   return;
512 }
513
514 static void
515 restore_binary_file (const char *filename, struct callback_data *data)
516 {
517   struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
518   FILE *file = fopen_with_cleanup (filename, FOPEN_RB);
519   long len;
520
521   /* Get the file size for reading.  */
522   if (fseek (file, 0, SEEK_END) == 0)
523     {
524       len = ftell (file);
525       if (len < 0)
526         perror_with_name (filename);
527     }
528   else
529     perror_with_name (filename);
530
531   if (len <= data->load_start)
532     error (_("Start address is greater than length of binary file %s."), 
533            filename);
534
535   /* Chop off "len" if it exceeds the requested load_end addr.  */
536   if (data->load_end != 0 && data->load_end < len)
537     len = data->load_end;
538   /* Chop off "len" if the requested load_start addr skips some bytes.  */
539   if (data->load_start > 0)
540     len -= data->load_start;
541
542   printf_filtered 
543     ("Restoring binary file %s into memory (0x%lx to 0x%lx)\n", 
544      filename, 
545      (unsigned long) (data->load_start + data->load_offset),
546      (unsigned long) (data->load_start + data->load_offset + len));
547
548   /* Now set the file pos to the requested load start pos.  */
549   if (fseek (file, data->load_start, SEEK_SET) != 0)
550     perror_with_name (filename);
551
552   /* Now allocate a buffer and read the file contents.  */
553   gdb::unique_ptr<gdb_byte[]> buf (new gdb_byte[len]);
554   if (fread (buf.get (), 1, len, file) != len)
555     perror_with_name (filename);
556
557   /* Now write the buffer into target memory.  */
558   len = target_write_memory (data->load_start + data->load_offset,
559                              buf.get (), len);
560   if (len != 0)
561     warning (_("restore: memory write failed (%s)."), safe_strerror (len));
562   do_cleanups (cleanup);
563 }
564
565 static void
566 restore_command (char *args_in, int from_tty)
567 {
568   char *filename;
569   struct callback_data data;
570   bfd *ibfd;
571   int binary_flag = 0;
572   const char *args = args_in;
573
574   if (!target_has_execution)
575     noprocess ();
576
577   data.load_offset = 0;
578   data.load_start  = 0;
579   data.load_end    = 0;
580
581   /* Parse the input arguments.  First is filename (required).  */
582   filename = scan_filename_with_cleanup (&args, NULL);
583   if (args != NULL && *args != '\0')
584     {
585       char *binary_string = "binary";
586
587       /* Look for optional "binary" flag.  */
588       if (startswith (args, binary_string))
589         {
590           binary_flag = 1;
591           args += strlen (binary_string);
592           args = skip_spaces_const (args);
593         }
594       /* Parse offset (optional).  */
595       if (args != NULL && *args != '\0')
596         data.load_offset = binary_flag ?
597           parse_and_eval_address (scan_expression_with_cleanup (&args, NULL)) :
598           parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
599       if (args != NULL && *args != '\0')
600         {
601           /* Parse start address (optional).  */
602           data.load_start = 
603             parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
604           if (args != NULL && *args != '\0')
605             {
606               /* Parse end address (optional).  */
607               data.load_end = parse_and_eval_long (args);
608               if (data.load_end <= data.load_start)
609                 error (_("Start must be less than end."));
610             }
611         }
612     }
613
614   if (info_verbose)
615     printf_filtered ("Restore file %s offset 0x%lx start 0x%lx end 0x%lx\n",
616                      filename, (unsigned long) data.load_offset, 
617                      (unsigned long) data.load_start, 
618                      (unsigned long) data.load_end);
619
620   if (binary_flag)
621     {
622       restore_binary_file (filename, &data);
623     }
624   else
625     {
626       /* Open the file for loading.  */
627       ibfd = bfd_openr_with_cleanup (filename, NULL);
628
629       /* Process the sections.  */
630       bfd_map_over_sections (ibfd, restore_section_callback, &data);
631     }
632   return;
633 }
634
635 static void
636 srec_dump_command (char *cmd, int from_tty)
637 {
638   printf_unfiltered (_("\"dump srec\" must be followed by a subcommand.\n"));
639   help_list (srec_cmdlist, "dump srec ", all_commands, gdb_stdout);
640 }
641
642 static void
643 ihex_dump_command (char *cmd, int from_tty)
644 {
645   printf_unfiltered (_("\"dump ihex\" must be followed by a subcommand.\n"));
646   help_list (ihex_cmdlist, "dump ihex ", all_commands, gdb_stdout);
647 }
648
649 static void
650 verilog_dump_command (char *cmd, int from_tty)
651 {
652   printf_unfiltered (_("\"dump verilog\" must be followed by a subcommand.\n"));
653   help_list (verilog_cmdlist, "dump verilog ", all_commands, gdb_stdout);
654 }
655
656 static void
657 tekhex_dump_command (char *cmd, int from_tty)
658 {
659   printf_unfiltered (_("\"dump tekhex\" must be followed by a subcommand.\n"));
660   help_list (tekhex_cmdlist, "dump tekhex ", all_commands, gdb_stdout);
661 }
662
663 static void
664 binary_dump_command (char *cmd, int from_tty)
665 {
666   printf_unfiltered (_("\"dump binary\" must be followed by a subcommand.\n"));
667   help_list (binary_dump_cmdlist, "dump binary ", all_commands, gdb_stdout);
668 }
669
670 static void
671 binary_append_command (char *cmd, int from_tty)
672 {
673   printf_unfiltered (_("\"append binary\" must be followed by a subcommand.\n"));
674   help_list (binary_append_cmdlist, "append binary ", all_commands,
675              gdb_stdout);
676 }
677
678 extern initialize_file_ftype _initialize_cli_dump; /* -Wmissing-prototypes */
679
680 void
681 _initialize_cli_dump (void)
682 {
683   struct cmd_list_element *c;
684
685   add_prefix_cmd ("dump", class_vars, dump_command,
686                   _("Dump target code/data to a local file."),
687                   &dump_cmdlist, "dump ",
688                   0/*allow-unknown*/,
689                   &cmdlist);
690   add_prefix_cmd ("append", class_vars, append_command,
691                   _("Append target code/data to a local file."),
692                   &append_cmdlist, "append ",
693                   0/*allow-unknown*/,
694                   &cmdlist);
695
696   add_dump_command ("memory", dump_memory_command, "\
697 Write contents of memory to a raw binary file.\n\
698 Arguments are FILE START STOP.  Writes the contents of memory within the\n\
699 range [START .. STOP) to the specified FILE in raw target ordered bytes.");
700
701   add_dump_command ("value", dump_value_command, "\
702 Write the value of an expression to a raw binary file.\n\
703 Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION to\n\
704 the specified FILE in raw target ordered bytes.");
705
706   add_prefix_cmd ("srec", all_commands, srec_dump_command,
707                   _("Write target code/data to an srec file."),
708                   &srec_cmdlist, "dump srec ", 
709                   0 /*allow-unknown*/, 
710                   &dump_cmdlist);
711
712   add_prefix_cmd ("ihex", all_commands, ihex_dump_command,
713                   _("Write target code/data to an intel hex file."),
714                   &ihex_cmdlist, "dump ihex ", 
715                   0 /*allow-unknown*/, 
716                   &dump_cmdlist);
717
718   add_prefix_cmd ("verilog", all_commands, verilog_dump_command,
719                   _("Write target code/data to a verilog hex file."),
720                   &verilog_cmdlist, "dump verilog ",
721                   0 /*allow-unknown*/,
722                   &dump_cmdlist);
723
724   add_prefix_cmd ("tekhex", all_commands, tekhex_dump_command,
725                   _("Write target code/data to a tekhex file."),
726                   &tekhex_cmdlist, "dump tekhex ", 
727                   0 /*allow-unknown*/, 
728                   &dump_cmdlist);
729
730   add_prefix_cmd ("binary", all_commands, binary_dump_command,
731                   _("Write target code/data to a raw binary file."),
732                   &binary_dump_cmdlist, "dump binary ", 
733                   0 /*allow-unknown*/, 
734                   &dump_cmdlist);
735
736   add_prefix_cmd ("binary", all_commands, binary_append_command,
737                   _("Append target code/data to a raw binary file."),
738                   &binary_append_cmdlist, "append binary ", 
739                   0 /*allow-unknown*/, 
740                   &append_cmdlist);
741
742   add_cmd ("memory", all_commands, dump_srec_memory, _("\
743 Write contents of memory to an srec file.\n\
744 Arguments are FILE START STOP.  Writes the contents of memory\n\
745 within the range [START .. STOP) to the specified FILE in srec format."),
746            &srec_cmdlist);
747
748   add_cmd ("value", all_commands, dump_srec_value, _("\
749 Write the value of an expression to an srec file.\n\
750 Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
751 to the specified FILE in srec format."),
752            &srec_cmdlist);
753
754   add_cmd ("memory", all_commands, dump_ihex_memory, _("\
755 Write contents of memory to an ihex file.\n\
756 Arguments are FILE START STOP.  Writes the contents of memory within\n\
757 the range [START .. STOP) to the specified FILE in intel hex format."),
758            &ihex_cmdlist);
759
760   add_cmd ("value", all_commands, dump_ihex_value, _("\
761 Write the value of an expression to an ihex file.\n\
762 Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
763 to the specified FILE in intel hex format."),
764            &ihex_cmdlist);
765
766   add_cmd ("memory", all_commands, dump_verilog_memory, _("\
767 Write contents of memory to a verilog hex file.\n\
768 Arguments are FILE START STOP.  Writes the contents of memory within\n\
769 the range [START .. STOP) to the specified FILE in verilog hex format."),
770            &verilog_cmdlist);
771
772   add_cmd ("value", all_commands, dump_verilog_value, _("\
773 Write the value of an expression to a verilog hex file.\n\
774 Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
775 to the specified FILE in verilog hex format."),
776            &verilog_cmdlist);
777
778   add_cmd ("memory", all_commands, dump_tekhex_memory, _("\
779 Write contents of memory to a tekhex file.\n\
780 Arguments are FILE START STOP.  Writes the contents of memory\n\
781 within the range [START .. STOP) to the specified FILE in tekhex format."),
782            &tekhex_cmdlist);
783
784   add_cmd ("value", all_commands, dump_tekhex_value, _("\
785 Write the value of an expression to a tekhex file.\n\
786 Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
787 to the specified FILE in tekhex format."),
788            &tekhex_cmdlist);
789
790   add_cmd ("memory", all_commands, dump_binary_memory, _("\
791 Write contents of memory to a raw binary file.\n\
792 Arguments are FILE START STOP.  Writes the contents of memory\n\
793 within the range [START .. STOP) to the specified FILE in binary format."),
794            &binary_dump_cmdlist);
795
796   add_cmd ("value", all_commands, dump_binary_value, _("\
797 Write the value of an expression to a raw binary file.\n\
798 Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
799 to the specified FILE in raw target ordered bytes."),
800            &binary_dump_cmdlist);
801
802   add_cmd ("memory", all_commands, append_binary_memory, _("\
803 Append contents of memory to a raw binary file.\n\
804 Arguments are FILE START STOP.  Writes the contents of memory within the\n\
805 range [START .. STOP) to the specified FILE in raw target ordered bytes."),
806            &binary_append_cmdlist);
807
808   add_cmd ("value", all_commands, append_binary_value, _("\
809 Append the value of an expression to a raw binary file.\n\
810 Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION\n\
811 to the specified FILE in raw target ordered bytes."),
812            &binary_append_cmdlist);
813
814   c = add_com ("restore", class_vars, restore_command, _("\
815 Restore the contents of FILE to target memory.\n\
816 Arguments are FILE OFFSET START END where all except FILE are optional.\n\
817 OFFSET will be added to the base address of the file (default zero).\n\
818 If START and END are given, only the file contents within that range\n\
819 (file relative) will be restored to target memory."));
820   c->completer = filename_completer;
821   /* FIXME: completers for other commands.  */
822 }