X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fcorelow.c;h=c130cf8b4c301fa3197589289bfddaa835ffb718;hb=b1acf338d3974d99af32899092989edeee7fbef4;hp=8fc3e669849924e474d94aa5248f767e36e0fd38;hpb=7be0c536371055e9b15403d88f6149bbd656df37;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/corelow.c b/gdb/corelow.c index 8fc3e66984..c130cf8b4c 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -1,7 +1,8 @@ /* Core dump and executable file functions below target vector, for GDB. Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + 1997, 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, + Inc. This file is part of GDB. @@ -41,17 +42,21 @@ #include "regset.h" #include "symfile.h" #include "exec.h" -#include - +#include "readline/readline.h" +#include "observer.h" #include "gdb_assert.h" #ifndef O_BINARY #define O_BINARY 0 #endif -/* List of all available core_fns. On gdb startup, each core file register - reader calls add_core_fns() to register information on each core format it - is prepared to read. */ +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif + +/* List of all available core_fns. On gdb startup, each core file + register reader calls deprecated_add_core_fns() to register + information on each core format it is prepared to read. */ static struct core_fns *core_file_fns = NULL; @@ -103,7 +108,7 @@ struct target_ops core_ops; handle. */ void -add_core_fns (struct core_fns *cf) +deprecated_add_core_fns (struct core_fns *cf) { cf->next = core_file_fns; core_file_fns = cf; @@ -279,6 +284,7 @@ core_open (char *filename, int from_tty) bfd *temp_bfd; int ontop; int scratch_chan; + int flags; target_preopen (from_tty); if (!filename) @@ -298,7 +304,12 @@ core_open (char *filename, int from_tty) old_chain = make_cleanup (xfree, filename); - scratch_chan = open (filename, O_BINARY | ( write_files ? O_RDWR : O_RDONLY ), 0); + flags = O_BINARY | O_LARGEFILE; + if (write_files) + flags |= O_RDWR; + else + flags |= O_RDONLY; + scratch_chan = open (filename, flags, 0); if (scratch_chan < 0) perror_with_name (filename); @@ -354,6 +365,10 @@ core_open (char *filename, int from_tty) ontop = !push_target (&core_ops); discard_cleanups (old_chain); + /* This is done first, before anything has a chance to query the + inferior for information such as symbols. */ + observer_notify_inferior_created (&core_ops, from_tty); + p = bfd_core_file_failing_command (core_bfd); if (p) printf_filtered ("Core was generated by `%s'.\n", p); @@ -387,8 +402,7 @@ core_open (char *filename, int from_tty) /* Now, set up the frame cache, and print the top of stack. */ flush_cached_frames (); select_frame (get_current_frame ()); - print_stack_frame (deprecated_selected_frame, - frame_relative_level (deprecated_selected_frame), 1); + print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); } else { @@ -477,7 +491,7 @@ get_core_register_section (char *name, } gdb_assert (core_vec); - core_vec->core_read_registers (contents, size, which, + core_vec->core_read_registers (contents, size, which, ((CORE_ADDR) bfd_section_vma (core_bfd, section))); } @@ -514,6 +528,95 @@ core_files_info (struct target_ops *t) { print_section_info (t, core_bfd); } + +static LONGEST +core_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, ULONGEST offset, LONGEST len) +{ + switch (object) + { + case TARGET_OBJECT_MEMORY: + if (readbuf) + return (*ops->deprecated_xfer_memory) (offset, readbuf, len, + 0/*write*/, NULL, ops); + if (writebuf) + return (*ops->deprecated_xfer_memory) (offset, readbuf, len, + 1/*write*/, NULL, ops); + return -1; + + case TARGET_OBJECT_AUXV: + if (readbuf) + { + /* When the aux vector is stored in core file, BFD + represents this with a fake section called ".auxv". */ + + struct bfd_section *section; + bfd_size_type size; + char *contents; + + section = bfd_get_section_by_name (core_bfd, ".auxv"); + if (section == NULL) + return -1; + + size = bfd_section_size (core_bfd, section); + if (offset >= size) + return 0; + size -= offset; + if (size > len) + size = len; + if (size > 0 + && !bfd_get_section_contents (core_bfd, section, readbuf, + (file_ptr) offset, size)) + { + warning ("Couldn't read NT_AUXV note in core file."); + return -1; + } + + return size; + } + return -1; + + case TARGET_OBJECT_WCOOKIE: + if (readbuf) + { + /* When the StackGhost cookie is stored in core file, BFD + represents this with a fake section called ".wcookie". */ + + struct bfd_section *section; + bfd_size_type size; + char *contents; + + section = bfd_get_section_by_name (core_bfd, ".wcookie"); + if (section == NULL) + return -1; + + size = bfd_section_size (core_bfd, section); + if (offset >= size) + return 0; + size -= offset; + if (size > len) + size = len; + if (size > 0 + && !bfd_get_section_contents (core_bfd, section, readbuf, + (file_ptr) offset, size)) + { + warning ("Couldn't read StackGhost cookie in core file."); + return -1; + } + + return size; + } + return -1; + + default: + if (ops->beneath != NULL) + return ops->beneath->to_xfer_partial (ops->beneath, object, annex, + readbuf, writebuf, offset, len); + return -1; + } +} + /* If mourn is being called in all the right places, this could be say `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ @@ -551,7 +654,8 @@ init_core_ops (void) core_ops.to_attach = find_default_attach; core_ops.to_detach = core_detach; core_ops.to_fetch_registers = get_core_registers; - core_ops.to_xfer_memory = xfer_memory; + core_ops.to_xfer_partial = core_xfer_partial; + core_ops.deprecated_xfer_memory = xfer_memory; core_ops.to_files_info = core_files_info; core_ops.to_insert_breakpoint = ignore; core_ops.to_remove_breakpoint = ignore;