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