xref: /netbsd-src/external/gpl3/binutils.old/dist/bfd/netbsd-core.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
175fd0b74Schristos /* BFD back end for NetBSD style core files
2*e992f068Schristos    Copyright (C) 1988-2022 Free Software Foundation, Inc.
375fd0b74Schristos    Written by Paul Kranenburg, EUR
475fd0b74Schristos 
575fd0b74Schristos    This file is part of BFD, the Binary File Descriptor library.
675fd0b74Schristos 
775fd0b74Schristos    This program is free software; you can redistribute it and/or modify
875fd0b74Schristos    it under the terms of the GNU General Public License as published by
975fd0b74Schristos    the Free Software Foundation; either version 3 of the License, or
1075fd0b74Schristos    (at your option) any later version.
1175fd0b74Schristos 
1275fd0b74Schristos    This program is distributed in the hope that it will be useful,
1375fd0b74Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1475fd0b74Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1575fd0b74Schristos    GNU General Public License for more details.
1675fd0b74Schristos 
1775fd0b74Schristos    You should have received a copy of the GNU General Public License
1875fd0b74Schristos    along with this program; if not, write to the Free Software
1975fd0b74Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2075fd0b74Schristos    MA 02110-1301, USA.  */
2175fd0b74Schristos 
2275fd0b74Schristos #include "sysdep.h"
2375fd0b74Schristos #include "bfd.h"
2475fd0b74Schristos #include "libbfd.h"
2575fd0b74Schristos #include "libaout.h"	       /* BFD a.out internal data structures.  */
2675fd0b74Schristos 
2775fd0b74Schristos #include <sys/param.h>
2875fd0b74Schristos #include <sys/dir.h>
2975fd0b74Schristos #include <signal.h>
3075fd0b74Schristos #include <sys/core.h>
3175fd0b74Schristos 
3275fd0b74Schristos /* The machine ID for OpenBSD/sparc64 and older versions of
3375fd0b74Schristos    NetBSD/sparc64 overlaps with M_MIPS1.  */
3475fd0b74Schristos #define M_SPARC64_OPENBSD	M_MIPS1
3575fd0b74Schristos 
3675fd0b74Schristos /* Offset of StackGhost cookie within `struct md_coredump' on
3775fd0b74Schristos    OpenBSD/sparc.  */
3875fd0b74Schristos #define SPARC_WCOOKIE_OFFSET	344
3975fd0b74Schristos 
4075fd0b74Schristos /* Offset of StackGhost cookie within `struct md_coredump' on
4175fd0b74Schristos    OpenBSD/sparc64.  */
4275fd0b74Schristos #define SPARC64_WCOOKIE_OFFSET	832
4375fd0b74Schristos 
4475fd0b74Schristos #define netbsd_core_file_matches_executable_p generic_core_file_matches_executable_p
4575fd0b74Schristos #define netbsd_core_file_pid _bfd_nocore_core_file_pid
4675fd0b74Schristos 
4775fd0b74Schristos struct netbsd_core_struct
4875fd0b74Schristos {
4975fd0b74Schristos   struct core core;
5075fd0b74Schristos } *rawptr;
5175fd0b74Schristos 
5275fd0b74Schristos /* Handle NetBSD-style core dump file.  */
5375fd0b74Schristos 
54*e992f068Schristos static bfd_cleanup
netbsd_core_file_p(bfd * abfd)5575fd0b74Schristos netbsd_core_file_p (bfd *abfd)
5675fd0b74Schristos {
5775fd0b74Schristos   int val;
5875fd0b74Schristos   unsigned i;
5975fd0b74Schristos   file_ptr offset;
6075fd0b74Schristos   asection *asect;
6175fd0b74Schristos   struct core core;
6275fd0b74Schristos   struct coreseg coreseg;
63*e992f068Schristos   size_t amt = sizeof core;
6475fd0b74Schristos 
6575fd0b74Schristos   val = bfd_bread (&core, amt, abfd);
6675fd0b74Schristos   if (val != sizeof core)
6775fd0b74Schristos     {
6875fd0b74Schristos       /* Too small to be a core file.  */
6975fd0b74Schristos       bfd_set_error (bfd_error_wrong_format);
7075fd0b74Schristos       return 0;
7175fd0b74Schristos     }
7275fd0b74Schristos 
7375fd0b74Schristos   if (CORE_GETMAGIC (core) != COREMAGIC)
7475fd0b74Schristos     {
7575fd0b74Schristos       bfd_set_error (bfd_error_wrong_format);
7675fd0b74Schristos       return 0;
7775fd0b74Schristos     }
7875fd0b74Schristos 
7975fd0b74Schristos   amt = sizeof (struct netbsd_core_struct);
8075fd0b74Schristos   rawptr = (struct netbsd_core_struct *) bfd_zalloc (abfd, amt);
8175fd0b74Schristos   if (rawptr == NULL)
8275fd0b74Schristos     return 0;
8375fd0b74Schristos 
8475fd0b74Schristos   rawptr->core = core;
8575fd0b74Schristos   abfd->tdata.netbsd_core_data = rawptr;
8675fd0b74Schristos 
8775fd0b74Schristos   offset = core.c_hdrsize;
8875fd0b74Schristos   for (i = 0; i < core.c_nseg; i++)
8975fd0b74Schristos     {
9075fd0b74Schristos       const char *sname;
9175fd0b74Schristos       flagword flags;
9275fd0b74Schristos 
9375fd0b74Schristos       if (bfd_seek (abfd, offset, SEEK_SET) != 0)
9475fd0b74Schristos 	goto punt;
9575fd0b74Schristos 
9675fd0b74Schristos       val = bfd_bread (&coreseg, sizeof coreseg, abfd);
9775fd0b74Schristos       if (val != sizeof coreseg)
9875fd0b74Schristos 	{
9975fd0b74Schristos 	  bfd_set_error (bfd_error_file_truncated);
10075fd0b74Schristos 	  goto punt;
10175fd0b74Schristos 	}
10275fd0b74Schristos       if (CORE_GETMAGIC (coreseg) != CORESEGMAGIC)
10375fd0b74Schristos 	{
10475fd0b74Schristos 	  bfd_set_error (bfd_error_wrong_format);
10575fd0b74Schristos 	  goto punt;
10675fd0b74Schristos 	}
10775fd0b74Schristos 
10875fd0b74Schristos       offset += core.c_seghdrsize;
10975fd0b74Schristos 
11075fd0b74Schristos       switch (CORE_GETFLAG (coreseg))
11175fd0b74Schristos 	{
11275fd0b74Schristos 	case CORE_CPU:
11375fd0b74Schristos 	  sname = ".reg";
11475fd0b74Schristos 	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
11575fd0b74Schristos 	  break;
11675fd0b74Schristos 	case CORE_DATA:
11775fd0b74Schristos 	  sname = ".data";
11875fd0b74Schristos 	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
11975fd0b74Schristos 	  break;
12075fd0b74Schristos 	case CORE_STACK:
12175fd0b74Schristos 	  sname = ".stack";
12275fd0b74Schristos 	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
12375fd0b74Schristos 	  break;
12475fd0b74Schristos 	default:
12575fd0b74Schristos 	  sname = ".unknown";
12675fd0b74Schristos 	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
12775fd0b74Schristos 	  break;
12875fd0b74Schristos 	}
12975fd0b74Schristos       asect = bfd_make_section_anyway_with_flags (abfd, sname, flags);
13075fd0b74Schristos       if (asect == NULL)
13175fd0b74Schristos 	goto punt;
13275fd0b74Schristos 
13375fd0b74Schristos       asect->size = coreseg.c_size;
13475fd0b74Schristos       asect->vma = coreseg.c_addr;
13575fd0b74Schristos       asect->filepos = offset;
13675fd0b74Schristos       asect->alignment_power = 2;
13775fd0b74Schristos 
13875fd0b74Schristos       if (CORE_GETFLAG (coreseg) == CORE_CPU)
13975fd0b74Schristos 	{
14075fd0b74Schristos 	  bfd_size_type wcookie_offset;
14175fd0b74Schristos 
14275fd0b74Schristos 	  switch (CORE_GETMID (core))
14375fd0b74Schristos 	    {
14475fd0b74Schristos 	    case M_SPARC_NETBSD:
14575fd0b74Schristos 	      wcookie_offset = SPARC_WCOOKIE_OFFSET;
14675fd0b74Schristos 	      break;
14775fd0b74Schristos 	    case M_SPARC64_OPENBSD:
14875fd0b74Schristos 	      wcookie_offset = SPARC64_WCOOKIE_OFFSET;
14975fd0b74Schristos 	      break;
15075fd0b74Schristos 	    default:
15175fd0b74Schristos 	      wcookie_offset = 0;
15275fd0b74Schristos 	      break;
15375fd0b74Schristos 	    }
15475fd0b74Schristos 
15575fd0b74Schristos 	  if (wcookie_offset > 0 && coreseg.c_size > wcookie_offset)
15675fd0b74Schristos 	    {
15775fd0b74Schristos 	      /* Truncate the .reg section.  */
15875fd0b74Schristos 	      asect->size = wcookie_offset;
15975fd0b74Schristos 
16075fd0b74Schristos 	      /* And create the .wcookie section.  */
16175fd0b74Schristos 	      flags = SEC_ALLOC + SEC_HAS_CONTENTS;
16275fd0b74Schristos 	      asect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
16375fd0b74Schristos 							  flags);
16475fd0b74Schristos 	      if (asect == NULL)
16575fd0b74Schristos 		goto punt;
16675fd0b74Schristos 
16775fd0b74Schristos 	      asect->size = coreseg.c_size - wcookie_offset;
16875fd0b74Schristos 	      asect->vma = 0;
16975fd0b74Schristos 	      asect->filepos = offset + wcookie_offset;
17075fd0b74Schristos 	      asect->alignment_power = 2;
17175fd0b74Schristos 	    }
17275fd0b74Schristos 	}
17375fd0b74Schristos 
17475fd0b74Schristos       offset += coreseg.c_size;
17575fd0b74Schristos     }
17675fd0b74Schristos 
17775fd0b74Schristos   /* Set architecture from machine ID.  */
17875fd0b74Schristos   switch (CORE_GETMID (core))
17975fd0b74Schristos     {
18075fd0b74Schristos     case M_ALPHA_NETBSD:
18175fd0b74Schristos       bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
18275fd0b74Schristos       break;
18375fd0b74Schristos 
18475fd0b74Schristos     case M_ARM6_NETBSD:
18575fd0b74Schristos       bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_3);
18675fd0b74Schristos       break;
18775fd0b74Schristos 
18875fd0b74Schristos     case M_X86_64_NETBSD:
18975fd0b74Schristos       bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
19075fd0b74Schristos       break;
19175fd0b74Schristos 
19275fd0b74Schristos     case M_386_NETBSD:
19375fd0b74Schristos       bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386);
19475fd0b74Schristos       break;
19575fd0b74Schristos 
19675fd0b74Schristos     case M_68K_NETBSD:
19775fd0b74Schristos     case M_68K4K_NETBSD:
19875fd0b74Schristos       bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
19975fd0b74Schristos       break;
20075fd0b74Schristos 
20175fd0b74Schristos     case M_HPPA_OPENBSD:
20275fd0b74Schristos       bfd_default_set_arch_mach (abfd, bfd_arch_hppa, bfd_mach_hppa11);
20375fd0b74Schristos       break;
20475fd0b74Schristos 
20575fd0b74Schristos     case M_POWERPC_NETBSD:
20675fd0b74Schristos       bfd_default_set_arch_mach (abfd, bfd_arch_powerpc, bfd_mach_ppc);
20775fd0b74Schristos       break;
20875fd0b74Schristos 
20975fd0b74Schristos     case M_SPARC_NETBSD:
21075fd0b74Schristos       bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc);
21175fd0b74Schristos       break;
21275fd0b74Schristos 
21375fd0b74Schristos     case M_SPARC64_NETBSD:
21475fd0b74Schristos     case M_SPARC64_OPENBSD:
21575fd0b74Schristos       bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v9);
21675fd0b74Schristos       break;
21775fd0b74Schristos 
21875fd0b74Schristos     case M_VAX_NETBSD:
21975fd0b74Schristos     case M_VAX4K_NETBSD:
22075fd0b74Schristos       bfd_default_set_arch_mach (abfd, bfd_arch_vax, 0);
22175fd0b74Schristos       break;
22275fd0b74Schristos     }
22375fd0b74Schristos 
22475fd0b74Schristos   /* OK, we believe you.  You're a core file (sure, sure).  */
225*e992f068Schristos   return _bfd_no_cleanup;
22675fd0b74Schristos 
22775fd0b74Schristos  punt:
22875fd0b74Schristos   bfd_release (abfd, abfd->tdata.any);
22975fd0b74Schristos   abfd->tdata.any = NULL;
23075fd0b74Schristos   bfd_section_list_clear (abfd);
23175fd0b74Schristos   return 0;
23275fd0b74Schristos }
23375fd0b74Schristos 
23475fd0b74Schristos static char*
netbsd_core_file_failing_command(bfd * abfd)23575fd0b74Schristos netbsd_core_file_failing_command (bfd *abfd)
23675fd0b74Schristos {
23775fd0b74Schristos   /*return core_command (abfd);*/
23875fd0b74Schristos   return abfd->tdata.netbsd_core_data->core.c_name;
23975fd0b74Schristos }
24075fd0b74Schristos 
24175fd0b74Schristos static int
netbsd_core_file_failing_signal(bfd * abfd)24275fd0b74Schristos netbsd_core_file_failing_signal (bfd *abfd)
24375fd0b74Schristos {
24475fd0b74Schristos   /*return core_signal (abfd);*/
24575fd0b74Schristos   return abfd->tdata.netbsd_core_data->core.c_signo;
24675fd0b74Schristos }
24775fd0b74Schristos 
24875fd0b74Schristos /* If somebody calls any byte-swapping routines, shoot them.  */
24975fd0b74Schristos 
25075fd0b74Schristos static void
swap_abort(void)25175fd0b74Schristos swap_abort (void)
25275fd0b74Schristos {
25375fd0b74Schristos  /* This way doesn't require any declaration for ANSI to fuck up.  */
25475fd0b74Schristos   abort ();
25575fd0b74Schristos }
25675fd0b74Schristos 
25775fd0b74Schristos #define	NO_GET ((bfd_vma (*) (const void *)) swap_abort)
25875fd0b74Schristos #define	NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
25975fd0b74Schristos #define	NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
260*e992f068Schristos #define	NO_GET64 ((uint64_t (*) (const void *)) swap_abort)
261*e992f068Schristos #define	NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort)
262*e992f068Schristos #define	NO_GETS64 ((int64_t (*) (const void *)) swap_abort)
26375fd0b74Schristos 
26475fd0b74Schristos const bfd_target core_netbsd_vec =
26575fd0b74Schristos   {
26675fd0b74Schristos     "netbsd-core",
26775fd0b74Schristos     bfd_target_unknown_flavour,
26875fd0b74Schristos     BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
26975fd0b74Schristos     BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
27075fd0b74Schristos     (HAS_RELOC | EXEC_P |	/* Object flags.  */
27175fd0b74Schristos      HAS_LINENO | HAS_DEBUG |
27275fd0b74Schristos      HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
27375fd0b74Schristos     (SEC_HAS_CONTENTS |		/* Section flags.  */
27475fd0b74Schristos      SEC_ALLOC | SEC_LOAD | SEC_RELOC),
27575fd0b74Schristos     0,				/* Symbol prefix.  */
27675fd0b74Schristos     ' ',			/* ar_pad_char.  */
27775fd0b74Schristos     16,				/* ar_max_namelen.  */
27875fd0b74Schristos     0,				/* Match priority.  */
279*e992f068Schristos     TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
28075fd0b74Schristos     NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit data.  */
28175fd0b74Schristos     NO_GET, NO_GETS, NO_PUT,		/* 32 bit data.  */
28275fd0b74Schristos     NO_GET, NO_GETS, NO_PUT,		/* 16 bit data.  */
28375fd0b74Schristos     NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit hdrs.  */
28475fd0b74Schristos     NO_GET, NO_GETS, NO_PUT,		/* 32 bit hdrs.  */
28575fd0b74Schristos     NO_GET, NO_GETS, NO_PUT,		/* 16 bit hdrs.  */
28675fd0b74Schristos 
28775fd0b74Schristos     {					/* bfd_check_format.  */
28875fd0b74Schristos       _bfd_dummy_target,		/* Unknown format.  */
28975fd0b74Schristos       _bfd_dummy_target,		/* Object file.  */
29075fd0b74Schristos       _bfd_dummy_target,		/* Archive.  */
29175fd0b74Schristos       netbsd_core_file_p		/* A core file.  */
29275fd0b74Schristos     },
29375fd0b74Schristos     {					/* bfd_set_format.  */
294ede78133Schristos       _bfd_bool_bfd_false_error,
295ede78133Schristos       _bfd_bool_bfd_false_error,
296ede78133Schristos       _bfd_bool_bfd_false_error,
297ede78133Schristos       _bfd_bool_bfd_false_error
29875fd0b74Schristos     },
29975fd0b74Schristos     {					/* bfd_write_contents.  */
300ede78133Schristos       _bfd_bool_bfd_false_error,
301ede78133Schristos       _bfd_bool_bfd_false_error,
302ede78133Schristos       _bfd_bool_bfd_false_error,
303ede78133Schristos       _bfd_bool_bfd_false_error
30475fd0b74Schristos     },
30575fd0b74Schristos 
30675fd0b74Schristos     BFD_JUMP_TABLE_GENERIC (_bfd_generic),
30775fd0b74Schristos     BFD_JUMP_TABLE_COPY (_bfd_generic),
30875fd0b74Schristos     BFD_JUMP_TABLE_CORE (netbsd),
30975fd0b74Schristos     BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
31075fd0b74Schristos     BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
31175fd0b74Schristos     BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
31275fd0b74Schristos     BFD_JUMP_TABLE_WRITE (_bfd_generic),
31375fd0b74Schristos     BFD_JUMP_TABLE_LINK (_bfd_nolink),
31475fd0b74Schristos     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
31575fd0b74Schristos 
31675fd0b74Schristos     NULL,
31775fd0b74Schristos 
31875fd0b74Schristos     NULL				/* Backend_data.  */
31975fd0b74Schristos   };
320