xref: /netbsd/external/gpl3/gdb/dist/bfd/netbsd-core.c (revision 0cfa55d4)
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