xref: /openbsd-src/gnu/usr.bin/binutils-2.17/bfd/hppabsd-core.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* BFD back-end for HPPA BSD core files.
2*3d8817e4Smiod    Copyright 1993, 1994, 1995, 1998, 1999, 2001, 2002, 2003, 2004, 2005
3*3d8817e4Smiod    Free Software Foundation, Inc.
4*3d8817e4Smiod 
5*3d8817e4Smiod    This file is part of BFD, the Binary File Descriptor library.
6*3d8817e4Smiod 
7*3d8817e4Smiod    This program is free software; you can redistribute it and/or modify
8*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
9*3d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
10*3d8817e4Smiod    (at your option) any later version.
11*3d8817e4Smiod 
12*3d8817e4Smiod    This program is distributed in the hope that it will be useful,
13*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*3d8817e4Smiod    GNU General Public License for more details.
16*3d8817e4Smiod 
17*3d8817e4Smiod    You should have received a copy of the GNU General Public License
18*3d8817e4Smiod    along with this program; if not, write to the Free Software
19*3d8817e4Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
20*3d8817e4Smiod 
21*3d8817e4Smiod    Written by the Center for Software Science at the University of Utah
22*3d8817e4Smiod    and by Cygnus Support.
23*3d8817e4Smiod 
24*3d8817e4Smiod    The core file structure for the Utah 4.3BSD and OSF1 ports on the
25*3d8817e4Smiod    PA is a mix between traditional cores and hpux cores -- just
26*3d8817e4Smiod    different enough that supporting this format would tend to add
27*3d8817e4Smiod    gross hacks to trad-core.c or hpux-core.c.  So instead we keep any
28*3d8817e4Smiod    gross hacks isolated to this file.  */
29*3d8817e4Smiod 
30*3d8817e4Smiod /* This file can only be compiled on systems which use HPPA-BSD style
31*3d8817e4Smiod    core files.
32*3d8817e4Smiod 
33*3d8817e4Smiod    I would not expect this to be of use to any other host/target, but
34*3d8817e4Smiod    you never know.  */
35*3d8817e4Smiod 
36*3d8817e4Smiod #include "bfd.h"
37*3d8817e4Smiod #include "sysdep.h"
38*3d8817e4Smiod #include "libbfd.h"
39*3d8817e4Smiod 
40*3d8817e4Smiod #if defined (HOST_HPPABSD)
41*3d8817e4Smiod 
42*3d8817e4Smiod #include "machine/vmparam.h"
43*3d8817e4Smiod 
44*3d8817e4Smiod #include <sys/param.h>
45*3d8817e4Smiod #include <sys/dir.h>
46*3d8817e4Smiod #include <signal.h>
47*3d8817e4Smiod #include <machine/reg.h>
48*3d8817e4Smiod #include <sys/user.h>		/* After a.out.h  */
49*3d8817e4Smiod #include <sys/file.h>
50*3d8817e4Smiod 
51*3d8817e4Smiod static asection *make_bfd_asection
52*3d8817e4Smiod   PARAMS ((bfd *, const char *, flagword, bfd_size_type, file_ptr,
53*3d8817e4Smiod 	   unsigned int));
54*3d8817e4Smiod static const bfd_target *hppabsd_core_core_file_p
55*3d8817e4Smiod   PARAMS ((bfd *));
56*3d8817e4Smiod static char *hppabsd_core_core_file_failing_command
57*3d8817e4Smiod   PARAMS ((bfd *));
58*3d8817e4Smiod static int hppabsd_core_core_file_failing_signal
59*3d8817e4Smiod   PARAMS ((bfd *));
60*3d8817e4Smiod #define hppabsd_core_core_file_matches_executable_p generic_core_file_matches_executable_p
61*3d8817e4Smiod static void swap_abort
62*3d8817e4Smiod   PARAMS ((void));
63*3d8817e4Smiod 
64*3d8817e4Smiod /* These are stored in the bfd's tdata.  */
65*3d8817e4Smiod 
66*3d8817e4Smiod struct hppabsd_core_struct
67*3d8817e4Smiod   {
68*3d8817e4Smiod     int sig;
69*3d8817e4Smiod     char cmd[MAXCOMLEN + 1];
70*3d8817e4Smiod     asection *data_section;
71*3d8817e4Smiod     asection *stack_section;
72*3d8817e4Smiod     asection *reg_section;
73*3d8817e4Smiod   };
74*3d8817e4Smiod 
75*3d8817e4Smiod #define core_hdr(bfd) ((bfd)->tdata.hppabsd_core_data)
76*3d8817e4Smiod #define core_signal(bfd) (core_hdr(bfd)->sig)
77*3d8817e4Smiod #define core_command(bfd) (core_hdr(bfd)->cmd)
78*3d8817e4Smiod #define core_datasec(bfd) (core_hdr(bfd)->data_section)
79*3d8817e4Smiod #define core_stacksec(bfd) (core_hdr(bfd)->stack_section)
80*3d8817e4Smiod #define core_regsec(bfd) (core_hdr(bfd)->reg_section)
81*3d8817e4Smiod 
82*3d8817e4Smiod static asection *
make_bfd_asection(abfd,name,flags,size,offset,alignment_power)83*3d8817e4Smiod make_bfd_asection (abfd, name, flags, size, offset, alignment_power)
84*3d8817e4Smiod      bfd *abfd;
85*3d8817e4Smiod      const char *name;
86*3d8817e4Smiod      flagword flags;
87*3d8817e4Smiod      bfd_size_type size;
88*3d8817e4Smiod      file_ptr offset;
89*3d8817e4Smiod      unsigned int alignment_power;
90*3d8817e4Smiod {
91*3d8817e4Smiod   asection *asect;
92*3d8817e4Smiod 
93*3d8817e4Smiod   asect = bfd_make_section (abfd, name);
94*3d8817e4Smiod   if (!asect)
95*3d8817e4Smiod     return NULL;
96*3d8817e4Smiod 
97*3d8817e4Smiod   asect->flags = flags;
98*3d8817e4Smiod   asect->size = size;
99*3d8817e4Smiod   asect->filepos = offset;
100*3d8817e4Smiod   asect->alignment_power = alignment_power;
101*3d8817e4Smiod 
102*3d8817e4Smiod   return asect;
103*3d8817e4Smiod }
104*3d8817e4Smiod 
105*3d8817e4Smiod static const bfd_target *
hppabsd_core_core_file_p(abfd)106*3d8817e4Smiod hppabsd_core_core_file_p (abfd)
107*3d8817e4Smiod      bfd *abfd;
108*3d8817e4Smiod {
109*3d8817e4Smiod   int val;
110*3d8817e4Smiod   struct user u;
111*3d8817e4Smiod   struct hppabsd_core_struct *coredata;
112*3d8817e4Smiod   int clicksz;
113*3d8817e4Smiod 
114*3d8817e4Smiod   /* Try to read in the u-area.  We will need information from this
115*3d8817e4Smiod      to know how to grok the rest of the core structures.  */
116*3d8817e4Smiod   val = bfd_bread ((void *) &u, (bfd_size_type) sizeof u, abfd);
117*3d8817e4Smiod   if (val != sizeof u)
118*3d8817e4Smiod     {
119*3d8817e4Smiod       if (bfd_get_error () != bfd_error_system_call)
120*3d8817e4Smiod 	bfd_set_error (bfd_error_wrong_format);
121*3d8817e4Smiod       return NULL;
122*3d8817e4Smiod     }
123*3d8817e4Smiod 
124*3d8817e4Smiod   /* Get the page size out of the u structure.  This will be different
125*3d8817e4Smiod      for PA 1.0 machines and PA 1.1 machines.   Yuk!  */
126*3d8817e4Smiod   clicksz = u.u_pcb.pcb_pgsz;
127*3d8817e4Smiod 
128*3d8817e4Smiod   /* clicksz must be a power of two >= 2k.  */
129*3d8817e4Smiod   if (clicksz < 0x800
130*3d8817e4Smiod       || clicksz != (clicksz & -clicksz))
131*3d8817e4Smiod     {
132*3d8817e4Smiod       bfd_set_error (bfd_error_wrong_format);
133*3d8817e4Smiod       return NULL;
134*3d8817e4Smiod     }
135*3d8817e4Smiod 
136*3d8817e4Smiod   /* Sanity checks.  Make sure the size of the core file matches the
137*3d8817e4Smiod      the size computed from information within the core itself.  */
138*3d8817e4Smiod   {
139*3d8817e4Smiod     struct stat statbuf;
140*3d8817e4Smiod 
141*3d8817e4Smiod     if (bfd_stat (abfd, &statbuf) < 0)
142*3d8817e4Smiod       return NULL;
143*3d8817e4Smiod 
144*3d8817e4Smiod     if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size)
145*3d8817e4Smiod       {
146*3d8817e4Smiod 	bfd_set_error (bfd_error_file_truncated);
147*3d8817e4Smiod 	return NULL;
148*3d8817e4Smiod       }
149*3d8817e4Smiod     if (clicksz * (UPAGES + u.u_dsize + u.u_ssize) < statbuf.st_size)
150*3d8817e4Smiod       {
151*3d8817e4Smiod 	/* The file is too big.  Maybe it's not a core file
152*3d8817e4Smiod 	   or we otherwise have bad values for u_dsize and u_ssize).  */
153*3d8817e4Smiod 	bfd_set_error (bfd_error_wrong_format);
154*3d8817e4Smiod 	return NULL;
155*3d8817e4Smiod       }
156*3d8817e4Smiod   }
157*3d8817e4Smiod 
158*3d8817e4Smiod   /* OK, we believe you.  You're a core file (sure, sure).  */
159*3d8817e4Smiod 
160*3d8817e4Smiod   coredata = (struct hppabsd_core_struct *)
161*3d8817e4Smiod     bfd_zalloc (abfd, (bfd_size_type) sizeof (struct hppabsd_core_struct));
162*3d8817e4Smiod   if (!coredata)
163*3d8817e4Smiod     return NULL;
164*3d8817e4Smiod 
165*3d8817e4Smiod   /* Make the core data and available via the tdata part of the BFD.  */
166*3d8817e4Smiod   abfd->tdata.hppabsd_core_data = coredata;
167*3d8817e4Smiod 
168*3d8817e4Smiod   /* Create the sections.  */
169*3d8817e4Smiod   core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
170*3d8817e4Smiod 					   SEC_ALLOC + SEC_HAS_CONTENTS,
171*3d8817e4Smiod 					   clicksz * u.u_ssize,
172*3d8817e4Smiod 					   NBPG * (USIZE + KSTAKSIZE)
173*3d8817e4Smiod 					     + clicksz * u.u_dsize, 2);
174*3d8817e4Smiod   if (core_stacksec (abfd) == NULL)
175*3d8817e4Smiod     goto fail;
176*3d8817e4Smiod   core_stacksec (abfd)->vma = USRSTACK;
177*3d8817e4Smiod 
178*3d8817e4Smiod   core_datasec (abfd) = make_bfd_asection (abfd, ".data",
179*3d8817e4Smiod 					  SEC_ALLOC + SEC_LOAD
180*3d8817e4Smiod 					    + SEC_HAS_CONTENTS,
181*3d8817e4Smiod 					  clicksz * u.u_dsize,
182*3d8817e4Smiod 					  NBPG * (USIZE + KSTAKSIZE), 2);
183*3d8817e4Smiod   if (core_datasec (abfd) == NULL)
184*3d8817e4Smiod     goto fail;
185*3d8817e4Smiod   core_datasec (abfd)->vma = UDATASEG;
186*3d8817e4Smiod 
187*3d8817e4Smiod   core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
188*3d8817e4Smiod 					 SEC_HAS_CONTENTS,
189*3d8817e4Smiod 					 KSTAKSIZE * NBPG,
190*3d8817e4Smiod 					 NBPG * USIZE, 2);
191*3d8817e4Smiod   if (core_regsec (abfd) == NULL)
192*3d8817e4Smiod     goto fail;
193*3d8817e4Smiod   core_regsec (abfd)->vma = 0;
194*3d8817e4Smiod 
195*3d8817e4Smiod   strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1);
196*3d8817e4Smiod   core_signal (abfd) = u.u_code;
197*3d8817e4Smiod   return abfd->xvec;
198*3d8817e4Smiod 
199*3d8817e4Smiod  fail:
200*3d8817e4Smiod   bfd_release (abfd, abfd->tdata.any);
201*3d8817e4Smiod   abfd->tdata.any = NULL;
202*3d8817e4Smiod   bfd_section_list_clear (abfd);
203*3d8817e4Smiod   return NULL;
204*3d8817e4Smiod }
205*3d8817e4Smiod 
206*3d8817e4Smiod static char *
hppabsd_core_core_file_failing_command(abfd)207*3d8817e4Smiod hppabsd_core_core_file_failing_command (abfd)
208*3d8817e4Smiod      bfd *abfd;
209*3d8817e4Smiod {
210*3d8817e4Smiod   return core_command (abfd);
211*3d8817e4Smiod }
212*3d8817e4Smiod 
213*3d8817e4Smiod static int
hppabsd_core_core_file_failing_signal(abfd)214*3d8817e4Smiod hppabsd_core_core_file_failing_signal (abfd)
215*3d8817e4Smiod      bfd *abfd;
216*3d8817e4Smiod {
217*3d8817e4Smiod   return core_signal (abfd);
218*3d8817e4Smiod }
219*3d8817e4Smiod 
220*3d8817e4Smiod /* If somebody calls any byte-swapping routines, shoot them.  */
221*3d8817e4Smiod static void
swap_abort()222*3d8817e4Smiod swap_abort ()
223*3d8817e4Smiod {
224*3d8817e4Smiod   /* This way doesn't require any declaration for ANSI to fuck up.  */
225*3d8817e4Smiod   abort ();
226*3d8817e4Smiod }
227*3d8817e4Smiod 
228*3d8817e4Smiod #define	NO_GET ((bfd_vma (*) (const void *)) swap_abort)
229*3d8817e4Smiod #define	NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
230*3d8817e4Smiod #define	NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
231*3d8817e4Smiod #define	NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
232*3d8817e4Smiod #define	NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
233*3d8817e4Smiod #define	NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
234*3d8817e4Smiod 
235*3d8817e4Smiod const bfd_target hppabsd_core_vec =
236*3d8817e4Smiod   {
237*3d8817e4Smiod     "hppabsd-core",
238*3d8817e4Smiod     bfd_target_unknown_flavour,
239*3d8817e4Smiod     BFD_ENDIAN_BIG,		/* target byte order */
240*3d8817e4Smiod     BFD_ENDIAN_BIG,		/* target headers byte order */
241*3d8817e4Smiod     (HAS_RELOC | EXEC_P |	/* object flags */
242*3d8817e4Smiod      HAS_LINENO | HAS_DEBUG |
243*3d8817e4Smiod      HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
244*3d8817e4Smiod     (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
245*3d8817e4Smiod     0,			                                   /* symbol prefix */
246*3d8817e4Smiod     ' ',						   /* ar_pad_char */
247*3d8817e4Smiod     16,							   /* ar_max_namelen */
248*3d8817e4Smiod     NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit data */
249*3d8817e4Smiod     NO_GET, NO_GETS, NO_PUT,		/* 32 bit data */
250*3d8817e4Smiod     NO_GET, NO_GETS, NO_PUT,		/* 16 bit data */
251*3d8817e4Smiod     NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit hdrs */
252*3d8817e4Smiod     NO_GET, NO_GETS, NO_PUT,		/* 32 bit hdrs */
253*3d8817e4Smiod     NO_GET, NO_GETS, NO_PUT,		/* 16 bit hdrs */
254*3d8817e4Smiod 
255*3d8817e4Smiod     {				/* bfd_check_format */
256*3d8817e4Smiod       _bfd_dummy_target,		/* unknown format */
257*3d8817e4Smiod       _bfd_dummy_target,		/* object file */
258*3d8817e4Smiod       _bfd_dummy_target,		/* archive */
259*3d8817e4Smiod       hppabsd_core_core_file_p		/* a core file */
260*3d8817e4Smiod     },
261*3d8817e4Smiod     {				/* bfd_set_format */
262*3d8817e4Smiod       bfd_false, bfd_false,
263*3d8817e4Smiod       bfd_false, bfd_false
264*3d8817e4Smiod     },
265*3d8817e4Smiod     {				/* bfd_write_contents */
266*3d8817e4Smiod       bfd_false, bfd_false,
267*3d8817e4Smiod       bfd_false, bfd_false
268*3d8817e4Smiod     },
269*3d8817e4Smiod 
270*3d8817e4Smiod     BFD_JUMP_TABLE_GENERIC (_bfd_generic),
271*3d8817e4Smiod     BFD_JUMP_TABLE_COPY (_bfd_generic),
272*3d8817e4Smiod     BFD_JUMP_TABLE_CORE (hppabsd_core),
273*3d8817e4Smiod     BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
274*3d8817e4Smiod     BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
275*3d8817e4Smiod     BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
276*3d8817e4Smiod     BFD_JUMP_TABLE_WRITE (_bfd_generic),
277*3d8817e4Smiod     BFD_JUMP_TABLE_LINK (_bfd_nolink),
278*3d8817e4Smiod     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
279*3d8817e4Smiod 
280*3d8817e4Smiod     NULL,
281*3d8817e4Smiod 
282*3d8817e4Smiod     (PTR) 0			/* backend_data */
283*3d8817e4Smiod   };
284*3d8817e4Smiod #endif
285