netbsd-core.c revision 60484
1/* BFD back end for NetBSD style core files
2   Copyright 1988, 89, 91, 92, 93, 96, 1998 Free Software Foundation, Inc.
3   Written by Paul Kranenburg, EUR
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include "bfd.h"
22#include "sysdep.h"
23#include "libbfd.h"
24#include "libaout.h"           /* BFD a.out internal data structures */
25
26#include <sys/param.h>
27#include <sys/dir.h>
28#include <signal.h>
29#include <sys/core.h>
30
31/*
32 * FIXME: On NetBSD/sparc CORE_FPU_OFFSET should be (sizeof(struct trapframe))
33 */
34
35struct netbsd_core_struct {
36	struct core core;
37} *rawptr;
38
39/* forward declarations */
40
41static const bfd_target *	netbsd_core_file_p PARAMS ((bfd *abfd));
42static char *		netbsd_core_file_failing_command PARAMS ((bfd *abfd));
43static int 		netbsd_core_file_failing_signal PARAMS ((bfd *abfd));
44static boolean		netbsd_core_file_matches_executable_p
45			 PARAMS ((bfd *core_bfd, bfd *exec_bfd));
46static void		swap_abort PARAMS ((void));
47
48/* Handle NetBSD-style core dump file.  */
49
50/* ARGSUSED */
51static const bfd_target *
52netbsd_core_file_p (abfd)
53     bfd *abfd;
54
55{
56	int		i, val, offset;
57	asection	*asect, *asect2;
58	struct core	core;
59	struct coreseg	coreseg;
60
61	val = bfd_read ((void *)&core, 1, sizeof core, abfd);
62	if (val != sizeof core) {
63		/* Too small to be a core file */
64		bfd_set_error(bfd_error_wrong_format);
65		return 0;
66	}
67
68	if (CORE_GETMAGIC(core) != COREMAGIC) {
69		bfd_set_error(bfd_error_wrong_format);
70		return 0;
71	}
72
73	rawptr = (struct netbsd_core_struct *)
74		bfd_zalloc (abfd, sizeof (struct netbsd_core_struct));
75	if (rawptr == NULL) {
76		bfd_set_error(bfd_error_no_memory);
77		return 0;
78	}
79
80	rawptr->core = core;
81	abfd->tdata.netbsd_core_data = rawptr;
82
83	offset = core.c_hdrsize;
84	for (i = 0; i < core.c_nseg; i++) {
85
86		if (bfd_seek (abfd, offset, SEEK_SET) != 0)
87			goto punt;
88
89		val = bfd_read ((void *)&coreseg, 1, sizeof coreseg, abfd);
90		if (val != sizeof coreseg) {
91			bfd_set_error(bfd_error_file_truncated);
92			goto punt;
93		}
94		if (CORE_GETMAGIC(coreseg) != CORESEGMAGIC) {
95			bfd_set_error(bfd_error_wrong_format);
96			goto punt;
97		}
98
99		offset += core.c_seghdrsize;
100
101		asect = (asection *) bfd_zalloc (abfd, sizeof(asection));
102		if (asect == NULL) {
103			bfd_set_error(bfd_error_no_memory);
104			goto punt;
105		}
106
107		asect->_raw_size = coreseg.c_size;
108		asect->vma = coreseg.c_addr;
109		asect->filepos = offset;
110		asect->alignment_power = 2;
111		asect->next = abfd->sections;
112		abfd->sections = asect;
113		abfd->section_count++;
114		offset += coreseg.c_size;
115
116		switch (CORE_GETFLAG(coreseg)) {
117		case CORE_CPU:
118			asect->name = ".reg";
119			asect->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
120#ifdef CORE_FPU_OFFSET
121			/* Hackish... */
122			asect->_raw_size = CORE_FPU_OFFSET;
123			asect2 = (asection *)bfd_zalloc (abfd,
124							 sizeof (asection));
125			if (asect2 == NULL) {
126				bfd_set_error(bfd_error_no_memory);
127				goto punt;
128			}
129			asect2->_raw_size = coreseg.c_size - CORE_FPU_OFFSET;
130			asect2->vma = 0;
131			asect2->filepos = asect->filepos + CORE_FPU_OFFSET;
132			asect2->alignment_power = 2;
133			asect2->next = abfd->sections;
134			asect2->name = ".reg2";
135			asect2->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
136			abfd->sections = asect2;
137			abfd->section_count++;
138#endif
139
140			break;
141		case CORE_DATA:
142			asect->name = ".data";
143			asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS;
144			break;
145		case CORE_STACK:
146			asect->name = ".stack";
147			asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS;
148			break;
149		}
150	}
151
152	/* OK, we believe you.  You're a core file (sure, sure).  */
153	return abfd->xvec;
154
155punt:	{
156		asection	*anext;
157		for (asect = abfd->sections; asect; asect = anext) {
158			anext = asect->next;
159			free((void *)asect);
160		}
161	}
162	free ((void *)rawptr);
163	abfd->tdata.netbsd_core_data = NULL;
164	abfd->sections = NULL;
165	abfd->section_count = 0;
166	return 0;
167}
168
169static char*
170netbsd_core_file_failing_command (abfd)
171	bfd *abfd;
172{
173 /*return core_command (abfd);*/
174  return abfd->tdata.netbsd_core_data->core.c_name;
175}
176
177/* ARGSUSED */
178static int
179netbsd_core_file_failing_signal (abfd)
180	bfd *abfd;
181{
182  /*return core_signal (abfd);*/
183  return abfd->tdata.netbsd_core_data->core.c_signo;
184}
185
186/* ARGSUSED */
187static boolean
188netbsd_core_file_matches_executable_p  (core_bfd, exec_bfd)
189     bfd *core_bfd, *exec_bfd;
190{
191  return true;		/* FIXME, We have no way of telling at this point */
192}
193
194/* If somebody calls any byte-swapping routines, shoot them.  */
195static void
196swap_abort()
197{
198  abort(); /* This way doesn't require any declaration for ANSI to fuck up */
199}
200#define	NO_GET	((bfd_vma (*) PARAMS ((   const bfd_byte *))) swap_abort )
201#define	NO_PUT	((void    (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
202#define	NO_SIGNED_GET \
203  ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
204
205const bfd_target netbsd_core_vec =
206  {
207    "netbsd-core",
208    bfd_target_unknown_flavour,
209    BFD_ENDIAN_UNKNOWN,		/* target byte order */
210    BFD_ENDIAN_UNKNOWN,		/* target headers byte order */
211    (HAS_RELOC | EXEC_P |	/* object flags */
212     HAS_LINENO | HAS_DEBUG |
213     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
214    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
215    0,			                                   /* symbol prefix */
216    ' ',						   /* ar_pad_char */
217    16,							   /* ar_max_namelen */
218    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 64 bit data */
219    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 32 bit data */
220    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 16 bit data */
221    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 64 bit hdrs */
222    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 32 bit hdrs */
223    NO_GET, NO_SIGNED_GET, NO_PUT,	/* 16 bit hdrs */
224
225    {				/* bfd_check_format */
226     _bfd_dummy_target,		/* unknown format */
227     _bfd_dummy_target,		/* object file */
228     _bfd_dummy_target,		/* archive */
229     netbsd_core_file_p		/* a core file */
230    },
231    {				/* bfd_set_format */
232     bfd_false, bfd_false,
233     bfd_false, bfd_false
234    },
235    {				/* bfd_write_contents */
236     bfd_false, bfd_false,
237     bfd_false, bfd_false
238    },
239
240       BFD_JUMP_TABLE_GENERIC (_bfd_generic),
241       BFD_JUMP_TABLE_COPY (_bfd_generic),
242       BFD_JUMP_TABLE_CORE (netbsd),
243       BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
244       BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
245       BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
246       BFD_JUMP_TABLE_WRITE (_bfd_generic),
247       BFD_JUMP_TABLE_LINK (_bfd_nolink),
248       BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
249
250    NULL,
251
252    (PTR) 0			/* backend_data */
253};
254