133965Sjdp/* BFD back-end for OSF/1 core files.
2218822Sdim   Copyright 1993, 1994, 1995, 1998, 1999, 2001, 2002, 2003, 2004, 2006,
3218822Sdim   2007 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
19218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2033965Sjdp
2133965Sjdp/* This file can only be compiled on systems which use OSF/1 style
2233965Sjdp   core files.  */
2333965Sjdp
24218822Sdim#include "sysdep.h"
2533965Sjdp#include "bfd.h"
2633965Sjdp#include "libbfd.h"
2733965Sjdp
2833965Sjdp#include <sys/user.h>
29218822Sdim#ifdef OSF_CORE
3033965Sjdp#include <sys/core.h>
31218822Sdim#endif
3233965Sjdp
3333965Sjdp/* forward declarations */
3433965Sjdp
3589857Sobrienstatic asection *make_bfd_asection
3689857Sobrien  PARAMS ((bfd *, const char *, flagword, bfd_size_type, bfd_vma, file_ptr));
37130561Sobrienstatic const bfd_target *osf_core_core_file_p
38130561Sobrien  PARAMS ((bfd *));
39130561Sobrienstatic char *osf_core_core_file_failing_command
40130561Sobrien  PARAMS ((bfd *));
41130561Sobrienstatic int osf_core_core_file_failing_signal
42130561Sobrien  PARAMS ((bfd *));
43218822Sdim#define osf_core_core_file_matches_executable_p generic_core_file_matches_executable_p
44130561Sobrienstatic void swap_abort
45130561Sobrien  PARAMS ((void));
4633965Sjdp
4733965Sjdp/* These are stored in the bfd's tdata */
4833965Sjdp
4989857Sobrienstruct osf_core_struct
5033965Sjdp{
5133965Sjdp  int sig;
5233965Sjdp  char cmd[MAXCOMLEN + 1];
5333965Sjdp};
5433965Sjdp
5533965Sjdp#define core_hdr(bfd) ((bfd)->tdata.osf_core_data)
5633965Sjdp#define core_signal(bfd) (core_hdr(bfd)->sig)
5733965Sjdp#define core_command(bfd) (core_hdr(bfd)->cmd)
5833965Sjdp
5933965Sjdpstatic asection *
60218822Sdimmake_bfd_asection (abfd, name, flags, size, vma, filepos)
6133965Sjdp     bfd *abfd;
6289857Sobrien     const char *name;
6333965Sjdp     flagword flags;
64218822Sdim     bfd_size_type size;
6533965Sjdp     bfd_vma vma;
6633965Sjdp     file_ptr filepos;
6733965Sjdp{
6833965Sjdp  asection *asect;
6933965Sjdp
70218822Sdim  asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
7133965Sjdp  if (!asect)
7233965Sjdp    return NULL;
7333965Sjdp
74218822Sdim  asect->size = 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
97218822Sdim  if (! CONST_STRNEQ (core_header.magic, "Core"))
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
17433965Sjdp/* If somebody calls any byte-swapping routines, shoot them.  */
17533965Sjdpstatic void
17633965Sjdpswap_abort()
17733965Sjdp{
17833965Sjdp  abort(); /* This way doesn't require any declaration for ANSI to fuck up */
17933965Sjdp}
18033965Sjdp
181130561Sobrien#define	NO_GET ((bfd_vma (*) (const void *)) swap_abort)
182130561Sobrien#define	NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
183130561Sobrien#define	NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
184130561Sobrien#define	NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
185130561Sobrien#define	NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
186130561Sobrien#define	NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
187130561Sobrien
18833965Sjdpconst bfd_target osf_core_vec =
18933965Sjdp  {
19033965Sjdp    "osf-core",
19133965Sjdp    bfd_target_unknown_flavour,
19291041Sobrien    BFD_ENDIAN_LITTLE,		/* target byte order */
19391041Sobrien    BFD_ENDIAN_LITTLE,		/* target headers byte order */
19433965Sjdp    (HAS_RELOC | EXEC_P |	/* object flags */
19533965Sjdp     HAS_LINENO | HAS_DEBUG |
19633965Sjdp     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
19733965Sjdp    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
19833965Sjdp    0,			                                   /* symbol prefix */
19933965Sjdp    ' ',						   /* ar_pad_char */
20033965Sjdp    16,							   /* ar_max_namelen */
201130561Sobrien    NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit data */
202130561Sobrien    NO_GET, NO_GETS, NO_PUT,		/* 32 bit data */
203130561Sobrien    NO_GET, NO_GETS, NO_PUT,		/* 16 bit data */
204130561Sobrien    NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit hdrs */
205130561Sobrien    NO_GET, NO_GETS, NO_PUT,		/* 32 bit hdrs */
206130561Sobrien    NO_GET, NO_GETS, NO_PUT,		/* 16 bit hdrs */
20733965Sjdp
20833965Sjdp    {				/* bfd_check_format */
209130561Sobrien      _bfd_dummy_target,		/* unknown format */
210130561Sobrien      _bfd_dummy_target,		/* object file */
211130561Sobrien      _bfd_dummy_target,		/* archive */
212130561Sobrien      osf_core_core_file_p		/* a core file */
21333965Sjdp    },
21433965Sjdp    {				/* bfd_set_format */
215130561Sobrien      bfd_false, bfd_false,
216130561Sobrien      bfd_false, bfd_false
21733965Sjdp    },
21833965Sjdp    {				/* bfd_write_contents */
219130561Sobrien      bfd_false, bfd_false,
220130561Sobrien      bfd_false, bfd_false
22133965Sjdp    },
22233965Sjdp
22389857Sobrien    BFD_JUMP_TABLE_GENERIC (_bfd_generic),
22489857Sobrien    BFD_JUMP_TABLE_COPY (_bfd_generic),
22589857Sobrien    BFD_JUMP_TABLE_CORE (osf_core),
22689857Sobrien    BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
22789857Sobrien    BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
22889857Sobrien    BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
22989857Sobrien    BFD_JUMP_TABLE_WRITE (_bfd_generic),
23089857Sobrien    BFD_JUMP_TABLE_LINK (_bfd_nolink),
23189857Sobrien    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
23289857Sobrien
23360484Sobrien    NULL,
23489857Sobrien
23533965Sjdp    (PTR) 0			/* backend_data */
236130561Sobrien  };
237