gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / sco5-core.c
CommitLineData
252b5132 1/* BFD back end for SCO5 core files (U-area and raw sections)
b3adc24a 2 Copyright (C) 1998-2020 Free Software Foundation, Inc.
252b5132
RH
3 Written by Jouke Numan <jnuman@hiscom.nl>
4
cd123cb7
NC
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
252b5132 21
252b5132 22#include "sysdep.h"
3db64b00 23#include "bfd.h"
252b5132 24#include "libbfd.h"
b34976b6 25#include "libaout.h" /* BFD a.out internal data structures */
252b5132
RH
26
27#include <stdio.h>
28#include <sys/types.h>
29#include <sys/param.h>
30#include <sys/dir.h>
31#include <signal.h>
32
b34976b6 33#include <sys/user.h> /* After a.out.h */
9b818146 34#ifdef SCO5_CORE
252b5132
RH
35#include <sys/paccess.h>
36#include <sys/region.h>
9b818146 37#endif
252b5132
RH
38
39struct sco5_core_struct
40{
41 struct user u;
42};
43
44/* forward declarations */
45
69d246d9 46#define sco5_core_file_matches_executable_p generic_core_file_matches_executable_p
261b8d08 47#define sco5_core_file_pid _bfd_nocore_core_file_pid
252b5132
RH
48
49static asection *
2c3fc389
NC
50make_bfd_asection (bfd *abfd,
51 const char *name,
52 flagword flags,
53 bfd_size_type size,
54 bfd_vma vma,
55 file_ptr filepos)
252b5132
RH
56{
57 asection *asect;
58
117ed4f8 59 asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
252b5132
RH
60 if (!asect)
61 return NULL;
eea6121a 62 asect->size = size;
252b5132
RH
63 asect->vma = vma;
64 asect->filepos = filepos;
65 asect->alignment_power = 2;
66
67 return asect;
68}
69
252b5132 70static struct user *
2c3fc389 71read_uarea (bfd *abfd, int filepos)
252b5132
RH
72{
73 struct sco5_core_struct *rawptr;
986f0783 74 size_t amt = sizeof (struct sco5_core_struct);
252b5132 75
dc810e39 76 rawptr = (struct sco5_core_struct *) bfd_zmalloc (amt);
252b5132
RH
77 if (rawptr == NULL)
78 return NULL;
79
80 abfd->tdata.sco5_core_data = rawptr;
81
dc810e39
AM
82 if (bfd_seek (abfd, (file_ptr) filepos, SEEK_SET) != 0
83 || bfd_bread ((void *) &rawptr->u, (bfd_size_type) sizeof rawptr->u,
84 abfd) != sizeof rawptr->u)
252b5132
RH
85 {
86 bfd_set_error (bfd_error_wrong_format);
87 return NULL;
88 }
89
90 /* Sanity check perhaps??? */
7b82c249 91 if (rawptr->u.u_dsize > 0x1000000) /* Remember, it's in pages... */
252b5132
RH
92 {
93 bfd_set_error (bfd_error_wrong_format);
94 return NULL;
95 }
96 if (rawptr->u.u_ssize > 0x1000000)
97 {
98 bfd_set_error (bfd_error_wrong_format);
99 return NULL;
100 }
101 return &rawptr->u;
102}
103
40b35c78 104bfd_cleanup
2c3fc389 105sco5_core_file_p (bfd *abfd)
252b5132
RH
106{
107 int coffset_siz, val, nsecs, cheadoffs;
108 int coresize;
109 struct user *u;
110 struct coreoffsets coffsets;
111 struct coresecthead chead;
112 char *secname;
113 flagword flags;
114
33216455 115 /* Read coreoffsets region at end of core (see core(FP)). */
252b5132
RH
116
117 {
252b5132 118 struct stat statbuf;
33216455 119
b677b8c0 120 if (bfd_stat (abfd, &statbuf) < 0)
3dff57e8 121 return NULL;
b677b8c0 122
252b5132
RH
123 coresize = statbuf.st_size;
124 }
125 /* Last long in core is sizeof struct coreoffsets, read it */
dc810e39
AM
126 if ((bfd_seek (abfd, (file_ptr) (coresize - sizeof coffset_siz),
127 SEEK_SET) != 0)
128 || bfd_bread ((void *) &coffset_siz, (bfd_size_type) sizeof coffset_siz,
129 abfd) != sizeof coffset_siz)
252b5132 130 {
7b82c249 131 bfd_set_error (bfd_error_wrong_format);
252b5132
RH
132 return NULL;
133 }
134
135 /* Use it to seek start of coreoffsets region, read it and determine
136 validity */
dc810e39
AM
137 if ((bfd_seek (abfd, (file_ptr) (coresize - coffset_siz), SEEK_SET) != 0)
138 || (bfd_bread ((void *) &coffsets, (bfd_size_type) sizeof coffsets, abfd)
252b5132
RH
139 != sizeof coffsets)
140 || ((coffsets.u_info != 1) && (coffsets.u_info != C_VERSION)))
141 {
7b82c249 142 bfd_set_error (bfd_error_wrong_format);
252b5132
RH
143 return NULL;
144 }
145
7b82c249
KH
146 if (coffsets.u_info == 1)
147 {
252b5132
RH
148 /* Old version, no section heads, read info from user struct */
149
9e7b37b3 150 u = read_uarea (abfd, coffsets.u_user);
252b5132 151 if (! u)
9e7b37b3 152 goto fail;
252b5132 153
7b82c249 154 if (!make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS,
b34976b6
AM
155 (bfd_size_type) coffsets.u_usize,
156 0 - (bfd_vma) u->u_ar0,
157 (file_ptr) coffsets.u_user))
9e7b37b3 158 goto fail;
7b82c249
KH
159
160 if (!make_bfd_asection (abfd, ".data",
252b5132 161 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
b34976b6 162 ((bfd_size_type) u->u_exdata.ux_dsize
252b5132 163 + u->u_exdata.ux_bsize),
b34976b6
AM
164 (bfd_vma) u->u_exdata.ux_datorg,
165 (file_ptr) coffsets.u_data))
9e7b37b3 166 goto fail;
7b82c249
KH
167
168 if (!make_bfd_asection (abfd, ".stack",
169 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
b34976b6
AM
170 (bfd_size_type) u->u_ssize * NBPC,
171 (bfd_vma) u->u_sub,
172 (file_ptr) coffsets.u_stack))
9e7b37b3 173 goto fail;
252b5132 174
40b35c78 175 return _bfd_no_cleanup; /* Done for version 1 */
7b82c249 176 }
252b5132
RH
177
178 /* Immediately before coreoffsets region is a long with offset in core
179 to first coresecthead (CORES_OFFSETS), the long before this is the
180 number of section heads in the list. Read both longs and read the
181 coresecthead and check its validity */
7b82c249
KH
182
183 if ((bfd_seek (abfd,
dc810e39 184 (file_ptr) (coresize - coffset_siz - 2 * sizeof coffset_siz),
252b5132 185 SEEK_SET) != 0)
dc810e39
AM
186 || (bfd_bread ((void *) &nsecs, (bfd_size_type) sizeof nsecs, abfd)
187 != sizeof nsecs)
188 || (bfd_bread ((void *) &cheadoffs, (bfd_size_type) sizeof cheadoffs,
189 abfd) != sizeof cheadoffs)
190 || (bfd_seek (abfd, (file_ptr) cheadoffs, SEEK_SET) != 0)
191 || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd)
192 != sizeof chead)
252b5132
RH
193 || (chead.cs_stype != CORES_OFFSETS)
194 || (chead.cs_x.csx_magic != COREMAGIC_NUMBER))
195 {
196 bfd_set_error (bfd_error_wrong_format);
9e7b37b3 197 goto fail;
252b5132
RH
198 }
199
200 /* OK, we believe you. You're a core file (sure, sure). */
201
202 /* Now loop over all regions and map them */
203 nsecs--; /* We've seen CORES_OFFSETS already */
7b82c249 204 for (; nsecs; nsecs--)
252b5132 205 {
dc810e39
AM
206 if ((bfd_seek (abfd, (file_ptr) chead.cs_hseek, SEEK_SET) != 0)
207 || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd)
208 != sizeof chead))
b34976b6
AM
209 {
210 bfd_set_error (bfd_error_wrong_format);
9e7b37b3 211 goto fail;
b34976b6 212 }
252b5132 213
7b82c249 214 switch (chead.cs_stype)
252b5132
RH
215 {
216 case CORES_MAGIC: /* Core header, check magic */
217 if (chead.cs_x.csx_magic != COREMAGIC_NUMBER)
218 {
219 bfd_set_error (bfd_error_wrong_format);
9e7b37b3 220 goto fail;
252b5132
RH
221 }
222 secname = NULL;
223 nsecs++; /* MAGIC not in section cnt!*/
224 break;
225 case CORES_UAREA: /* U-area, read in tdata */
9e7b37b3 226 u = read_uarea (abfd, chead.cs_sseek);
252b5132 227 if (! u)
9e7b37b3 228 goto fail;
252b5132 229
b34976b6 230 /* This is tricky. As the "register section", we give them
252b5132
RH
231 the entire upage and stack. u.u_ar0 points to where
232 "register 0" is stored. There are two tricks with this,
233 though. One is that the rest of the registers might be
234 at positive or negative (or both) displacements from
235 *u_ar0. The other is that u_ar0 is sometimes an absolute
236 address in kernel memory, and on other systems it is an
237 offset from the beginning of the `struct user'.
7b82c249 238
252b5132
RH
239 As a practical matter, we don't know where the registers
240 actually are, so we have to pass the whole area to GDB.
241 We encode the value of u_ar0 by setting the .regs section
242 up so that its virtual memory address 0 is at the place
243 pointed to by u_ar0 (by setting the vma of the start of
244 the section to -u_ar0). GDB uses this info to locate the
245 regs, using minor trickery to get around the
7b82c249 246 offset-or-absolute-addr problem. */
252b5132
RH
247
248 chead.cs_vaddr = 0 - (bfd_vma) u->u_ar0;
249
b34976b6
AM
250 secname = ".reg";
251 flags = SEC_HAS_CONTENTS;
252b5132 252
b34976b6 253 break;
252b5132
RH
254 case CORES_PREGION: /* A program region, map it */
255 switch (chead.cs_x.csx_preg.csxp_rtyp)
256 {
257 case PT_DATA:
b34976b6 258 secname = ".data"; /* Data region. */
252b5132
RH
259 break;
260 case PT_STACK:
b34976b6 261 secname = ".stack"; /* Stack region. */
252b5132
RH
262 break;
263 case PT_SHMEM:
b34976b6 264 secname = ".shmem"; /* Shared memory */
252b5132
RH
265 break;
266 case PT_LIBDAT:
b34976b6 267 secname = ".libdat"; /* Shared library data */
252b5132
RH
268 break;
269 case PT_V86:
b34976b6 270 secname = ".virt86"; /* Virtual 8086 mode */
252b5132
RH
271 break;
272 case PT_SHFIL:
b34976b6 273 secname = ".mmfile"; /* Memory mapped file */
252b5132
RH
274 break;
275 case PT_XDATA0:
b34976b6 276 secname = ".Xdat0"; /* XENIX data region, virtual 0 */
252b5132
RH
277 break;
278 default:
279 secname = "";
280 }
281 flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
282 break;
283 case CORES_PROC: /* struct proc */
284 case CORES_ITIMER: /* interval timers */
285 case CORES_SCOUTSNAME: /* struct scoutsname */
286 secname = NULL; /* Ignore these */
287 break;
b34976b6 288 default:
4eca0228
AM
289 _bfd_error_handler ("Unhandled SCO core file section type %d\n",
290 chead.cs_stype);
b34976b6
AM
291 continue;
292 }
252b5132
RH
293
294 if (secname
295 && !make_bfd_asection (abfd, secname, flags,
296 (bfd_size_type) chead.cs_vsize,
297 (bfd_vma) chead.cs_vaddr,
298 (file_ptr) chead.cs_sseek))
9e7b37b3 299 goto fail;
252b5132
RH
300
301 }
302
601b73d5 303 return _bfd_no_cleanup;
252b5132 304
9e7b37b3
AM
305 fail:
306 if (abfd->tdata.any)
307 {
308 bfd_release (abfd, abfd->tdata.any);
309 abfd->tdata.any = NULL;
310 }
311 bfd_section_list_clear (abfd);
312 return NULL;
252b5132
RH
313}
314
315char *
2c3fc389 316sco5_core_file_failing_command (bfd *abfd)
252b5132
RH
317{
318 char *com = abfd->tdata.sco5_core_data->u.u_comm;
319 if (*com)
320 return com;
321 else
322 return NULL;
323}
324
252b5132 325int
2c3fc389 326sco5_core_file_failing_signal (bfd *ignore_abfd)
252b5132 327{
7b82c249
KH
328 return ((ignore_abfd->tdata.sco5_core_data->u.u_sysabort != 0)
329 ? ignore_abfd->tdata.sco5_core_data->u.u_sysabort
252b5132
RH
330 : -1);
331}
332
252b5132
RH
333/* If somebody calls any byte-swapping routines, shoot them. */
334static void
2c3fc389 335swap_abort (void)
252b5132 336{
7b82c249 337 abort (); /* This way doesn't require any declaration for ANSI to fuck up */
252b5132 338}
8ce8c090 339
edeb6e24
AM
340#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
341#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
342#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
8ce8c090
AM
343#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
344#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
345#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
252b5132 346
6d00b590 347const bfd_target core_sco5_vec =
252b5132
RH
348 {
349 "sco5-core",
350 bfd_target_unknown_flavour,
b34976b6
AM
351 BFD_ENDIAN_LITTLE, /* target byte order */
352 BFD_ENDIAN_LITTLE, /* target headers byte order */
353 (HAS_RELOC | EXEC_P | /* object flags */
252b5132
RH
354 HAS_LINENO | HAS_DEBUG |
355 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
356 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
d3aeb6ee
AM
357 0, /* symbol prefix */
358 ' ', /* ar_pad_char */
359 16, /* ar_max_namelen */
360 0, /* match priority. */
8ce8c090 361 NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
edeb6e24
AM
362 NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
363 NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
8ce8c090 364 NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
edeb6e24
AM
365 NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
366 NO_GET, NO_GETS, NO_PUT, /* 16 bit hdrs */
b34976b6
AM
367
368 { /* bfd_check_format */
8ce8c090
AM
369 _bfd_dummy_target, /* unknown format */
370 _bfd_dummy_target, /* object file */
371 _bfd_dummy_target, /* archive */
372 sco5_core_file_p /* a core file */
252b5132 373 },
b34976b6 374 { /* bfd_set_format */
40b35c78
AM
375 _bfd_bool_bfd_false_error,
376 _bfd_bool_bfd_false_error,
377 _bfd_bool_bfd_false_error,
378 _bfd_bool_bfd_false_error
252b5132 379 },
b34976b6 380 { /* bfd_write_contents */
40b35c78
AM
381 _bfd_bool_bfd_false_error,
382 _bfd_bool_bfd_false_error,
383 _bfd_bool_bfd_false_error,
384 _bfd_bool_bfd_false_error
252b5132
RH
385 },
386
3f3c5c34
AM
387 BFD_JUMP_TABLE_GENERIC (_bfd_generic),
388 BFD_JUMP_TABLE_COPY (_bfd_generic),
389 BFD_JUMP_TABLE_CORE (sco5),
390 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
391 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
392 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
393 BFD_JUMP_TABLE_WRITE (_bfd_generic),
394 BFD_JUMP_TABLE_LINK (_bfd_nolink),
395 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
252b5132 396
c3c89269 397 NULL,
7b82c249 398
2c3fc389 399 NULL /* backend_data */
8ce8c090 400 };
This page took 1.156136 seconds and 4 git commands to generate.