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