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