ptrace-core.c revision 77298
133965Sjdp/* BFD backend for core files which use the ptrace_user structure
260484Sobrien   Copyright 1993, 94, 95, 96, 1998 Free Software Foundation, Inc.
333965Sjdp   The structure of this file is based on trad-core.c written by John Gilmore
433965Sjdp   of Cygnus Support.
533965Sjdp   Modified to work with the ptrace_user structure by Kevin A. Buettner.
633965Sjdp   (Longterm it may be better to merge this file with trad-core.c)
733965Sjdp
833965SjdpThis file is part of BFD, the Binary File Descriptor library.
933965Sjdp
1033965SjdpThis program is free software; you can redistribute it and/or modify
1133965Sjdpit under the terms of the GNU General Public License as published by
1233965Sjdpthe Free Software Foundation; either version 2 of the License, or
1333965Sjdp(at your option) any later version.
1433965Sjdp
1533965SjdpThis program is distributed in the hope that it will be useful,
1633965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
1733965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1833965SjdpGNU General Public License for more details.
1933965Sjdp
2033965SjdpYou should have received a copy of the GNU General Public License
2133965Sjdpalong with this program; if not, write to the Free Software
2233965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2333965Sjdp
2433965Sjdp#ifdef PTRACE_CORE
2533965Sjdp
2633965Sjdp#include "bfd.h"
2733965Sjdp#include "sysdep.h"
2833965Sjdp#include "libbfd.h"
2933965Sjdp
3033965Sjdp#include <sys/param.h>
3133965Sjdp#include <sys/dir.h>
3233965Sjdp#include <signal.h>
3333965Sjdp#include <sys/ptrace.h>
3433965Sjdp
3533965Sjdpstruct trad_core_struct
3633965Sjdp  {
3733965Sjdp    asection *data_section;
3833965Sjdp    asection *stack_section;
3933965Sjdp    asection *reg_section;
4033965Sjdp    struct ptrace_user u;
4133965Sjdp  };
4233965Sjdp
4333965Sjdp#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u))
4433965Sjdp#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section)
4533965Sjdp#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section)
4633965Sjdp#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section)
4733965Sjdp
4833965Sjdp/* forward declarations */
4933965Sjdp
5033965Sjdpconst bfd_target *ptrace_unix_core_file_p PARAMS ((bfd *abfd));
5133965Sjdpchar *		ptrace_unix_core_file_failing_command PARAMS ((bfd *abfd));
5233965Sjdpint		ptrace_unix_core_file_failing_signal PARAMS ((bfd *abfd));
5333965Sjdpboolean		ptrace_unix_core_file_matches_executable_p
5433965Sjdp			 PARAMS ((bfd *core_bfd, bfd *exec_bfd));
5533965Sjdpstatic void	swap_abort PARAMS ((void));
5633965Sjdp
5733965Sjdp/* ARGSUSED */
5833965Sjdpconst bfd_target *
5933965Sjdpptrace_unix_core_file_p (abfd)
6033965Sjdp     bfd *abfd;
6133965Sjdp
6233965Sjdp{
6333965Sjdp  int val;
6433965Sjdp  struct ptrace_user u;
6533965Sjdp  struct trad_core_struct *rawptr;
6633965Sjdp
6733965Sjdp  val = bfd_read ((void *)&u, 1, sizeof u, abfd);
6877298Sobrien  if (val != sizeof u || u.pt_magic != _BCS_PTRACE_MAGIC
6933965Sjdp      || u.pt_rev != _BCS_PTRACE_REV)
7033965Sjdp    {
7133965Sjdp      /* Too small to be a core file */
7233965Sjdp      bfd_set_error (bfd_error_wrong_format);
7333965Sjdp      return 0;
7433965Sjdp    }
7533965Sjdp
7633965Sjdp  /* OK, we believe you.  You're a core file (sure, sure).  */
7733965Sjdp
7833965Sjdp  /* Allocate both the upage and the struct core_data at once, so
7933965Sjdp     a single free() will free them both.  */
8033965Sjdp  rawptr = (struct trad_core_struct *)
8133965Sjdp		bfd_zalloc (abfd, sizeof (struct trad_core_struct));
8233965Sjdp
8333965Sjdp  if (rawptr == NULL)
8433965Sjdp    return 0;
8577298Sobrien
8633965Sjdp  abfd->tdata.trad_core_data = rawptr;
8733965Sjdp
8833965Sjdp  rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
8933965Sjdp
9033965Sjdp  /* Create the sections.  This is raunchy, but bfd_close wants to free
9133965Sjdp     them separately.  */
9233965Sjdp
9333965Sjdp  core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
9433965Sjdp  if (core_stacksec (abfd) == NULL)
9533965Sjdp    return NULL;
9633965Sjdp  core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
9733965Sjdp  if (core_datasec (abfd) == NULL)
9833965Sjdp    return NULL;
9933965Sjdp  core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
10033965Sjdp  if (core_regsec (abfd) == NULL)
10133965Sjdp    return NULL;
10233965Sjdp
10333965Sjdp  core_stacksec (abfd)->name = ".stack";
10433965Sjdp  core_datasec (abfd)->name = ".data";
10533965Sjdp  core_regsec (abfd)->name = ".reg";
10633965Sjdp
10733965Sjdp  /* FIXME:  Need to worry about shared memory, library data, and library
10833965Sjdp     text.  I don't think that any of these things are supported on the
10977298Sobrien     system on which I am developing this for though.  */
11033965Sjdp
11133965Sjdp  core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
11233965Sjdp  core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
11333965Sjdp  core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
11433965Sjdp
11533965Sjdp  core_datasec (abfd)->_raw_size =  u.pt_dsize;
11633965Sjdp  core_stacksec (abfd)->_raw_size = u.pt_ssize;
11777298Sobrien  core_regsec (abfd)->_raw_size = sizeof (u);
11833965Sjdp
11933965Sjdp  core_datasec (abfd)->vma = u.pt_o_data_start;
12033965Sjdp  core_stacksec (abfd)->vma = USRSTACK - u.pt_ssize;
12177298Sobrien  core_regsec (abfd)->vma = 0 - sizeof (u);	/* see trad-core.c */
12233965Sjdp
12333965Sjdp  core_datasec (abfd)->filepos = (int) u.pt_dataptr;
12433965Sjdp  core_stacksec (abfd)->filepos = (int) (u.pt_dataptr + u.pt_dsize);
12533965Sjdp  core_regsec (abfd)->filepos = 0; /* Register segment is ptrace_user */
12633965Sjdp
12733965Sjdp  /* Align to word at least */
12833965Sjdp  core_stacksec (abfd)->alignment_power = 2;
12933965Sjdp  core_datasec (abfd)->alignment_power = 2;
13033965Sjdp  core_regsec (abfd)->alignment_power = 2;
13133965Sjdp
13233965Sjdp  abfd->sections = core_stacksec (abfd);
13333965Sjdp  core_stacksec (abfd)->next = core_datasec (abfd);
13433965Sjdp  core_datasec (abfd)->next = core_regsec (abfd);
13533965Sjdp  abfd->section_count = 3;
13633965Sjdp
13733965Sjdp  return abfd->xvec;
13833965Sjdp}
13933965Sjdp
14033965Sjdpchar *
14133965Sjdpptrace_unix_core_file_failing_command (abfd)
14233965Sjdp     bfd *abfd;
14333965Sjdp{
14433965Sjdp  char *com = abfd->tdata.trad_core_data->u.pt_comm;
14533965Sjdp  if (*com)
14633965Sjdp    return com;
14733965Sjdp  else
14833965Sjdp    return 0;
14933965Sjdp}
15033965Sjdp
15133965Sjdp/* ARGSUSED */
15233965Sjdpint
15333965Sjdpptrace_unix_core_file_failing_signal (abfd)
15433965Sjdp     bfd *abfd;
15533965Sjdp{
15633965Sjdp  return abfd->tdata.trad_core_data->u.pt_sigframe.sig_num;
15733965Sjdp}
15833965Sjdp
15933965Sjdp/* ARGSUSED */
16033965Sjdpboolean
16133965Sjdpptrace_unix_core_file_matches_executable_p  (core_bfd, exec_bfd)
16233965Sjdp     bfd *core_bfd, *exec_bfd;
16333965Sjdp{
16477298Sobrien  /* FIXME: Use pt_timdat field of the ptrace_user structure to match
16533965Sjdp     the date of the executable */
16633965Sjdp  return true;
16733965Sjdp}
16833965Sjdp
16933965Sjdp/* If somebody calls any byte-swapping routines, shoot them.  */
17033965Sjdpstatic void
17177298Sobrienswap_abort ()
17233965Sjdp{
17377298Sobrien  abort (); /* This way doesn't require any declaration for ANSI to fuck up */
17433965Sjdp}
17533965Sjdp#define	NO_GET	((bfd_vma (*) PARAMS ((   const bfd_byte *))) swap_abort )
17633965Sjdp#define	NO_PUT	((void    (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
17733965Sjdp#define	NO_SIGNED_GET \
17833965Sjdp  ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
17933965Sjdp
18033965Sjdpconst bfd_target ptrace_core_vec =
18133965Sjdp  {
18233965Sjdp    "trad-core",
18333965Sjdp    bfd_target_unknown_flavour,
18433965Sjdp    BFD_ENDIAN_UNKNOWN,		/* target byte order */
18533965Sjdp    BFD_ENDIAN_UNKNOWN,		/* target headers byte order */
18633965Sjdp    (HAS_RELOC | EXEC_P |	/* object flags */
18733965Sjdp     HAS_LINENO | HAS_DEBUG |
18833965Sjdp     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
18933965Sjdp    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
19033965Sjdp    0,			                                   /* symbol prefix */
19133965Sjdp    ' ',						   /* ar_pad_char */
19233965Sjdp    16,							   /* ar_max_namelen */
19333965Sjdp    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 64 bit data */
19433965Sjdp    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 32 bit data */
19533965Sjdp    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 16 bit data */
19633965Sjdp    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 64 bit hdrs */
19733965Sjdp    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 32 bit hdrs */
19833965Sjdp    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 16 bit hdrs */
19933965Sjdp
20033965Sjdp    {				/* bfd_check_format */
20133965Sjdp     _bfd_dummy_target,		/* unknown format */
20233965Sjdp     _bfd_dummy_target,		/* object file */
20333965Sjdp     _bfd_dummy_target,		/* archive */
20433965Sjdp     ptrace_unix_core_file_p	/* a core file */
20533965Sjdp    },
20633965Sjdp    {				/* bfd_set_format */
20733965Sjdp     bfd_false, bfd_false,
20833965Sjdp     bfd_false, bfd_false
20933965Sjdp    },
21033965Sjdp    {				/* bfd_write_contents */
21133965Sjdp     bfd_false, bfd_false,
21233965Sjdp     bfd_false, bfd_false
21333965Sjdp    },
21477298Sobrien
21533965Sjdp       BFD_JUMP_TABLE_GENERIC (_bfd_generic),
21633965Sjdp       BFD_JUMP_TABLE_COPY (_bfd_generic),
21733965Sjdp       BFD_JUMP_TABLE_CORE (ptrace_unix),
21833965Sjdp       BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
21933965Sjdp       BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
22033965Sjdp       BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
22133965Sjdp       BFD_JUMP_TABLE_WRITE (_bfd_generic),
22233965Sjdp       BFD_JUMP_TABLE_LINK (_bfd_nolink),
22333965Sjdp       BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
22433965Sjdp
22560484Sobrien    NULL,
22677298Sobrien
22733965Sjdp    (PTR) 0			/* backend_data */
22833965Sjdp};
22933965Sjdp
23033965Sjdp#endif /* PTRACE_CORE */
231