gdb
authorTom Tromey <tromey@redhat.com>
Fri, 14 Dec 2012 15:30:38 +0000 (15:30 +0000)
committerTom Tromey <tromey@redhat.com>
Fri, 14 Dec 2012 15:30:38 +0000 (15:30 +0000)
        * NEWS: Mention "info proc" and core files.
        * corelow.c (core_info_proc): New function.
        (init_core_ops): Set to_info_proc.
        * gdbarch.c, gdbarch.h: Rebuild.
        * gdbarch.sh (core_info_proc): New method.
        * infcmd.c (info_proc_cmd_1): Invoke target_info_proc first.
        * linux-tdep.c (linux_core_info_proc_mappings)
        (linux_core_info_proc): New functions.
        (linux_find_memory_region_ftype): New typedef.
        (linux_find_memory_regions_full): New function, from
        linux_find_memory_regions.
        (struct linux_find_memory_regions_data): New.
        (linux_find_memory_regions_thunk): New function.
        (linux_find_memory_regions): Rewrite.
        (struct linux_make_mappings_data): New.
        (linux_make_mappings_callback)
        (linux_make_mappings_corefile_notes): New functions.
        (linux_make_corefile_notes): Call linux_make_mappings_corefile_notes.
        (linux_init_abi): Call set_gdbarch_core_info_proc.
        * target.c (target_info_proc): Return 'int'.
        * target.h (target_info_proc): Update.
gdb/doc
        * gdb.texinfo (SVR4 Process Information): Mention core files.
gdb/testsuite
        * gdb.base/info-proc.exp: Add core file tests.
bfd
        * elf.c (elfcore_grok_note) <NT_FILE>: New case.

16 files changed:
bfd/ChangeLog
bfd/elf.c
gdb/ChangeLog
gdb/NEWS
gdb/corelow.c
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/infcmd.c
gdb/linux-tdep.c
gdb/target.c
gdb/target.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/info-proc.exp

index 1ff8574..87cc9d7 100644 (file)
@@ -1,3 +1,7 @@
+2012-12-14  Tom Tromey  <tromey@redhat.com>
+
+        * elf.c (elfcore_grok_note) <NT_FILE>: New case.
+
 2012-12-13  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/14956
index f010f5a..a92dd5d 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -8626,6 +8626,10 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
        return TRUE;
       }
 
+    case NT_FILE:
+      return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.file",
+                                             note);
+
     case NT_SIGINFO:
       return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
                                              note);
index d3c886d..b8dee93 100644 (file)
@@ -1,3 +1,27 @@
+2012-12-14  Tom Tromey  <tromey@redhat.com>
+
+        * NEWS: Mention "info proc" and core files.
+        * corelow.c (core_info_proc): New function.
+        (init_core_ops): Set to_info_proc.
+        * gdbarch.c, gdbarch.h: Rebuild.
+        * gdbarch.sh (core_info_proc): New method.
+        * infcmd.c (info_proc_cmd_1): Invoke target_info_proc first.
+        * linux-tdep.c (linux_core_info_proc_mappings)
+        (linux_core_info_proc): New functions.
+        (linux_find_memory_region_ftype): New typedef.
+        (linux_find_memory_regions_full): New function, from
+        linux_find_memory_regions.
+        (struct linux_find_memory_regions_data): New.
+        (linux_find_memory_regions_thunk): New function.
+        (linux_find_memory_regions): Rewrite.
+        (struct linux_make_mappings_data): New.
+        (linux_make_mappings_callback)
+        (linux_make_mappings_corefile_notes): New functions.
+        (linux_make_corefile_notes): Call linux_make_mappings_corefile_notes.
+        (linux_init_abi): Call set_gdbarch_core_info_proc.
+        * target.c (target_info_proc): Return 'int'.
+        * target.h (target_info_proc): Update.
+
 2012-12-14  Pierre Muller  <muller@sourceware.org>
 
        * windows-nat.c (windows_xfer_shared_libraries): Avoid
index 7c467f8..775e7d3 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -18,6 +18,8 @@
 * The 'ptype' and 'whatis' commands now accept an argument to control
   type formatting.
 
+* 'info proc' now works on some core files.
+
 * Python scripting
 
   ** Vectors can be created with gdb.Type.vector.
