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