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