OLD | NEW |
1 /* Dump-to-file commands, for GDB, the GNU debugger. | 1 /* Dump-to-file commands, for GDB, the GNU debugger. |
2 | 2 |
3 Copyright (c) 2002, 2005, 2007-2012 Free Software Foundation, Inc. | 3 Copyright (C) 2002-2013 Free Software Foundation, Inc. |
4 | 4 |
5 Contributed by Red Hat. | 5 Contributed by Red Hat. |
6 | 6 |
7 This file is part of GDB. | 7 This file is part of GDB. |
8 | 8 |
9 This program is free software; you can redistribute it and/or modify | 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 | 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 | 11 the Free Software Foundation; either version 3 of the License, or |
12 (at your option) any later version. | 12 (at your option) any later version. |
13 | 13 |
14 This program is distributed in the hope that it will be useful, | 14 This program is distributed in the hope that it will be useful, |
15 but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 GNU General Public License for more details. | 17 GNU General Public License for more details. |
18 | 18 |
19 You should have received a copy of the GNU General Public License | 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/>. */ | 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
21 | 21 |
22 #include "defs.h" | 22 #include "defs.h" |
23 #include "gdb_string.h" | 23 #include <string.h> |
24 #include "cli/cli-decode.h" | 24 #include "cli/cli-decode.h" |
25 #include "cli/cli-cmds.h" | 25 #include "cli/cli-cmds.h" |
26 #include "value.h" | 26 #include "value.h" |
27 #include "completer.h" | 27 #include "completer.h" |
28 #include "cli/cli-dump.h" | |
29 #include "gdb_assert.h" | 28 #include "gdb_assert.h" |
30 #include <ctype.h> | 29 #include <ctype.h> |
31 #include "target.h" | 30 #include "target.h" |
32 #include "readline/readline.h" | 31 #include "readline/readline.h" |
33 #include "gdbcore.h" | 32 #include "gdbcore.h" |
34 #include "cli/cli-utils.h" | 33 #include "cli/cli-utils.h" |
35 | 34 #include "gdb_bfd.h" |
36 #define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) | 35 #include "filestuff.h" |
37 | 36 |
38 | 37 |
39 char * | 38 static char * |
40 scan_expression_with_cleanup (char **cmd, const char *def) | 39 scan_expression_with_cleanup (char **cmd, const char *def) |
41 { | 40 { |
42 if ((*cmd) == NULL || (**cmd) == '\0') | 41 if ((*cmd) == NULL || (**cmd) == '\0') |
43 { | 42 { |
44 char *exp = xstrdup (def); | 43 char *exp = xstrdup (def); |
45 | 44 |
46 make_cleanup (xfree, exp); | 45 make_cleanup (xfree, exp); |
47 return exp; | 46 return exp; |
48 } | 47 } |
49 else | 48 else |
50 { | 49 { |
51 char *exp; | 50 char *exp; |
52 char *end; | 51 char *end; |
53 | 52 |
54 end = (*cmd) + strcspn (*cmd, " \t"); | 53 end = (*cmd) + strcspn (*cmd, " \t"); |
55 exp = savestring ((*cmd), end - (*cmd)); | 54 exp = savestring ((*cmd), end - (*cmd)); |
56 make_cleanup (xfree, exp); | 55 make_cleanup (xfree, exp); |
57 (*cmd) = skip_spaces (end); | 56 (*cmd) = skip_spaces (end); |
58 return exp; | 57 return exp; |
59 } | 58 } |
60 } | 59 } |
61 | 60 |
62 | 61 |
63 char * | 62 static char * |
64 scan_filename_with_cleanup (char **cmd, const char *defname) | 63 scan_filename_with_cleanup (char **cmd, const char *defname) |
65 { | 64 { |
66 char *filename; | 65 char *filename; |
67 char *fullname; | 66 char *fullname; |
68 | 67 |
69 /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere. */ | 68 /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere. */ |
70 | 69 |
71 /* File. */ | 70 /* File. */ |
72 if ((*cmd) == NULL) | 71 if ((*cmd) == NULL) |
73 { | 72 { |
(...skipping 14 matching lines...) Expand all Loading... |
88 (*cmd) = skip_spaces (end); | 87 (*cmd) = skip_spaces (end); |
89 } | 88 } |
90 gdb_assert (filename != NULL); | 89 gdb_assert (filename != NULL); |
91 | 90 |
92 fullname = tilde_expand (filename); | 91 fullname = tilde_expand (filename); |
93 make_cleanup (xfree, fullname); | 92 make_cleanup (xfree, fullname); |
94 | 93 |
95 return fullname; | 94 return fullname; |
96 } | 95 } |
97 | 96 |
98 FILE * | 97 static FILE * |
99 fopen_with_cleanup (const char *filename, const char *mode) | 98 fopen_with_cleanup (const char *filename, const char *mode) |
100 { | 99 { |
101 FILE *file = fopen (filename, mode); | 100 FILE *file = gdb_fopen_cloexec (filename, mode); |
102 | 101 |
103 if (file == NULL) | 102 if (file == NULL) |
104 perror_with_name (filename); | 103 perror_with_name (filename); |
105 make_cleanup_fclose (file); | 104 make_cleanup_fclose (file); |
106 return file; | 105 return file; |
107 } | 106 } |
108 | 107 |
109 static bfd * | 108 static bfd * |
110 bfd_openr_with_cleanup (const char *filename, const char *target) | 109 bfd_openr_with_cleanup (const char *filename, const char *target) |
111 { | 110 { |
112 bfd *ibfd; | 111 bfd *ibfd; |
113 | 112 |
114 ibfd = bfd_openr (filename, target); | 113 ibfd = gdb_bfd_openr (filename, target); |
115 if (ibfd == NULL) | 114 if (ibfd == NULL) |
116 error (_("Failed to open %s: %s."), filename, | 115 error (_("Failed to open %s: %s."), filename, |
117 bfd_errmsg (bfd_get_error ())); | 116 bfd_errmsg (bfd_get_error ())); |
118 | 117 |
119 make_cleanup_bfd_close (ibfd); | 118 make_cleanup_bfd_unref (ibfd); |
120 if (!bfd_check_format (ibfd, bfd_object)) | 119 if (!bfd_check_format (ibfd, bfd_object)) |
121 error (_("'%s' is not a recognized file format."), filename); | 120 error (_("'%s' is not a recognized file format."), filename); |
122 | 121 |
123 return ibfd; | 122 return ibfd; |
124 } | 123 } |
125 | 124 |
126 static bfd * | 125 static bfd * |
127 bfd_openw_with_cleanup (const char *filename, const char *target, | 126 bfd_openw_with_cleanup (const char *filename, const char *target, |
128 const char *mode) | 127 const char *mode) |
129 { | 128 { |
130 bfd *obfd; | 129 bfd *obfd; |
131 | 130 |
132 if (*mode == 'w') /* Write: create new file */ | 131 if (*mode == 'w') /* Write: create new file */ |
133 { | 132 { |
134 obfd = bfd_openw (filename, target); | 133 obfd = gdb_bfd_openw (filename, target); |
135 if (obfd == NULL) | 134 if (obfd == NULL) |
136 error (_("Failed to open %s: %s."), filename, | 135 error (_("Failed to open %s: %s."), filename, |
137 bfd_errmsg (bfd_get_error ())); | 136 bfd_errmsg (bfd_get_error ())); |
138 make_cleanup_bfd_close (obfd); | 137 make_cleanup_bfd_unref (obfd); |
139 if (!bfd_set_format (obfd, bfd_object)) | 138 if (!bfd_set_format (obfd, bfd_object)) |
140 error (_("bfd_openw_with_cleanup: %s."), bfd_errmsg (bfd_get_error ())); | 139 error (_("bfd_openw_with_cleanup: %s."), bfd_errmsg (bfd_get_error ())); |
141 } | 140 } |
142 else if (*mode == 'a') /* Append to existing file. */ | 141 else if (*mode == 'a') /* Append to existing file. */ |
143 { /* FIXME -- doesn't work... */ | 142 { /* FIXME -- doesn't work... */ |
144 error (_("bfd_openw does not work with append.")); | 143 error (_("bfd_openw does not work with append.")); |
145 } | 144 } |
146 else | 145 else |
147 error (_("bfd_openw_with_cleanup: unknown mode %s."), mode); | 146 error (_("bfd_openw_with_cleanup: unknown mode %s."), mode); |
148 | 147 |
149 return obfd; | 148 return obfd; |
150 } | 149 } |
151 | 150 |
152 struct cmd_list_element *dump_cmdlist; | 151 static struct cmd_list_element *dump_cmdlist; |
153 struct cmd_list_element *append_cmdlist; | 152 static struct cmd_list_element *append_cmdlist; |
154 struct cmd_list_element *srec_cmdlist; | 153 static struct cmd_list_element *srec_cmdlist; |
155 struct cmd_list_element *ihex_cmdlist; | 154 static struct cmd_list_element *ihex_cmdlist; |
156 struct cmd_list_element *tekhex_cmdlist; | 155 static struct cmd_list_element *tekhex_cmdlist; |
157 struct cmd_list_element *binary_dump_cmdlist; | 156 static struct cmd_list_element *binary_dump_cmdlist; |
158 struct cmd_list_element *binary_append_cmdlist; | 157 static struct cmd_list_element *binary_append_cmdlist; |
159 | 158 |
160 static void | 159 static void |
161 dump_command (char *cmd, int from_tty) | 160 dump_command (char *cmd, int from_tty) |
162 { | 161 { |
163 printf_unfiltered (_("\"dump\" must be followed by a subcommand.\n\n")); | 162 printf_unfiltered (_("\"dump\" must be followed by a subcommand.\n\n")); |
164 help_list (dump_cmdlist, "dump ", -1, gdb_stdout); | 163 help_list (dump_cmdlist, "dump ", -1, gdb_stdout); |
165 } | 164 } |
166 | 165 |
167 static void | 166 static void |
168 append_command (char *cmd, int from_tty) | 167 append_command (char *cmd, int from_tty) |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 }; | 379 }; |
381 | 380 |
382 static void | 381 static void |
383 call_dump_func (struct cmd_list_element *c, char *args, int from_tty) | 382 call_dump_func (struct cmd_list_element *c, char *args, int from_tty) |
384 { | 383 { |
385 struct dump_context *d = get_cmd_context (c); | 384 struct dump_context *d = get_cmd_context (c); |
386 | 385 |
387 d->func (args, d->mode); | 386 d->func (args, d->mode); |
388 } | 387 } |
389 | 388 |
390 void | 389 static void |
391 add_dump_command (char *name, void (*func) (char *args, char *mode), | 390 add_dump_command (char *name, void (*func) (char *args, char *mode), |
392 char *descr) | 391 char *descr) |
393 | 392 |
394 { | 393 { |
395 struct cmd_list_element *c; | 394 struct cmd_list_element *c; |
396 struct dump_context *d; | 395 struct dump_context *d; |
397 | 396 |
398 c = add_cmd (name, all_commands, NULL, descr, &dump_cmdlist); | 397 c = add_cmd (name, all_commands, NULL, descr, &dump_cmdlist); |
399 c->completer = filename_completer; | 398 c->completer = filename_completer; |
400 d = XMALLOC (struct dump_context); | 399 d = XMALLOC (struct dump_context); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 error (_("Failed to read bfd file %s: '%s'."), bfd_get_filename (ibfd), | 477 error (_("Failed to read bfd file %s: '%s'."), bfd_get_filename (ibfd), |
479 bfd_errmsg (bfd_get_error ())); | 478 bfd_errmsg (bfd_get_error ())); |
480 | 479 |
481 printf_filtered ("Restoring section %s (0x%lx to 0x%lx)", | 480 printf_filtered ("Restoring section %s (0x%lx to 0x%lx)", |
482 bfd_section_name (ibfd, isec), | 481 bfd_section_name (ibfd, isec), |
483 (unsigned long) sec_start, | 482 (unsigned long) sec_start, |
484 (unsigned long) sec_end); | 483 (unsigned long) sec_end); |
485 | 484 |
486 if (data->load_offset != 0 || data->load_start != 0 || data->load_end != 0) | 485 if (data->load_offset != 0 || data->load_start != 0 || data->load_end != 0) |
487 printf_filtered (" into memory (%s to %s)\n", | 486 printf_filtered (" into memory (%s to %s)\n", |
488 » » paddress (target_gdbarch, | 487 » » paddress (target_gdbarch (), |
489 (unsigned long) sec_start | 488 (unsigned long) sec_start |
490 + sec_offset + data->load_offset), | 489 + sec_offset + data->load_offset), |
491 » » paddress (target_gdbarch, | 490 » » paddress (target_gdbarch (), |
492 (unsigned long) sec_start + sec_offset | 491 (unsigned long) sec_start + sec_offset |
493 + data->load_offset + sec_load_count)); | 492 + data->load_offset + sec_load_count)); |
494 else | 493 else |
495 puts_filtered ("\n"); | 494 puts_filtered ("\n"); |
496 | 495 |
497 /* Write the data. */ | 496 /* Write the data. */ |
498 ret = target_write_memory (sec_start + sec_offset + data->load_offset, | 497 ret = target_write_memory (sec_start + sec_offset + data->load_offset, |
499 buf + sec_offset, sec_load_count); | 498 buf + sec_offset, sec_load_count); |
500 if (ret != 0) | 499 if (ret != 0) |
501 warning (_("restore: memory write failed (%s)."), safe_strerror (ret)); | 500 warning (_("restore: memory write failed (%s)."), safe_strerror (ret)); |
502 do_cleanups (old_chain); | 501 do_cleanups (old_chain); |
503 return; | 502 return; |
504 } | 503 } |
505 | 504 |
506 static void | 505 static void |
507 restore_binary_file (char *filename, struct callback_data *data) | 506 restore_binary_file (char *filename, struct callback_data *data) |
508 { | 507 { |
| 508 struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); |
509 FILE *file = fopen_with_cleanup (filename, FOPEN_RB); | 509 FILE *file = fopen_with_cleanup (filename, FOPEN_RB); |
510 gdb_byte *buf; | 510 gdb_byte *buf; |
511 long len; | 511 long len; |
512 | 512 |
513 /* Get the file size for reading. */ | 513 /* Get the file size for reading. */ |
514 if (fseek (file, 0, SEEK_END) == 0) | 514 if (fseek (file, 0, SEEK_END) == 0) |
515 { | 515 { |
516 len = ftell (file); | 516 len = ftell (file); |
517 if (len < 0) | 517 if (len < 0) |
518 perror_with_name (filename); | 518 perror_with_name (filename); |
(...skipping 25 matching lines...) Expand all Loading... |
544 /* Now allocate a buffer and read the file contents. */ | 544 /* Now allocate a buffer and read the file contents. */ |
545 buf = xmalloc (len); | 545 buf = xmalloc (len); |
546 make_cleanup (xfree, buf); | 546 make_cleanup (xfree, buf); |
547 if (fread (buf, 1, len, file) != len) | 547 if (fread (buf, 1, len, file) != len) |
548 perror_with_name (filename); | 548 perror_with_name (filename); |
549 | 549 |
550 /* Now write the buffer into target memory. */ | 550 /* Now write the buffer into target memory. */ |
551 len = target_write_memory (data->load_start + data->load_offset, buf, len); | 551 len = target_write_memory (data->load_start + data->load_offset, buf, len); |
552 if (len != 0) | 552 if (len != 0) |
553 warning (_("restore: memory write failed (%s)."), safe_strerror (len)); | 553 warning (_("restore: memory write failed (%s)."), safe_strerror (len)); |
554 return; | 554 do_cleanups (cleanup); |
555 } | 555 } |
556 | 556 |
557 static void | 557 static void |
558 restore_command (char *args, int from_tty) | 558 restore_command (char *args, int from_tty) |
559 { | 559 { |
560 char *filename; | 560 char *filename; |
561 struct callback_data data; | 561 struct callback_data data; |
562 bfd *ibfd; | 562 bfd *ibfd; |
563 int binary_flag = 0; | 563 int binary_flag = 0; |
564 | 564 |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
777 | 777 |
778 c = add_com ("restore", class_vars, restore_command, _("\ | 778 c = add_com ("restore", class_vars, restore_command, _("\ |
779 Restore the contents of FILE to target memory.\n\ | 779 Restore the contents of FILE to target memory.\n\ |
780 Arguments are FILE OFFSET START END where all except FILE are optional.\n\ | 780 Arguments are FILE OFFSET START END where all except FILE are optional.\n\ |
781 OFFSET will be added to the base address of the file (default zero).\n\ | 781 OFFSET will be added to the base address of the file (default zero).\n\ |
782 If START and END are given, only the file contents within that range\n\ | 782 If START and END are given, only the file contents within that range\n\ |
783 (file relative) will be restored to target memory.")); | 783 (file relative) will be restored to target memory.")); |
784 c->completer = filename_completer; | 784 c->completer = filename_completer; |
785 /* FIXME: completers for other commands. */ | 785 /* FIXME: completers for other commands. */ |
786 } | 786 } |
OLD | NEW |