index 99611ba..589f231 100644 (file)
@@ -927,6 +927,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
@@ -953,6 +966,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)
index 535f266..f65e4b7 100644 (file)
@@ -1,3 +1,7 @@
+2012-12-14  Tom Tromey  <tromey@redhat.com>
+
+        * gdb.texinfo (SVR4 Process Information): Mention core files.
+
 2012-12-12 Mircea Gherzan <mircea.gherzan@intel.com>
     
        * gdb.texinfo (GDB/MI Catchpoint Commands): New section.
index c23e5de..f96d498 100644 (file)
@@ -18649,13 +18649,17 @@ modern FreeBSD systems.
 
 Many versions of SVR4 and compatible systems provide a facility called
 @samp{/proc} that can be used to examine the image of a running
-process using file-system subroutines.  If @value{GDBN} is configured
-for an operating system with this facility, the command @code{info
-proc} is available to report information about the process running
-your program, or about any process running on your system.  @code{info
-proc} works only on SVR4 systems that include the @code{procfs} code.
-This includes, as of this writing, @sc{gnu}/Linux, OSF/1 (Digital
-Unix), Solaris, Irix, but not HP-UX, for example.
+process using file-system subroutines.
+
+If @value{GDBN} is configured for an operating system with this
+facility, the command @code{info proc} is available to report
+information about the process running your program, or about any
+process running on your system.  This includes, as of this writing,
+@sc{gnu}/Linux, OSF/1 (Digital Unix), Solaris, and Irix, but
+not HP-UX, for example.
+
+This command may also work on core files that were created on a system
+that has the @samp{/proc} facility.
 
 @table @code
 @kindex info proc
index 6ae453e..32fe26b 100644 (file)
@@ -283,6 +283,7 @@ struct gdbarch
   int has_dos_based_file_system;
   gdbarch_gen_return_address_ftype *gen_return_address;
   gdbarch_info_proc_ftype *info_proc;
+  gdbarch_core_info_proc_ftype *core_info_proc;
   gdbarch_iterate_over_objfiles_in_search_order_ftype *iterate_over_objfiles_in_search_order;
 };
 
@@ -451,6 +452,7 @@ struct gdbarch startup_gdbarch =
   0,  /* has_dos_based_file_system */
   default_gen_return_address,  /* gen_return_address */
   0,  /* info_proc */
+  0,  /* core_info_proc */
   default_iterate_over_objfiles_in_search_order,  /* iterate_over_objfiles_in_search_order */
   /* startup_gdbarch() */
 };
@@ -750,6 +752,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of has_dos_based_file_system, invalid_p == 0 */
   /* Skip verify of gen_return_address, invalid_p == 0 */
   /* Skip verify of info_proc, has predicate.  */
+  /* Skip verify of core_info_proc, has predicate.  */
   /* Skip verify of iterate_over_objfiles_in_search_order, invalid_p == 0 */
   buf = ui_file_xstrdup (log, &length);
   make_cleanup (xfree, buf);
@@ -868,6 +871,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: convert_register_p = <%s>\n",
                       host_address_to_string (gdbarch->convert_register_p));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_core_info_proc_p() = %d\n",
