Index: gdb/corelow.c |
diff --git a/gdb/corelow.c b/gdb/corelow.c |
index dd625604c935b2642c2be40c1dd870f431ad4eb9..2869eeaaffa7c511d16d877e2e2b11ac3eedf441 100644 |
--- a/gdb/corelow.c |
+++ b/gdb/corelow.c |
@@ -1,7 +1,6 @@ |
/* Core dump and executable file functions below target vector, for GDB. |
- Copyright (C) 1986-1987, 1989, 1991-2001, 2003-2012 Free Software |
- Foundation, Inc. |
+ Copyright (C) 1986-2013 Free Software Foundation, Inc. |
This file is part of GDB. |
@@ -20,7 +19,7 @@ |
#include "defs.h" |
#include "arch-utils.h" |
-#include "gdb_string.h" |
+#include <string.h> |
#include <errno.h> |
#include <signal.h> |
#include <fcntl.h> |
@@ -46,6 +45,9 @@ |
#include "filenames.h" |
#include "progspace.h" |
#include "objfiles.h" |
+#include "gdb_bfd.h" |
+#include "completer.h" |
+#include "filestuff.h" |
#ifndef O_LARGEFILE |
#define O_LARGEFILE 0 |
@@ -65,7 +67,7 @@ static struct core_fns *core_vec = NULL; |
/* FIXME: kettenis/20031023: Eventually this variable should |
disappear. */ |
-struct gdbarch *core_gdbarch = NULL; |
+static struct gdbarch *core_gdbarch = NULL; |
/* Per-core data. Currently, only the section table. Note that these |
target sections are *not* mapped in the current address spaces' set |
@@ -83,9 +85,7 @@ static int gdb_check_format (bfd *); |
static void core_open (char *, int); |
-static void core_detach (struct target_ops *ops, char *, int); |
- |
-static void core_close (int); |
+static void core_close (void); |
static void core_close_cleanup (void *ignore); |
@@ -192,10 +192,8 @@ gdb_check_format (bfd *abfd) |
stack spaces as empty. */ |
static void |
-core_close (int quitting) |
+core_close (void) |
{ |
- char *name; |
- |
if (core_bfd) |
{ |
int pid = ptid_get_pid (inferior_ptid); |
@@ -215,9 +213,7 @@ core_close (int quitting) |
core_data = NULL; |
} |
- name = bfd_get_filename (core_bfd); |
- gdb_bfd_close_or_warn (core_bfd); |
- xfree (name); |
+ gdb_bfd_unref (core_bfd); |
core_bfd = NULL; |
} |
core_vec = NULL; |
@@ -227,7 +223,7 @@ core_close (int quitting) |
static void |
core_close_cleanup (void *ignore) |
{ |
- core_close (0/*ignored*/); |
+ core_close (); |
} |
/* Look for sections whose names start with `.reg/' so that we can |
@@ -315,13 +311,13 @@ core_open (char *filename, int from_tty) |
flags |= O_RDWR; |
else |
flags |= O_RDONLY; |
- scratch_chan = open (filename, flags, 0); |
+ scratch_chan = gdb_open_cloexec (filename, flags, 0); |
if (scratch_chan < 0) |
perror_with_name (filename); |
- temp_bfd = bfd_fopen (filename, gnutarget, |
- write_files ? FOPEN_RUB : FOPEN_RB, |
- scratch_chan); |
+ temp_bfd = gdb_bfd_fopen (filename, gnutarget, |
+ write_files ? FOPEN_RUB : FOPEN_RB, |
+ scratch_chan); |
if (temp_bfd == NULL) |
perror_with_name (filename); |
@@ -332,7 +328,7 @@ core_open (char *filename, int from_tty) |
/* FIXME: should be checking for errors from bfd_close (for one |
thing, on error it does not free all the storage associated |
with the bfd). */ |
- make_cleanup_bfd_close (temp_bfd); |
+ make_cleanup_bfd_unref (temp_bfd); |
error (_("\"%s\" is not a core dump: %s"), |
filename, bfd_errmsg (bfd_get_error ())); |
} |
@@ -340,17 +336,11 @@ core_open (char *filename, int from_tty) |
/* Looks semi-reasonable. Toss the old core file and work on the |
new. */ |
- discard_cleanups (old_chain); /* Don't free filename any more */ |
+ do_cleanups (old_chain); |
unpush_target (&core_ops); |
core_bfd = temp_bfd; |
old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/); |
- /* FIXME: kettenis/20031023: This is very dangerous. The |
- CORE_GDBARCH that results from this call may very well be |
- different from CURRENT_GDBARCH. However, its methods may only |
- work if it is selected as the current architecture, because they |
- rely on swapped data (see gdbarch.c). We should get rid of that |
- swapped data. */ |
core_gdbarch = gdbarch_from_bfd (core_bfd); |
/* Find a suitable core file handler to munch on core_bfd */ |
@@ -437,6 +427,9 @@ core_open (char *filename, int from_tty) |
if (p) |
printf_filtered (_("Core was generated by `%s'.\n"), p); |
+ /* Clearing any previous state of convenience variables. */ |
+ clear_exit_convenience_vars (); |
+ |
siggy = bfd_core_file_failing_signal (core_bfd); |
if (siggy > 0) |
{ |
@@ -452,8 +445,13 @@ core_open (char *filename, int from_tty) |
siggy) |
: gdb_signal_from_host (siggy)); |
- printf_filtered (_("Program terminated with signal %d, %s.\n"), |
- siggy, gdb_signal_to_string (sig)); |
+ printf_filtered (_("Program terminated with signal %s, %s.\n"), |
+ gdb_signal_to_name (sig), gdb_signal_to_string (sig)); |
+ |
+ /* Set the value of the internal variable $_exitsignal, |
+ which holds the signal uncaught by the inferior. */ |
+ set_internalvar_integer (lookup_internalvar ("_exitsignal"), |
+ siggy); |
} |
/* Fetch all registers from core file. */ |
@@ -461,11 +459,11 @@ core_open (char *filename, int from_tty) |
/* Now, set up the frame cache, and print the top of stack. */ |
reinit_frame_cache (); |
- print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); |
+ print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1); |
} |
static void |
-core_detach (struct target_ops *ops, char *args, int from_tty) |
+core_detach (struct target_ops *ops, const char *args, int from_tty) |
{ |
if (args) |
error (_("Too many arguments")); |
@@ -475,24 +473,6 @@ core_detach (struct target_ops *ops, char *args, int from_tty) |
printf_filtered (_("No core file now.\n")); |
} |
-#ifdef DEPRECATED_IBM6000_TARGET |
- |
-/* Resize the core memory's section table, by NUM_ADDED. Returns a |
- pointer into the first new slot. This will not be necessary when |
- the rs6000 target is converted to use the standard solib |
- framework. */ |
- |
-struct target_section * |
-deprecated_core_resize_section_table (int num_added) |
-{ |
- int old_count; |
- |
- old_count = resize_section_table (core_data, num_added); |
- return core_data->sections + old_count; |
-} |
- |
-#endif |
- |
/* Try to retrieve registers from a section in core_bfd, and supply |
them to core_vec->core_read_registers, as the register set numbered |
WHICH. |
@@ -663,6 +643,35 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p) |
list->pos += 4; |
} |
+/* Read siginfo data from the core, if possible. Returns -1 on |
+ failure. Otherwise, returns the number of bytes read. ABFD is the |
+ core file's BFD; READBUF, OFFSET, and LEN are all as specified by |
+ the to_xfer_partial interface. */ |
+ |
+static LONGEST |
+get_core_siginfo (bfd *abfd, gdb_byte *readbuf, ULONGEST offset, LONGEST len) |
+{ |
+ asection *section; |
+ char *section_name; |
+ const char *name = ".note.linuxcore.siginfo"; |
+ |
+ if (ptid_get_lwp (inferior_ptid)) |
+ section_name = xstrprintf ("%s/%ld", name, |
+ ptid_get_lwp (inferior_ptid)); |
+ else |
+ section_name = xstrdup (name); |
+ |
+ section = bfd_get_section_by_name (abfd, section_name); |
+ xfree (section_name); |
+ if (section == NULL) |
+ return -1; |
+ |
+ if (!bfd_get_section_contents (abfd, section, readbuf, offset, len)) |
+ return -1; |
+ |
+ return len; |
+} |
+ |
static LONGEST |
core_xfer_partial (struct target_ops *ops, enum target_object object, |
const char *annex, gdb_byte *readbuf, |
@@ -753,6 +762,18 @@ core_xfer_partial (struct target_ops *ops, enum target_object object, |
} |
/* FALL THROUGH */ |
+ case TARGET_OBJECT_LIBRARIES_AIX: |
+ if (core_gdbarch |
+ && gdbarch_core_xfer_shared_libraries_aix_p (core_gdbarch)) |
+ { |
+ if (writebuf) |
+ return -1; |
+ return |
+ gdbarch_core_xfer_shared_libraries_aix (core_gdbarch, |
+ readbuf, offset, len); |
+ } |
+ /* FALL THROUGH */ |
+ |
case TARGET_OBJECT_SPU: |
if (readbuf && annex) |
{ |
@@ -801,6 +822,11 @@ core_xfer_partial (struct target_ops *ops, enum target_object object, |
} |
return -1; |
+ case TARGET_OBJECT_SIGNAL_INFO: |
+ if (readbuf) |
+ return get_core_siginfo (core_bfd, readbuf, offset, len); |
+ return -1; |
+ |
default: |
if (ops->beneath != NULL) |
return ops->beneath->to_xfer_partial (ops->beneath, object, |
@@ -899,6 +925,19 @@ core_has_registers (struct target_ops *ops) |
return (core_bfd != NULL); |
} |
+/* Implement the to_info_proc method. */ |
+ |
+static void |
+core_info_proc (struct target_ops *ops, char *args, enum info_proc_what request) |
+{ |
+ struct gdbarch *gdbarch = get_current_arch (); |
+ |
+ /* Since this is the core file target, call the 'core_info_proc' |
+ method on gdbarch, not 'info_proc'. */ |
+ if (gdbarch_core_info_proc_p (gdbarch)) |
+ gdbarch_core_info_proc (gdbarch, args, request); |
+} |
+ |
/* Fill in core_ops with its defined operations and properties. */ |
static void |
@@ -925,6 +964,7 @@ init_core_ops (void) |
core_ops.to_has_memory = core_has_memory; |
core_ops.to_has_stack = core_has_stack; |
core_ops.to_has_registers = core_has_registers; |
+ core_ops.to_info_proc = core_info_proc; |
core_ops.to_magic = OPS_MAGIC; |
if (core_target) |
@@ -939,5 +979,5 @@ _initialize_corelow (void) |
{ |
init_core_ops (); |
- add_target (&core_ops); |
+ add_target_with_completer (&core_ops, filename_completer); |
} |