diff options
author | K. Richard Pixley <rich@cygnus> | 1992-09-25 17:03:55 +0000 |
---|---|---|
committer | K. Richard Pixley <rich@cygnus> | 1992-09-25 17:03:55 +0000 |
commit | 8afd6ca5473249c7a206284ad75f1b8abd612284 (patch) | |
tree | d6ae568a01496a6a42ba0189db66b8f0d81a3fe9 /gdb/corelow.c | |
parent | c38f5470c204cdc884419ab40808599a58e63862 (diff) | |
download | binutils-gdb-8afd6ca5473249c7a206284ad75f1b8abd612284.tar.gz |
Separate core functions along target vector in preparation for
native support. Functions above vector now live in core.c. Those
below in corelow.c.
* core.c (solib_add_stub, core_close, core_open, core_detach,
get_core_registers, core_files_info, core_ops): moved to corelow.c
(_initialize_core): removed addition of core_ops target.
* corelow.c: new file.
(solib_add_stub, core_close, core_open, core_detach,
get_core_registers, core_files_info, core_ops): moved from core.c
(_initialize_corelow): new function.
* gdbcore.h (core_open, core_detach): added prototypes.
(core_ops): add forward declaration.
* Makefile.in (SFILES_MAINDIR): add core.c
(OBS): add core.o
(TSOBS): change core.o to corelow.o
Diffstat (limited to 'gdb/corelow.c')
-rw-r--r-- | gdb/corelow.c | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/gdb/corelow.c b/gdb/corelow.c new file mode 100644 index 00000000000..d9d51526488 --- /dev/null +++ b/gdb/corelow.c @@ -0,0 +1,270 @@ +/* Core dump and executable file functions below target vector, for GDB. + Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc. + +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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "defs.h" +#include <errno.h> +#include <signal.h> +#include <fcntl.h> +#include "frame.h" /* required by inferior.h */ +#include "inferior.h" +#include "symtab.h" +#include "command.h" +#include "bfd.h" +#include "target.h" +#include "gdbcore.h" + +static void +core_files_info PARAMS ((struct target_ops *)); + +#ifdef SOLIB_ADD +static int +solib_add_stub PARAMS ((char *)); +#endif + +static void +core_close PARAMS ((int)); + +static void +get_core_registers PARAMS ((int)); + +/* Discard all vestiges of any previous core file + and mark data and stack spaces as empty. */ + +/* ARGSUSED */ +static void +core_close (quitting) + int quitting; +{ + if (core_bfd) { + free (bfd_get_filename (core_bfd)); + bfd_close (core_bfd); + core_bfd = NULL; +#ifdef CLEAR_SOLIB + CLEAR_SOLIB (); +#endif + if (core_ops.to_sections) { + free ((PTR)core_ops.to_sections); + core_ops.to_sections = NULL; + core_ops.to_sections_end = NULL; + } + } +} + +#ifdef SOLIB_ADD +/* Stub function for catch_errors around shared library hacking. */ + +static int +solib_add_stub (from_tty) + char *from_tty; +{ + SOLIB_ADD (NULL, (int)from_tty, &core_ops); + return 0; +} +#endif /* SOLIB_ADD */ + +/* This routine opens and sets up the core file bfd */ + +void +core_open (filename, from_tty) + char *filename; + int from_tty; +{ + const char *p; + int siggy; + struct cleanup *old_chain; + char *temp; + bfd *temp_bfd; + int ontop; + int scratch_chan; + + target_preopen (from_tty); + if (!filename) + { + error (core_bfd? + "No core file specified. (Use `detach' to stop debugging a core file.)" + : "No core file specified."); + } + + filename = tilde_expand (filename); + if (filename[0] != '/') { + temp = concat (current_directory, "/", filename, NULL); + free (filename); + filename = temp; + } + + old_chain = make_cleanup (free, filename); + + scratch_chan = open (filename, write_files? O_RDWR: O_RDONLY, 0); + if (scratch_chan < 0) + perror_with_name (filename); + + temp_bfd = bfd_fdopenr (filename, NULL, scratch_chan); + if (temp_bfd == NULL) + { + perror_with_name (filename); + } + + if (!bfd_check_format (temp_bfd, bfd_core)) + { + /* Do it after the err msg */ + make_cleanup (bfd_close, temp_bfd); + error ("\"%s\" is not a core dump: %s", filename, bfd_errmsg(bfd_error)); + } + + /* Looks semi-reasonable. Toss the old core file and work on the new. */ + + discard_cleanups (old_chain); /* Don't free filename any more */ + unpush_target (&core_ops); + core_bfd = temp_bfd; + old_chain = make_cleanup (core_close, core_bfd); + + validate_files (); + + /* Find the data section */ + if (build_section_table (core_bfd, &core_ops.to_sections, + &core_ops.to_sections_end)) + error ("Can't find sections in `%s': %s", bfd_get_filename(core_bfd), + bfd_errmsg (bfd_error)); + + ontop = !push_target (&core_ops); + discard_cleanups (old_chain); + + p = bfd_core_file_failing_command (core_bfd); + if (p) + printf_filtered ("Core was generated by `%s'.\n", p); + + siggy = bfd_core_file_failing_signal (core_bfd); + if (siggy > 0) + printf_filtered ("Program terminated with signal %d, %s.\n", siggy, + safe_strsignal (siggy)); + + if (ontop) { + /* Fetch all registers from core file */ + target_fetch_registers (-1); + + /* Add symbols and section mappings for any shared libraries */ +#ifdef SOLIB_ADD + catch_errors (solib_add_stub, (char *)from_tty, (char *)0); +#endif + + /* Now, set up the frame cache, and print the top of stack */ + set_current_frame (create_new_frame (read_register (FP_REGNUM), + read_pc ())); + select_frame (get_current_frame (), 0); + print_stack_frame (selected_frame, selected_frame_level, 1); + } else { + warning ( +"you won't be able to access this core file until you terminate\n\ +your %s; do ``info files''", current_target->to_longname); + } +} + +void +core_detach (args, from_tty) + char *args; + int from_tty; +{ + if (args) + error ("Too many arguments"); + unpush_target (&core_ops); + if (from_tty) + printf_filtered ("No core file now.\n"); +} + +/* Get the registers out of a core file. This is the machine- + independent part. Fetch_core_registers is the machine-dependent + part, typically implemented in the xm-file for each architecture. */ + +/* We just get all the registers, so we don't use regno. */ +/* ARGSUSED */ +static void +get_core_registers (regno) + int regno; +{ + sec_ptr reg_sec; + unsigned size; + char *the_regs; + + reg_sec = bfd_get_section_by_name (core_bfd, ".reg"); + if (!reg_sec) goto cant; + size = bfd_section_size (core_bfd, reg_sec); + the_regs = alloca (size); + if (bfd_get_section_contents (core_bfd, reg_sec, the_regs, (file_ptr)0, size)) + { + fetch_core_registers (the_regs, size, 0, + (unsigned) bfd_section_vma (abfd,reg_sec)); + } + else + { +cant: + fprintf_filtered (stderr, "Couldn't fetch registers from core file: %s\n", + bfd_errmsg (bfd_error)); + } + + /* Now do it again for the float registers, if they exist. */ + reg_sec = bfd_get_section_by_name (core_bfd, ".reg2"); + if (reg_sec) { + size = bfd_section_size (core_bfd, reg_sec); + the_regs = alloca (size); + if (bfd_get_section_contents (core_bfd, reg_sec, the_regs, (file_ptr)0, + size)) + { + fetch_core_registers (the_regs, size, 2, + (unsigned) bfd_section_vma (abfd,reg_sec)); + } + else + { + fprintf_filtered (stderr, "Couldn't fetch register set 2 from core file: %s\n", + bfd_errmsg (bfd_error)); + } + } + registers_fetched(); +} + +static void +core_files_info (t) + struct target_ops *t; +{ + print_section_info (t, core_bfd); +} + +struct target_ops core_ops = { + "core", "Local core dump file", + "Use a core file as a target. Specify the filename of the core file.", + core_open, core_close, + find_default_attach, core_detach, 0, 0, /* resume, wait */ + get_core_registers, + 0, 0, /* store_regs, prepare_to_store */ + xfer_memory, core_files_info, + 0, 0, /* core_insert_breakpoint, core_remove_breakpoint, */ + 0, 0, 0, 0, 0, /* terminal stuff */ + 0, 0, 0, /* kill, load, lookup sym */ + find_default_create_inferior, 0, /* mourn_inferior */ + 0, /* can_run */ + core_stratum, 0, /* next */ + 0, 1, 1, 1, 0, /* all mem, mem, stack, regs, exec */ + 0, 0, /* section pointers */ + OPS_MAGIC, /* Always the last thing */ +}; + +void +_initialize_corelow() +{ + add_target (&core_ops); +} |