+                      gdbarch_core_info_proc_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: core_info_proc = <%s>\n",
+                      host_address_to_string (gdbarch->core_info_proc));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: gdbarch_core_pid_to_str_p() = %d\n",
                       gdbarch_core_pid_to_str_p (gdbarch));
   fprintf_unfiltered (file,
@@ -4250,6 +4259,30 @@ set_gdbarch_info_proc (struct gdbarch *gdbarch,
   gdbarch->info_proc = info_proc;
 }
 
+int
+gdbarch_core_info_proc_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->core_info_proc != NULL;
+}
+
+void
+gdbarch_core_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->core_info_proc != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_core_info_proc called\n");
+  gdbarch->core_info_proc (gdbarch, args, what);
+}
+
+void
+set_gdbarch_core_info_proc (struct gdbarch *gdbarch,
+                            gdbarch_core_info_proc_ftype core_info_proc)
+{
+  gdbarch->core_info_proc = core_info_proc;
+}
+
 void
 gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile)
 {
index 3d9dc79..572aca3 100644 (file)
@@ -1193,6 +1193,16 @@ typedef void (gdbarch_info_proc_ftype) (struct gdbarch *gdbarch, char *args, enu
 extern void gdbarch_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
 extern void set_gdbarch_info_proc (struct gdbarch *gdbarch, gdbarch_info_proc_ftype *info_proc);
 
+/* Implement the "info proc" command for core files.  Noe that there
+   are two "info_proc"-like methods on gdbarch -- one for core files,
+   one for live targets. */
+
+extern int gdbarch_core_info_proc_p (struct gdbarch *gdbarch);
+
+typedef void (gdbarch_core_info_proc_ftype) (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
+extern void gdbarch_core_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
+extern void set_gdbarch_core_info_proc (struct gdbarch *gdbarch, gdbarch_core_info_proc_ftype *core_info_proc);
+
 /* Iterate over all objfiles in the order that makes the most sense
    for the architecture to make global symbol searches.
   
index 8a56106..daa1228 100755 (executable)
@@ -943,6 +943,11 @@ m:void:gen_return_address:struct agent_expr *ax, struct axs_value *value, CORE_A
 # Implement the "info proc" command.
 M:void:info_proc:char *args, enum info_proc_what what:args, what
 
+# Implement the "info proc" command for core files.  Noe that there
+# are two "info_proc"-like methods on gdbarch -- one for core files,
+# one for live targets.
+M:void:core_info_proc:char *args, enum info_proc_what what:args, what
+
 # Iterate over all objfiles in the order that makes the most sense
 # for the architecture to make global symbol searches.
 #
index db9b9b5..4e38725 100644 (file)
@@ -2883,10 +2883,13 @@ info_proc_cmd_1 (char *args, enum info_proc_what what, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
 
-  if (gdbarch_info_proc_p (gdbarch))
-    gdbarch_info_proc (gdbarch, args, what);
-  else
-    target_info_proc (args, what);
+  if (!target_info_proc (args, what))
+    {
+      if (gdbarch_info_proc_p (gdbarch))
+       gdbarch_info_proc (gdbarch, args, what);
+      else
+       error (_("Not supported on this target."));
+    }
 }
 
 /* Implement `info proc' when given without any futher parameters.  */
index dbeed36..d5ad6e3 100644 (file)
@@ -30,6 +30,8 @@
 #include "elf-bfd.h"            /* for elfcore_write_* */
 #include "inferior.h"
 #include "cli/cli-utils.h"
+#include "arch-utils.h"
+#include "gdb_obstack.h"
 
 #include <ctype.h>
 
@@ -533,11 +535,149 @@ linux_info_proc (struct gdbarch *gdbarch, char *args,
     }
 }
 
+/* Implement "info proc mappings" for a corefile.  */
+
+static void
+linux_core_info_proc_mappings (struct gdbarch *gdbarch, char *args)
+{
+  asection *section;
+  ULONGEST count, page_size;
+  unsigned char *descdata, *filenames, *descend, *contents;
+  size_t note_size;
+  unsigned int addr_size_bits, addr_size;
+  struct cleanup *cleanup;
+  struct gdbarch *core_gdbarch = gdbarch_from_bfd (core_bfd);
+  /* We assume this for reading 64-bit core files.  */
+  gdb_static_assert (sizeof (ULONGEST) >= 8);
+
+  section = bfd_get_section_by_name (core_bfd, ".note.linuxcore.file");
+  if (section == NULL)
+    {
+      warning (_("unable to find mappings in core file"));
+      return;
+    }
+
+  addr_size_bits = gdbarch_addr_bit (core_gdbarch);
+  addr_size = addr_size_bits / 8;
+  note_size = bfd_get_section_size (section);
+
+  if (note_size < 2 * addr_size)
+    error (_("malformed core note - too short for header"));
+
+  contents = xmalloc (note_size);
+  cleanup = make_cleanup (xfree, contents);
+  if (!bfd_get_section_contents (core_bfd, section, contents, 0, note_size))
+    error (_("could not get core note contents"));
+
+  descdata = contents;
+  descend = descdata + note_size;
+
+  if (descdata[note_size - 1] != '\0')
+    error (_("malformed note - does not end with \\0"));
+
+  count = bfd_get (addr_size_bits, core_bfd, descdata);
+  descdata += addr_size;
+
+  page_size = bfd_get (addr_size_bits, core_bfd, descdata);
+  descdata += addr_size;
+
+  if (note_size < 2 * addr_size + count * 3 * addr_size)
+    error (_("malformed note - too short for supplied file count"));
+
+  printf_filtered (_("Mapped address spaces:\n\n"));
+  if (gdbarch_addr_bit (gdbarch) == 32)
+    {
+      printf_filtered ("\t%10s %10s %10s %10s %s\n",
+                      "Start Addr",
+                      "  End Addr",
+                      "      Size", "    Offset", "objfile");
+    }
+  else
+    {
+      printf_filtered ("  %18s %18s %10s %10s %s\n",
+                      "Start Addr",
+                      "  End Addr",
+                      "      Size", "    Offset", "objfile");
+    }
+
+  filenames = descdata + count * 3 * addr_size;
+  while (--count > 0)
+    {
+      ULONGEST start, end, file_ofs;
+
+      if (filenames == descend)
+       error (_("malformed note - filenames end too early"));
+
+      start = bfd_get (addr_size_bits, core_bfd, descdata);
+      descdata += addr_size;
+      end = bfd_get (addr_size_bits, core_bfd, descdata);
+      descdata += addr_size;
+      file_ofs = bfd_get (addr_size_bits, core_bfd, descdata);
+      descdata += addr_size;
+
+      file_ofs *= page_size;
+
+      if (gdbarch_addr_bit (gdbarch) == 32)
+       printf_filtered ("\t%10s %10s %10s %10s %s\n",
+                        paddress (gdbarch, start),
+                        paddress (gdbarch, end),
+                        hex_string (end - start),
+                        hex_string (file_ofs),
+                        filenames);
+      else
+       printf_filtered ("  %18s %18s %10s %10s %s\n",
+                        paddress (gdbarch, start),
+                        paddress (gdbarch, end),
+                        hex_string (end - start),
+                        hex_string (file_ofs),
+                        filenames);
+
+      filenames += 1 + strlen ((char *) filenames);
+    }
+
+  do_cleanups (cleanup);
+}
+
+/* Implement "info proc" for a corefile.  */
+
+static void
+linux_core_info_proc (struct gdbarch *gdbarch, char *args,
+                     enum info_proc_what what)
+{
+  int exe_f = (what == IP_MINIMAL || what == IP_EXE || what == IP_ALL);
+  int mappings_f = (what == IP_MAPPINGS || what == IP_ALL);
+
+  if (exe_f)
+    {
+      const char *exe;
+
+      exe = bfd_core_file_failing_command (core_bfd);
+      if (exe != NULL)
+       printf_filtered ("exe = '%s'\n", exe);
+      else
+       warning (_("unable to find command name in core file"));
+    }
+
+  if (mappings_f)
+    linux_core_info_proc_mappings (gdbarch, args);
+
+  if (!exe_f && !mappings_f)
+    error (_("unable to handle request"));
+}
+
+typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size,
+                                           ULONGEST offset, ULONGEST inode,
+                                           int read, int write,
+                                           int exec, int modified,
+                                           const char *filename,
+                                           void *data);
+
 /* List memory regions in the inferior for a corefile.  */
 
 static int
-linux_find_memory_regions (struct gdbarch *gdbarch,
-                          find_memory_region_ftype func, void *obfd)
+linux_find_memory_regions_full (struct gdbarch *gdbarch,
+                               linux_find_memory_region_ftype *func,
+                               void *obfd)
 {
   char filename[100];
   gdb_byte *data;
@@ -606,7 +746,8 @@ linux_find_memory_regions (struct gdbarch *gdbarch,
            modified = 1;
 
          /* Invoke the callback function to create the corefile segment.  */
-         func (addr, endaddr - addr, read, write, exec, modified, obfd);
+         func (addr, endaddr - addr, offset, inode,
+               read, write, exec, modified, filename, obfd);
        }
 
       do_cleanups (cleanup);
@@ -616,6 +757,51 @@ linux_find_memory_regions (struct gdbarch *gdbarch,
   return 1;
 }
 
+/* A structure for passing information through
+   linux_find_memory_regions_full.  */
+
+struct linux_find_memory_regions_data
+{
+  /* The original callback.  */
+
+  find_memory_region_ftype func;
+
+  /* The original datum.  */
+
+  void *obfd;
+};
+
+/* A callback for linux_find_memory_regions that converts between the
+   "full"-style callback and find_memory_region_ftype.  */
+
+static int
+linux_find_memory_regions_thunk (ULONGEST vaddr, ULONGEST size,
+                                ULONGEST offset, ULONGEST inode,
+                                int read, int write, int exec, int modified,
+                                const char *filename, void *arg)
+{
+  struct linux_find_memory_regions_data *data = arg;
+
+  return data->func (vaddr, size, read, write, exec, modified, data->obfd);
+}
+
+/* A variant of linux_find_memory_regions_full that is suitable as the
+   gdbarch find_memory_regions method.  */
+
+static int
+linux_find_memory_regions (struct gdbarch *gdbarch,
+                          find_memory_region_ftype func, void *obfd)
+{
+  struct linux_find_memory_regions_data data;
+
+  data.func = func;
+  data.obfd = obfd;
+
+  return linux_find_memory_regions_full (gdbarch,
+                                        linux_find_memory_regions_thunk,
+                                        &data);
+}
+
 /* Determine which signal stopped execution.  */
 
 static int
@@ -712,6 +898,112 @@ linux_spu_make_corefile_notes (bfd *obfd, char *note_data, int *note_size)
   return note_data;
 }
 
+/* This is used to pass information from
+   linux_make_mappings_corefile_notes through
+   linux_find_memory_regions_full.  */
+
+struct linux_make_mappings_data
+{
+  /* Number of files mapped.  */
+  ULONGEST file_count;
+
+  /* The obstack for the main part of the data.  */
+  struct obstack *data_obstack;
+
+  /* The filename obstack.  */
+  struct obstack *filename_obstack;
+
+  /* The architecture's "long" type.  */
+  struct type *long_type;
+};
+
+static linux_find_memory_region_ftype linux_make_mappings_callback;
+
+/* A callback for linux_find_memory_regions_full that updates the
+   mappings data for linux_make_mappings_corefile_notes.  */
+
+static int
+linux_make_mappings_callback (ULONGEST vaddr, ULONGEST size,
+                             ULONGEST offset, ULONGEST inode,
+                             int read, int write, int exec, int modified,
+                             const char *filename, void *data)
+{
+  struct linux_make_mappings_data *map_data = data;
+  gdb_byte buf[sizeof (ULONGEST)];
+
+  if (*filename == '\0' || inode == 0)
+    return 0;
+
+  ++map_data->file_count;
+
+  pack_long (buf, map_data->long_type, vaddr);
+  obstack_grow (map_data->data_obstack, buf, TYPE_LENGTH (map_data->long_type));
+  pack_long (buf, map_data->long_type, vaddr + size);
+  obstack_grow (map_data->data_obstack, buf, TYPE_LENGTH (map_data->long_type));
+  pack_long (buf, map_data->long_type, offset);
+  obstack_grow (map_data->data_obstack, buf, TYPE_LENGTH (map_data->long_type));
+
+  obstack_grow_str0 (map_data->filename_obstack, filename);
+
+  return 0;
+}
+
+/* Write the file mapping data to the core file, if possible.  OBFD is
+   the output BFD.  NOTE_DATA is the current note data, and NOTE_SIZE
+   is a pointer to the note size.  Returns the new NOTE_DATA and
+   updates NOTE_SIZE.  */
+
+static char *
+linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
+                                   char *note_data, int *note_size)
+{
+  struct cleanup *cleanup;
+  struct obstack data_obstack, filename_obstack;
+  struct linux_make_mappings_data mapping_data;
+  struct type *long_type
+    = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch), 0, "long");
+  gdb_byte buf[sizeof (ULONGEST)];
+
+  obstack_init (&data_obstack);
+  cleanup = make_cleanup_obstack_free (&data_obstack);
+  obstack_init (&filename_obstack);
+  make_cleanup_obstack_free (&filename_obstack);
+
+  mapping_data.file_count = 0;
+  mapping_data.data_obstack = &data_obstack;
+  mapping_data.filename_obstack = &filename_obstack;
+  mapping_data.long_type = long_type;
+
+  /* Reserve space for the count.  */
+  obstack_blank (&data_obstack, TYPE_LENGTH (long_type));
+  /* We always write the page size as 1 since we have no good way to
+     determine the correct value.  */
+  pack_long (buf, long_type, 1);
+  obstack_grow (&data_obstack, buf, TYPE_LENGTH (long_type));
+
+  linux_find_memory_regions_full (gdbarch, linux_make_mappings_callback,
+                                 &mapping_data);
+
+  if (mapping_data.file_count != 0)
+    {
+      /* Write the count to the obstack.  */
+      pack_long (obstack_base (&data_obstack), long_type,
+                mapping_data.file_count);
+
+      /* Copy the filenames to the data obstack.  */
+      obstack_grow (&data_obstack, obstack_base (&filename_obstack),
+                   obstack_object_size (&filename_obstack));
+
+      note_data = elfcore_write_note (obfd, note_data, note_size,
+                                     "CORE", NT_FILE,
+                                     obstack_base (&data_obstack),
+                                     obstack_object_size (&data_obstack));
+    }
+
+  do_cleanups (cleanup);
+  return note_data;
+}
+
 /* Records the thread's register state for the corefile note
    section.  */
 
