xref: /openbsd-src/gnu/usr.bin/binutils/bfd/hppabsd-core.c (revision c88b1d6c2990dec69cf89c9efe884ddff6a0bbe5)
12159047fSniklas /* BFD back-end for HPPA BSD core files.
22159047fSniklas    Copyright 1993, 1994 Free Software Foundation, Inc.
32159047fSniklas 
42159047fSniklas    This file is part of BFD, the Binary File Descriptor library.
52159047fSniklas 
62159047fSniklas    This program is free software; you can redistribute it and/or modify
72159047fSniklas    it under the terms of the GNU General Public License as published by
82159047fSniklas    the Free Software Foundation; either version 2 of the License, or
92159047fSniklas    (at your option) any later version.
102159047fSniklas 
112159047fSniklas    This program is distributed in the hope that it will be useful,
122159047fSniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
132159047fSniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
142159047fSniklas    GNU General Public License for more details.
152159047fSniklas 
162159047fSniklas    You should have received a copy of the GNU General Public License
172159047fSniklas    along with this program; if not, write to the Free Software
182159047fSniklas    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
192159047fSniklas 
202159047fSniklas    Written by the Center for Software Science at the University of Utah
212159047fSniklas    and by Cygnus Support.
222159047fSniklas 
232159047fSniklas    The core file structure for the Utah 4.3BSD and OSF1 ports on the
242159047fSniklas    PA is a mix between traditional cores and hpux cores -- just
252159047fSniklas    different enough that supporting this format would tend to add
262159047fSniklas    gross hacks to trad-core.c or hpux-core.c.  So instead we keep any
272159047fSniklas    gross hacks isolated to this file.  */
282159047fSniklas 
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 <stdio.h>
452159047fSniklas #include <sys/types.h>
462159047fSniklas #include <sys/param.h>
472159047fSniklas #include <sys/dir.h>
482159047fSniklas #include <signal.h>
492159047fSniklas #include <machine/reg.h>
502159047fSniklas #include <sys/user.h>		/* After a.out.h  */
512159047fSniklas #include <sys/file.h>
522159047fSniklas #include <errno.h>
532159047fSniklas 
542159047fSniklas static asection *make_bfd_asection PARAMS ((bfd *, CONST char *,
552159047fSniklas 					    flagword, bfd_size_type,
562159047fSniklas 					    file_ptr, unsigned int));
572159047fSniklas static asymbol *hppabsd_core_make_empty_symbol PARAMS ((bfd *));
582159047fSniklas static const bfd_target *hppabsd_core_core_file_p PARAMS ((bfd *));
592159047fSniklas static char *hppabsd_core_core_file_failing_command PARAMS ((bfd *));
602159047fSniklas static int hppabsd_core_core_file_failing_signal PARAMS ((bfd *));
612159047fSniklas static boolean hppabsd_core_core_file_matches_executable_p
622159047fSniklas   PARAMS ((bfd *, bfd *));
632159047fSniklas static void swap_abort 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 *
842159047fSniklas make_bfd_asection (abfd, name, flags, _raw_size, offset, alignment_power)
852159047fSniklas      bfd *abfd;
862159047fSniklas      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 asymbol *
1072159047fSniklas hppabsd_core_make_empty_symbol (abfd)
1082159047fSniklas      bfd *abfd;
1092159047fSniklas {
1102159047fSniklas   asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
1112159047fSniklas   if (new)
1122159047fSniklas     new->the_bfd = abfd;
1132159047fSniklas   return new;
1142159047fSniklas }
1152159047fSniklas 
1162159047fSniklas static const bfd_target *
1172159047fSniklas hppabsd_core_core_file_p (abfd)
1182159047fSniklas      bfd *abfd;
1192159047fSniklas {
1202159047fSniklas   int val;
1212159047fSniklas   struct user u;
1222159047fSniklas   struct hppabsd_core_struct *coredata;
1232159047fSniklas   int clicksz;
1242159047fSniklas 
1252159047fSniklas   /* Try to read in the u-area.  We will need information from this
1262159047fSniklas      to know how to grok the rest of the core structures.  */
1272159047fSniklas   val = bfd_read ((void *) &u, 1, sizeof u, abfd);
1282159047fSniklas   if (val != sizeof u)
1292159047fSniklas     {
1302159047fSniklas       if (bfd_get_error () != bfd_error_system_call)
1312159047fSniklas 	bfd_set_error (bfd_error_wrong_format);
1322159047fSniklas       return NULL;
1332159047fSniklas     }
1342159047fSniklas 
1352159047fSniklas   /* Get the page size out of the u structure.  This will be different
1362159047fSniklas      for PA 1.0 machines and PA 1.1 machines.   Yuk!  */
1372159047fSniklas   clicksz = u.u_pcb.pcb_pgsz;
1382159047fSniklas 
1392159047fSniklas   /* clicksz must be a power of two >= 2k.  */
1402159047fSniklas   if (clicksz < 0x800
1412159047fSniklas       || clicksz != (clicksz & -clicksz))
1422159047fSniklas     {
1432159047fSniklas       bfd_set_error (bfd_error_wrong_format);
1442159047fSniklas       return NULL;
1452159047fSniklas     }
1462159047fSniklas 
1472159047fSniklas 
1482159047fSniklas   /* Sanity checks.  Make sure the size of the core file matches the
1492159047fSniklas      the size computed from information within the core itself.  */
1502159047fSniklas   {
1512159047fSniklas     FILE *stream = bfd_cache_lookup (abfd);
1522159047fSniklas     struct stat statbuf;
1532159047fSniklas     if (stream == NULL || fstat (fileno (stream), &statbuf) < 0)
1542159047fSniklas       {
1552159047fSniklas 	bfd_set_error (bfd_error_system_call);
1562159047fSniklas 	return NULL;
1572159047fSniklas       }
1582159047fSniklas     if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size)
1592159047fSniklas       {
1602159047fSniklas 	bfd_set_error (bfd_error_file_truncated);
1612159047fSniklas 	return NULL;
1622159047fSniklas       }
1632159047fSniklas     if (clicksz * (UPAGES + u.u_dsize + u.u_ssize) < statbuf.st_size)
1642159047fSniklas       {
1652159047fSniklas 	/* The file is too big.  Maybe it's not a core file
1662159047fSniklas 	   or we otherwise have bad values for u_dsize and u_ssize).  */
1672159047fSniklas 	bfd_set_error (bfd_error_wrong_format);
1682159047fSniklas 	return NULL;
1692159047fSniklas       }
1702159047fSniklas   }
1712159047fSniklas 
1722159047fSniklas   /* OK, we believe you.  You're a core file (sure, sure).  */
1732159047fSniklas 
1742159047fSniklas   coredata = (struct hppabsd_core_struct *)
1752159047fSniklas     bfd_zalloc (abfd, sizeof (struct hppabsd_core_struct));
1762159047fSniklas   if (!coredata)
1772159047fSniklas     return NULL;
1782159047fSniklas 
1792159047fSniklas   /* Make the core data and available via the tdata part of the BFD.  */
1802159047fSniklas   abfd->tdata.hppabsd_core_data = coredata;
1812159047fSniklas 
1822159047fSniklas   /* Create the sections.  */
1832159047fSniklas   core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
1842159047fSniklas 					   SEC_ALLOC + SEC_HAS_CONTENTS,
1852159047fSniklas 					   clicksz * u.u_ssize,
1862159047fSniklas 					   NBPG * (USIZE + KSTAKSIZE)
1872159047fSniklas 					     + clicksz * u.u_dsize, 2);
1882159047fSniklas   core_stacksec (abfd)->vma = USRSTACK;
1892159047fSniklas 
1902159047fSniklas   core_datasec (abfd) = make_bfd_asection (abfd, ".data",
1912159047fSniklas 					  SEC_ALLOC + SEC_LOAD
1922159047fSniklas 					    + SEC_HAS_CONTENTS,
1932159047fSniklas 					  clicksz * u.u_dsize,
1942159047fSniklas 					  NBPG * (USIZE + KSTAKSIZE), 2);
1952159047fSniklas   core_datasec (abfd)->vma = UDATASEG;
1962159047fSniklas 
1972159047fSniklas   core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
1982159047fSniklas 					 SEC_HAS_CONTENTS,
1992159047fSniklas 					 KSTAKSIZE * NBPG,
2002159047fSniklas 					 NBPG * USIZE, 2);
2012159047fSniklas   core_regsec (abfd)->vma = 0;
2022159047fSniklas 
2032159047fSniklas   strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1);
2042159047fSniklas   core_signal (abfd) = u.u_code;
2052159047fSniklas   return abfd->xvec;
2062159047fSniklas }
2072159047fSniklas 
2082159047fSniklas static char *
2092159047fSniklas hppabsd_core_core_file_failing_command (abfd)
2102159047fSniklas      bfd *abfd;
2112159047fSniklas {
2122159047fSniklas   return core_command (abfd);
2132159047fSniklas }
2142159047fSniklas 
2152159047fSniklas /* ARGSUSED */
2162159047fSniklas static int
2172159047fSniklas hppabsd_core_core_file_failing_signal (abfd)
2182159047fSniklas      bfd *abfd;
2192159047fSniklas {
2202159047fSniklas   return core_signal (abfd);
2212159047fSniklas }
2222159047fSniklas 
2232159047fSniklas /* ARGSUSED */
2242159047fSniklas static boolean
2252159047fSniklas hppabsd_core_core_file_matches_executable_p (core_bfd, exec_bfd)
2262159047fSniklas      bfd *core_bfd, *exec_bfd;
2272159047fSniklas {
2282159047fSniklas   /* There's no way to know this...  */
2292159047fSniklas   return true;
2302159047fSniklas }
2312159047fSniklas 
2322159047fSniklas 
2332159047fSniklas #define hppabsd_core_get_symtab_upper_bound \
2342159047fSniklas   _bfd_nosymbols_get_symtab_upper_bound
2352159047fSniklas #define hppabsd_core_get_symtab _bfd_nosymbols_get_symtab
2362159047fSniklas #define hppabsd_core_print_symbol _bfd_nosymbols_print_symbol
2372159047fSniklas #define hppabsd_core_get_symbol_info _bfd_nosymbols_get_symbol_info
2382159047fSniklas #define hppabsd_core_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label
2392159047fSniklas #define hppabsd_core_get_lineno _bfd_nosymbols_get_lineno
2402159047fSniklas #define hppabsd_core_find_nearest_line _bfd_nosymbols_find_nearest_line
2412159047fSniklas #define hppabsd_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
2422159047fSniklas #define hppabsd_core_read_minisymbols _bfd_nosymbols_read_minisymbols
2432159047fSniklas #define hppabsd_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
2442159047fSniklas 
2452159047fSniklas /* If somebody calls any byte-swapping routines, shoot them.  */
2462159047fSniklas static void
2472159047fSniklas swap_abort ()
2482159047fSniklas {
2492159047fSniklas   /* This way doesn't require any declaration for ANSI to fuck up.  */
2502159047fSniklas   abort ();
2512159047fSniklas }
2522159047fSniklas 
2532159047fSniklas #define	NO_GET	((bfd_vma (*) PARAMS ((   const bfd_byte *))) swap_abort )
2542159047fSniklas #define	NO_PUT	((void    (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
2552159047fSniklas #define	NO_SIGNED_GET \
2562159047fSniklas   ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
2572159047fSniklas 
2582159047fSniklas const bfd_target hppabsd_core_vec =
2592159047fSniklas   {
2602159047fSniklas     "hppabsd-core",
2612159047fSniklas     bfd_target_unknown_flavour,
262*c88b1d6cSniklas     BFD_ENDIAN_BIG,		/* target byte order */
263*c88b1d6cSniklas     BFD_ENDIAN_BIG,		/* target headers byte order */
2642159047fSniklas     (HAS_RELOC | EXEC_P |	/* object flags */
2652159047fSniklas      HAS_LINENO | HAS_DEBUG |
2662159047fSniklas      HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2672159047fSniklas     (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2682159047fSniklas     0,			                                   /* symbol prefix */
2692159047fSniklas     ' ',						   /* ar_pad_char */
2702159047fSniklas     16,							   /* ar_max_namelen */
2712159047fSniklas     NO_GET, NO_SIGNED_GET, NO_PUT,	/* 64 bit data */
2722159047fSniklas     NO_GET, NO_SIGNED_GET, NO_PUT,	/* 32 bit data */
2732159047fSniklas     NO_GET, NO_SIGNED_GET, NO_PUT,	/* 16 bit data */
2742159047fSniklas     NO_GET, NO_SIGNED_GET, NO_PUT,	/* 64 bit hdrs */
2752159047fSniklas     NO_GET, NO_SIGNED_GET, NO_PUT,	/* 32 bit hdrs */
2762159047fSniklas     NO_GET, NO_SIGNED_GET, NO_PUT,	/* 16 bit hdrs */
2772159047fSniklas 
2782159047fSniklas     {				/* bfd_check_format */
2792159047fSniklas      _bfd_dummy_target,		/* unknown format */
2802159047fSniklas      _bfd_dummy_target,		/* object file */
2812159047fSniklas      _bfd_dummy_target,		/* archive */
2822159047fSniklas      hppabsd_core_core_file_p	/* a core file */
2832159047fSniklas     },
2842159047fSniklas     {				/* bfd_set_format */
2852159047fSniklas      bfd_false, bfd_false,
2862159047fSniklas      bfd_false, bfd_false
2872159047fSniklas     },
2882159047fSniklas     {				/* bfd_write_contents */
2892159047fSniklas      bfd_false, bfd_false,
2902159047fSniklas      bfd_false, bfd_false
2912159047fSniklas     },
2922159047fSniklas 
2932159047fSniklas        BFD_JUMP_TABLE_GENERIC (_bfd_generic),
2942159047fSniklas        BFD_JUMP_TABLE_COPY (_bfd_generic),
2952159047fSniklas        BFD_JUMP_TABLE_CORE (hppabsd_core),
2962159047fSniklas        BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
2972159047fSniklas        BFD_JUMP_TABLE_SYMBOLS (hppabsd_core),
2982159047fSniklas        BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
2992159047fSniklas        BFD_JUMP_TABLE_WRITE (_bfd_generic),
3002159047fSniklas        BFD_JUMP_TABLE_LINK (_bfd_nolink),
3012159047fSniklas        BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
3022159047fSniklas 
3032159047fSniklas     (PTR) 0			/* backend_data */
3042159047fSniklas };
3052159047fSniklas #endif
306