Home | History | Annotate | Line # | Download | only in bfd
      1       1.1     skrll /* BFD back end for Lynx core files
      2  1.1.1.11  christos    Copyright (C) 1993-2026 Free Software Foundation, Inc.
      3       1.1     skrll    Written by Stu Grossman of Cygnus Support.
      4       1.1     skrll 
      5       1.1     skrll    This file is part of BFD, the Binary File Descriptor library.
      6       1.1     skrll 
      7       1.1     skrll    This program is free software; you can redistribute it and/or modify
      8       1.1     skrll    it under the terms of the GNU General Public License as published by
      9       1.1     skrll    the Free Software Foundation; either version 3 of the License, or
     10       1.1     skrll    (at your option) any later version.
     11       1.1     skrll 
     12       1.1     skrll    This program is distributed in the hope that it will be useful,
     13       1.1     skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14       1.1     skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15       1.1     skrll    GNU General Public License for more details.
     16       1.1     skrll 
     17       1.1     skrll    You should have received a copy of the GNU General Public License
     18       1.1     skrll    along with this program; if not, write to the Free Software
     19       1.1     skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20       1.1     skrll    MA 02110-1301, USA.  */
     21       1.1     skrll 
     22       1.1     skrll #include "sysdep.h"
     23       1.1     skrll #include "bfd.h"
     24       1.1     skrll #include "libbfd.h"
     25       1.1     skrll 
     26       1.1     skrll #ifdef LYNX_CORE
     27       1.1     skrll 
     28       1.1     skrll #include <sys/conf.h>
     29       1.1     skrll #include <sys/kernel.h>
     30       1.1     skrll /* sys/kernel.h should define this, but doesn't always, sigh.  */
     31       1.1     skrll #ifndef __LYNXOS
     32       1.1     skrll #define __LYNXOS
     33       1.1     skrll #endif
     34       1.1     skrll #include <sys/mem.h>
     35       1.1     skrll #include <sys/signal.h>
     36       1.1     skrll #include <sys/time.h>
     37       1.1     skrll #include <sys/resource.h>
     38       1.1     skrll #include <sys/itimer.h>
     39       1.1     skrll #include <sys/file.h>
     40       1.1     skrll #include <sys/proc.h>
     41       1.1     skrll 
     42       1.1     skrll /* These are stored in the bfd's tdata */
     43       1.1     skrll 
     44       1.1     skrll struct lynx_core_struct
     45       1.1     skrll {
     46       1.1     skrll   int sig;
     47       1.1     skrll   char cmd[PNMLEN + 1];
     48       1.1     skrll };
     49       1.1     skrll 
     50       1.1     skrll #define core_hdr(bfd) ((bfd)->tdata.lynx_core_data)
     51       1.1     skrll #define core_signal(bfd) (core_hdr(bfd)->sig)
     52       1.1     skrll #define core_command(bfd) (core_hdr(bfd)->cmd)
     53       1.1     skrll 
     54       1.1     skrll #define lynx_core_file_matches_executable_p generic_core_file_matches_executable_p
     55   1.1.1.2  christos #define lynx_core_file_pid _bfd_nocore_core_file_pid
     56       1.1     skrll 
     57       1.1     skrll /* Handle Lynx core dump file.  */
     58       1.1     skrll 
     59       1.1     skrll static asection *
     60   1.1.1.3  christos make_bfd_asection (bfd *abfd,
     61   1.1.1.3  christos 		   const char *name,
     62   1.1.1.3  christos 		   flagword flags,
     63   1.1.1.3  christos 		   bfd_size_type size,
     64   1.1.1.3  christos 		   bfd_vma vma,
     65   1.1.1.3  christos 		   file_ptr filepos)
     66       1.1     skrll {
     67       1.1     skrll   asection *asect;
     68       1.1     skrll   char *newname;
     69       1.1     skrll 
     70       1.1     skrll   newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
     71       1.1     skrll   if (!newname)
     72       1.1     skrll     return NULL;
     73       1.1     skrll 
     74       1.1     skrll   strcpy (newname, name);
     75       1.1     skrll 
     76       1.1     skrll   asect = bfd_make_section_with_flags (abfd, newname, flags);
     77       1.1     skrll   if (!asect)
     78       1.1     skrll     return NULL;
     79       1.1     skrll 
     80       1.1     skrll   asect->size = size;
     81       1.1     skrll   asect->vma = vma;
     82       1.1     skrll   asect->filepos = filepos;
     83       1.1     skrll   asect->alignment_power = 2;
     84       1.1     skrll 
     85       1.1     skrll   return asect;
     86       1.1     skrll }
     87       1.1     skrll 
     88   1.1.1.8  christos bfd_cleanup
     89   1.1.1.3  christos lynx_core_file_p (bfd *abfd)
     90       1.1     skrll {
     91       1.1     skrll   int secnum;
     92       1.1     skrll   struct pssentry pss;
     93       1.1     skrll   bfd_size_type tcontext_size;
     94       1.1     skrll   core_st_t *threadp;
     95       1.1     skrll   int pagesize;
     96       1.1     skrll   asection *newsect;
     97   1.1.1.8  christos   size_t amt;
     98       1.1     skrll 
     99       1.1     skrll   pagesize = getpagesize ();	/* Serious cross-target issue here...  This
    100       1.1     skrll 				   really needs to come from a system-specific
    101       1.1     skrll 				   header file.  */
    102       1.1     skrll 
    103       1.1     skrll   /* Get the pss entry from the core file */
    104       1.1     skrll 
    105   1.1.1.9  christos   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    106       1.1     skrll     return NULL;
    107       1.1     skrll 
    108       1.1     skrll   amt = sizeof pss;
    109   1.1.1.9  christos   if (bfd_read (&pss, amt, abfd) != amt)
    110       1.1     skrll     {
    111       1.1     skrll       /* Too small to be a core file */
    112       1.1     skrll       if (bfd_get_error () != bfd_error_system_call)
    113       1.1     skrll 	bfd_set_error (bfd_error_wrong_format);
    114       1.1     skrll       return NULL;
    115       1.1     skrll     }
    116       1.1     skrll 
    117       1.1     skrll   amt = sizeof (struct lynx_core_struct);
    118       1.1     skrll   core_hdr (abfd) = (struct lynx_core_struct *) bfd_zalloc (abfd, amt);
    119       1.1     skrll 
    120       1.1     skrll   if (!core_hdr (abfd))
    121       1.1     skrll     return NULL;
    122       1.1     skrll 
    123  1.1.1.10  christos   strncpy (core_command (abfd), pss.pname, PNMLEN);
    124  1.1.1.10  christos   core_command (abfd)[PNMLEN] = 0;
    125       1.1     skrll 
    126       1.1     skrll   /* Compute the size of the thread contexts */
    127       1.1     skrll 
    128       1.1     skrll   tcontext_size = pss.threadcnt * sizeof (core_st_t);
    129       1.1     skrll 
    130       1.1     skrll   /* Save thread contexts */
    131   1.1.1.8  christos   if (bfd_seek (abfd, pagesize, SEEK_SET) != 0)
    132   1.1.1.8  christos     goto fail;
    133   1.1.1.8  christos   threadp = (core_st_t *) _bfd_alloc_and_read (abfd, tcontext_size,
    134   1.1.1.8  christos 					       tcontext_size);
    135   1.1.1.8  christos   if (!threadp)
    136       1.1     skrll     goto fail;
    137       1.1     skrll 
    138       1.1     skrll   core_signal (abfd) = threadp->currsig;
    139       1.1     skrll 
    140       1.1     skrll   newsect = make_bfd_asection (abfd, ".stack",
    141       1.1     skrll 			       SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
    142       1.1     skrll 			       pss.ssize,
    143       1.1     skrll 			       pss.slimit,
    144       1.1     skrll 			       pagesize + tcontext_size);
    145       1.1     skrll   if (!newsect)
    146       1.1     skrll     goto fail;
    147       1.1     skrll 
    148       1.1     skrll   newsect = make_bfd_asection (abfd, ".data",
    149       1.1     skrll 			       SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
    150       1.1     skrll 			       pss.data_len + pss.bss_len,
    151       1.1     skrll 			       pss.data_start,
    152       1.1     skrll 			       pagesize + tcontext_size + pss.ssize
    153       1.1     skrll #if defined (SPARC) || defined (__SPARC__)
    154       1.1     skrll 			       /* SPARC Lynx seems to start dumping
    155   1.1.1.6  christos 				  the .data section at a page
    156   1.1.1.6  christos 				  boundary.  It's OK to check a
    157   1.1.1.6  christos 				  #define like SPARC here because this
    158   1.1.1.6  christos 				  file can only be compiled on a Lynx
    159   1.1.1.6  christos 				  host.  */
    160       1.1     skrll 			       + pss.data_start % pagesize
    161       1.1     skrll #endif
    162       1.1     skrll 			       );
    163       1.1     skrll   if (!newsect)
    164       1.1     skrll     goto fail;
    165       1.1     skrll 
    166       1.1     skrll /* And, now for the .reg/XXX pseudo sections.  Each thread has it's own
    167       1.1     skrll    .reg/XXX section, where XXX is the thread id (without leading zeros).  The
    168       1.1     skrll    currently running thread (at the time of the core dump) also has an alias
    169       1.1     skrll    called `.reg' (just to keep GDB happy).  Note that we use `.reg/XXX' as
    170       1.1     skrll    opposed to `.regXXX' because GDB expects that .reg2 will be the floating-
    171       1.1     skrll    point registers.  */
    172       1.1     skrll 
    173       1.1     skrll   newsect = make_bfd_asection (abfd, ".reg",
    174       1.1     skrll 			       SEC_HAS_CONTENTS,
    175       1.1     skrll 			       sizeof (core_st_t),
    176       1.1     skrll 			       0,
    177       1.1     skrll 			       pagesize);
    178       1.1     skrll   if (!newsect)
    179       1.1     skrll     goto fail;
    180       1.1     skrll 
    181       1.1     skrll   for (secnum = 0; secnum < pss.threadcnt; secnum++)
    182       1.1     skrll     {
    183       1.1     skrll       char secname[100];
    184       1.1     skrll 
    185       1.1     skrll       sprintf (secname, ".reg/%d", BUILDPID (0, threadp[secnum].tid));
    186       1.1     skrll       newsect = make_bfd_asection (abfd, secname,
    187       1.1     skrll 				   SEC_HAS_CONTENTS,
    188       1.1     skrll 				   sizeof (core_st_t),
    189       1.1     skrll 				   0,
    190       1.1     skrll 				   pagesize + secnum * sizeof (core_st_t));
    191       1.1     skrll       if (!newsect)
    192       1.1     skrll 	goto fail;
    193       1.1     skrll     }
    194       1.1     skrll 
    195   1.1.1.8  christos   return _bfd_no_cleanup;
    196       1.1     skrll 
    197       1.1     skrll  fail:
    198       1.1     skrll   bfd_release (abfd, core_hdr (abfd));
    199       1.1     skrll   core_hdr (abfd) = NULL;
    200       1.1     skrll   bfd_section_list_clear (abfd);
    201       1.1     skrll   return NULL;
    202       1.1     skrll }
    203       1.1     skrll 
    204       1.1     skrll char *
    205   1.1.1.3  christos lynx_core_file_failing_command (bfd *abfd)
    206       1.1     skrll {
    207       1.1     skrll   return core_command (abfd);
    208       1.1     skrll }
    209       1.1     skrll 
    210       1.1     skrll int
    211   1.1.1.3  christos lynx_core_file_failing_signal (bfd *abfd)
    212       1.1     skrll {
    213       1.1     skrll   return core_signal (abfd);
    214       1.1     skrll }
    215       1.1     skrll 
    216       1.1     skrll #endif /* LYNX_CORE */
    217