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