1377e23a2Schristos /* BFD back end for NetBSD style core files
2f72a8c67Schristos Copyright (C) 1988-2020 Free Software Foundation, Inc.
3377e23a2Schristos Written by Paul Kranenburg, EUR
4377e23a2Schristos
5377e23a2Schristos This file is part of BFD, the Binary File Descriptor library.
6377e23a2Schristos
7377e23a2Schristos This program is free software; you can redistribute it and/or modify
8377e23a2Schristos it under the terms of the GNU General Public License as published by
9377e23a2Schristos the Free Software Foundation; either version 3 of the License, or
10377e23a2Schristos (at your option) any later version.
11377e23a2Schristos
12377e23a2Schristos This program is distributed in the hope that it will be useful,
13377e23a2Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
14377e23a2Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15377e23a2Schristos GNU General Public License for more details.
16377e23a2Schristos
17377e23a2Schristos You should have received a copy of the GNU General Public License
18377e23a2Schristos along with this program; if not, write to the Free Software
19377e23a2Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20377e23a2Schristos MA 02110-1301, USA. */
21377e23a2Schristos
22377e23a2Schristos #include "sysdep.h"
23377e23a2Schristos #include "bfd.h"
24377e23a2Schristos #include "libbfd.h"
25377e23a2Schristos #include "libaout.h" /* BFD a.out internal data structures. */
26377e23a2Schristos
27377e23a2Schristos #include <sys/param.h>
28377e23a2Schristos #include <sys/dir.h>
29377e23a2Schristos #include <signal.h>
30377e23a2Schristos #include <sys/core.h>
31377e23a2Schristos
32377e23a2Schristos /* The machine ID for OpenBSD/sparc64 and older versions of
33377e23a2Schristos NetBSD/sparc64 overlaps with M_MIPS1. */
34377e23a2Schristos #define M_SPARC64_OPENBSD M_MIPS1
35377e23a2Schristos
36377e23a2Schristos /* Offset of StackGhost cookie within `struct md_coredump' on
37377e23a2Schristos OpenBSD/sparc. */
38377e23a2Schristos #define SPARC_WCOOKIE_OFFSET 344
39377e23a2Schristos
40377e23a2Schristos /* Offset of StackGhost cookie within `struct md_coredump' on
41377e23a2Schristos OpenBSD/sparc64. */
42377e23a2Schristos #define SPARC64_WCOOKIE_OFFSET 832
43377e23a2Schristos
44377e23a2Schristos #define netbsd_core_file_matches_executable_p generic_core_file_matches_executable_p
45377e23a2Schristos #define netbsd_core_file_pid _bfd_nocore_core_file_pid
46377e23a2Schristos
47377e23a2Schristos struct netbsd_core_struct
48377e23a2Schristos {
49377e23a2Schristos struct core core;
50377e23a2Schristos } *rawptr;
51377e23a2Schristos
52377e23a2Schristos /* Handle NetBSD-style core dump file. */
53377e23a2Schristos
54f72a8c67Schristos static bfd_cleanup
netbsd_core_file_p(bfd * abfd)55377e23a2Schristos netbsd_core_file_p (bfd *abfd)
56377e23a2Schristos {
57377e23a2Schristos int val;
58377e23a2Schristos unsigned i;
59377e23a2Schristos file_ptr offset;
60377e23a2Schristos asection *asect;
61377e23a2Schristos struct core core;
62377e23a2Schristos struct coreseg coreseg;
63f72a8c67Schristos size_t amt = sizeof core;
64377e23a2Schristos
65377e23a2Schristos val = bfd_bread (&core, amt, abfd);
66377e23a2Schristos if (val != sizeof core)
67377e23a2Schristos {
68377e23a2Schristos /* Too small to be a core file. */
69377e23a2Schristos bfd_set_error (bfd_error_wrong_format);
70377e23a2Schristos return 0;
71377e23a2Schristos }
72377e23a2Schristos
73377e23a2Schristos if (CORE_GETMAGIC (core) != COREMAGIC)
74377e23a2Schristos {
75377e23a2Schristos bfd_set_error (bfd_error_wrong_format);
76377e23a2Schristos return 0;
77377e23a2Schristos }
78377e23a2Schristos
79377e23a2Schristos amt = sizeof (struct netbsd_core_struct);
80377e23a2Schristos rawptr = (struct netbsd_core_struct *) bfd_zalloc (abfd, amt);
81377e23a2Schristos if (rawptr == NULL)
82377e23a2Schristos return 0;
83377e23a2Schristos
84377e23a2Schristos rawptr->core = core;
85377e23a2Schristos abfd->tdata.netbsd_core_data = rawptr;
86377e23a2Schristos
87377e23a2Schristos offset = core.c_hdrsize;
88377e23a2Schristos for (i = 0; i < core.c_nseg; i++)
89377e23a2Schristos {
90377e23a2Schristos const char *sname;
91377e23a2Schristos flagword flags;
92377e23a2Schristos
93377e23a2Schristos if (bfd_seek (abfd, offset, SEEK_SET) != 0)
94377e23a2Schristos goto punt;
95377e23a2Schristos
96377e23a2Schristos val = bfd_bread (&coreseg, sizeof coreseg, abfd);
97377e23a2Schristos if (val != sizeof coreseg)
98377e23a2Schristos {
99377e23a2Schristos bfd_set_error (bfd_error_file_truncated);
100377e23a2Schristos goto punt;
101377e23a2Schristos }
102377e23a2Schristos if (CORE_GETMAGIC (coreseg) != CORESEGMAGIC)
103377e23a2Schristos {
104377e23a2Schristos bfd_set_error (bfd_error_wrong_format);
105377e23a2Schristos goto punt;
106377e23a2Schristos }
107377e23a2Schristos
108377e23a2Schristos offset += core.c_seghdrsize;
109377e23a2Schristos
110377e23a2Schristos switch (CORE_GETFLAG (coreseg))
111377e23a2Schristos {
112377e23a2Schristos case CORE_CPU:
113377e23a2Schristos sname = ".reg";
114377e23a2Schristos flags = SEC_ALLOC + SEC_HAS_CONTENTS;
115377e23a2Schristos break;
116377e23a2Schristos case CORE_DATA:
117377e23a2Schristos sname = ".data";
118377e23a2Schristos flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
119377e23a2Schristos break;
120377e23a2Schristos case CORE_STACK:
121377e23a2Schristos sname = ".stack";
122377e23a2Schristos flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
123377e23a2Schristos break;
124377e23a2Schristos default:
125377e23a2Schristos sname = ".unknown";
126377e23a2Schristos flags = SEC_ALLOC + SEC_HAS_CONTENTS;
127377e23a2Schristos break;
128377e23a2Schristos }
129377e23a2Schristos asect = bfd_make_section_anyway_with_flags (abfd, sname, flags);
130377e23a2Schristos if (asect == NULL)
131377e23a2Schristos goto punt;
132377e23a2Schristos
133377e23a2Schristos asect->size = coreseg.c_size;
134377e23a2Schristos asect->vma = coreseg.c_addr;
135377e23a2Schristos asect->filepos = offset;
136377e23a2Schristos asect->alignment_power = 2;
137377e23a2Schristos
138377e23a2Schristos if (CORE_GETFLAG (coreseg) == CORE_CPU)
139377e23a2Schristos {
140377e23a2Schristos bfd_size_type wcookie_offset;
141377e23a2Schristos
142377e23a2Schristos switch (CORE_GETMID (core))
143377e23a2Schristos {
144377e23a2Schristos case M_SPARC_NETBSD:
145377e23a2Schristos wcookie_offset = SPARC_WCOOKIE_OFFSET;
146377e23a2Schristos break;
147377e23a2Schristos case M_SPARC64_OPENBSD:
148377e23a2Schristos wcookie_offset = SPARC64_WCOOKIE_OFFSET;
149377e23a2Schristos break;
150377e23a2Schristos default:
151377e23a2Schristos wcookie_offset = 0;
152377e23a2Schristos break;
153377e23a2Schristos }
154377e23a2Schristos
155377e23a2Schristos if (wcookie_offset > 0 && coreseg.c_size > wcookie_offset)
156377e23a2Schristos {
157377e23a2Schristos /* Truncate the .reg section. */
158377e23a2Schristos asect->size = wcookie_offset;
159377e23a2Schristos
160377e23a2Schristos /* And create the .wcookie section. */
161377e23a2Schristos flags = SEC_ALLOC + SEC_HAS_CONTENTS;
162377e23a2Schristos asect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
163377e23a2Schristos flags);
164377e23a2Schristos if (asect == NULL)
165377e23a2Schristos goto punt;
166377e23a2Schristos
167377e23a2Schristos asect->size = coreseg.c_size - wcookie_offset;
168377e23a2Schristos asect->vma = 0;
169377e23a2Schristos asect->filepos = offset + wcookie_offset;
170377e23a2Schristos asect->alignment_power = 2;
171377e23a2Schristos }
172377e23a2Schristos }
173377e23a2Schristos
174377e23a2Schristos offset += coreseg.c_size;
175377e23a2Schristos }
176377e23a2Schristos
177377e23a2Schristos /* Set architecture from machine ID. */
178377e23a2Schristos switch (CORE_GETMID (core))
179377e23a2Schristos {
180377e23a2Schristos case M_ALPHA_NETBSD:
181377e23a2Schristos bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
182377e23a2Schristos break;
183377e23a2Schristos
184377e23a2Schristos case M_ARM6_NETBSD:
185377e23a2Schristos bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_3);
186377e23a2Schristos break;
187377e23a2Schristos
188377e23a2Schristos case M_X86_64_NETBSD:
189377e23a2Schristos bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
190377e23a2Schristos break;
191377e23a2Schristos
192377e23a2Schristos case M_386_NETBSD:
193377e23a2Schristos bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386);
194377e23a2Schristos break;
195377e23a2Schristos
196377e23a2Schristos case M_68K_NETBSD:
197377e23a2Schristos case M_68K4K_NETBSD:
198377e23a2Schristos bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
199377e23a2Schristos break;
200377e23a2Schristos
201377e23a2Schristos case M_HPPA_OPENBSD:
202377e23a2Schristos bfd_default_set_arch_mach (abfd, bfd_arch_hppa, bfd_mach_hppa11);
203377e23a2Schristos break;
204377e23a2Schristos
205377e23a2Schristos case M_POWERPC_NETBSD:
206377e23a2Schristos bfd_default_set_arch_mach (abfd, bfd_arch_powerpc, bfd_mach_ppc);
207377e23a2Schristos break;
208377e23a2Schristos
209377e23a2Schristos case M_SPARC_NETBSD:
210377e23a2Schristos bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc);
211377e23a2Schristos break;
212377e23a2Schristos
213377e23a2Schristos case M_SPARC64_NETBSD:
214377e23a2Schristos case M_SPARC64_OPENBSD:
215377e23a2Schristos bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v9);
216377e23a2Schristos break;
217377e23a2Schristos
218377e23a2Schristos case M_VAX_NETBSD:
219377e23a2Schristos case M_VAX4K_NETBSD:
220377e23a2Schristos bfd_default_set_arch_mach (abfd, bfd_arch_vax, 0);
221377e23a2Schristos break;
222377e23a2Schristos }
223377e23a2Schristos
224377e23a2Schristos /* OK, we believe you. You're a core file (sure, sure). */
225f72a8c67Schristos return _bfd_no_cleanup;
226377e23a2Schristos
227377e23a2Schristos punt:
228377e23a2Schristos bfd_release (abfd, abfd->tdata.any);
229377e23a2Schristos abfd->tdata.any = NULL;
230377e23a2Schristos bfd_section_list_clear (abfd);
231377e23a2Schristos return 0;
232377e23a2Schristos }
233377e23a2Schristos
234377e23a2Schristos static char*
netbsd_core_file_failing_command(bfd * abfd)235377e23a2Schristos netbsd_core_file_failing_command (bfd *abfd)
236377e23a2Schristos {
237377e23a2Schristos /*return core_command (abfd);*/
238377e23a2Schristos return abfd->tdata.netbsd_core_data->core.c_name;
239377e23a2Schristos }
240377e23a2Schristos
241377e23a2Schristos static int
netbsd_core_file_failing_signal(bfd * abfd)242377e23a2Schristos netbsd_core_file_failing_signal (bfd *abfd)
243377e23a2Schristos {
244377e23a2Schristos /*return core_signal (abfd);*/
245377e23a2Schristos return abfd->tdata.netbsd_core_data->core.c_signo;
246377e23a2Schristos }
247377e23a2Schristos
248377e23a2Schristos /* If somebody calls any byte-swapping routines, shoot them. */
249377e23a2Schristos
250377e23a2Schristos static void
swap_abort(void)251377e23a2Schristos swap_abort (void)
252377e23a2Schristos {
253377e23a2Schristos /* This way doesn't require any declaration for ANSI to fuck up. */
254377e23a2Schristos abort ();
255377e23a2Schristos }
256377e23a2Schristos
257377e23a2Schristos #define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
258377e23a2Schristos #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
259377e23a2Schristos #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
260377e23a2Schristos #define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
261377e23a2Schristos #define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
262377e23a2Schristos #define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
263377e23a2Schristos
2649ecd38dbSchristos const bfd_target core_netbsd_vec =
265377e23a2Schristos {
266377e23a2Schristos "netbsd-core",
267377e23a2Schristos bfd_target_unknown_flavour,
268377e23a2Schristos BFD_ENDIAN_UNKNOWN, /* Target byte order. */
269377e23a2Schristos BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */
270377e23a2Schristos (HAS_RELOC | EXEC_P | /* Object flags. */
271377e23a2Schristos HAS_LINENO | HAS_DEBUG |
272377e23a2Schristos HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
273377e23a2Schristos (SEC_HAS_CONTENTS | /* Section flags. */
274377e23a2Schristos SEC_ALLOC | SEC_LOAD | SEC_RELOC),
275377e23a2Schristos 0, /* Symbol prefix. */
276377e23a2Schristos ' ', /* ar_pad_char. */
277377e23a2Schristos 16, /* ar_max_namelen. */
278*0cfa55d4Skamil 0, /* Match priority. */
279377e23a2Schristos NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data. */
280377e23a2Schristos NO_GET, NO_GETS, NO_PUT, /* 32 bit data. */
281377e23a2Schristos NO_GET, NO_GETS, NO_PUT, /* 16 bit data. */
282377e23a2Schristos NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs. */
283377e23a2Schristos NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs. */
284377e23a2Schristos NO_GET, NO_GETS, NO_PUT, /* 16 bit hdrs. */
285377e23a2Schristos
286377e23a2Schristos { /* bfd_check_format. */
287377e23a2Schristos _bfd_dummy_target, /* Unknown format. */
288377e23a2Schristos _bfd_dummy_target, /* Object file. */
289377e23a2Schristos _bfd_dummy_target, /* Archive. */
290377e23a2Schristos netbsd_core_file_p /* A core file. */
291377e23a2Schristos },
292377e23a2Schristos { /* bfd_set_format. */
293f8d82957Schristos _bfd_bool_bfd_false_error,
294f8d82957Schristos _bfd_bool_bfd_false_error,
295f8d82957Schristos _bfd_bool_bfd_false_error,
296f8d82957Schristos _bfd_bool_bfd_false_error
297377e23a2Schristos },
298377e23a2Schristos { /* bfd_write_contents. */
299f8d82957Schristos _bfd_bool_bfd_false_error,
300f8d82957Schristos _bfd_bool_bfd_false_error,
301f8d82957Schristos _bfd_bool_bfd_false_error,
302f8d82957Schristos _bfd_bool_bfd_false_error
303377e23a2Schristos },
304377e23a2Schristos
305377e23a2Schristos BFD_JUMP_TABLE_GENERIC (_bfd_generic),
306377e23a2Schristos BFD_JUMP_TABLE_COPY (_bfd_generic),
307377e23a2Schristos BFD_JUMP_TABLE_CORE (netbsd),
308377e23a2Schristos BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
309377e23a2Schristos BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
310377e23a2Schristos BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
311377e23a2Schristos BFD_JUMP_TABLE_WRITE (_bfd_generic),
312377e23a2Schristos BFD_JUMP_TABLE_LINK (_bfd_nolink),
313377e23a2Schristos BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
314377e23a2Schristos
315377e23a2Schristos NULL,
316377e23a2Schristos
3177c36a932Schristos NULL /* Backend_data. */
318377e23a2Schristos };
319