osf-core.c revision 130561
133965Sjdp/* BFD back-end for OSF/1 core files.
2130561Sobrien   Copyright 1993, 1994, 1995, 1998, 1999, 2001, 2002, 2003, 2004
389857Sobrien   Free Software Foundation, Inc.
433965Sjdp
533965SjdpThis file is part of BFD, the Binary File Descriptor library.
633965Sjdp
733965SjdpThis program is free software; you can redistribute it and/or modify
833965Sjdpit under the terms of the GNU General Public License as published by
933965Sjdpthe Free Software Foundation; either version 2 of the License, or
1033965Sjdp(at your option) any later version.
1133965Sjdp
1233965SjdpThis program is distributed in the hope that it will be useful,
1333965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
1433965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1533965SjdpGNU General Public License for more details.
1633965Sjdp
1733965SjdpYou should have received a copy of the GNU General Public License
1833965Sjdpalong with this program; if not, write to the Free Software
1933965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2033965Sjdp
2133965Sjdp/* This file can only be compiled on systems which use OSF/1 style
2233965Sjdp   core files.  */
2333965Sjdp
2433965Sjdp#include "bfd.h"
2533965Sjdp#include "sysdep.h"
2633965Sjdp#include "libbfd.h"
2733965Sjdp
2833965Sjdp#include <sys/user.h>
2933965Sjdp#include <sys/core.h>
3033965Sjdp
3133965Sjdp/* forward declarations */
3233965Sjdp
3389857Sobrienstatic asection *make_bfd_asection
3489857Sobrien  PARAMS ((bfd *, const char *, flagword, bfd_size_type, bfd_vma, file_ptr));
35130561Sobrienstatic const bfd_target *osf_core_core_file_p
36130561Sobrien  PARAMS ((bfd *));
37130561Sobrienstatic char *osf_core_core_file_failing_command
38130561Sobrien  PARAMS ((bfd *));
39130561Sobrienstatic int osf_core_core_file_failing_signal
40130561Sobrien  PARAMS ((bfd *));
41130561Sobrienstatic bfd_boolean osf_core_core_file_matches_executable_p
42130561Sobrien  PARAMS ((bfd *, bfd *));
43130561Sobrienstatic void swap_abort
44130561Sobrien  PARAMS ((void));
4533965Sjdp
4633965Sjdp/* These are stored in the bfd's tdata */
4733965Sjdp
4889857Sobrienstruct osf_core_struct
4933965Sjdp{
5033965Sjdp  int sig;
5133965Sjdp  char cmd[MAXCOMLEN + 1];
5233965Sjdp};
5333965Sjdp
5433965Sjdp#define core_hdr(bfd) ((bfd)->tdata.osf_core_data)
5533965Sjdp#define core_signal(bfd) (core_hdr(bfd)->sig)
5633965Sjdp#define core_command(bfd) (core_hdr(bfd)->cmd)
5733965Sjdp
5833965Sjdpstatic asection *
5933965Sjdpmake_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
6033965Sjdp     bfd *abfd;
6189857Sobrien     const char *name;
6233965Sjdp     flagword flags;
6333965Sjdp     bfd_size_type _raw_size;
6433965Sjdp     bfd_vma vma;
6533965Sjdp     file_ptr filepos;
6633965Sjdp{
6733965Sjdp  asection *asect;
6833965Sjdp
6933965Sjdp  asect = bfd_make_section_anyway (abfd, name);
7033965Sjdp  if (!asect)
7133965Sjdp    return NULL;
7233965Sjdp
7333965Sjdp  asect->flags = flags;
7433965Sjdp  asect->_raw_size = _raw_size;
7533965Sjdp  asect->vma = vma;
7633965Sjdp  asect->filepos = filepos;
7733965Sjdp  asect->alignment_power = 8;
7833965Sjdp
7933965Sjdp  return asect;
8033965Sjdp}
8133965Sjdp
8233965Sjdpstatic const bfd_target *
8333965Sjdposf_core_core_file_p (abfd)
8433965Sjdp     bfd *abfd;
8533965Sjdp{
8633965Sjdp  int val;
8733965Sjdp  int i;
8833965Sjdp  char *secname;
8933965Sjdp  struct core_filehdr core_header;
9089857Sobrien  bfd_size_type amt;
9133965Sjdp
9289857Sobrien  amt = sizeof core_header;
9389857Sobrien  val = bfd_bread ((PTR) &core_header, amt, abfd);
9433965Sjdp  if (val != sizeof core_header)
9533965Sjdp    return NULL;
9633965Sjdp
9733965Sjdp  if (strncmp (core_header.magic, "Core", 4) != 0)
9833965Sjdp    return NULL;
9933965Sjdp
10033965Sjdp  core_hdr (abfd) = (struct osf_core_struct *)
10189857Sobrien    bfd_zalloc (abfd, (bfd_size_type) sizeof (struct osf_core_struct));
10233965Sjdp  if (!core_hdr (abfd))
10333965Sjdp    return NULL;
10433965Sjdp
10533965Sjdp  strncpy (core_command (abfd), core_header.name, MAXCOMLEN + 1);
10633965Sjdp  core_signal (abfd) = core_header.signo;
10733965Sjdp
10833965Sjdp  for (i = 0; i < core_header.nscns; i++)
10933965Sjdp    {
11033965Sjdp      struct core_scnhdr core_scnhdr;
11133965Sjdp      flagword flags;
11233965Sjdp
11389857Sobrien      amt = sizeof core_scnhdr;
11489857Sobrien      val = bfd_bread ((PTR) &core_scnhdr, amt, abfd);
11533965Sjdp      if (val != sizeof core_scnhdr)
11633965Sjdp	break;
11733965Sjdp
11833965Sjdp      /* Skip empty sections.  */
11933965Sjdp      if (core_scnhdr.size == 0 || core_scnhdr.scnptr == 0)
12033965Sjdp	continue;
12133965Sjdp
12233965Sjdp      switch (core_scnhdr.scntype)
12333965Sjdp	{
12433965Sjdp	case SCNRGN:
12533965Sjdp	  secname = ".data";
12633965Sjdp	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
12733965Sjdp	  break;
12833965Sjdp	case SCNSTACK:
12933965Sjdp	  secname = ".stack";
13033965Sjdp	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
13133965Sjdp	  break;
13233965Sjdp	case SCNREGS:
13333965Sjdp	  secname = ".reg";
13433965Sjdp	  flags = SEC_HAS_CONTENTS;
13533965Sjdp	  break;
13633965Sjdp	default:
13760484Sobrien	  (*_bfd_error_handler) (_("Unhandled OSF/1 core file section type %d\n"),
13833965Sjdp				 core_scnhdr.scntype);
13933965Sjdp	  continue;
14033965Sjdp	}
14133965Sjdp
14233965Sjdp      if (!make_bfd_asection (abfd, secname, flags,
14333965Sjdp			      (bfd_size_type) core_scnhdr.size,
14433965Sjdp			      (bfd_vma) core_scnhdr.vaddr,
14533965Sjdp			      (file_ptr) core_scnhdr.scnptr))
14689857Sobrien	goto fail;
14733965Sjdp    }
14833965Sjdp
14933965Sjdp  /* OK, we believe you.  You're a core file (sure, sure).  */
15033965Sjdp
15133965Sjdp  return abfd->xvec;
15289857Sobrien
15389857Sobrien fail:
15489857Sobrien  bfd_release (abfd, core_hdr (abfd));
15589857Sobrien  core_hdr (abfd) = NULL;
15689857Sobrien  bfd_section_list_clear (abfd);
15789857Sobrien  return NULL;
15833965Sjdp}
15933965Sjdp
16033965Sjdpstatic char *
16133965Sjdposf_core_core_file_failing_command (abfd)
16233965Sjdp     bfd *abfd;
16333965Sjdp{
16433965Sjdp  return core_command (abfd);
16533965Sjdp}
16633965Sjdp
16733965Sjdpstatic int
16833965Sjdposf_core_core_file_failing_signal (abfd)
16933965Sjdp     bfd *abfd;
17033965Sjdp{
17133965Sjdp  return core_signal (abfd);
17233965Sjdp}
17333965Sjdp
174130561Sobrienstatic bfd_boolean
17533965Sjdposf_core_core_file_matches_executable_p (core_bfd, exec_bfd)
17689857Sobrien     bfd *core_bfd ATTRIBUTE_UNUSED;
17789857Sobrien     bfd *exec_bfd ATTRIBUTE_UNUSED;
17833965Sjdp{
179130561Sobrien  return TRUE;		/* FIXME, We have no way of telling at this point */
18033965Sjdp}
18133965Sjdp
18233965Sjdp/* If somebody calls any byte-swapping routines, shoot them.  */
18333965Sjdpstatic void
18433965Sjdpswap_abort()
18533965Sjdp{
18633965Sjdp  abort(); /* This way doesn't require any declaration for ANSI to fuck up */
18733965Sjdp}
18833965Sjdp
189130561Sobrien#define	NO_GET ((bfd_vma (*) (const void *)) swap_abort)
190130561Sobrien#define	NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
191130561Sobrien#define	NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
192130561Sobrien#define	NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
193130561Sobrien#define	NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
194130561Sobrien#define	NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
195130561Sobrien
19633965Sjdpconst bfd_target osf_core_vec =
19733965Sjdp  {
19833965Sjdp    "osf-core",
19933965Sjdp    bfd_target_unknown_flavour,
20091041Sobrien    BFD_ENDIAN_LITTLE,		/* target byte order */
20191041Sobrien    BFD_ENDIAN_LITTLE,		/* target headers byte order */
20233965Sjdp    (HAS_RELOC | EXEC_P |	/* object flags */
20333965Sjdp     HAS_LINENO | HAS_DEBUG |
20433965Sjdp     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
20533965Sjdp    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
20633965Sjdp    0,			                                   /* symbol prefix */
20733965Sjdp    ' ',						   /* ar_pad_char */
20833965Sjdp    16,							   /* ar_max_namelen */
209130561Sobrien    NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit data */
210130561Sobrien    NO_GET, NO_GETS, NO_PUT,		/* 32 bit data */
211130561Sobrien    NO_GET, NO_GETS, NO_PUT,		/* 16 bit data */
212130561Sobrien    NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit hdrs */
213130561Sobrien    NO_GET, NO_GETS, NO_PUT,		/* 32 bit hdrs */
214130561Sobrien    NO_GET, NO_GETS, NO_PUT,		/* 16 bit hdrs */
21533965Sjdp
21633965Sjdp    {				/* bfd_check_format */
217130561Sobrien      _bfd_dummy_target,		/* unknown format */
218130561Sobrien      _bfd_dummy_target,		/* object file */
219130561Sobrien      _bfd_dummy_target,		/* archive */
220130561Sobrien      osf_core_core_file_p		/* a core file */
22133965Sjdp    },
22233965Sjdp    {				/* bfd_set_format */
223130561Sobrien      bfd_false, bfd_false,
224130561Sobrien      bfd_false, bfd_false
22533965Sjdp    },
22633965Sjdp    {				/* bfd_write_contents */
227130561Sobrien      bfd_false, bfd_false,
228130561Sobrien      bfd_false, bfd_false
22933965Sjdp    },
23033965Sjdp
23189857Sobrien    BFD_JUMP_TABLE_GENERIC (_bfd_generic),
23289857Sobrien    BFD_JUMP_TABLE_COPY (_bfd_generic),
23389857Sobrien    BFD_JUMP_TABLE_CORE (osf_core),
23489857Sobrien    BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
23589857Sobrien    BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
23689857Sobrien    BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
23789857Sobrien    BFD_JUMP_TABLE_WRITE (_bfd_generic),
23889857Sobrien    BFD_JUMP_TABLE_LINK (_bfd_nolink),
23989857Sobrien    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
24089857Sobrien
24160484Sobrien    NULL,
24289857Sobrien
24333965Sjdp    (PTR) 0			/* backend_data */
244130561Sobrien  };
245