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