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