comment change. This is a mips file, not 88k.
[deliverable/binutils-gdb.git] / bfd / trad-core.c
CommitLineData
9712c6e2 1/* BFD back end for traditional Unix core files (U-area and raw sections)
0dc1bc8b 2 Copyright 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
9712c6e2
SG
3 Written by John Gilmore of Cygnus Support.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
ff37ea55 20
6a469027
JG
21/* To use this file on a particular host, configure the host with these
22 parameters in the config/h-HOST file:
23
637942e4 24 HDEFINES=-DTRAD_CORE
6a469027
JG
25 HDEPFILES=trad-core.o
26
27 */
28
ff37ea55 29#include "bfd.h"
637942e4 30#include "sysdep.h"
ff37ea55 31#include "libbfd.h"
359f1dee 32#include "libaout.h" /* BFD a.out internal data structures */
ff37ea55 33
637942e4 34#include <stdio.h>
ff37ea55
JG
35#include <sys/types.h>
36#include <sys/param.h>
37#include <sys/dir.h>
38#include <signal.h>
ff37ea55
JG
39
40#include <sys/user.h> /* After a.out.h */
41#include <sys/file.h>
ff37ea55
JG
42
43#include <errno.h>
44
1f29e30b
JG
45 struct trad_core_struct
46 {
47 asection *data_section;
48 asection *stack_section;
49 asection *reg_section;
50 struct user u;
51 } *rawptr;
52
53#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u))
54#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section)
55#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section)
56#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section)
57
58/* forward declarations */
ff37ea55 59
1f29e30b
JG
60bfd_target * trad_unix_core_file_p PARAMS ((bfd *abfd));
61char * trad_unix_core_file_failing_command PARAMS ((bfd *abfd));
62int trad_unix_core_file_failing_signal PARAMS ((bfd *abfd));
63boolean trad_unix_core_file_matches_executable_p
64 PARAMS ((bfd *core_bfd, bfd *exec_bfd));
6a469027 65
637942e4
JG
66/* Handle 4.2-style (and perhaps also sysV-style) core dump file. */
67
7ed4093a 68/* ARGSUSED */
ff37ea55
JG
69bfd_target *
70trad_unix_core_file_p (abfd)
71 bfd *abfd;
1f29e30b 72
ff37ea55 73{
ff37ea55 74 int val;
ff37ea55 75 struct user u;
ff37ea55
JG
76
77 val = bfd_read ((void *)&u, 1, sizeof u, abfd);
78 if (val != sizeof u)
31568a6f
JK
79 {
80 /* Too small to be a core file */
81 bfd_error = wrong_format;
82 return 0;
83 }
ff37ea55
JG
84
85 /* Sanity check perhaps??? */
86 if (u.u_dsize > 0x1000000) /* Remember, it's in pages... */
31568a6f
JK
87 {
88 bfd_error = wrong_format;
89 return 0;
90 }
ff37ea55 91 if (u.u_ssize > 0x1000000)
31568a6f
JK
92 {
93 bfd_error = wrong_format;
94 return 0;
95 }
96
97 /* Check that the size claimed is no greater than the file size. */
98 {
99 FILE *stream = bfd_cache_lookup (abfd);
100 struct stat statbuf;
101 if (stream == NULL)
102 return 0;
103 if (fstat (fileno (stream), &statbuf) < 0)
104 {
105 bfd_error = system_call_error;
106 return 0;
107 }
108 if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size)
109 {
110 bfd_error = file_truncated;
111 return 0;
112 }
113 if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) < statbuf.st_size)
114 {
115 /* The file is too big. Maybe it's not a core file
116 or we otherwise have bad values for u_dsize and u_ssize). */
117 bfd_error = wrong_format;
118 return 0;
119 }
120 }
ff37ea55
JG
121
122 /* OK, we believe you. You're a core file (sure, sure). */
123
124 /* Allocate both the upage and the struct core_data at once, so
125 a single free() will free them both. */
1f29e30b
JG
126 rawptr = (struct trad_core_struct *)
127 bfd_zalloc (abfd, sizeof (struct trad_core_struct));
ff37ea55
JG
128 if (rawptr == NULL) {
129 bfd_error = no_memory;
130 return 0;
131 }
132
1f29e30b
JG
133 abfd->tdata.trad_core_data = rawptr;
134
135 rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
ff37ea55 136
637942e4
JG
137 /* Create the sections. This is raunchy, but bfd_close wants to free
138 them separately. */
1f29e30b
JG
139
140 core_stacksec(abfd) = (asection *) zalloc (sizeof (asection));
ff37ea55 141 if (core_stacksec (abfd) == NULL) {
1f29e30b 142 loser:
ff37ea55
JG
143 bfd_error = no_memory;
144 free ((void *)rawptr);
145 return 0;
146 }
147 core_datasec (abfd) = (asection *) zalloc (sizeof (asection));
148 if (core_datasec (abfd) == NULL) {
1f29e30b 149 loser1:
ff37ea55
JG
150 free ((void *)core_stacksec (abfd));
151 goto loser;
152 }
153 core_regsec (abfd) = (asection *) zalloc (sizeof (asection));
154 if (core_regsec (abfd) == NULL) {
ff37ea55
JG
155 free ((void *)core_datasec (abfd));
156 goto loser1;
157 }
158
159 core_stacksec (abfd)->name = ".stack";
160 core_datasec (abfd)->name = ".data";
161 core_regsec (abfd)->name = ".reg";
162
6a469027
JG
163 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
164 core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
165 core_regsec (abfd)->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
ff37ea55 166
1f29e30b
JG
167 core_datasec (abfd)->_raw_size = NBPG * u.u_dsize;
168 core_stacksec (abfd)->_raw_size = NBPG * u.u_ssize;
169 core_regsec (abfd)->_raw_size = NBPG * UPAGES; /* Larger than sizeof struct u */
ff37ea55
JG
170
171 /* What a hack... we'd like to steal it from the exec file,
172 since the upage does not seem to provide it. FIXME. */
9712c6e2
SG
173#ifdef HOST_DATA_START_ADDR
174 core_datasec (abfd)->vma = HOST_DATA_START_ADDR;
175#else
176 core_datasec (abfd)->vma = HOST_TEXT_START_ADDR + (NBPG * u.u_tsize);
177#endif
178 core_stacksec (abfd)->vma = HOST_STACK_END_ADDR - (NBPG * u.u_ssize);
637942e4
JG
179 /* This is tricky. As the "register section", we give them the entire
180 upage and stack. u.u_ar0 points to where "register 0" is stored.
181 There are two tricks with this, though. One is that the rest of the
182 registers might be at positive or negative (or both) displacements
183 from *u_ar0. The other is that u_ar0 is sometimes an absolute address
184 in kernel memory, and on other systems it is an offset from the beginning
185 of the `struct user'.
1f29e30b 186
637942e4
JG
187 As a practical matter, we don't know where the registers actually are,
188 so we have to pass the whole area to GDB. We encode the value of u_ar0
189 by setting the .regs section up so that its virtual memory address
190 0 is at the place pointed to by u_ar0 (by setting the vma of the start
191 of the section to -u_ar0). GDB uses this info to locate the regs,
192 using minor trickery to get around the offset-or-absolute-addr problem. */
193 core_regsec (abfd)->vma = 0 - (int) u.u_ar0;
ff37ea55
JG
194
195 core_datasec (abfd)->filepos = NBPG * UPAGES;
196 core_stacksec (abfd)->filepos = (NBPG * UPAGES) + NBPG * u.u_dsize;
1f29e30b 197 core_regsec (abfd)->filepos = 0; /* Register segment is the upage */
ff37ea55
JG
198
199 /* Align to word at least */
200 core_stacksec (abfd)->alignment_power = 2;
201 core_datasec (abfd)->alignment_power = 2;
202 core_regsec (abfd)->alignment_power = 2;
203
204 abfd->sections = core_stacksec (abfd);
205 core_stacksec (abfd)->next = core_datasec (abfd);
206 core_datasec (abfd)->next = core_regsec (abfd);
207 abfd->section_count = 3;
208
209 return abfd->xvec;
ff37ea55
JG
210}
211
212char *
213trad_unix_core_file_failing_command (abfd)
214 bfd *abfd;
215{
1f29e30b
JG
216#ifndef NO_CORE_COMMAND
217 char *com = abfd->tdata.trad_core_data->u.u_comm;
218 if (*com)
219 return com;
ff37ea55 220 else
1f29e30b 221#endif
ff37ea55
JG
222 return 0;
223}
224
7ed4093a 225/* ARGSUSED */
ff37ea55 226int
7ed4093a
SC
227trad_unix_core_file_failing_signal (ignore_abfd)
228 bfd *ignore_abfd;
ff37ea55 229{
31568a6f
JK
230#ifdef TRAD_UNIX_CORE_FILE_FAILING_SIGNAL
231 return TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(ignore_abfd);
232#else
ff37ea55 233 return -1; /* FIXME, where is it? */
31568a6f 234#endif
ff37ea55
JG
235}
236
7ed4093a 237/* ARGSUSED */
ff37ea55
JG
238boolean
239trad_unix_core_file_matches_executable_p (core_bfd, exec_bfd)
240 bfd *core_bfd, *exec_bfd;
241{
242 return true; /* FIXME, We have no way of telling at this point */
243}
6a469027
JG
244\f
245/* No archive file support via this BFD */
246#define trad_unix_openr_next_archived_file bfd_generic_openr_next_archived_file
247#define trad_unix_generic_stat_arch_elt bfd_generic_stat_arch_elt
248#define trad_unix_slurp_armap bfd_false
249#define trad_unix_slurp_extended_name_table bfd_true
1f29e30b
JG
250#define trad_unix_write_armap (boolean (*) PARAMS \
251 ((bfd *arch, unsigned int elength, struct orl *map, \
252 unsigned int orl_count, int stridx))) bfd_false
6a469027
JG
253#define trad_unix_truncate_arname bfd_dont_truncate_arname
254#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
255
256#define trad_unix_close_and_cleanup bfd_generic_close_and_cleanup
1f29e30b
JG
257#define trad_unix_set_section_contents (boolean (*) PARAMS \
258 ((bfd *abfd, asection *section, PTR data, file_ptr offset, \
259 bfd_size_type count))) bfd_false
6a469027 260#define trad_unix_get_section_contents bfd_generic_get_section_contents
1f29e30b
JG
261#define trad_unix_new_section_hook (boolean (*) PARAMS \
262 ((bfd *, sec_ptr))) bfd_true
6a469027 263#define trad_unix_get_symtab_upper_bound bfd_0u
1f29e30b
JG
264#define trad_unix_get_symtab (unsigned int (*) PARAMS \
265 ((bfd *, struct symbol_cache_entry **))) bfd_0u
266#define trad_unix_get_reloc_upper_bound (unsigned int (*) PARAMS \
267 ((bfd *, sec_ptr))) bfd_0u
268#define trad_unix_canonicalize_reloc (unsigned int (*) PARAMS \
269 ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u
270#define trad_unix_make_empty_symbol (struct symbol_cache_entry * \
31568a6f 271 (*) PARAMS ((bfd *))) bfd_false
1f29e30b
JG
272#define trad_unix_print_symbol (void (*) PARAMS \
273 ((bfd *, PTR, struct symbol_cache_entry *, \
274 bfd_print_symbol_type))) bfd_false
275#define trad_unix_get_lineno (alent * (*) PARAMS \
276 ((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr
277#define trad_unix_set_arch_mach (boolean (*) PARAMS \
0dc1bc8b 278 ((bfd *, enum bfd_architecture, unsigned long))) bfd_false
1f29e30b 279#define trad_unix_find_nearest_line (boolean (*) PARAMS \
0dc1bc8b 280 ((bfd *abfd, struct sec *section, \
6a469027
JG
281 struct symbol_cache_entry **symbols,bfd_vma offset, \
282 CONST char **file, CONST char **func, unsigned int *line))) bfd_false
1f29e30b 283#define trad_unix_sizeof_headers (int (*) PARAMS \
0dc1bc8b 284 ((bfd *, boolean))) bfd_0
6a469027
JG
285
286#define trad_unix_bfd_debug_info_start bfd_void
287#define trad_unix_bfd_debug_info_end bfd_void
1f29e30b 288#define trad_unix_bfd_debug_info_accumulate (void (*) PARAMS \
0dc1bc8b 289 ((bfd *, struct sec *))) bfd_void
1f29e30b
JG
290#define trad_unix_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
291#define trad_unix_bfd_relax_section bfd_generic_relax_section
0dc1bc8b
ILT
292#define trad_unix_bfd_seclet_link \
293 ((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false)
31568a6f
JK
294#define trad_unix_bfd_reloc_type_lookup \
295 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
296#define trad_unix_bfd_make_debug_symbol \
297 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
0dc1bc8b 298
637942e4
JG
299/* If somebody calls any byte-swapping routines, shoot them. */
300void
301swap_abort()
302{
303 abort(); /* This way doesn't require any declaration for ANSI to fuck up */
304}
1f29e30b
JG
305#define NO_GET ((bfd_vma (*) PARAMS (( bfd_byte *))) swap_abort )
306#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
6a469027 307
637942e4 308bfd_target trad_core_vec =
6a469027 309 {
637942e4 310 "trad-core",
6a469027
JG
311 bfd_target_unknown_flavour,
312 true, /* target byte order */
313 true, /* target headers byte order */
314 (HAS_RELOC | EXEC_P | /* object flags */
315 HAS_LINENO | HAS_DEBUG |
316 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
317 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
0dc1bc8b 318 0, /* symbol prefix */
6a469027
JG
319 ' ', /* ar_pad_char */
320 16, /* ar_max_namelen */
321 3, /* minimum alignment power */
31568a6f
JK
322 NO_GET, NO_GET, NO_PUT, /* 64 bit data */
323 NO_GET, NO_GET, NO_PUT, /* 32 bit data */
324 NO_GET, NO_GET, NO_PUT, /* 16 bit data */
325 NO_GET, NO_GET, NO_PUT, /* 64 bit hdrs */
326 NO_GET, NO_GET, NO_PUT, /* 32 bit hdrs */
327 NO_GET, NO_GET, NO_PUT, /* 16 bit hdrs */
328
329 { /* bfd_check_format */
330 _bfd_dummy_target, /* unknown format */
331 _bfd_dummy_target, /* object file */
332 _bfd_dummy_target, /* archive */
333 trad_unix_core_file_p /* a core file */
334 },
335 { /* bfd_set_format */
336 bfd_false, bfd_false,
337 bfd_false, bfd_false
338 },
339 { /* bfd_write_contents */
340 bfd_false, bfd_false,
341 bfd_false, bfd_false
342 },
6a469027 343
31568a6f
JK
344 JUMP_TABLE(trad_unix),
345 (PTR) 0 /* backend_data */
6a469027 346};
This page took 0.089036 seconds and 4 git commands to generate.