X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fcli%2Fcli-dump.c;h=7c4f63be06d38ab0c76370e6b0f76a91f74f0b9d;hb=7cac64af7bc6a7f7a86f90a1465f7c3d2b6f07e8;hp=2449dc5d89cadf1bf4d1a235767cdb023756da91;hpb=6faec16b1c633a8043791e0d15d7e7f1c8d448c1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c index 2449dc5d89..7c4f63be06 100644 --- a/gdb/cli/cli-dump.c +++ b/gdb/cli/cli-dump.c @@ -1,6 +1,6 @@ /* Dump-to-file commands, for GDB, the GNU debugger. - Copyright (C) 2002-2015 Free Software Foundation, Inc. + Copyright (C) 2002-2019 Free Software Foundation, Inc. Contributed by Red Hat. @@ -26,23 +26,19 @@ #include "completer.h" #include #include "target.h" -#include "readline/readline.h" +#include "readline/tilde.h" #include "gdbcore.h" #include "cli/cli-utils.h" #include "gdb_bfd.h" -#include "filestuff.h" +#include "gdbsupport/filestuff.h" +#include "gdbsupport/byte-vector.h" +#include "gdbarch.h" - -static const char * -scan_expression_with_cleanup (const char **cmd, const char *def) +static gdb::unique_xmalloc_ptr +scan_expression (const char **cmd, const char *def) { if ((*cmd) == NULL || (**cmd) == '\0') - { - char *exp = xstrdup (def); - - make_cleanup (xfree, exp); - return exp; - } + return make_unique_xstrdup (def); else { char *exp; @@ -50,18 +46,16 @@ scan_expression_with_cleanup (const char **cmd, const char *def) end = (*cmd) + strcspn (*cmd, " \t"); exp = savestring ((*cmd), end - (*cmd)); - make_cleanup (xfree, exp); - (*cmd) = skip_spaces_const (end); - return exp; + (*cmd) = skip_spaces (end); + return gdb::unique_xmalloc_ptr (exp); } } -static char * -scan_filename_with_cleanup (const char **cmd, const char *defname) +static gdb::unique_xmalloc_ptr +scan_filename (const char **cmd, const char *defname) { - char *filename; - char *fullname; + gdb::unique_xmalloc_ptr filename; /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere. */ @@ -70,78 +64,57 @@ scan_filename_with_cleanup (const char **cmd, const char *defname) { if (defname == NULL) error (_("Missing filename.")); - filename = xstrdup (defname); - make_cleanup (xfree, filename); + filename.reset (xstrdup (defname)); } else { /* FIXME: should parse a possibly quoted string. */ const char *end; - (*cmd) = skip_spaces_const (*cmd); + (*cmd) = skip_spaces (*cmd); end = *cmd + strcspn (*cmd, " \t"); - filename = savestring ((*cmd), end - (*cmd)); - make_cleanup (xfree, filename); - (*cmd) = skip_spaces_const (end); + filename.reset (savestring ((*cmd), end - (*cmd))); + (*cmd) = skip_spaces (end); } gdb_assert (filename != NULL); - fullname = tilde_expand (filename); - make_cleanup (xfree, fullname); - - return fullname; -} - -static FILE * -fopen_with_cleanup (const char *filename, const char *mode) -{ - FILE *file = gdb_fopen_cloexec (filename, mode); - - if (file == NULL) - perror_with_name (filename); - make_cleanup_fclose (file); - return file; + return gdb::unique_xmalloc_ptr (tilde_expand (filename.get ())); } -static bfd * -bfd_openr_with_cleanup (const char *filename, const char *target) +static gdb_bfd_ref_ptr +bfd_openr_or_error (const char *filename, const char *target) { - bfd *ibfd; - - ibfd = gdb_bfd_openr (filename, target); + gdb_bfd_ref_ptr ibfd (gdb_bfd_openr (filename, target)); if (ibfd == NULL) - error (_("Failed to open %s: %s."), filename, + error (_("Failed to open %s: %s."), filename, bfd_errmsg (bfd_get_error ())); - make_cleanup_bfd_unref (ibfd); - if (!bfd_check_format (ibfd, bfd_object)) + if (!bfd_check_format (ibfd.get (), bfd_object)) error (_("'%s' is not a recognized file format."), filename); return ibfd; } -static bfd * -bfd_openw_with_cleanup (const char *filename, const char *target, - const char *mode) +static gdb_bfd_ref_ptr +bfd_openw_or_error (const char *filename, const char *target, const char *mode) { - bfd *obfd; + gdb_bfd_ref_ptr obfd; if (*mode == 'w') /* Write: create new file */ { obfd = gdb_bfd_openw (filename, target); if (obfd == NULL) - error (_("Failed to open %s: %s."), filename, + error (_("Failed to open %s: %s."), filename, bfd_errmsg (bfd_get_error ())); - make_cleanup_bfd_unref (obfd); - if (!bfd_set_format (obfd, bfd_object)) - error (_("bfd_openw_with_cleanup: %s."), bfd_errmsg (bfd_get_error ())); + if (!bfd_set_format (obfd.get (), bfd_object)) + error (_("bfd_openw_or_error: %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); + error (_("bfd_openw_or_error: unknown mode %s."), mode); return obfd; } @@ -156,14 +129,14 @@ static struct cmd_list_element *binary_dump_cmdlist; static struct cmd_list_element *binary_append_cmdlist; static void -dump_command (char *cmd, int from_tty) +dump_command (const char *cmd, int from_tty) { printf_unfiltered (_("\"dump\" must be followed by a subcommand.\n\n")); help_list (dump_cmdlist, "dump ", all_commands, gdb_stdout); } static void -append_command (char *cmd, int from_tty) +append_command (const char *cmd, int from_tty) { printf_unfiltered (_("\"append\" must be followed by a subcommand.\n\n")); help_list (dump_cmdlist, "append ", all_commands, gdb_stdout); @@ -173,11 +146,10 @@ static void dump_binary_file (const char *filename, const char *mode, const bfd_byte *buf, ULONGEST len) { - FILE *file; int status; - file = fopen_with_cleanup (filename, mode); - status = fwrite (buf, len, 1, file); + gdb_file_up file = gdb_fopen_cloexec (filename, mode); + status = fwrite (buf, len, 1, file.get ()); if (status != 1) perror_with_name (filename); } @@ -187,49 +159,42 @@ dump_bfd_file (const char *filename, const char *mode, const char *target, CORE_ADDR vaddr, const bfd_byte *buf, ULONGEST 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, (SEC_HAS_CONTENTS - | SEC_ALLOC - | SEC_LOAD)); + gdb_bfd_ref_ptr obfd (bfd_openw_or_error (filename, target, mode)); + osection = bfd_make_section_anyway (obfd.get (), ".newsec"); + bfd_set_section_size (osection, len); + bfd_set_section_vma (osection, vaddr); + bfd_set_section_alignment (osection, 0); + bfd_set_section_flags (osection, (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD)); osection->entsize = 0; - if (!bfd_set_section_contents (obfd, osection, buf, 0, len)) - warning (_("writing dump file '%s' (%s)"), filename, + if (!bfd_set_section_contents (obfd.get (), osection, buf, 0, len)) + warning (_("writing dump file '%s' (%s)"), filename, bfd_errmsg (bfd_get_error ())); } static void dump_memory_to_file (const char *cmd, const char *mode, const char *file_format) { - struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL); CORE_ADDR lo; CORE_ADDR hi; ULONGEST count; - const char *filename; - void *buf; - const char *lo_exp; const char *hi_exp; /* Open the file. */ - filename = scan_filename_with_cleanup (&cmd, NULL); + gdb::unique_xmalloc_ptr filename = scan_filename (&cmd, NULL); /* Find the low address. */ if (cmd == NULL || *cmd == '\0') error (_("Missing start address.")); - lo_exp = scan_expression_with_cleanup (&cmd, NULL); + gdb::unique_xmalloc_ptr lo_exp = scan_expression (&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); + lo = parse_and_eval_address (lo_exp.get ()); hi = parse_and_eval_address (hi_exp); if (hi <= lo) error (_("Invalid memory address range (start >= end).")); @@ -237,25 +202,18 @@ dump_memory_to_file (const char *cmd, const char *mode, const char *file_format) /* FIXME: Should use read_memory_partial() and a magic blocking value. */ - buf = xmalloc (count); - make_cleanup (xfree, buf); - read_memory (lo, buf, count); + gdb::byte_vector buf (count); + read_memory (lo, buf.data (), count); /* Have everything. Open/write the data. */ if (file_format == NULL || strcmp (file_format, "binary") == 0) - { - dump_binary_file (filename, mode, buf, count); - } + dump_binary_file (filename.get (), mode, buf.data (), count); else - { - dump_bfd_file (filename, mode, file_format, lo, buf, count); - } - - do_cleanups (old_cleanups); + dump_bfd_file (filename.get (), mode, file_format, lo, buf.data (), count); } static void -dump_memory_command (char *cmd, char *mode) +dump_memory_command (const char *cmd, const char *mode) { dump_memory_to_file (cmd, mode, "binary"); } @@ -263,12 +221,10 @@ dump_memory_command (char *cmd, char *mode) static void dump_value_to_file (const char *cmd, const char *mode, const char *file_format) { - struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL); struct value *val; - const char *filename; /* Open the file. */ - filename = scan_filename_with_cleanup (&cmd, NULL); + gdb::unique_xmalloc_ptr filename = scan_filename (&cmd, NULL); /* Find the value. */ if (cmd == NULL || *cmd == '\0') @@ -279,10 +235,8 @@ dump_value_to_file (const char *cmd, const char *mode, const char *file_format) /* 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))); - } + dump_binary_file (filename.get (), mode, value_contents (val), + TYPE_LENGTH (value_type (val))); else { CORE_ADDR vaddr; @@ -297,115 +251,114 @@ dump_value_to_file (const char *cmd, const char *mode, const char *file_format) warning (_("value is not an lval: address assumed to be zero")); } - dump_bfd_file (filename, mode, file_format, vaddr, + dump_bfd_file (filename.get (), mode, file_format, vaddr, value_contents (val), TYPE_LENGTH (value_type (val))); } - - do_cleanups (old_cleanups); } static void -dump_value_command (char *cmd, char *mode) +dump_value_command (const char *cmd, const char *mode) { dump_value_to_file (cmd, mode, "binary"); } static void -dump_srec_memory (char *args, int from_tty) +dump_srec_memory (const char *args, int from_tty) { dump_memory_to_file (args, FOPEN_WB, "srec"); } static void -dump_srec_value (char *args, int from_tty) +dump_srec_value (const char *args, int from_tty) { dump_value_to_file (args, FOPEN_WB, "srec"); } static void -dump_ihex_memory (char *args, int from_tty) +dump_ihex_memory (const char *args, int from_tty) { dump_memory_to_file (args, FOPEN_WB, "ihex"); } static void -dump_ihex_value (char *args, int from_tty) +dump_ihex_value (const char *args, int from_tty) { dump_value_to_file (args, FOPEN_WB, "ihex"); } static void -dump_verilog_memory (char *args, int from_tty) +dump_verilog_memory (const char *args, int from_tty) { dump_memory_to_file (args, FOPEN_WB, "verilog"); } static void -dump_verilog_value (char *args, int from_tty) +dump_verilog_value (const char *args, int from_tty) { dump_value_to_file (args, FOPEN_WB, "verilog"); } static void -dump_tekhex_memory (char *args, int from_tty) +dump_tekhex_memory (const char *args, int from_tty) { dump_memory_to_file (args, FOPEN_WB, "tekhex"); } static void -dump_tekhex_value (char *args, int from_tty) +dump_tekhex_value (const char *args, int from_tty) { dump_value_to_file (args, FOPEN_WB, "tekhex"); } static void -dump_binary_memory (char *args, int from_tty) +dump_binary_memory (const char *args, int from_tty) { dump_memory_to_file (args, FOPEN_WB, "binary"); } static void -dump_binary_value (char *args, int from_tty) +dump_binary_value (const char *args, int from_tty) { dump_value_to_file (args, FOPEN_WB, "binary"); } static void -append_binary_memory (char *args, int from_tty) +append_binary_memory (const char *args, int from_tty) { dump_memory_to_file (args, FOPEN_AB, "binary"); } static void -append_binary_value (char *args, int from_tty) +append_binary_value (const char *args, int from_tty) { dump_value_to_file (args, FOPEN_AB, "binary"); } struct dump_context { - void (*func) (char *cmd, char *mode); - char *mode; + void (*func) (const char *cmd, const char *mode); + const char *mode; }; static void -call_dump_func (struct cmd_list_element *c, char *args, int from_tty) +call_dump_func (struct cmd_list_element *c, const char *args, int from_tty) { - struct dump_context *d = get_cmd_context (c); + struct dump_context *d = (struct dump_context *) get_cmd_context (c); d->func (args, d->mode); } static void -add_dump_command (char *name, void (*func) (char *args, char *mode), - char *descr) +add_dump_command (const char *name, + void (*func) (const char *args, const char *mode), + const char *descr) { struct cmd_list_element *c; struct dump_context *d; - c = add_cmd (name, all_commands, NULL, descr, &dump_cmdlist); + c = add_cmd (name, all_commands, descr, &dump_cmdlist); c->completer = filename_completer; d = XNEW (struct dump_context); d->func = func; @@ -413,7 +366,7 @@ add_dump_command (char *name, void (*func) (char *args, char *mode), set_cmd_context (c, d); c->func = call_dump_func; - c = add_cmd (name, all_commands, NULL, descr, &append_cmdlist); + c = add_cmd (name, all_commands, descr, &append_cmdlist); c->completer = filename_completer; d = XNEW (struct dump_context); d->func = func; @@ -447,18 +400,16 @@ struct callback_data { static void restore_section_callback (bfd *ibfd, asection *isec, void *args) { - struct callback_data *data = args; - bfd_vma sec_start = bfd_section_vma (ibfd, isec); - bfd_size_type size = bfd_section_size (ibfd, isec); + struct callback_data *data = (struct callback_data *) args; + bfd_vma sec_start = bfd_section_vma (isec); + bfd_size_type size = bfd_section_size (isec); bfd_vma sec_end = sec_start + size; bfd_size_type sec_offset = 0; bfd_size_type sec_load_count = size; - struct cleanup *old_chain; - gdb_byte *buf; int ret; /* Ignore non-loadable sections, eg. from elf files. */ - if (!(bfd_get_section_flags (ibfd, isec) & SEC_LOAD)) + if (!(bfd_section_flags (isec) & SEC_LOAD)) return; /* Does the section overlap with the desired restore range? */ @@ -467,7 +418,7 @@ restore_section_callback (bfd *ibfd, asection *isec, void *args) { /* No, no useable data in this section. */ printf_filtered (_("skipping section %s...\n"), - bfd_section_name (ibfd, isec)); + bfd_section_name (isec)); return; } @@ -482,14 +433,13 @@ restore_section_callback (bfd *ibfd, asection *isec, void *args) sec_load_count -= sec_end - data->load_end; /* Get the data. */ - buf = xmalloc (size); - old_chain = make_cleanup (xfree, buf); - if (!bfd_get_section_contents (ibfd, isec, buf, 0, size)) + gdb::byte_vector buf (size); + if (!bfd_get_section_contents (ibfd, isec, buf.data (), 0, size)) error (_("Failed to read bfd file %s: '%s'."), bfd_get_filename (ibfd), bfd_errmsg (bfd_get_error ())); printf_filtered ("Restoring section %s (0x%lx to 0x%lx)", - bfd_section_name (ibfd, isec), + bfd_section_name (isec), (unsigned long) sec_start, (unsigned long) sec_end); @@ -506,25 +456,24 @@ restore_section_callback (bfd *ibfd, asection *isec, void *args) /* Write the data. */ ret = target_write_memory (sec_start + sec_offset + data->load_offset, - buf + sec_offset, sec_load_count); + &buf[sec_offset], sec_load_count); if (ret != 0) warning (_("restore: memory write failed (%s)."), safe_strerror (ret)); - do_cleanups (old_chain); - return; } static void restore_binary_file (const char *filename, struct callback_data *data) { - struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); - FILE *file = fopen_with_cleanup (filename, FOPEN_RB); - gdb_byte *buf; + gdb_file_up file = gdb_fopen_cloexec (filename, FOPEN_RB); long len; + if (file == NULL) + error (_("Failed to open %s: %s"), filename, safe_strerror (errno)); + /* Get the file size for reading. */ - if (fseek (file, 0, SEEK_END) == 0) + if (fseek (file.get (), 0, SEEK_END) == 0) { - len = ftell (file); + len = ftell (file.get ()); if (len < 0) perror_with_name (filename); } @@ -549,30 +498,26 @@ restore_binary_file (const char *filename, struct callback_data *data) (unsigned long) (data->load_start + data->load_offset + len)); /* Now set the file pos to the requested load start pos. */ - if (fseek (file, data->load_start, SEEK_SET) != 0) + if (fseek (file.get (), data->load_start, SEEK_SET) != 0) perror_with_name (filename); /* Now allocate a buffer and read the file contents. */ - buf = xmalloc (len); - make_cleanup (xfree, buf); - if (fread (buf, 1, len, file) != len) + gdb::byte_vector buf (len); + if (fread (buf.data (), 1, len, file.get ()) != len) perror_with_name (filename); /* Now write the buffer into target memory. */ - len = target_write_memory (data->load_start + data->load_offset, buf, len); + len = target_write_memory (data->load_start + data->load_offset, + buf.data (), len); if (len != 0) warning (_("restore: memory write failed (%s)."), safe_strerror (len)); - do_cleanups (cleanup); } static void -restore_command (char *args_in, int from_tty) +restore_command (const char *args, int from_tty) { - char *filename; struct callback_data data; - bfd *ibfd; int binary_flag = 0; - const char *args = args_in; if (!target_has_execution) noprocess (); @@ -582,27 +527,28 @@ restore_command (char *args_in, int from_tty) data.load_end = 0; /* Parse the input arguments. First is filename (required). */ - filename = scan_filename_with_cleanup (&args, NULL); + gdb::unique_xmalloc_ptr filename = scan_filename (&args, NULL); if (args != NULL && *args != '\0') { - char *binary_string = "binary"; + static const char binary_string[] = "binary"; /* Look for optional "binary" flag. */ if (startswith (args, binary_string)) { binary_flag = 1; args += strlen (binary_string); - args = skip_spaces_const (args); + args = skip_spaces (args); } /* Parse offset (optional). */ if (args != NULL && *args != '\0') - data.load_offset = - parse_and_eval_address (scan_expression_with_cleanup (&args, NULL)); + data.load_offset = binary_flag ? + parse_and_eval_address (scan_expression (&args, NULL).get ()) : + parse_and_eval_long (scan_expression (&args, NULL).get ()); if (args != NULL && *args != '\0') { /* Parse start address (optional). */ data.load_start = - parse_and_eval_long (scan_expression_with_cleanup (&args, NULL)); + parse_and_eval_long (scan_expression (&args, NULL).get ()); if (args != NULL && *args != '\0') { /* Parse end address (optional). */ @@ -615,70 +561,67 @@ restore_command (char *args_in, int from_tty) if (info_verbose) printf_filtered ("Restore file %s offset 0x%lx start 0x%lx end 0x%lx\n", - filename, (unsigned long) data.load_offset, + filename.get (), (unsigned long) data.load_offset, (unsigned long) data.load_start, (unsigned long) data.load_end); if (binary_flag) { - restore_binary_file (filename, &data); + restore_binary_file (filename.get (), &data); } else { /* Open the file for loading. */ - ibfd = bfd_openr_with_cleanup (filename, NULL); + gdb_bfd_ref_ptr ibfd (bfd_openr_or_error (filename.get (), NULL)); /* Process the sections. */ - bfd_map_over_sections (ibfd, restore_section_callback, &data); + bfd_map_over_sections (ibfd.get (), restore_section_callback, &data); } - return; } static void -srec_dump_command (char *cmd, int from_tty) +srec_dump_command (const char *cmd, int from_tty) { printf_unfiltered (_("\"dump srec\" must be followed by a subcommand.\n")); help_list (srec_cmdlist, "dump srec ", all_commands, gdb_stdout); } static void -ihex_dump_command (char *cmd, int from_tty) +ihex_dump_command (const char *cmd, int from_tty) { printf_unfiltered (_("\"dump ihex\" must be followed by a subcommand.\n")); help_list (ihex_cmdlist, "dump ihex ", all_commands, gdb_stdout); } static void -verilog_dump_command (char *cmd, int from_tty) +verilog_dump_command (const char *cmd, int from_tty) { printf_unfiltered (_("\"dump verilog\" must be followed by a subcommand.\n")); help_list (verilog_cmdlist, "dump verilog ", all_commands, gdb_stdout); } static void -tekhex_dump_command (char *cmd, int from_tty) +tekhex_dump_command (const char *cmd, int from_tty) { printf_unfiltered (_("\"dump tekhex\" must be followed by a subcommand.\n")); help_list (tekhex_cmdlist, "dump tekhex ", all_commands, gdb_stdout); } static void -binary_dump_command (char *cmd, int from_tty) +binary_dump_command (const char *cmd, int from_tty) { printf_unfiltered (_("\"dump binary\" must be followed by a subcommand.\n")); help_list (binary_dump_cmdlist, "dump binary ", all_commands, gdb_stdout); } static void -binary_append_command (char *cmd, int from_tty) +binary_append_command (const char *cmd, int from_tty) { printf_unfiltered (_("\"append binary\" must be followed by a subcommand.\n")); help_list (binary_append_cmdlist, "append binary ", all_commands, gdb_stdout); } -extern initialize_file_ftype _initialize_cli_dump; /* -Wmissing-prototypes */ - void _initialize_cli_dump (void) {