@@ -923,6 +1215,10 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size,
   if (!note_data)
     return NULL;
 
+  /* File mappings.  */
+  note_data = linux_make_mappings_corefile_notes (gdbarch, obfd,
+                                                 note_data, note_size);
+
   make_cleanup (xfree, note_data);
   return note_data;
 }
@@ -949,6 +1245,7 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   set_gdbarch_core_pid_to_str (gdbarch, linux_core_pid_to_str);
   set_gdbarch_info_proc (gdbarch, linux_info_proc);
+  set_gdbarch_core_info_proc (gdbarch, linux_core_info_proc);
   set_gdbarch_find_memory_regions (gdbarch, linux_find_memory_regions);
   set_gdbarch_make_corefile_notes (gdbarch, linux_make_corefile_notes_1);
   set_gdbarch_has_shared_address_space (gdbarch,
index 5015e51..ebd8085 100644 (file)
@@ -3144,7 +3144,7 @@ target_supports_non_stop (void)
 
 /* Implement the "info proc" command.  */
 
-void
+int
 target_info_proc (char *args, enum info_proc_what what)
 {
   struct target_ops *t;
@@ -3167,11 +3167,11 @@ target_info_proc (char *args, enum info_proc_what what)
            fprintf_unfiltered (gdb_stdlog,
                                "target_info_proc (\"%s\", %d)\n", args, what);
 
-         return;
+         return 1;
        }
     }
 
-  error (_("Not supported on this target."));
+  return 0;
 }
 
 static int
index 7907ee1..a832ef8 100644 (file)
@@ -976,9 +976,12 @@ extern void target_store_registers (struct regcache *regcache, int regs);
 
 struct address_space *target_thread_address_space (ptid_t);
 
-/* Implement the "info proc" command.  */
+/* Implement the "info proc" command.  This returns one if the request
+   was handled, and zero otherwise.  It can also throw an exception if
+   an error was encountered while attempting to handle the
+   request.  */
 
-void target_info_proc (char *, enum info_proc_what);
+int target_info_proc (char *, enum info_proc_what);
 
 /* Returns true if this target can debug multiple processes
    simultaneously.  */
index 9044a76..f584518 100644 (file)
@@ -1,3 +1,7 @@
+2012-12-14  Tom Tromey  <tromey@redhat.com>
+
+        * gdb.base/info-proc.exp: Add core file tests.
+
 2012-12-14  Yufeng Zhang  <yufeng.zhang@arm.com>
 
        * gdb.base/kill-after-signal.exp: Disable if gdb,nosignals.
index 1cefb6d..0ac0b6e 100644 (file)
@@ -68,3 +68,17 @@ gdb_test "info proc" "process ${decimal}.*" "info proc with process"
 gdb_test "info proc mapping" \
        ".*Mapped address spaces:.*${hex}${ws}${hex}${ws}${hex}${ws}${hex}.*" \
        "info proc mapping"
+
+if {[istarget "*-*-linux*"]} {
+    set gcorefile [standard_output_file $testfile.gcore]
+    if {[gdb_gcore_cmd $gcorefile "save a core file"]} {
+       clean_restart $binfile
+
+       gdb_test "core $gcorefile" "Core was generated by.*" \
+           "core [file tail $gcorefile]"
+
+       gdb_test "info proc mapping" \
+           ".*Mapped address spaces:.*${hex}${ws}${hex}${ws}${hex}${ws}${hex}.*" \
+           "info proc mapping with core file"
+    }
+}