xref: /openbsd-src/gnu/usr.bin/binutils/bfd/hppabsd-core.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
12159047fSniklas /* BFD back-end for HPPA BSD core files.
2*007c2a45Smiod    Copyright 1993, 1994, 1995, 1998, 1999, 2001, 2002, 2003, 2004
3b55d4692Sfgsch    Free Software Foundation, Inc.
42159047fSniklas 
52159047fSniklas    This file is part of BFD, the Binary File Descriptor library.
62159047fSniklas 
72159047fSniklas    This program is free software; you can redistribute it and/or modify
82159047fSniklas    it under the terms of the GNU General Public License as published by
92159047fSniklas    the Free Software Foundation; either version 2 of the License, or
102159047fSniklas    (at your option) any later version.
112159047fSniklas 
122159047fSniklas    This program is distributed in the hope that it will be useful,
132159047fSniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
142159047fSniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152159047fSniklas    GNU General Public License for more details.
162159047fSniklas 
172159047fSniklas    You should have received a copy of the GNU General Public License
182159047fSniklas    along with this program; if not, write to the Free Software
192159047fSniklas    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
202159047fSniklas 
212159047fSniklas    Written by the Center for Software Science at the University of Utah
222159047fSniklas    and by Cygnus Support.
232159047fSniklas 
242159047fSniklas    The core file structure for the Utah 4.3BSD and OSF1 ports on the
252159047fSniklas    PA is a mix between traditional cores and hpux cores -- just
262159047fSniklas    different enough that supporting this format would tend to add
272159047fSniklas    gross hacks to trad-core.c or hpux-core.c.  So instead we keep any
282159047fSniklas    gross hacks isolated to this file.  */
292159047fSniklas 
302159047fSniklas /* This file can only be compiled on systems which use HPPA-BSD style
312159047fSniklas    core files.
322159047fSniklas 
332159047fSniklas    I would not expect this to be of use to any other host/target, but
342159047fSniklas    you never know.  */
352159047fSniklas 
362159047fSniklas #include "bfd.h"
372159047fSniklas #include "sysdep.h"
382159047fSniklas #include "libbfd.h"
392159047fSniklas 
402159047fSniklas #if defined (HOST_HPPABSD)
412159047fSniklas 
422159047fSniklas #include "machine/vmparam.h"
432159047fSniklas 
442159047fSniklas #include <sys/param.h>
452159047fSniklas #include <sys/dir.h>
462159047fSniklas #include <signal.h>
472159047fSniklas #include <machine/reg.h>
482159047fSniklas #include <sys/user.h>		/* After a.out.h  */
492159047fSniklas #include <sys/file.h>
502159047fSniklas 
51c074d1c9Sdrahn static asection *make_bfd_asection
52c074d1c9Sdrahn   PARAMS ((bfd *, const char *, flagword, bfd_size_type, file_ptr,
53c074d1c9Sdrahn 	   unsigned int));
54c074d1c9Sdrahn static const bfd_target *hppabsd_core_core_file_p
55c074d1c9Sdrahn   PARAMS ((bfd *));
56c074d1c9Sdrahn static char *hppabsd_core_core_file_failing_command
57c074d1c9Sdrahn   PARAMS ((bfd *));
58c074d1c9Sdrahn static int hppabsd_core_core_file_failing_signal
59c074d1c9Sdrahn   PARAMS ((bfd *));
60c074d1c9Sdrahn static bfd_boolean hppabsd_core_core_file_matches_executable_p
612159047fSniklas   PARAMS ((bfd *, bfd *));
62c074d1c9Sdrahn static void swap_abort
63c074d1c9Sdrahn   PARAMS ((void));
642159047fSniklas 
652159047fSniklas /* These are stored in the bfd's tdata.  */
662159047fSniklas 
672159047fSniklas struct hppabsd_core_struct
682159047fSniklas   {
692159047fSniklas     int sig;
702159047fSniklas     char cmd[MAXCOMLEN + 1];
712159047fSniklas     asection *data_section;
722159047fSniklas     asection *stack_section;
732159047fSniklas     asection *reg_section;
742159047fSniklas   };
752159047fSniklas 
762159047fSniklas #define core_hdr(bfd) ((bfd)->tdata.hppabsd_core_data)
772159047fSniklas #define core_signal(bfd) (core_hdr(bfd)->sig)
782159047fSniklas #define core_command(bfd) (core_hdr(bfd)->cmd)
792159047fSniklas #define core_datasec(bfd) (core_hdr(bfd)->data_section)
802159047fSniklas #define core_stacksec(bfd) (core_hdr(bfd)->stack_section)
812159047fSniklas #define core_regsec(bfd) (core_hdr(bfd)->reg_section)
822159047fSniklas 
832159047fSniklas static asection *
make_bfd_asection(abfd,name,flags,_raw_size,offset,alignment_power)842159047fSniklas make_bfd_asection (abfd, name, flags, _raw_size, offset, alignment_power)
852159047fSniklas      bfd *abfd;
86c074d1c9Sdrahn      const char *name;
872159047fSniklas      flagword flags;
882159047fSniklas      bfd_size_type _raw_size;
892159047fSniklas      file_ptr offset;
902159047fSniklas      unsigned int alignment_power;
912159047fSniklas {
922159047fSniklas   asection *asect;
932159047fSniklas 
942159047fSniklas   asect = bfd_make_section (abfd, name);
952159047fSniklas   if (!asect)
962159047fSniklas     return NULL;
972159047fSniklas 
982159047fSniklas   asect->flags = flags;
992159047fSniklas   asect->_raw_size = _raw_size;
1002159047fSniklas   asect->filepos = offset;
1012159047fSniklas   asect->alignment_power = alignment_power;
1022159047fSniklas 
1032159047fSniklas   return asect;
1042159047fSniklas }
1052159047fSniklas 
1062159047fSniklas static const bfd_target *
hppabsd_core_core_file_p(abfd)1072159047fSniklas hppabsd_core_core_file_p (abfd)
1082159047fSniklas      bfd *abfd;
1092159047fSniklas {
1102159047fSniklas   int val;
1112159047fSniklas   struct user u;
1122159047fSniklas   struct hppabsd_core_struct *coredata;
1132159047fSniklas   int clicksz;
1142159047fSniklas 
1152159047fSniklas   /* Try to read in the u-area.  We will need information from this
1162159047fSniklas      to know how to grok the rest of the core structures.  */
117c074d1c9Sdrahn   val = bfd_bread ((void *) &u, (bfd_size_type) sizeof u, abfd);
1182159047fSniklas   if (val != sizeof u)
1192159047fSniklas     {
1202159047fSniklas       if (bfd_get_error () != bfd_error_system_call)
1212159047fSniklas 	bfd_set_error (bfd_error_wrong_format);
1222159047fSniklas       return NULL;
1232159047fSniklas     }
1242159047fSniklas 
1252159047fSniklas   /* Get the page size out of the u structure.  This will be different
1262159047fSniklas      for PA 1.0 machines and PA 1.1 machines.   Yuk!  */
1272159047fSniklas   clicksz = u.u_pcb.pcb_pgsz;
1282159047fSniklas 
1292159047fSniklas   /* clicksz must be a power of two >= 2k.  */
1302159047fSniklas   if (clicksz < 0x800
1312159047fSniklas       || clicksz != (clicksz & -clicksz))
1322159047fSniklas     {
1332159047fSniklas       bfd_set_error (bfd_error_wrong_format);
1342159047fSniklas       return NULL;
1352159047fSniklas     }
1362159047fSniklas 
1372159047fSniklas   /* Sanity checks.  Make sure the size of the core file matches the
1382159047fSniklas      the size computed from information within the core itself.  */
1392159047fSniklas   {
1402159047fSniklas     FILE *stream = bfd_cache_lookup (abfd);
1412159047fSniklas     struct stat statbuf;
1422159047fSniklas     if (stream == NULL || fstat (fileno (stream), &statbuf) < 0)
1432159047fSniklas       {
1442159047fSniklas 	bfd_set_error (bfd_error_system_call);
1452159047fSniklas 	return NULL;
1462159047fSniklas       }
1472159047fSniklas     if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size)
1482159047fSniklas       {
1492159047fSniklas 	bfd_set_error (bfd_error_file_truncated);
1502159047fSniklas 	return NULL;
1512159047fSniklas       }
1522159047fSniklas     if (clicksz * (UPAGES + u.u_dsize + u.u_ssize) < statbuf.st_size)
1532159047fSniklas       {
1542159047fSniklas 	/* The file is too big.  Maybe it's not a core file
1552159047fSniklas 	   or we otherwise have bad values for u_dsize and u_ssize).  */
1562159047fSniklas 	bfd_set_error (bfd_error_wrong_format);
1572159047fSniklas 	return NULL;
1582159047fSniklas       }
1592159047fSniklas   }
1602159047fSniklas 
1612159047fSniklas   /* OK, we believe you.  You're a core file (sure, sure).  */
1622159047fSniklas 
1632159047fSniklas   coredata = (struct hppabsd_core_struct *)
164c074d1c9Sdrahn     bfd_zalloc (abfd, (bfd_size_type) sizeof (struct hppabsd_core_struct));
1652159047fSniklas   if (!coredata)
1662159047fSniklas     return NULL;
1672159047fSniklas 
1682159047fSniklas   /* Make the core data and available via the tdata part of the BFD.  */
1692159047fSniklas   abfd->tdata.hppabsd_core_data = coredata;
1702159047fSniklas 
1712159047fSniklas   /* Create the sections.  */
1722159047fSniklas   core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
1732159047fSniklas 					   SEC_ALLOC + SEC_HAS_CONTENTS,
1742159047fSniklas 					   clicksz * u.u_ssize,
1752159047fSniklas 					   NBPG * (USIZE + KSTAKSIZE)
1762159047fSniklas 					     + clicksz * u.u_dsize, 2);
177c074d1c9Sdrahn   if (core_stacksec (abfd) == NULL)
178c074d1c9Sdrahn     goto fail;
1792159047fSniklas   core_stacksec (abfd)->vma = USRSTACK;
1802159047fSniklas 
1812159047fSniklas   core_datasec (abfd) = make_bfd_asection (abfd, ".data",
1822159047fSniklas 					  SEC_ALLOC + SEC_LOAD
1832159047fSniklas 					    + SEC_HAS_CONTENTS,
1842159047fSniklas 					  clicksz * u.u_dsize,
1852159047fSniklas 					  NBPG * (USIZE + KSTAKSIZE), 2);
186c074d1c9Sdrahn   if (core_datasec (abfd) == NULL)
187c074d1c9Sdrahn     goto fail;
1882159047fSniklas   core_datasec (abfd)->vma = UDATASEG;
1892159047fSniklas 
1902159047fSniklas   core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
1912159047fSniklas 					 SEC_HAS_CONTENTS,
1922159047fSniklas 					 KSTAKSIZE * NBPG,
1932159047fSniklas 					 NBPG * USIZE, 2);
194c074d1c9Sdrahn   if (core_regsec (abfd) == NULL)
195c074d1c9Sdrahn     goto fail;
1962159047fSniklas   core_regsec (abfd)->vma = 0;
1972159047fSniklas 
1982159047fSniklas   strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1);
1992159047fSniklas   core_signal (abfd) = u.u_code;
2002159047fSniklas   return abfd->xvec;
201c074d1c9Sdrahn 
202c074d1c9Sdrahn  fail:
203c074d1c9Sdrahn   bfd_release (abfd, abfd->tdata.any);
204c074d1c9Sdrahn   abfd->tdata.any = NULL;
205c074d1c9Sdrahn   bfd_section_list_clear (abfd);
206c074d1c9Sdrahn   return NULL;
2072159047fSniklas }
2082159047fSniklas 
2092159047fSniklas static char *
hppabsd_core_core_file_failing_command(abfd)2102159047fSniklas hppabsd_core_core_file_failing_command (abfd)
2112159047fSniklas      bfd *abfd;
2122159047fSniklas {
2132159047fSniklas   return core_command (abfd);
2142159047fSniklas }
2152159047fSniklas 
2162159047fSniklas static int
hppabsd_core_core_file_failing_signal(abfd)2172159047fSniklas hppabsd_core_core_file_failing_signal (abfd)
2182159047fSniklas      bfd *abfd;
2192159047fSniklas {
2202159047fSniklas   return core_signal (abfd);
2212159047fSniklas }
2222159047fSniklas 
223c074d1c9Sdrahn static bfd_boolean
hppabsd_core_core_file_matches_executable_p(core_bfd,exec_bfd)2242159047fSniklas hppabsd_core_core_file_matches_executable_p (core_bfd, exec_bfd)
2252159047fSniklas      bfd *core_bfd, *exec_bfd;
2262159047fSniklas {
2272159047fSniklas   /* There's no way to know this...  */
228c074d1c9Sdrahn   return TRUE;
2292159047fSniklas }
2302159047fSniklas 
2312159047fSniklas /* If somebody calls any byte-swapping routines, shoot them.  */
2322159047fSniklas static void
swap_abort()2332159047fSniklas swap_abort ()
2342159047fSniklas {
2352159047fSniklas   /* This way doesn't require any declaration for ANSI to fuck up.  */
2362159047fSniklas   abort ();
2372159047fSniklas }
2382159047fSniklas 
239*007c2a45Smiod #define	NO_GET ((bfd_vma (*) (const void *)) swap_abort)
240*007c2a45Smiod #define	NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
241*007c2a45Smiod #define	NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
242*007c2a45Smiod #define	NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
243*007c2a45Smiod #define	NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
244*007c2a45Smiod #define	NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
2452159047fSniklas 
2462159047fSniklas const bfd_target hppabsd_core_vec =
2472159047fSniklas   {
2482159047fSniklas     "hppabsd-core",
2492159047fSniklas     bfd_target_unknown_flavour,
250c88b1d6cSniklas     BFD_ENDIAN_BIG,		/* target byte order */
251c88b1d6cSniklas     BFD_ENDIAN_BIG,		/* target headers byte order */
2522159047fSniklas     (HAS_RELOC | EXEC_P |	/* object flags */
2532159047fSniklas      HAS_LINENO | HAS_DEBUG |
2542159047fSniklas      HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2552159047fSniklas     (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2562159047fSniklas     0,			                                   /* symbol prefix */
2572159047fSniklas     ' ',						   /* ar_pad_char */
2582159047fSniklas     16,							   /* ar_max_namelen */
259*007c2a45Smiod     NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit data */
260*007c2a45Smiod     NO_GET, NO_GETS, NO_PUT,		/* 32 bit data */
261*007c2a45Smiod     NO_GET, NO_GETS, NO_PUT,		/* 16 bit data */
262*007c2a45Smiod     NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit hdrs */
263*007c2a45Smiod     NO_GET, NO_GETS, NO_PUT,		/* 32 bit hdrs */
264*007c2a45Smiod     NO_GET, NO_GETS, NO_PUT,		/* 16 bit hdrs */
2652159047fSniklas 
2662159047fSniklas     {				/* bfd_check_format */
2672159047fSniklas       _bfd_dummy_target,		/* unknown format */
2682159047fSniklas       _bfd_dummy_target,		/* object file */
2692159047fSniklas       _bfd_dummy_target,		/* archive */
2702159047fSniklas       hppabsd_core_core_file_p		/* a core file */
2712159047fSniklas     },
2722159047fSniklas     {				/* bfd_set_format */
2732159047fSniklas       bfd_false, bfd_false,
2742159047fSniklas       bfd_false, bfd_false
2752159047fSniklas     },
2762159047fSniklas     {				/* bfd_write_contents */
2772159047fSniklas       bfd_false, bfd_false,
2782159047fSniklas       bfd_false, bfd_false
2792159047fSniklas     },
2802159047fSniklas 
2812159047fSniklas     BFD_JUMP_TABLE_GENERIC (_bfd_generic),
2822159047fSniklas     BFD_JUMP_TABLE_COPY (_bfd_generic),
2832159047fSniklas     BFD_JUMP_TABLE_CORE (hppabsd_core),
2842159047fSniklas     BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
285c074d1c9Sdrahn     BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
2862159047fSniklas     BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
2872159047fSniklas     BFD_JUMP_TABLE_WRITE (_bfd_generic),
2882159047fSniklas     BFD_JUMP_TABLE_LINK (_bfd_nolink),
2892159047fSniklas     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2902159047fSniklas 
291b305b0f1Sespie     NULL,
292b305b0f1Sespie 
2932159047fSniklas     (PTR) 0			/* backend_data */
2942159047fSniklas   };
2952159047fSniklas #endif
296