/* BFD back end for Lynx core files
- Copyright 1993 Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1995, 2001 Free Software Foundation, Inc.
Written by Stu Grossman of Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#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 */
-struct lynx_core_struct
+struct lynx_core_struct
{
int sig;
char cmd[PNMLEN + 1];
return asect;
}
-/* ARGSUSED */
-bfd_target *
+const bfd_target *
lynx_core_file_p (abfd)
bfd *abfd;
{
/* Get the pss entry from the core file */
- bfd_seek (abfd, 0, SEEK_SET);
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ return NULL;
val = bfd_read ((void *)&pss, 1, sizeof pss, abfd);
if (val != sizeof pss)
{
/* 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;
- }
+ }
core_hdr (abfd) = (struct lynx_core_struct *)
bfd_zalloc (abfd, sizeof (struct lynx_core_struct));
if (!core_hdr (abfd))
- {
- bfd_error = no_memory;
- return NULL;
- }
+ return NULL;
strncpy (core_command (abfd), pss.pname, PNMLEN + 1);
/* 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)
- {
- bfd_error = no_memory;
- return NULL;
- }
+ return NULL;
/* Save thread contexts */
- bfd_seek (abfd, pagesize, SEEK_SET);
+ if (bfd_seek (abfd, pagesize, SEEK_SET) != 0)
+ return NULL;
val = bfd_read ((void *)threadp, pss.threadcnt, sizeof (core_st_t), abfd);
if (val != tcontext_size)
{
/* Probably 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;
}
-
+
core_signal (abfd) = threadp->currsig;
newsect = make_bfd_asection (abfd, ".stack",
pss.slimit,
pagesize + tcontext_size);
if (!newsect)
- {
- bfd_error = no_memory;
- return NULL;
- }
+ return NULL;
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)
- {
- bfd_error = no_memory;
- return NULL;
- }
+ return NULL;
+
+/* 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)
+ return NULL;
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,
- SEC_ALLOC + SEC_HAS_CONTENTS,
+ SEC_HAS_CONTENTS,
sizeof (core_st_t),
0,
pagesize + secnum * sizeof (core_st_t));
if (!newsect)
- {
- bfd_error = no_memory;
- return NULL;
- }
+ return NULL;
}
return abfd->xvec;
return core_command (abfd);
}
-/* ARGSUSED */
int
lynx_core_file_failing_signal (abfd)
bfd *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 */