Back to index

cell-binutils  2.17cvs20070401
netbsd-core.c
Go to the documentation of this file.
00001 /* BFD back end for NetBSD style core files
00002    Copyright 1988, 1989, 1991, 1992, 1993, 1996, 1998, 1999, 2000, 2001,
00003    2002, 2003, 2004, 2005, 2006
00004    Free Software Foundation, Inc.
00005    Written by Paul Kranenburg, EUR
00006 
00007    This file is part of BFD, the Binary File Descriptor library.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "libbfd.h"
00026 #include "libaout.h"           /* BFD a.out internal data structures.  */
00027 
00028 #include <sys/param.h>
00029 #include <sys/dir.h>
00030 #include <signal.h>
00031 #include <sys/core.h>
00032 
00033 /* The machine ID for OpenBSD/sparc64 and older versions of
00034    NetBSD/sparc64 overlaps with M_MIPS1.  */
00035 #define M_SPARC64_OPENBSD   M_MIPS1
00036 
00037 /* Offset of StackGhost cookie within `struct md_coredump' on
00038    OpenBSD/sparc.  */
00039 #define SPARC_WCOOKIE_OFFSET       344
00040 
00041 /* Offset of StackGhost cookie within `struct md_coredump' on
00042    OpenBSD/sparc64.  */
00043 #define SPARC64_WCOOKIE_OFFSET     832
00044 
00045 #define netbsd_core_file_matches_executable_p generic_core_file_matches_executable_p
00046 
00047 struct netbsd_core_struct
00048 {
00049   struct core core;
00050 } *rawptr;
00051 
00052 /* Handle NetBSD-style core dump file.  */
00053 
00054 static const bfd_target *
00055 netbsd_core_file_p (bfd *abfd)
00056 {
00057   int val;
00058   unsigned i;
00059   file_ptr offset;
00060   asection *asect;
00061   struct core core;
00062   struct coreseg coreseg;
00063   bfd_size_type amt = sizeof core;
00064 
00065   val = bfd_bread (&core, amt, abfd);
00066   if (val != sizeof core)
00067     {
00068       /* Too small to be a core file.  */
00069       bfd_set_error (bfd_error_wrong_format);
00070       return 0;
00071     }
00072 
00073   if (CORE_GETMAGIC (core) != COREMAGIC)
00074     {
00075       bfd_set_error (bfd_error_wrong_format);
00076       return 0;
00077     }
00078 
00079   amt = sizeof (struct netbsd_core_struct);
00080   rawptr = (struct netbsd_core_struct *) bfd_zalloc (abfd, amt);
00081   if (rawptr == NULL)
00082     return 0;
00083 
00084   rawptr->core = core;
00085   abfd->tdata.netbsd_core_data = rawptr;
00086 
00087   offset = core.c_hdrsize;
00088   for (i = 0; i < core.c_nseg; i++)
00089     {
00090       const char *sname;
00091       flagword flags;
00092 
00093       if (bfd_seek (abfd, offset, SEEK_SET) != 0)
00094        goto punt;
00095 
00096       val = bfd_bread (&coreseg, sizeof coreseg, abfd);
00097       if (val != sizeof coreseg)
00098        {
00099          bfd_set_error (bfd_error_file_truncated);
00100          goto punt;
00101        }
00102       if (CORE_GETMAGIC (coreseg) != CORESEGMAGIC)
00103        {
00104          bfd_set_error (bfd_error_wrong_format);
00105          goto punt;
00106        }
00107 
00108       offset += core.c_seghdrsize;
00109 
00110       switch (CORE_GETFLAG (coreseg))
00111        {
00112        case CORE_CPU:
00113          sname = ".reg";
00114          flags = SEC_ALLOC + SEC_HAS_CONTENTS;
00115          break;
00116        case CORE_DATA:
00117          sname = ".data";
00118          flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
00119          break;
00120        case CORE_STACK:
00121          sname = ".stack";
00122          flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
00123          break;
00124        default:
00125          sname = ".unknown";
00126          flags = SEC_ALLOC + SEC_HAS_CONTENTS;
00127          break;
00128        }
00129       asect = bfd_make_section_anyway_with_flags (abfd, sname, flags);
00130       if (asect == NULL)
00131        goto punt;
00132 
00133       asect->size = coreseg.c_size;
00134       asect->vma = coreseg.c_addr;
00135       asect->filepos = offset;
00136       asect->alignment_power = 2;
00137 
00138       if (CORE_GETFLAG (coreseg) == CORE_CPU)
00139        {
00140          bfd_size_type wcookie_offset;
00141 
00142          switch (CORE_GETMID (core))
00143            {
00144            case M_SPARC_NETBSD:
00145              wcookie_offset = SPARC_WCOOKIE_OFFSET;
00146              break;
00147            case M_SPARC64_OPENBSD:
00148              wcookie_offset = SPARC64_WCOOKIE_OFFSET;
00149              break;
00150            default:
00151              wcookie_offset = 0;
00152              break;
00153            }
00154 
00155          if (wcookie_offset > 0 && coreseg.c_size > wcookie_offset)
00156            {
00157              /* Truncate the .reg section.  */
00158              asect->size = wcookie_offset;
00159 
00160              /* And create the .wcookie section.  */
00161              flags = SEC_ALLOC + SEC_HAS_CONTENTS;
00162              asect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
00163                                                    flags);
00164              if (asect == NULL)
00165               goto punt;
00166 
00167              asect->size = coreseg.c_size - wcookie_offset;
00168              asect->vma = 0;
00169              asect->filepos = offset + wcookie_offset;
00170              asect->alignment_power = 2;
00171            }
00172        }
00173 
00174       offset += coreseg.c_size;
00175     }
00176 
00177   /* Set architecture from machine ID.  */
00178   switch (CORE_GETMID (core))
00179     {
00180     case M_ALPHA_NETBSD:
00181       bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
00182       break;
00183 
00184     case M_ARM6_NETBSD:
00185       bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_3);
00186       break;
00187 
00188     case M_X86_64_NETBSD:
00189       bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
00190       break;
00191 
00192     case M_386_NETBSD:
00193       bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386);
00194       break;
00195 
00196     case M_68K_NETBSD:
00197     case M_68K4K_NETBSD:
00198       bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
00199       break;
00200 
00201     case M_88K_OPENBSD:
00202       bfd_default_set_arch_mach (abfd, bfd_arch_m88k, 0);
00203       break;
00204 
00205     case M_HPPA_OPENBSD:
00206       bfd_default_set_arch_mach (abfd, bfd_arch_hppa, bfd_mach_hppa11);
00207       break;
00208 
00209     case M_POWERPC_NETBSD:
00210       bfd_default_set_arch_mach (abfd, bfd_arch_powerpc, bfd_mach_ppc);
00211       break;
00212 
00213     case M_SPARC_NETBSD:
00214       bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc);
00215       break;
00216 
00217     case M_SPARC64_NETBSD:
00218     case M_SPARC64_OPENBSD:
00219       bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v9);
00220       break;
00221 
00222     case M_VAX_NETBSD:
00223     case M_VAX4K_NETBSD:
00224       bfd_default_set_arch_mach (abfd, bfd_arch_vax, 0);
00225       break;
00226     }
00227 
00228   /* OK, we believe you.  You're a core file (sure, sure).  */
00229   return abfd->xvec;
00230 
00231  punt:
00232   bfd_release (abfd, abfd->tdata.any);
00233   abfd->tdata.any = NULL;
00234   bfd_section_list_clear (abfd);
00235   return 0;
00236 }
00237 
00238 static char*
00239 netbsd_core_file_failing_command (bfd *abfd)
00240 {
00241   /*return core_command (abfd);*/
00242   return abfd->tdata.netbsd_core_data->core.c_name;
00243 }
00244 
00245 static int
00246 netbsd_core_file_failing_signal (bfd *abfd)
00247 {
00248   /*return core_signal (abfd);*/
00249   return abfd->tdata.netbsd_core_data->core.c_signo;
00250 }
00251 
00252 /* If somebody calls any byte-swapping routines, shoot them.  */
00253 
00254 static void
00255 swap_abort (void)
00256 {
00257  /* This way doesn't require any declaration for ANSI to fuck up.  */
00258   abort ();
00259 }
00260 
00261 #define       NO_GET ((bfd_vma (*) (const void *)) swap_abort)
00262 #define       NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
00263 #define       NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
00264 #define       NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
00265 #define       NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
00266 #define       NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
00267 
00268 const bfd_target netbsd_core_vec =
00269   {
00270     "netbsd-core",
00271     bfd_target_unknown_flavour,
00272     BFD_ENDIAN_UNKNOWN,            /* Target byte order.  */
00273     BFD_ENDIAN_UNKNOWN,            /* Target headers byte order.  */
00274     (HAS_RELOC | EXEC_P |   /* Object flags.  */
00275      HAS_LINENO | HAS_DEBUG |
00276      HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
00277     (SEC_HAS_CONTENTS |            /* Section flags.  */
00278      SEC_ALLOC | SEC_LOAD | SEC_RELOC),
00279     0,                      /* Symbol prefix.  */
00280     ' ',                    /* ar_pad_char.  */
00281     16,                            /* ar_max_namelen.  */
00282     NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data.  */
00283     NO_GET, NO_GETS, NO_PUT,              /* 32 bit data.  */
00284     NO_GET, NO_GETS, NO_PUT,              /* 16 bit data.  */
00285     NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs.  */
00286     NO_GET, NO_GETS, NO_PUT,              /* 32 bit hdrs.  */
00287     NO_GET, NO_GETS, NO_PUT,              /* 16 bit hdrs.  */
00288 
00289     {                              /* bfd_check_format.  */
00290       _bfd_dummy_target,           /* Unknown format.  */
00291       _bfd_dummy_target,           /* Object file.  */
00292       _bfd_dummy_target,           /* Archive.  */
00293       netbsd_core_file_p           /* A core file.  */
00294     },
00295     {                              /* bfd_set_format.  */
00296       bfd_false, bfd_false,
00297       bfd_false, bfd_false
00298     },
00299     {                              /* bfd_write_contents.  */
00300       bfd_false, bfd_false,
00301       bfd_false, bfd_false
00302     },
00303 
00304     BFD_JUMP_TABLE_GENERIC (_bfd_generic),
00305     BFD_JUMP_TABLE_COPY (_bfd_generic),
00306     BFD_JUMP_TABLE_CORE (netbsd),
00307     BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
00308     BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
00309     BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
00310     BFD_JUMP_TABLE_WRITE (_bfd_generic),
00311     BFD_JUMP_TABLE_LINK (_bfd_nolink),
00312     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00313 
00314     NULL,
00315 
00316     (PTR) 0                         /* Backend_data.  */
00317   };