source: trunk/src/binutils/bfd/trad-core.c@ 720

Last change on this file since 720 was 618, checked in by bird, 22 years ago

Joined the port of 2.11.2 with 2.14.

  • Property cvs2svn:cvs-rev set to 1.4
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 11.6 KB
Line 
1/* BFD back end for traditional Unix core files (U-area and raw sections)
2 Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
3 2000, 2001, 2002
4 Free Software Foundation, Inc.
5 Written by John Gilmore of Cygnus Support.
6
7This file is part of BFD, the Binary File Descriptor library.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23#include "bfd.h"
24#include "sysdep.h"
25#include "libbfd.h"
26#include "libaout.h" /* BFD a.out internal data structures */
27
28#include <sys/param.h>
29#ifdef HAVE_DIRENT_H
30# include <dirent.h>
31#else
32# ifdef HAVE_SYS_NDIR_H
33# include <sys/ndir.h>
34# endif
35# ifdef HAVE_SYS_DIR_H
36# include <sys/dir.h>
37# endif
38# ifdef HAVE_NDIR_H
39# include <ndir.h>
40# endif
41#endif
42#include <signal.h>
43
44#include <sys/user.h> /* After a.out.h */
45
46#ifndef __EMX__ /* r=bird: Code was initially removed. Why don't we include it? anything to do with sysdep.h? */
47#ifdef TRAD_HEADER
48#include TRAD_HEADER
49#endif
50#endif /* !__EMX__ */
51
52struct trad_core_struct
53{
54 asection *data_section;
55#ifdef EMX
56 asection *heap_section;
57#endif /* EMX */
58 asection *stack_section;
59 asection *reg_section;
60 struct user u;
61};
62
63#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u))
64#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section)
65#ifdef EMX
66#define core_heapsec(bfd) ((bfd)->tdata.trad_core_data->heap_section)
67#endif /* EMX */
68#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section)
69#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section)
70
71/* forward declarations */
72
73const bfd_target *trad_unix_core_file_p PARAMS ((bfd *abfd));
74char * trad_unix_core_file_failing_command PARAMS ((bfd *abfd));
75int trad_unix_core_file_failing_signal PARAMS ((bfd *abfd));
76bfd_boolean trad_unix_core_file_matches_executable_p
77 PARAMS ((bfd *core_bfd, bfd *exec_bfd));
78static void swap_abort PARAMS ((void));
79
80/* Handle 4.2-style (and perhaps also sysV-style) core dump file. */
81
82/* ARGSUSED */
83const bfd_target *
84trad_unix_core_file_p (abfd)
85 bfd *abfd;
86
87{
88 int val;
89 struct user u;
90 struct trad_core_struct *rawptr;
91 bfd_size_type amt;
92
93#ifdef TRAD_CORE_USER_OFFSET
94 /* If defined, this macro is the file position of the user struct. */
95 if (bfd_seek (abfd, (file_ptr) TRAD_CORE_USER_OFFSET, SEEK_SET) != 0)
96 return 0;
97#endif
98
99 val = bfd_bread ((void *) &u, (bfd_size_type) sizeof u, abfd);
100 if (val != sizeof u)
101 {
102 /* Too small to be a core file */
103 bfd_set_error (bfd_error_wrong_format);
104 return 0;
105 }
106
107 /* Sanity check perhaps??? */
108#ifdef __EMX__ /* r=bird: EMX not __EMX__ thing?? */
109 if (u.u_magic != UMAGIC)
110 return 0;
111#else /* !__EMX__ */
112 if (u.u_dsize > 0x1000000) /* Remember, it's in pages... */
113 {
114 bfd_set_error (bfd_error_wrong_format);
115 return 0;
116 }
117 if (u.u_ssize > 0x1000000)
118 {
119 bfd_set_error (bfd_error_wrong_format);
120 return 0;
121 }
122
123 /* Check that the size claimed is no greater than the file size. */
124 {
125 FILE *stream = bfd_cache_lookup (abfd);
126 struct stat statbuf;
127 if (stream == NULL)
128 return 0;
129 if (fstat (fileno (stream), &statbuf) < 0)
130 {
131 bfd_set_error (bfd_error_system_call);
132 return 0;
133 }
134 if ((unsigned long) (NBPG * (UPAGES + u.u_dsize
135#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
136 - u.u_tsize
137#endif
138 + u.u_ssize))
139 > (unsigned long) statbuf.st_size)
140 {
141 bfd_set_error (bfd_error_wrong_format);
142 return 0;
143 }
144#ifndef TRAD_CORE_ALLOW_ANY_EXTRA_SIZE
145 if ((unsigned long) (NBPG * (UPAGES + u.u_dsize + u.u_ssize)
146#ifdef TRAD_CORE_EXTRA_SIZE_ALLOWED
147 /* Some systems write the file too big. */
148 + TRAD_CORE_EXTRA_SIZE_ALLOWED
149#endif
150 )
151 < (unsigned long) statbuf.st_size)
152 {
153 /* The file is too big. Maybe it's not a core file
154 or we otherwise have bad values for u_dsize and u_ssize). */
155 bfd_set_error (bfd_error_wrong_format);
156 return 0;
157 }
158#endif
159 }
160#endif /* !__EMX__ */
161
162 /* OK, we believe you. You're a core file (sure, sure). */
163
164 /* Allocate both the upage and the struct core_data at once, so
165 a single free() will free them both. */
166 amt = sizeof (struct trad_core_struct);
167 rawptr = (struct trad_core_struct *) bfd_zmalloc (amt);
168 if (rawptr == NULL)
169 return 0;
170
171 abfd->tdata.trad_core_data = rawptr;
172
173 rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
174
175 /* Create the sections. */
176
177 core_stacksec(abfd) = bfd_make_section_anyway (abfd, ".stack");
178 if (core_stacksec (abfd) == NULL)
179 goto fail;
180 core_datasec (abfd) = bfd_make_section_anyway (abfd, ".data");
181 if (core_datasec (abfd) == NULL)
182 goto fail;
183 core_regsec (abfd) = bfd_make_section_anyway (abfd, ".reg");
184 if (core_regsec (abfd) == NULL)
185 goto fail;
186#ifdef EMX
187 core_heapsec (abfd) = bfd_make_section_anyway (abfd, ".heap");
188 if (core_heapsec (abfd) == NULL)
189 goto fail;
190#endif /* EMX */
191
192 core_stacksec (abfd)->name = ".stack";
193 core_datasec (abfd)->name = ".data";
194#ifdef EMX
195 core_heapsec (abfd)->name = ".heap";
196#endif /* EMX */
197 core_regsec (abfd)->name = ".reg";
198
199 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
200 core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
201 core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
202#ifdef EMX
203 core_heapsec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
204#endif /* EMX */
205
206#ifdef EMX
207 core_datasec (abfd)->_raw_size = u.u_data_end - u.u_data_base;
208 core_heapsec (abfd)->_raw_size = u.u_heap_brk - u.u_heap_base;
209 core_stacksec (abfd)->_raw_size = u.u_stack_end - u.u_stack_low;
210 core_regsec (abfd)->_raw_size = sizeof (struct user);
211#else /* not EMX */
212 core_datasec (abfd)->_raw_size = NBPG * u.u_dsize
213#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
214 - NBPG * u.u_tsize
215#endif
216 ;
217 core_stacksec (abfd)->_raw_size = NBPG * u.u_ssize;
218 core_regsec (abfd)->_raw_size = NBPG * UPAGES; /* Larger than sizeof struct u */
219#endif /* not EMX */
220
221 /* What a hack... we'd like to steal it from the exec file,
222 since the upage does not seem to provide it. FIXME. */
223#ifdef EMX
224 core_datasec (abfd)->vma = u.u_data_base;
225 core_heapsec (abfd)->vma = u.u_heap_base;
226 core_stacksec (abfd)->vma = u.u_stack_low;
227#else /* not EMX */
228#ifdef HOST_DATA_START_ADDR
229 core_datasec (abfd)->vma = HOST_DATA_START_ADDR;
230#else
231 core_datasec (abfd)->vma = HOST_TEXT_START_ADDR + (NBPG * u.u_tsize);
232#endif
233
234#ifdef HOST_STACK_START_ADDR
235 core_stacksec (abfd)->vma = HOST_STACK_START_ADDR;
236#else
237 core_stacksec (abfd)->vma = HOST_STACK_END_ADDR - (NBPG * u.u_ssize);
238#endif
239#endif /* not EMX */
240
241 /* This is tricky. As the "register section", we give them the entire
242 upage and stack. u.u_ar0 points to where "register 0" is stored.
243 There are two tricks with this, though. One is that the rest of the
244 registers might be at positive or negative (or both) displacements
245 from *u_ar0. The other is that u_ar0 is sometimes an absolute address
246 in kernel memory, and on other systems it is an offset from the beginning
247 of the `struct user'.
248
249 As a practical matter, we don't know where the registers actually are,
250 so we have to pass the whole area to GDB. We encode the value of u_ar0
251 by setting the .regs section up so that its virtual memory address
252 0 is at the place pointed to by u_ar0 (by setting the vma of the start
253 of the section to -u_ar0). GDB uses this info to locate the regs,
254 using minor trickery to get around the offset-or-absolute-addr problem. */
255 core_regsec (abfd)->vma = - (bfd_vma) (unsigned long) u.u_ar0;
256
257#ifdef EMX
258 core_datasec (abfd)->filepos = u.u_data_off;
259 core_heapsec (abfd)->filepos = u.u_heap_off;
260 core_stacksec (abfd)->filepos = u.u_stack_off;
261#else /* not EMX */
262 core_datasec (abfd)->filepos = NBPG * UPAGES;
263 core_stacksec (abfd)->filepos = (NBPG * UPAGES) + NBPG * u.u_dsize
264#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
265 - NBPG * u.u_tsize
266#endif
267 ;
268#endif /* not EMX */
269
270 core_regsec (abfd)->filepos = 0; /* Register segment is the upage */
271
272 /* Align to word at least */
273 core_stacksec (abfd)->alignment_power = 2;
274 core_datasec (abfd)->alignment_power = 2;
275#ifdef EMX
276 core_heapsec (abfd)->alignment_power = 2;
277#endif /* EMX */
278 core_regsec (abfd)->alignment_power = 2;
279
280 return abfd->xvec;
281
282 fail:
283 bfd_release (abfd, abfd->tdata.any);
284 abfd->tdata.any = NULL;
285 bfd_section_list_clear (abfd);
286 return NULL;
287}
288
289char *
290trad_unix_core_file_failing_command (abfd)
291 bfd *abfd;
292{
293#ifndef NO_CORE_COMMAND
294 char *com = abfd->tdata.trad_core_data->u.u_comm;
295 if (*com)
296 return com;
297 else
298#endif
299 return 0;
300}
301
302/* ARGSUSED */
303int
304trad_unix_core_file_failing_signal (ignore_abfd)
305 bfd *ignore_abfd ATTRIBUTE_UNUSED;
306{
307#ifdef TRAD_UNIX_CORE_FILE_FAILING_SIGNAL
308 return TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(ignore_abfd);
309#else
310 return -1; /* FIXME, where is it? */
311#endif
312}
313
314/* ARGSUSED */
315bfd_boolean
316trad_unix_core_file_matches_executable_p (core_bfd, exec_bfd)
317 bfd *core_bfd ATTRIBUTE_UNUSED;
318 bfd *exec_bfd ATTRIBUTE_UNUSED;
319{
320 return TRUE; /* FIXME, We have no way of telling at this point */
321}
322
323
324/* If somebody calls any byte-swapping routines, shoot them. */
325static void
326swap_abort ()
327{
328 abort (); /* This way doesn't require any declaration for ANSI to fuck up */
329}
330#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
331#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
332#define NO_SIGNED_GET \
333 ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
334
335const bfd_target trad_core_vec =
336 {
337 "trad-core",
338 bfd_target_unknown_flavour,
339 BFD_ENDIAN_UNKNOWN, /* target byte order */
340 BFD_ENDIAN_UNKNOWN, /* target headers byte order */
341 (HAS_RELOC | EXEC_P | /* object flags */
342 HAS_LINENO | HAS_DEBUG |
343 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
344 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
345 0, /* symbol prefix */
346 ' ', /* ar_pad_char */
347 16, /* ar_max_namelen */
348 NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
349 NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
350 NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
351 NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
352 NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
353 NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
354
355 { /* bfd_check_format */
356 _bfd_dummy_target, /* unknown format */
357 _bfd_dummy_target, /* object file */
358 _bfd_dummy_target, /* archive */
359 trad_unix_core_file_p /* a core file */
360 },
361 { /* bfd_set_format */
362 bfd_false, bfd_false,
363 bfd_false, bfd_false
364 },
365 { /* bfd_write_contents */
366 bfd_false, bfd_false,
367 bfd_false, bfd_false
368 },
369
370 BFD_JUMP_TABLE_GENERIC (_bfd_generic),
371 BFD_JUMP_TABLE_COPY (_bfd_generic),
372 BFD_JUMP_TABLE_CORE (trad_unix),
373 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
374 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
375 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
376 BFD_JUMP_TABLE_WRITE (_bfd_generic),
377 BFD_JUMP_TABLE_LINK (_bfd_nolink),
378 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
379
380 NULL,
381
382 (PTR) 0 /* backend_data */
383};
Note: See TracBrowser for help on using the repository browser.