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