ptrace-core.c revision 78828
129415Sjmg/* BFD backend for core files which use the ptrace_user structure
250723Scg   Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2001
339899Sluigi   Free Software Foundation, Inc.
429415Sjmg   The structure of this file is based on trad-core.c written by John Gilmore
529415Sjmg   of Cygnus Support.
629415Sjmg   Modified to work with the ptrace_user structure by Kevin A. Buettner.
729415Sjmg   (Longterm it may be better to merge this file with trad-core.c)
850723Scg
950723ScgThis file is part of BFD, the Binary File Descriptor library.
1029415Sjmg
1129415SjmgThis program is free software; you can redistribute it and/or modify
1230869Sjmgit under the terms of the GNU General Public License as published by
1330869Sjmgthe Free Software Foundation; either version 2 of the License, or
1430869Sjmg(at your option) any later version.
1530869Sjmg
1650723ScgThis program is distributed in the hope that it will be useful,
1750723Scgbut WITHOUT ANY WARRANTY; without even the implied warranty of
1830869SjmgMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1950723ScgGNU General Public License for more details.
2050723Scg
2150723ScgYou should have received a copy of the GNU General Public License
2250723Scgalong with this program; if not, write to the Free Software
2350723ScgFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2450723Scg
2550723Scg#ifdef PTRACE_CORE
2650723Scg
2750723Scg#include "bfd.h"
2850723Scg#include "sysdep.h"
2950723Scg#include "libbfd.h"
3050723Scg
3150959Speter#include <sys/param.h>
3229415Sjmg#include <sys/dir.h>
3329415Sjmg#include <signal.h>
3453465Scg#include <sys/ptrace.h>
3529415Sjmg
3629415Sjmgstruct trad_core_struct
3729415Sjmg  {
3853465Scg    asection *data_section;
3929415Sjmg    asection *stack_section;
4050723Scg    asection *reg_section;
4150723Scg    struct ptrace_user u;
4250723Scg  };
4350723Scg
4450723Scg#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u))
4550723Scg#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section)
4650723Scg#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section)
4750723Scg#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section)
4850723Scg
4929415Sjmg/* forward declarations */
5050925Scg
5150925Scgconst bfd_target *ptrace_unix_core_file_p PARAMS ((bfd *abfd));
5250925Scgchar *		ptrace_unix_core_file_failing_command PARAMS ((bfd *abfd));
5350925Scgint		ptrace_unix_core_file_failing_signal PARAMS ((bfd *abfd));
5450925Scgboolean		ptrace_unix_core_file_matches_executable_p
5550925Scg			 PARAMS ((bfd *core_bfd, bfd *exec_bfd));
5650925Scgstatic void	swap_abort PARAMS ((void));
5750925Scg
5850925Scg/* ARGSUSED */
5950925Scgconst bfd_target *
6050925Scgptrace_unix_core_file_p (abfd)
6150723Scg     bfd *abfd;
6250723Scg
6350723Scg{
6450723Scg  int val;
6550723Scg  struct ptrace_user u;
6629415Sjmg  struct trad_core_struct *rawptr;
6750723Scg
6850723Scg  val = bfd_read ((void *)&u, 1, sizeof u, abfd);
6950723Scg  if (val != sizeof u || u.pt_magic != _BCS_PTRACE_MAGIC
7050723Scg      || u.pt_rev != _BCS_PTRACE_REV)
7150723Scg    {
7229415Sjmg      /* Too small to be a core file */
7350723Scg      bfd_set_error (bfd_error_wrong_format);
7450723Scg      return 0;
7550723Scg    }
7650723Scg
7750723Scg  /* OK, we believe you.  You're a core file (sure, sure).  */
7829415Sjmg
7950723Scg  /* Allocate both the upage and the struct core_data at once, so
8050723Scg     a single free() will free them both.  */
8150723Scg  rawptr = (struct trad_core_struct *)
8250723Scg		bfd_zalloc (abfd, sizeof (struct trad_core_struct));
8350723Scg
8429415Sjmg  if (rawptr == NULL)
8550723Scg    return 0;
8650723Scg
8750723Scg  abfd->tdata.trad_core_data = rawptr;
8850723Scg
8950723Scg  rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
9029415Sjmg
9150723Scg  /* Create the sections.  This is raunchy, but bfd_close wants to free
9250723Scg     them separately.  */
9350723Scg
9450723Scg  core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
9550723Scg  if (core_stacksec (abfd) == NULL)
9629415Sjmg    return NULL;
9750723Scg  core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
9850723Scg  if (core_datasec (abfd) == NULL)
9950723Scg    return NULL;
10050723Scg  core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
10150723Scg  if (core_regsec (abfd) == NULL)
10229415Sjmg    return NULL;
10350723Scg
10450723Scg  core_stacksec (abfd)->name = ".stack";
10550723Scg  core_datasec (abfd)->name = ".data";
10650723Scg  core_regsec (abfd)->name = ".reg";
10750723Scg
10829415Sjmg  /* FIXME:  Need to worry about shared memory, library data, and library
10950723Scg     text.  I don't think that any of these things are supported on the
11050723Scg     system on which I am developing this for though.  */
11150723Scg
11250723Scg  core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
11350723Scg  core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
11450723Scg  core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
11550723Scg
11650723Scg  core_datasec (abfd)->_raw_size =  u.pt_dsize;
11750723Scg  core_stacksec (abfd)->_raw_size = u.pt_ssize;
11850723Scg  core_regsec (abfd)->_raw_size = sizeof (u);
11929415Sjmg
12050925Scg  core_datasec (abfd)->vma = u.pt_o_data_start;
12150925Scg  core_stacksec (abfd)->vma = USRSTACK - u.pt_ssize;
12250925Scg  core_regsec (abfd)->vma = 0 - sizeof (u);	/* see trad-core.c */
12350925Scg
12450925Scg  core_datasec (abfd)->filepos = (int) u.pt_dataptr;
12550925Scg  core_stacksec (abfd)->filepos = (int) (u.pt_dataptr + u.pt_dsize);
12650925Scg  core_regsec (abfd)->filepos = 0; /* Register segment is ptrace_user */
12750925Scg
12850925Scg  /* Align to word at least */
12950925Scg  core_stacksec (abfd)->alignment_power = 2;
13050723Scg  core_datasec (abfd)->alignment_power = 2;
13129415Sjmg  core_regsec (abfd)->alignment_power = 2;
13250723Scg
13329415Sjmg  abfd->sections = core_stacksec (abfd);
13450723Scg  core_stacksec (abfd)->next = core_datasec (abfd);
13550723Scg  core_datasec (abfd)->next = core_regsec (abfd);
13650723Scg  abfd->section_count = 3;
13750723Scg
13850723Scg  return abfd->xvec;
13950723Scg}
14050925Scg
14150723Scgchar *
14229415Sjmgptrace_unix_core_file_failing_command (abfd)
14350723Scg     bfd *abfd;
14450723Scg{
14550723Scg  char *com = abfd->tdata.trad_core_data->u.pt_comm;
14650723Scg  if (*com)
14750723Scg    return com;
14850723Scg  else
14950723Scg    return 0;
15050723Scg}
15150723Scg
15250723Scg/* ARGSUSED */
15329415Sjmgint
15450723Scgptrace_unix_core_file_failing_signal (abfd)
15550723Scg     bfd *abfd;
15650723Scg{
15750723Scg  return abfd->tdata.trad_core_data->u.pt_sigframe.sig_num;
15850723Scg}
15950723Scg
16050723Scg/* ARGSUSED */
16150723Scgboolean
16250723Scgptrace_unix_core_file_matches_executable_p  (core_bfd, exec_bfd)
16350723Scg     bfd *core_bfd, *exec_bfd;
16450723Scg{
16550723Scg  /* FIXME: Use pt_timdat field of the ptrace_user structure to match
16650723Scg     the date of the executable */
16750723Scg  return true;
16850723Scg}
16950723Scg
17029415Sjmg/* If somebody calls any byte-swapping routines, shoot them.  */
17150723Scgstatic void
17250723Scgswap_abort ()
17329415Sjmg{
17450723Scg  abort (); /* This way doesn't require any declaration for ANSI to fuck up */
17550723Scg}
17629415Sjmg#define	NO_GET	((bfd_vma (*) PARAMS ((   const bfd_byte *))) swap_abort )
17750723Scg#define	NO_PUT	((void    (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
17850925Scg#define	NO_SIGNED_GET \
17950723Scg  ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
18050723Scg
18150723Scgconst bfd_target ptrace_core_vec =
18250723Scg  {
18350723Scg    "trad-core",
18450723Scg    bfd_target_unknown_flavour,
18550723Scg    BFD_ENDIAN_UNKNOWN,		/* target byte order */
18650723Scg    BFD_ENDIAN_UNKNOWN,		/* target headers byte order */
18750925Scg    (HAS_RELOC | EXEC_P |	/* object flags */
18850925Scg     HAS_LINENO | HAS_DEBUG |
18950925Scg     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
19050925Scg    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
19150925Scg    0,			                                   /* symbol prefix */
19250723Scg    ' ',						   /* ar_pad_char */
19350723Scg    16,							   /* ar_max_namelen */
19450723Scg    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 64 bit data */
19550723Scg    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 32 bit data */
19650723Scg    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 16 bit data */
19750723Scg    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 64 bit hdrs */
19850723Scg    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 32 bit hdrs */
19950723Scg    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 16 bit hdrs */
20050723Scg
20150723Scg    {				/* bfd_check_format */
20250723Scg     _bfd_dummy_target,		/* unknown format */
20350723Scg     _bfd_dummy_target,		/* object file */
20450723Scg     _bfd_dummy_target,		/* archive */
20529415Sjmg     ptrace_unix_core_file_p	/* a core file */
20650723Scg    },
20729415Sjmg    {				/* bfd_set_format */
20850723Scg     bfd_false, bfd_false,
20950723Scg     bfd_false, bfd_false
21050723Scg    },
21150723Scg    {				/* bfd_write_contents */
21250723Scg     bfd_false, bfd_false,
21350723Scg     bfd_false, bfd_false
21450723Scg    },
21529415Sjmg
21629415Sjmg       BFD_JUMP_TABLE_GENERIC (_bfd_generic),
21729415Sjmg       BFD_JUMP_TABLE_COPY (_bfd_generic),
21850723Scg       BFD_JUMP_TABLE_CORE (ptrace_unix),
21929415Sjmg       BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
22050723Scg       BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
22150723Scg       BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
22250723Scg       BFD_JUMP_TABLE_WRITE (_bfd_generic),
22350723Scg       BFD_JUMP_TABLE_LINK (_bfd_nolink),
22429415Sjmg       BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
22550723Scg
22650723Scg    NULL,
22750723Scg
22850723Scg    (PTR) 0			/* backend_data */
22950723Scg};
23050723Scg
23129415Sjmg#endif /* PTRACE_CORE */
23229415Sjmg