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