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