]> Git Repo - binutils.git/blob - gdb/cli/cli-dump.c
gdb: remove TYPE_LENGTH
[binutils.git] / gdb / cli / cli-dump.c
1 /* Dump-to-file commands, for GDB, the GNU debugger.
2
3    Copyright (C) 2002-2022 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).data (),
228                       value_type (val)->length ());
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).data (), 
245                      value_type (val)->length ());
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 (const char *args, int from_tty, cmd_list_element *c)
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       gdb_printf (_("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   gdb_printf ("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     gdb_printf (" 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     gdb_puts ("\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   gdb_printf 
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     gdb_printf ("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.066791 seconds and 4 git commands to generate.