]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/cli/cli-dump.c
143d02ab88d70e35635e69c5dc170db793899fea
[thirdparty/binutils-gdb.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 }