Index: gcore.c =================================================================== RCS file: /cvs/src/src/gdb/gcore.c,v retrieving revision 1.17 diff -p -r1.17 gcore.c *** gcore.c 15 Feb 2005 15:49:10 -0000 1.17 --- gcore.c 3 Nov 2005 01:19:53 -0000 *************** gcore_memory_sections (bfd *obfd) *** 488,493 **** --- 488,621 ---- return 1; } + /* OK now, I want to add a new command to read a corefile, + and restore its state into the inferior process. Obviously + dangerous, probably want to make certain that they are + actually the same process! But we can put that off till + later. Let's see what's required. This should actually + be pretty easy. */ + + static void + load_core_sections (bfd *abfd, asection *asect, void *arg) + { + unsigned long from_tty = (unsigned long) arg; + char *memhunk; + + if ((bfd_section_size (abfd, asect) > 0) && + (bfd_get_section_flags (abfd, asect) & SEC_LOAD)) + { + if (info_verbose && from_tty) + { + printf_filtered (_("Load core section %s"), + bfd_section_name (abfd, asect)); + printf_filtered (_(", address 0x%08lx"), + (unsigned long) bfd_section_vma (abfd, asect)); + printf_filtered (_(", size = %d"), + (int) bfd_section_size (abfd, asect)); + printf_filtered (_(".\n")); + } + /* Fixme cleanup? */ + memhunk = xmalloc (bfd_section_size (abfd, asect)); + bfd_get_section_contents (abfd, asect, memhunk, 0, + bfd_section_size (abfd, asect)); + target_write_memory (bfd_section_vma (abfd, asect), + memhunk, + bfd_section_size (abfd, asect)); + xfree (memhunk); + } + } + + #include + #ifndef O_BINARY + #define O_BINARY 0 + #endif + + #include "regcache.h" + #include "regset.h" + + static void + rcore_command (char *args, int from_tty) + { + /* corelow.c core_open */ + /* scratch_chan = open (filename) + temp_bfd = bfd_fdopenr (filename, gnutarget, scratch_chan) + bfd_check_format (temp_bfd, bfd_core) + build_section_table (core_bfd, to_sections, to_sections_end) + bfd_map_over_sections (core_bfd, myfunc) + myfunc will check for loadable, contents, and size, + and then write the section contents into memory at vma. + */ + char *corefilename, corefilename_buffer[40], *scratch_path; + int scratch_chan; + bfd *core_bfd; + + /* Can't restore a corefile without a target process. */ + if (!target_has_execution) + noprocess (); + + if (args && *args) + corefilename = args; + else + { + /* Default corefile name is "core.PID". */ + sprintf (corefilename_buffer, "core.%d", PIDGET (inferior_ptid)); + corefilename = corefilename_buffer; + } + + if (info_verbose) + fprintf_filtered (gdb_stdout, + _("Opening corefile '%s' for input.\n"), corefilename); + + scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, corefilename, + O_BINARY | O_RDONLY | O_LARGEFILE, 0, &scratch_path); + if (scratch_chan < 0) + perror_with_name (corefilename); + + core_bfd = bfd_fdopenr (scratch_path, gnutarget, scratch_chan); + if (!core_bfd) + perror_with_name (scratch_path); + + if (!bfd_check_format (core_bfd, bfd_core)) + { + make_cleanup_bfd_close (core_bfd); + error (_("\"%s\" is not a core file: %s"), + corefilename, bfd_errmsg (bfd_get_error ())); + } + + bfd_map_over_sections (core_bfd, load_core_sections, (void *) from_tty); + /* Now need to get/set registers. */ + { + struct bfd_section *regsect = bfd_get_section_by_name (core_bfd, ".reg"); + char *contents; + int size; + + if (!regsect) + error (_("Couldn't find .reg section.")); + + size = bfd_section_size (core_bfd, regsect); + contents = xmalloc (size); + bfd_get_section_contents (core_bfd, regsect, contents, 0, size); + + if (gdbarch_regset_from_core_section_p (current_gdbarch)) + { + const struct regset *regset; + + regset = gdbarch_regset_from_core_section (current_gdbarch, + ".reg", size); + if (!regset) + error (_("Failed to allocate regset.")); + + registers_changed (); + regset->supply_regset (regset, current_regcache, + -1, contents, size); + reinit_frame_cache (); + target_store_registers (-1); + } + } + + bfd_close (core_bfd); + } + void _initialize_gcore (void) { *************** Argument is optional filename. Default *** 497,500 **** --- 625,633 ---- add_com_alias ("gcore", "generate-core-file", class_files, 1); exec_set_find_memory_regions (objfile_find_memory_regions); + + add_com ("restore-core-file", class_files, rcore_command, _("\ + Restore the machine state from a core file into the debugged process.\n\ + Argument is optional filename. Default filename is 'core.'.")); + add_com_alias ("rcore", "restore-core-file", class_files, 1); }