Add a pseudosection for the NT_FREEBSD_THRMISC note.
[deliverable/binutils-gdb.git] / gdb / corelow.c
index 02caeefc1cb7feab185f281f98d12aa059a59f1e..90e3d562539a88db975ccca54aa435ec3d29fe62 100644 (file)
@@ -1,6 +1,6 @@
 /* Core dump and executable file functions below target vector, for GDB.
 
-   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+   Copyright (C) 1986-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -19,8 +19,6 @@
 
 #include "defs.h"
 #include "arch-utils.h"
-#include <string.h>
-#include <errno.h>
 #include <signal.h>
 #include <fcntl.h>
 #ifdef HAVE_SYS_FILE_H
@@ -28,6 +26,7 @@
 #endif
 #include "frame.h"             /* required by inferior.h */
 #include "inferior.h"
+#include "infrun.h"
 #include "symtab.h"
 #include "command.h"
 #include "bfd.h"
@@ -39,8 +38,6 @@
 #include "symfile.h"
 #include "exec.h"
 #include "readline/readline.h"
-#include "gdb_assert.h"
-#include "exceptions.h"
 #include "solib.h"
 #include "filenames.h"
 #include "progspace.h"
@@ -83,8 +80,6 @@ static struct core_fns *sniff_core_bfd (bfd *);
 
 static int gdb_check_format (bfd *);
 
-static void core_open (char *, int);
-
 static void core_close (struct target_ops *self);
 
 static void core_close_cleanup (void *ignore);
@@ -138,7 +133,7 @@ sniff_core_bfd (bfd *abfd)
 
   /* Don't sniff if we have support for register sets in
      CORE_GDBARCH.  */
-  if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch))
+  if (core_gdbarch && gdbarch_iterate_over_regset_sections_p (core_gdbarch))
     return NULL;
 
   for (cf = core_file_fns; cf != NULL; cf = cf->next)
@@ -239,7 +234,7 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
   int fake_pid_p = 0;
   struct inferior *inf;
 
-  if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
+  if (!startswith (bfd_section_name (abfd, asect), ".reg/"))
     return;
 
   core_tid = atoi (bfd_section_name (abfd, asect) + 5);
@@ -274,7 +269,7 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
 /* This routine opens and sets up the core file bfd.  */
 
 static void
-core_open (char *filename, int from_tty)
+core_open (const char *arg, int from_tty)
 {
   const char *p;
   int siggy;
@@ -283,10 +278,10 @@ core_open (char *filename, int from_tty)
   bfd *temp_bfd;
   int scratch_chan;
   int flags;
-  volatile struct gdb_exception except;
+  char *filename;
 
   target_preopen (from_tty);
-  if (!filename)
+  if (!arg)
     {
       if (core_bfd)
        error (_("No core file specified.  (Use `detach' "
@@ -295,7 +290,7 @@ core_open (char *filename, int from_tty)
        error (_("No core file specified."));
     }
 
-  filename = tilde_expand (filename);
+  filename = tilde_expand (arg);
   if (!IS_ABSOLUTE_PATH (filename))
     {
       temp = concat (current_directory, "/",
@@ -415,13 +410,16 @@ core_open (char *filename, int from_tty)
      may be a thread_stratum target loaded on top of target core by
      now.  The layer above should claim threads found in the BFD
      sections.  */
-  TRY_CATCH (except, RETURN_MASK_ERROR)
+  TRY
     {
-      target_find_new_threads ();
+      target_update_thread_list ();
     }
 
-  if (except.reason < 0)
-    exception_print (gdb_stderr, except);
+  CATCH (except, RETURN_MASK_ERROR)
+    {
+      exception_print (gdb_stderr, except);
+    }
+  END_CATCH
 
   p = bfd_core_file_failing_command (core_bfd);
   if (p)
@@ -460,6 +458,22 @@ 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, 1);
+
+  /* Current thread should be NUM 1 but the user does not know that.
+     If a program is single threaded gdb in general does not mention
+     anything about threads.  That is why the test is >= 2.  */
+  if (thread_count () >= 2)
+    {
+      TRY
+       {
+         thread_command (NULL, from_tty);
+       }
+      CATCH (except, RETURN_MASK_ERROR)
+       {
+         exception_print (gdb_stderr, except);
+       }
+      END_CATCH
+    }
 }
 
 static void
@@ -492,7 +506,9 @@ core_detach (struct target_ops *ops, const char *args, int from_tty)
 
 static void
 get_core_register_section (struct regcache *regcache,
+                          const struct regset *regset,
                           const char *name,
+                          int min_size,
                           int which,
                           const char *human_name,
                           int required)
@@ -520,7 +536,18 @@ get_core_register_section (struct regcache *regcache,
     }
 
   size = bfd_section_size (core_bfd, section);
-  contents = alloca (size);
+  if (size < min_size)
+    {
+      warning (_("Section `%s' in core file too small."), section_name);
+      return;
+    }
+  if (size != min_size && !(regset->flags & REGSET_VARIABLE_SIZE))
+    {
+      warning (_("Unexpected size of section `%s' in core file."),
+              section_name);
+    }
+
+  contents = (char *) alloca (size);
   if (! bfd_get_section_contents (core_bfd, section, contents,
                                  (file_ptr) 0, size))
     {
@@ -529,20 +556,8 @@ get_core_register_section (struct regcache *regcache,
       return;
     }
 
-  if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch))
+  if (regset != NULL)
     {
-      const struct regset *regset;
-
-      regset = gdbarch_regset_from_core_section (core_gdbarch,
-                                                name, size);
-      if (regset == NULL)
-       {
-         if (required)
-           warning (_("Couldn't recognize %s registers in core file."),
-                    human_name);
-         return;
-       }
-
       regset->supply_regset (regset, regcache, -1, contents, size);
       return;
     }
@@ -553,6 +568,34 @@ get_core_register_section (struct regcache *regcache,
                                  bfd_section_vma (core_bfd, section)));
 }
 
