📄 cli-dump.c
字号:
/* Dump-to-file commands, for GDB, the GNU debugger. Copyright 2002 Free Software Foundation, Inc. Contributed by Red Hat. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "defs.h"#include "gdb_string.h"#include "cli/cli-decode.h"#include "cli/cli-cmds.h"#include "value.h"#include "completer.h"#include "cli/cli-dump.h"#include "gdb_assert.h"#include <ctype.h>#include "target.h"#include "readline/readline.h"#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))char *skip_spaces (char *chp){ if (chp == NULL) return NULL; while (isspace (*chp)) chp++; return chp;}char *scan_expression_with_cleanup (char **cmd, const char *def){ if ((*cmd) == NULL || (**cmd) == '\0') { char *exp = xstrdup (def); make_cleanup (xfree, exp); return exp; } else { char *exp; char *end; end = (*cmd) + strcspn (*cmd, " \t"); exp = savestring ((*cmd), end - (*cmd)); make_cleanup (xfree, exp); (*cmd) = skip_spaces (end); return exp; }}static voiddo_fclose_cleanup (void *arg){ FILE *file = arg; fclose (arg);}static struct cleanup *make_cleanup_fclose (FILE *file){ return make_cleanup (do_fclose_cleanup, file);}char *scan_filename_with_cleanup (char **cmd, const char *defname){ char *filename; char *fullname; /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere. */ /* File. */ if ((*cmd) == NULL) { if (defname == NULL) error ("Missing filename."); filename = xstrdup (defname); make_cleanup (xfree, filename); } else { /* FIXME: should parse a possibly quoted string. */ char *end; (*cmd) = skip_spaces (*cmd); end = *cmd + strcspn (*cmd, " \t"); filename = savestring ((*cmd), end - (*cmd)); make_cleanup (xfree, filename); (*cmd) = skip_spaces (end); } gdb_assert (filename != NULL); fullname = tilde_expand (filename); make_cleanup (xfree, fullname); return fullname;}FILE *fopen_with_cleanup (char *filename, const char *mode){ FILE *file = fopen (filename, mode); if (file == NULL) perror_with_name (filename); make_cleanup_fclose (file); return file;}static bfd *bfd_openr_with_cleanup (const char *filename, const char *target){ bfd *ibfd; ibfd = bfd_openr (filename, target); if (ibfd == NULL) error ("Failed to open %s: %s.", filename, bfd_errmsg (bfd_get_error ())); make_cleanup_bfd_close (ibfd); if (!bfd_check_format (ibfd, bfd_object)) error ("'%s' is not a recognized file format.", filename); return ibfd;}static bfd *bfd_openw_with_cleanup (char *filename, const char *target, char *mode){ bfd *obfd; if (*mode == 'w') /* Write: create new file */ { obfd = bfd_openw (filename, target); if (obfd == NULL) error ("Failed to open %s: %s.", filename, bfd_errmsg (bfd_get_error ())); make_cleanup_bfd_close (obfd); if (!bfd_set_format (obfd, bfd_object)) error ("bfd_openw_with_cleanup: %s.", bfd_errmsg (bfd_get_error ())); } else if (*mode == 'a') /* Append to existing file */ { /* FIXME -- doesn't work... */ error ("bfd_openw does not work with append."); } else error ("bfd_openw_with_cleanup: unknown mode %s.", mode); return obfd;}struct cmd_list_element *dump_cmdlist;struct cmd_list_element *append_cmdlist;struct cmd_list_element *srec_cmdlist;struct cmd_list_element *ihex_cmdlist;struct cmd_list_element *tekhex_cmdlist;struct cmd_list_element *binary_dump_cmdlist;struct cmd_list_element *binary_append_cmdlist;static voiddump_command (char *cmd, int from_tty){ printf_unfiltered ("\"dump\" must be followed by a subcommand.\n\n"); help_list (dump_cmdlist, "dump ", -1, gdb_stdout);}static voidappend_command (char *cmd, int from_tty){ printf_unfiltered ("\"append\" must be followed by a subcommand.\n\n"); help_list (dump_cmdlist, "append ", -1, gdb_stdout);}static voiddump_binary_file (char *filename, char *mode, char *buf, int len){ FILE *file; int status; file = fopen_with_cleanup (filename, mode); status = fwrite (buf, len, 1, file); if (status != 1) perror_with_name (filename);}static voiddump_bfd_file (char *filename, char *mode, char *target, CORE_ADDR vaddr, char *buf, int len){ bfd *obfd; asection *osection; obfd = bfd_openw_with_cleanup (filename, target, mode); osection = bfd_make_section_anyway (obfd, ".newsec"); bfd_set_section_size (obfd, osection, len); bfd_set_section_vma (obfd, osection, vaddr); bfd_set_section_alignment (obfd, osection, 0); bfd_set_section_flags (obfd, osection, 0x203); osection->entsize = 0; bfd_set_section_contents (obfd, osection, buf, 0, len);}static voiddump_memory_to_file (char *cmd, char *mode, char *file_format){ struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL); CORE_ADDR lo; CORE_ADDR hi; ULONGEST count; char *filename; void *buf; char *lo_exp; char *hi_exp; int len; /* Open the file. */ filename = scan_filename_with_cleanup (&cmd, NULL); /* Find the low address. */ if (cmd == NULL || *cmd == '\0') error ("Missing start address."); lo_exp = scan_expression_with_cleanup (&cmd, NULL); /* Find the second address - rest of line. */ if (cmd == NULL || *cmd == '\0') error ("Missing stop address."); hi_exp = cmd; lo = parse_and_eval_address (lo_exp); hi = parse_and_eval_address (hi_exp); if (hi <= lo) error ("Invalid memory address range (start >= end)."); count = hi - lo; /* FIXME: Should use read_memory_partial() and a magic blocking value. */ buf = xmalloc (count); make_cleanup (xfree, buf); target_read_memory (lo, buf, count); /* Have everything. Open/write the data. */ if (file_format == NULL || strcmp (file_format, "binary") == 0) { dump_binary_file (filename, mode, buf, count); } else { dump_bfd_file (filename, mode, file_format, lo, buf, count); } do_cleanups (old_cleanups);}static voiddump_memory_command (char *cmd, char *mode){ dump_memory_to_file (cmd, mode, "binary");}static voiddump_value_to_file (char *cmd, char *mode, char *file_format){ struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL); struct value *val; char *filename; /* Open the file. */ filename = scan_filename_with_cleanup (&cmd, NULL); /* Find the value. */ if (cmd == NULL || *cmd == '\0') error ("No value to %s.", *mode == 'a' ? "append" : "dump"); val = parse_and_eval (cmd); if (val == NULL) error ("Invalid expression."); /* Have everything. Open/write the data. */ if (file_format == NULL || strcmp (file_format, "binary") == 0) { dump_binary_file (filename, mode, VALUE_CONTENTS (val), TYPE_LENGTH (VALUE_TYPE (val))); } else { CORE_ADDR vaddr; if (VALUE_LVAL (val)) { vaddr = VALUE_ADDRESS (val); } else { vaddr = 0; warning ("value is not an lval: address assumed to be zero"); } dump_bfd_file (filename, mode, file_format, vaddr, VALUE_CONTENTS (val), TYPE_LENGTH (VALUE_TYPE (val))); } do_cleanups (old_cleanups);}static voiddump_value_command (char *cmd, char *mode){ dump_value_to_file (cmd, mode, "binary");}static voiddump_srec_memory (char *args, int from_tty){ dump_memory_to_file (args, FOPEN_WB, "srec");}static voiddump_srec_value (char *args, int from_tty){ dump_value_to_file (args, FOPEN_WB, "srec");}static voiddump_ihex_memory (char *args, int from_tty){ dump_memory_to_file (args, FOPEN_WB, "ihex");}static voiddump_ihex_value (char *args, int from_tty){ dump_value_to_file (args, FOPEN_WB, "ihex");}static voiddump_tekhex_memory (char *args, int from_tty){ dump_memory_to_file (args, FOPEN_WB, "tekhex");}static voiddump_tekhex_value (char *args, int from_tty){ dump_value_to_file (args, FOPEN_WB, "tekhex");}static voiddump_binary_memory (char *args, int from_tty){ dump_memory_to_file (args, FOPEN_WB, "binary");}static voiddump_binary_value (char *args, int from_tty){ dump_value_to_file (args, FOPEN_WB, "binary");}static voidappend_binary_memory (char *args, int from_tty){ dump_memory_to_file (args, FOPEN_AB, "binary");}static voidappend_binary_value (char *args, int from_tty){ dump_value_to_file (args, FOPEN_AB, "binary");}struct dump_context{ void (*func) (char *cmd, char *mode); char *mode;};static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -