bfd/
[deliverable/binutils-gdb.git] / bfd / lynx-core.c
index 5c5e2bea320da5455cfbe0ff1572f63d59973ba7..ef243fbef19547176db4c4dcedbea1efe4e53b13 100644 (file)
@@ -1,5 +1,6 @@
 /* BFD back end for Lynx core files
 /* BFD back end for Lynx core files
-   Copyright 1993 Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1995, 2001, 2002, 2004
+   Free Software Foundation, Inc.
    Written by Stu Grossman of Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
    Written by Stu Grossman of Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -16,17 +17,31 @@ 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
 
 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.  */
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
 
 
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
 
-#ifdef HOST_LYNX               /* Core files only work locally for now */
+#ifdef LYNX_CORE
+
+#include <sys/conf.h>
+#include <sys/kernel.h>
+/* sys/kernel.h should define this, but doesn't always, sigh.  */
+#ifndef __LYNXOS
+#define __LYNXOS
+#endif
+#include <sys/mem.h>
+#include <sys/signal.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/itimer.h>
+#include <sys/file.h>
+#include <sys/proc.h>
 
 /* These are stored in the bfd's tdata */
 
 
 /* These are stored in the bfd's tdata */
 
-struct lynx_core_struct 
+struct lynx_core_struct
 {
   int sig;
   char cmd[PNMLEN + 1];
 {
   int sig;
   char cmd[PNMLEN + 1];
@@ -36,21 +51,23 @@ struct lynx_core_struct
 #define core_signal(bfd) (core_hdr(bfd)->sig)
 #define core_command(bfd) (core_hdr(bfd)->cmd)
 
 #define core_signal(bfd) (core_hdr(bfd)->sig)
 #define core_command(bfd) (core_hdr(bfd)->cmd)
 
+#define lynx_core_file_matches_executable_p generic_core_file_matches_executable_p
+
 /* Handle Lynx core dump file.  */
 
 static asection *
 /* Handle Lynx core dump file.  */
 
 static asection *
-make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
+make_bfd_asection (abfd, name, flags, size, vma, filepos)
      bfd *abfd;
      bfd *abfd;
-     CONST char *name;
+     const char *name;
      flagword flags;
      flagword flags;
-     bfd_size_type _raw_size;
+     bfd_size_type size;
      bfd_vma vma;
      file_ptr filepos;
 {
   asection *asect;
   char *newname;
 
      bfd_vma vma;
      file_ptr filepos;
 {
   asection *asect;
   char *newname;
 
-  newname = bfd_alloc (abfd, strlen (name) + 1);
+  newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
   if (!newname)
     return NULL;
 
   if (!newname)
     return NULL;
 
@@ -61,7 +78,7 @@ make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
     return NULL;
 
   asect->flags = flags;
     return NULL;
 
   asect->flags = flags;
-  asect->_raw_size = _raw_size;
+  asect->size = size;
   asect->vma = vma;
   asect->filepos = filepos;
   asect->alignment_power = 2;
   asect->vma = vma;
   asect->filepos = filepos;
   asect->alignment_power = 2;
@@ -69,18 +86,17 @@ make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
   return asect;
 }
 
   return asect;
 }
 
-/* ARGSUSED */
-bfd_target *
+const bfd_target *
 lynx_core_file_p (abfd)
      bfd *abfd;
 {
 lynx_core_file_p (abfd)
      bfd *abfd;
 {
-  int val;
   int secnum;
   struct pssentry pss;
   int secnum;
   struct pssentry pss;
-  size_t tcontext_size;
+  bfd_size_type tcontext_size;
   core_st_t *threadp;
   int pagesize;
   asection *newsect;
   core_st_t *threadp;
   int pagesize;
   asection *newsect;
+  bfd_size_type amt;
 
   pagesize = getpagesize ();   /* Serious cross-target issue here...  This
                                   really needs to come from a system-specific
 
   pagesize = getpagesize ();   /* Serious cross-target issue here...  This
                                   really needs to come from a system-specific
@@ -88,24 +104,23 @@ lynx_core_file_p (abfd)
 
   /* Get the pss entry from the core file */
 
 
   /* Get the pss entry from the core file */
 
-  bfd_seek (abfd, 0, SEEK_SET);
+  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+    return NULL;
 
 
-  val = bfd_read ((void *)&pss, 1, sizeof pss, abfd);
-  if (val != sizeof pss)
+  amt = sizeof pss;
+  if (bfd_bread ((void *) &pss, amt, abfd) != amt)
     {
       /* Too small to be a core file */
     {
       /* Too small to be a core file */
-      bfd_error = wrong_format;
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_wrong_format);
       return NULL;
       return NULL;
-  }
+    }
 
 
-  core_hdr (abfd) = (struct lynx_core_struct *)
-    bfd_zalloc (abfd, sizeof (struct lynx_core_struct));
+  amt = sizeof (struct lynx_core_struct);
+  core_hdr (abfd) = (struct lynx_core_struct *) bfd_zalloc (abfd, amt);
 
   if (!core_hdr (abfd))
 
   if (!core_hdr (abfd))
-    {
-      bfd_error = no_memory;
-      return NULL;
-    }
+    return NULL;
 
   strncpy (core_command (abfd), pss.pname, PNMLEN + 1);
 
 
   strncpy (core_command (abfd), pss.pname, PNMLEN + 1);
 
@@ -115,26 +130,23 @@ lynx_core_file_p (abfd)
 
   /* Allocate space for the thread contexts */
 
 
   /* Allocate space for the thread contexts */
 
-  threadp = (core_st_t *)bfd_zalloc (abfd, tcontext_size);
+  threadp = (core_st_t *) bfd_alloc (abfd, tcontext_size);
   if (!threadp)
   if (!threadp)
-    {
-      bfd_error = no_memory;
-      return NULL;
-    }
+    goto fail;
 
   /* Save thread contexts */
 
 
   /* Save thread contexts */
 
-  bfd_seek (abfd, pagesize, SEEK_SET);
-
-  val = bfd_read ((void *)threadp, pss.threadcnt, sizeof (core_st_t), abfd);
+  if (bfd_seek (abfd, (file_ptr) pagesize, SEEK_SET) != 0)
+    goto fail;
 
 
-  if (val != tcontext_size)
+  if (bfd_bread ((void *) threadp, tcontext_size, abfd) != tcontext_size)
     {
       /* Probably too small to be a core file */
     {
       /* Probably too small to be a core file */
-      bfd_error = wrong_format;
-      return NULL;
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_wrong_format);
+      goto fail;
     }
     }
-  
+
   core_signal (abfd) = threadp->currsig;
 
   newsect = make_bfd_asection (abfd, ".stack",
   core_signal (abfd) = threadp->currsig;
 
   newsect = make_bfd_asection (abfd, ".stack",
@@ -143,40 +155,62 @@ lynx_core_file_p (abfd)
                               pss.slimit,
                               pagesize + tcontext_size);
   if (!newsect)
                               pss.slimit,
                               pagesize + tcontext_size);
   if (!newsect)
-    {
-      bfd_error = no_memory;
-      return NULL;
-    }
+    goto fail;
 
   newsect = make_bfd_asection (abfd, ".data",
                               SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
                               pss.data_len + pss.bss_len,
                               pss.data_start,
 
   newsect = make_bfd_asection (abfd, ".data",
                               SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
                               pss.data_len + pss.bss_len,
                               pss.data_start,
-                              pagesize + tcontext_size + pss.ssize);
+                              pagesize + tcontext_size + pss.ssize
+#if defined (SPARC) || defined (__SPARC__)
+                              /* SPARC Lynx seems to start dumping
+                                  the .data section at a page
+                                  boundary.  It's OK to check a
+                                  #define like SPARC here because this
+                                  file can only be compiled on a Lynx
+                                  host.  */
+                              + pss.data_start % pagesize
+#endif
+                              );
   if (!newsect)
   if (!newsect)
-    {
-      bfd_error = no_memory;
-      return NULL;
-    }
+    goto fail;
+
+/* And, now for the .reg/XXX pseudo sections.  Each thread has it's own
+   .reg/XXX section, where XXX is the thread id (without leading zeros).  The
+   currently running thread (at the time of the core dump) also has an alias
+   called `.reg' (just to keep GDB happy).  Note that we use `.reg/XXX' as
+   opposed to `.regXXX' because GDB expects that .reg2 will be the floating-
+   point registers.  */
+
+  newsect = make_bfd_asection (abfd, ".reg",
+                              SEC_HAS_CONTENTS,
+                              sizeof (core_st_t),
+                              0,
+                              pagesize);
+  if (!newsect)
+    goto fail;
 
   for (secnum = 0; secnum < pss.threadcnt; secnum++)
     {
       char secname[100];
 
 
   for (secnum = 0; secnum < pss.threadcnt; secnum++)
     {
       char secname[100];
 
-      sprintf (secname, ".reg%d", threadp[secnum].tid);
+      sprintf (secname, ".reg/%d", BUILDPID (0, threadp[secnum].tid));
       newsect = make_bfd_asection (abfd, secname,
       newsect = make_bfd_asection (abfd, secname,
-                                  SEC_ALLOC + SEC_HAS_CONTENTS,
+                                  SEC_HAS_CONTENTS,
                                   sizeof (core_st_t),
                                   0,
                                   pagesize + secnum * sizeof (core_st_t));
       if (!newsect)
                                   sizeof (core_st_t),
                                   0,
                                   pagesize + secnum * sizeof (core_st_t));
       if (!newsect)
-       {
-         bfd_error = no_memory;
-         return NULL;
-       }
+       goto fail;
     }
 
   return abfd->xvec;
     }
 
   return abfd->xvec;
+
+ fail:
+  bfd_release (abfd, core_hdr (abfd));
+  core_hdr (abfd) = NULL;
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 char *
 }
 
 char *
@@ -186,7 +220,6 @@ lynx_core_file_failing_command (abfd)
   return core_command (abfd);
 }
 
   return core_command (abfd);
 }
 
-/* ARGSUSED */
 int
 lynx_core_file_failing_signal (abfd)
      bfd *abfd;
 int
 lynx_core_file_failing_signal (abfd)
      bfd *abfd;
@@ -194,12 +227,4 @@ lynx_core_file_failing_signal (abfd)
   return core_signal (abfd);
 }
 
   return core_signal (abfd);
 }
 
-/* ARGSUSED */
-boolean
-lynx_core_file_matches_executable_p  (core_bfd, exec_bfd)
-     bfd *core_bfd, *exec_bfd;
-{
-  return true;         /* FIXME, We have no way of telling at this point */
-}
-
-#endif /* HOST_LYNX */
+#endif /* LYNX_CORE */
This page took 0.026479 seconds and 4 git commands to generate.