+/* Callback for get_core_registers that handles a single core file
+   register note section. */
+
+static void
+get_core_registers_cb (const char *sect_name, int size,
+                      const struct regset *regset,
+                      const char *human_name, void *cb_data)
+{
+  struct regcache *regcache = (struct regcache *) cb_data;
+  int required = 0;
+
+  if (strcmp (sect_name, ".reg") == 0)
+    {
+      required = 1;
+      if (human_name == NULL)
+       human_name = "general-purpose";
+    }
+  else if (strcmp (sect_name, ".reg2") == 0)
+    {
+      if (human_name == NULL)
+       human_name = "floating-point";
+    }
+
+  /* The 'which' parameter is only used when no regset is provided.
+     Thus we just set it to -1. */
+  get_core_register_section (regcache, regset, sect_name,
+                            size, -1, human_name, required);
+}
 
 /* Get the registers out of a core file.  This is the machine-
    independent part.  Fetch_core_registers is the machine-dependent
@@ -565,10 +608,10 @@ static void
 get_core_registers (struct target_ops *ops,
                    struct regcache *regcache, int regno)
 {
-  struct core_regset_section *sect_list;
   int i;
+  struct gdbarch *gdbarch;
 
-  if (!(core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch))
+  if (!(core_gdbarch && gdbarch_iterate_over_regset_sections_p (core_gdbarch))
       && (core_vec == NULL || core_vec->core_read_registers == NULL))
     {
       fprintf_filtered (gdb_stderr,
@@ -576,29 +619,17 @@ get_core_registers (struct target_ops *ops,
       return;
     }
 
-  sect_list = gdbarch_core_regset_sections (get_regcache_arch (regcache));
-  if (sect_list)
-    while (sect_list->sect_name != NULL)
-      {
-        if (strcmp (sect_list->sect_name, ".reg") == 0)
-         get_core_register_section (regcache, sect_list->sect_name,
-                                    0, sect_list->human_name, 1);
-        else if (strcmp (sect_list->sect_name, ".reg2") == 0)
-         get_core_register_section (regcache, sect_list->sect_name,
-                                    2, sect_list->human_name, 0);
-       else
-         get_core_register_section (regcache, sect_list->sect_name,
-                                    3, sect_list->human_name, 0);
-
-       sect_list++;
-      }
-
+  gdbarch = get_regcache_arch (regcache);
+  if (gdbarch_iterate_over_regset_sections_p (gdbarch))
+    gdbarch_iterate_over_regset_sections (gdbarch,
+                                         get_core_registers_cb,
+                                         (void *) regcache, NULL);
   else
     {
-      get_core_register_section (regcache,
-                                ".reg", 0, "general-purpose", 1);
-      get_core_register_section (regcache,
-                                ".reg2", 2, "floating-point", 0);
+      get_core_register_section (regcache, NULL,
+                                ".reg", 0, 0, "general-purpose", 1);
+      get_core_register_section (regcache, NULL,
+                                ".reg2", 0, 2, "floating-point", 0);
     }
 
   /* Mark all registers not found in the core as unavailable.  */
@@ -625,7 +656,7 @@ struct spuid_list
 static void
 add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
 {
-  struct spuid_list *list = list_p;
+  struct spuid_list *list = (struct spuid_list *) list_p;
   enum bfd_endian byte_order
     = bfd_big_endian (abfd) ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
   int fd, pos = 0;
@@ -737,7 +768,7 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
 
          size = bfd_section_size (core_bfd, section);
          if (offset >= size)
-           return 0;
+           return TARGET_XFER_EOF;
          size -= offset;
          if (size > len)
            size = len;
@@ -870,12 +901,10 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
       return TARGET_XFER_E_IO;
 
     default:
-      if (ops->beneath != NULL)
-       return ops->beneath->to_xfer_partial (ops->beneath, object,
-                                             annex, readbuf,
-                                             writebuf, offset, len,
-                                             xfered_len);
-      return TARGET_XFER_E_IO;
+      return ops->beneath->to_xfer_partial (ops->beneath, object,
+                                           annex, readbuf,
+                                           writebuf, offset, len,
+                                           xfered_len);
     }
 }
 
@@ -948,7 +977,7 @@ core_pid_to_str (struct target_ops *ops, ptid_t ptid)
 
   /* Otherwise, this isn't a "threaded" core -- use the PID field, but
      only if it isn't a fake PID.  */
-  inf = find_inferior_pid (ptid_get_pid (ptid));
+  inf = find_inferior_ptid (ptid);
   if (inf != NULL && !inf->fake_pid_p)
     return normal_pid_to_str (ptid);
 
@@ -978,7 +1007,8 @@ core_has_registers (struct target_ops *ops)
 /* Implement the to_info_proc method.  */
 
 static void
-core_info_proc (struct target_ops *ops, char *args, enum info_proc_what request)
+core_info_proc (struct target_ops *ops, const char *args,
+               enum info_proc_what request)
 {
   struct gdbarch *gdbarch = get_current_arch ();
 
This page took 0.028906 seconds and 4 git commands to generate.