(root)/
binutils-2.41/
bfd/
netbsd-core.c
       1  /* BFD back end for NetBSD style core files
       2     Copyright (C) 1988-2023 Free Software Foundation, Inc.
       3     Written by Paul Kranenburg, EUR
       4  
       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.  */
      21  
      22  #include "sysdep.h"
      23  #include "bfd.h"
      24  #include "libbfd.h"
      25  #include "libaout.h"	       /* BFD a.out internal data structures.  */
      26  
      27  #include <sys/param.h>
      28  #include <sys/dir.h>
      29  #include <signal.h>
      30  #include <sys/core.h>
      31  
      32  /* The machine ID for OpenBSD/sparc64 and older versions of
      33     NetBSD/sparc64 overlaps with M_MIPS1.  */
      34  #define M_SPARC64_OPENBSD	M_MIPS1
      35  
      36  /* Offset of StackGhost cookie within `struct md_coredump' on
      37     OpenBSD/sparc.  */
      38  #define SPARC_WCOOKIE_OFFSET	344
      39  
      40  /* Offset of StackGhost cookie within `struct md_coredump' on
      41     OpenBSD/sparc64.  */
      42  #define SPARC64_WCOOKIE_OFFSET	832
      43  
      44  #define netbsd_core_file_matches_executable_p generic_core_file_matches_executable_p
      45  #define netbsd_core_file_pid _bfd_nocore_core_file_pid
      46  
      47  struct netbsd_core_struct
      48  {
      49    struct core core;
      50  } *rawptr;
      51  
      52  /* Handle NetBSD-style core dump file.  */
      53  
      54  static bfd_cleanup
      55  netbsd_core_file_p (bfd *abfd)
      56  {
      57    int val;
      58    unsigned i;
      59    file_ptr offset;
      60    asection *asect;
      61    struct core core;
      62    struct coreseg coreseg;
      63    size_t amt = sizeof core;
      64  
      65    val = bfd_bread (&core, amt, abfd);
      66    if (val != sizeof core)
      67      {
      68        /* Too small to be a core file.  */
      69        bfd_set_error (bfd_error_wrong_format);
      70        return 0;
      71      }
      72  
      73    if (CORE_GETMAGIC (core) != COREMAGIC)
      74      {
      75        bfd_set_error (bfd_error_wrong_format);
      76        return 0;
      77      }
      78  
      79    amt = sizeof (struct netbsd_core_struct);
      80    rawptr = (struct netbsd_core_struct *) bfd_zalloc (abfd, amt);
      81    if (rawptr == NULL)
      82      return 0;
      83  
      84    rawptr->core = core;
      85    abfd->tdata.netbsd_core_data = rawptr;
      86  
      87    offset = core.c_hdrsize;
      88    for (i = 0; i < core.c_nseg; i++)
      89      {
      90        const char *sname;
      91        flagword flags;
      92  
      93        if (bfd_seek (abfd, offset, SEEK_SET) != 0)
      94  	goto punt;
      95  
      96        val = bfd_bread (&coreseg, sizeof coreseg, abfd);
      97        if (val != sizeof coreseg)
      98  	{
      99  	  bfd_set_error (bfd_error_file_truncated);
     100  	  goto punt;
     101  	}
     102        if (CORE_GETMAGIC (coreseg) != CORESEGMAGIC)
     103  	{
     104  	  bfd_set_error (bfd_error_wrong_format);
     105  	  goto punt;
     106  	}
     107  
     108        offset += core.c_seghdrsize;
     109  
     110        switch (CORE_GETFLAG (coreseg))
     111  	{
     112  	case CORE_CPU:
     113  	  sname = ".reg";
     114  	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
     115  	  break;
     116  	case CORE_DATA:
     117  	  sname = ".data";
     118  	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
     119  	  break;
     120  	case CORE_STACK:
     121  	  sname = ".stack";
     122  	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
     123  	  break;
     124  	default:
     125  	  sname = ".unknown";
     126  	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
     127  	  break;
     128  	}
     129        asect = bfd_make_section_anyway_with_flags (abfd, sname, flags);
     130        if (asect == NULL)
     131  	goto punt;
     132  
     133        asect->size = coreseg.c_size;
     134        asect->vma = coreseg.c_addr;
     135        asect->filepos = offset;
     136        asect->alignment_power = 2;
     137  
     138        if (CORE_GETFLAG (coreseg) == CORE_CPU)
     139  	{
     140  	  bfd_size_type wcookie_offset;
     141  
     142  	  switch (CORE_GETMID (core))
     143  	    {
     144  	    case M_SPARC_NETBSD:
     145  	      wcookie_offset = SPARC_WCOOKIE_OFFSET;
     146  	      break;
     147  	    case M_SPARC64_OPENBSD:
     148  	      wcookie_offset = SPARC64_WCOOKIE_OFFSET;
     149  	      break;
     150  	    default:
     151  	      wcookie_offset = 0;
     152  	      break;
     153  	    }
     154  
     155  	  if (wcookie_offset > 0 && coreseg.c_size > wcookie_offset)
     156  	    {
     157  	      /* Truncate the .reg section.  */
     158  	      asect->size = wcookie_offset;
     159  
     160  	      /* And create the .wcookie section.  */
     161  	      flags = SEC_ALLOC + SEC_HAS_CONTENTS;
     162  	      asect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
     163  							  flags);
     164  	      if (asect == NULL)
     165  		goto punt;
     166  
     167  	      asect->size = coreseg.c_size - wcookie_offset;
     168  	      asect->vma = 0;
     169  	      asect->filepos = offset + wcookie_offset;
     170  	      asect->alignment_power = 2;
     171  	    }
     172  	}
     173  
     174        offset += coreseg.c_size;
     175      }
     176  
     177    /* Set architecture from machine ID.  */
     178    switch (CORE_GETMID (core))
     179      {
     180      case M_ALPHA_NETBSD:
     181        bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
     182        break;
     183  
     184      case M_ARM6_NETBSD:
     185        bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_3);
     186        break;
     187  
     188      case M_X86_64_NETBSD:
     189        bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
     190        break;
     191  
     192      case M_386_NETBSD:
     193        bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386);
     194        break;
     195  
     196      case M_68K_NETBSD:
     197      case M_68K4K_NETBSD:
     198        bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
     199        break;
     200  
     201      case M_HPPA_OPENBSD:
     202        bfd_default_set_arch_mach (abfd, bfd_arch_hppa, bfd_mach_hppa11);
     203        break;
     204  
     205      case M_POWERPC_NETBSD:
     206        bfd_default_set_arch_mach (abfd, bfd_arch_powerpc, bfd_mach_ppc);
     207        break;
     208  
     209      case M_SPARC_NETBSD:
     210        bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc);
     211        break;
     212  
     213      case M_SPARC64_NETBSD:
     214      case M_SPARC64_OPENBSD:
     215        bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v9);
     216        break;
     217  
     218      case M_VAX_NETBSD:
     219      case M_VAX4K_NETBSD:
     220        bfd_default_set_arch_mach (abfd, bfd_arch_vax, 0);
     221        break;
     222      }
     223  
     224    /* OK, we believe you.  You're a core file (sure, sure).  */
     225    return _bfd_no_cleanup;
     226  
     227   punt:
     228    bfd_release (abfd, abfd->tdata.any);
     229    abfd->tdata.any = NULL;
     230    bfd_section_list_clear (abfd);
     231    return 0;
     232  }
     233  
     234  static char*
     235  netbsd_core_file_failing_command (bfd *abfd)
     236  {
     237    /*return core_command (abfd);*/
     238    return abfd->tdata.netbsd_core_data->core.c_name;
     239  }
     240  
     241  static int
     242  netbsd_core_file_failing_signal (bfd *abfd)
     243  {
     244    /*return core_signal (abfd);*/
     245    return abfd->tdata.netbsd_core_data->core.c_signo;
     246  }
     247  
     248  /* If somebody calls any byte-swapping routines, shoot them.  */
     249  
     250  static void
     251  swap_abort (void)
     252  {
     253   /* This way doesn't require any declaration for ANSI to fuck up.  */
     254    abort ();
     255  }
     256  
     257  #define	NO_GET ((bfd_vma (*) (const void *)) swap_abort)
     258  #define	NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
     259  #define	NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
     260  #define	NO_GET64 ((uint64_t (*) (const void *)) swap_abort)
     261  #define	NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort)
     262  #define	NO_GETS64 ((int64_t (*) (const void *)) swap_abort)
     263  
     264  const bfd_target core_netbsd_vec =
     265    {
     266      "netbsd-core",
     267      bfd_target_unknown_flavour,
     268      BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
     269      BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
     270      (HAS_RELOC | EXEC_P |	/* Object flags.  */
     271       HAS_LINENO | HAS_DEBUG |
     272       HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
     273      (SEC_HAS_CONTENTS |		/* Section flags.  */
     274       SEC_ALLOC | SEC_LOAD | SEC_RELOC),
     275      0,				/* Symbol prefix.  */
     276      ' ',			/* ar_pad_char.  */
     277      16,				/* ar_max_namelen.  */
     278      0,				/* Match priority.  */
     279      TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
     280      NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit data.  */
     281      NO_GET, NO_GETS, NO_PUT,		/* 32 bit data.  */
     282      NO_GET, NO_GETS, NO_PUT,		/* 16 bit data.  */
     283      NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit hdrs.  */
     284      NO_GET, NO_GETS, NO_PUT,		/* 32 bit hdrs.  */
     285      NO_GET, NO_GETS, NO_PUT,		/* 16 bit hdrs.  */
     286  
     287      {					/* bfd_check_format.  */
     288        _bfd_dummy_target,		/* Unknown format.  */
     289        _bfd_dummy_target,		/* Object file.  */
     290        _bfd_dummy_target,		/* Archive.  */
     291        netbsd_core_file_p		/* A core file.  */
     292      },
     293      {					/* bfd_set_format.  */
     294        _bfd_bool_bfd_false_error,
     295        _bfd_bool_bfd_false_error,
     296        _bfd_bool_bfd_false_error,
     297        _bfd_bool_bfd_false_error
     298      },
     299      {					/* bfd_write_contents.  */
     300        _bfd_bool_bfd_false_error,
     301        _bfd_bool_bfd_false_error,
     302        _bfd_bool_bfd_false_error,
     303        _bfd_bool_bfd_false_error
     304      },
     305  
     306      BFD_JUMP_TABLE_GENERIC (_bfd_generic),
     307      BFD_JUMP_TABLE_COPY (_bfd_generic),
     308      BFD_JUMP_TABLE_CORE (netbsd),
     309      BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
     310      BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
     311      BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
     312      BFD_JUMP_TABLE_WRITE (_bfd_generic),
     313      BFD_JUMP_TABLE_LINK (_bfd_nolink),
     314      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
     315  
     316      NULL,
     317  
     318      NULL				/* Backend_data.  */
     319    };