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