133965Sjdp/* BFD backend for core files which use the ptrace_user structure 2218822Sdim Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2002, 2003, 2004, 3218822Sdim 2006, 2007 Free Software Foundation, Inc. 433965Sjdp The structure of this file is based on trad-core.c written by John Gilmore 533965Sjdp of Cygnus Support. 633965Sjdp Modified to work with the ptrace_user structure by Kevin A. Buettner. 733965Sjdp (Longterm it may be better to merge this file with trad-core.c) 833965Sjdp 933965SjdpThis file is part of BFD, the Binary File Descriptor library. 1033965Sjdp 1133965SjdpThis program is free software; you can redistribute it and/or modify 1233965Sjdpit under the terms of the GNU General Public License as published by 1333965Sjdpthe Free Software Foundation; either version 2 of the License, or 1433965Sjdp(at your option) any later version. 1533965Sjdp 1633965SjdpThis program is distributed in the hope that it will be useful, 1733965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1833965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1933965SjdpGNU General Public License for more details. 2033965Sjdp 2133965SjdpYou should have received a copy of the GNU General Public License 2233965Sjdpalong with this program; if not, write to the Free Software 23218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2433965Sjdp 2533965Sjdp#ifdef PTRACE_CORE 2633965Sjdp 27218822Sdim#include "sysdep.h" 2833965Sjdp#include "bfd.h" 2933965Sjdp#include "libbfd.h" 3033965Sjdp 3133965Sjdp#include <sys/param.h> 3233965Sjdp#include <sys/dir.h> 3333965Sjdp#include <signal.h> 3433965Sjdp#include <sys/ptrace.h> 3533965Sjdp 3633965Sjdpstruct trad_core_struct 3733965Sjdp { 3833965Sjdp asection *data_section; 3933965Sjdp asection *stack_section; 4033965Sjdp asection *reg_section; 4133965Sjdp struct ptrace_user u; 4233965Sjdp }; 4333965Sjdp 4433965Sjdp#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u)) 4533965Sjdp#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section) 4633965Sjdp#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section) 4733965Sjdp#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section) 4833965Sjdp 4933965Sjdp/* forward declarations */ 5033965Sjdp 5133965Sjdpconst bfd_target *ptrace_unix_core_file_p PARAMS ((bfd *abfd)); 52130561Sobrienchar * ptrace_unix_core_file_failing_command PARAMS ((bfd *abfd)); 53130561Sobrienint ptrace_unix_core_file_failing_signal PARAMS ((bfd *abfd)); 54218822Sdim#define ptrace_unix_core_file_matches_executable_p generic_core_file_matches_executable_p 55130561Sobrienstatic void swap_abort PARAMS ((void)); 5633965Sjdp 5733965Sjdpconst bfd_target * 5833965Sjdpptrace_unix_core_file_p (abfd) 5933965Sjdp bfd *abfd; 6033965Sjdp 6133965Sjdp{ 6233965Sjdp int val; 6333965Sjdp struct ptrace_user u; 6433965Sjdp struct trad_core_struct *rawptr; 6589857Sobrien bfd_size_type amt; 66218822Sdim flagword flags; 6733965Sjdp 6889857Sobrien val = bfd_bread ((void *)&u, (bfd_size_type) sizeof u, abfd); 6977298Sobrien if (val != sizeof u || u.pt_magic != _BCS_PTRACE_MAGIC 7033965Sjdp || u.pt_rev != _BCS_PTRACE_REV) 7133965Sjdp { 7233965Sjdp /* Too small to be a core file */ 7333965Sjdp bfd_set_error (bfd_error_wrong_format); 7433965Sjdp return 0; 7533965Sjdp } 7633965Sjdp 7733965Sjdp /* OK, we believe you. You're a core file (sure, sure). */ 7833965Sjdp 7933965Sjdp /* Allocate both the upage and the struct core_data at once, so 8033965Sjdp a single free() will free them both. */ 8189857Sobrien amt = sizeof (struct trad_core_struct); 8289857Sobrien rawptr = (struct trad_core_struct *) bfd_zalloc (abfd, amt); 8333965Sjdp 8433965Sjdp if (rawptr == NULL) 8533965Sjdp return 0; 8677298Sobrien 8733965Sjdp abfd->tdata.trad_core_data = rawptr; 8833965Sjdp 8933965Sjdp rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */ 9033965Sjdp 9189857Sobrien /* Create the sections. */ 9233965Sjdp 93218822Sdim flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; 94218822Sdim core_stacksec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".stack", 95218822Sdim flags); 9633965Sjdp if (core_stacksec (abfd) == NULL) 9789857Sobrien goto fail; 98218822Sdim core_datasec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".data", 99218822Sdim flags); 10033965Sjdp if (core_datasec (abfd) == NULL) 10189857Sobrien goto fail; 102218822Sdim core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg", 103218822Sdim SEC_HAS_CONTENTS); 10433965Sjdp if (core_regsec (abfd) == NULL) 10589857Sobrien goto fail; 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 111218822Sdim core_datasec (abfd)->size = u.pt_dsize; 112218822Sdim core_stacksec (abfd)->size = u.pt_ssize; 113218822Sdim core_regsec (abfd)->size = sizeof (u); 11433965Sjdp 11533965Sjdp core_datasec (abfd)->vma = u.pt_o_data_start; 11633965Sjdp core_stacksec (abfd)->vma = USRSTACK - u.pt_ssize; 11777298Sobrien core_regsec (abfd)->vma = 0 - sizeof (u); /* see trad-core.c */ 11833965Sjdp 11933965Sjdp core_datasec (abfd)->filepos = (int) u.pt_dataptr; 12033965Sjdp core_stacksec (abfd)->filepos = (int) (u.pt_dataptr + u.pt_dsize); 12133965Sjdp core_regsec (abfd)->filepos = 0; /* Register segment is ptrace_user */ 12233965Sjdp 12333965Sjdp /* Align to word at least */ 12433965Sjdp core_stacksec (abfd)->alignment_power = 2; 12533965Sjdp core_datasec (abfd)->alignment_power = 2; 12633965Sjdp core_regsec (abfd)->alignment_power = 2; 12733965Sjdp 12889857Sobrien return abfd->xvec; 12933965Sjdp 13089857Sobrien fail: 13189857Sobrien bfd_release (abfd, abfd->tdata.any); 13289857Sobrien abfd->tdata.any = NULL; 13389857Sobrien bfd_section_list_clear (abfd); 13489857Sobrien return NULL; 13533965Sjdp} 13633965Sjdp 13733965Sjdpchar * 13833965Sjdpptrace_unix_core_file_failing_command (abfd) 13933965Sjdp bfd *abfd; 14033965Sjdp{ 14133965Sjdp char *com = abfd->tdata.trad_core_data->u.pt_comm; 14233965Sjdp if (*com) 14333965Sjdp return com; 14433965Sjdp else 14533965Sjdp return 0; 14633965Sjdp} 14733965Sjdp 14833965Sjdpint 14933965Sjdpptrace_unix_core_file_failing_signal (abfd) 15033965Sjdp bfd *abfd; 15133965Sjdp{ 15233965Sjdp return abfd->tdata.trad_core_data->u.pt_sigframe.sig_num; 15333965Sjdp} 15433965Sjdp 15533965Sjdp/* If somebody calls any byte-swapping routines, shoot them. */ 15633965Sjdpstatic void 15777298Sobrienswap_abort () 15833965Sjdp{ 15977298Sobrien abort (); /* This way doesn't require any declaration for ANSI to fuck up */ 16033965Sjdp} 16133965Sjdp 162130561Sobrien#define NO_GET ((bfd_vma (*) (const void *)) swap_abort) 163130561Sobrien#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) 164130561Sobrien#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) 165130561Sobrien#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) 166130561Sobrien#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) 167130561Sobrien#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) 168130561Sobrien 16933965Sjdpconst bfd_target ptrace_core_vec = 17033965Sjdp { 17133965Sjdp "trad-core", 17233965Sjdp bfd_target_unknown_flavour, 17333965Sjdp BFD_ENDIAN_UNKNOWN, /* target byte order */ 17433965Sjdp BFD_ENDIAN_UNKNOWN, /* target headers byte order */ 17533965Sjdp (HAS_RELOC | EXEC_P | /* object flags */ 17633965Sjdp HAS_LINENO | HAS_DEBUG | 17733965Sjdp HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 17833965Sjdp (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ 17933965Sjdp 0, /* symbol prefix */ 18033965Sjdp ' ', /* ar_pad_char */ 18133965Sjdp 16, /* ar_max_namelen */ 182130561Sobrien NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */ 183130561Sobrien NO_GET, NO_GETS, NO_PUT, /* 32 bit data */ 184130561Sobrien NO_GET, NO_GETS, NO_PUT, /* 16 bit data */ 185130561Sobrien NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */ 186130561Sobrien NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */ 187130561Sobrien NO_GET, NO_GETS, NO_PUT, /* 16 bit hdrs */ 18833965Sjdp 18933965Sjdp { /* bfd_check_format */ 190130561Sobrien _bfd_dummy_target, /* unknown format */ 191130561Sobrien _bfd_dummy_target, /* object file */ 192130561Sobrien _bfd_dummy_target, /* archive */ 193130561Sobrien ptrace_unix_core_file_p /* a core file */ 19433965Sjdp }, 19533965Sjdp { /* bfd_set_format */ 196130561Sobrien bfd_false, bfd_false, 197130561Sobrien bfd_false, bfd_false 19833965Sjdp }, 19933965Sjdp { /* bfd_write_contents */ 200130561Sobrien bfd_false, bfd_false, 201130561Sobrien bfd_false, bfd_false 20233965Sjdp }, 20377298Sobrien 204130561Sobrien BFD_JUMP_TABLE_GENERIC (_bfd_generic), 205130561Sobrien BFD_JUMP_TABLE_COPY (_bfd_generic), 206130561Sobrien BFD_JUMP_TABLE_CORE (ptrace_unix), 207130561Sobrien BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), 208130561Sobrien BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), 209130561Sobrien BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), 210130561Sobrien BFD_JUMP_TABLE_WRITE (_bfd_generic), 211130561Sobrien BFD_JUMP_TABLE_LINK (_bfd_nolink), 212130561Sobrien BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 21333965Sjdp 21460484Sobrien NULL, 21577298Sobrien 21633965Sjdp (PTR) 0 /* backend_data */ 217130561Sobrien }; 21833965Sjdp 21933965Sjdp#endif /* PTRACE_CORE */ 220