Back to index

cell-binutils  2.17cvs20070401
irix-core.c
Go to the documentation of this file.
00001 /* BFD back-end for Irix core files.
00002    Copyright 1993, 1994, 1996, 1999, 2001, 2002, 2004, 2006
00003    Free Software Foundation, Inc.
00004    Written by Stu Grossman, Cygnus Support.
00005    Converted to back-end form by Ian Lance Taylor, Cygnus Support
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 /* This file can only be compiled on systems which use Irix style core
00024    files (namely, Irix 4 and Irix 5, so far).  */
00025 
00026 #include "bfd.h"
00027 #include "sysdep.h"
00028 #include "libbfd.h"
00029 
00030 #ifdef IRIX_CORE
00031 
00032 #include <core.out.h>
00033 
00034 struct sgi_core_struct
00035 {
00036   int sig;
00037   char cmd[CORE_NAMESIZE];
00038 };
00039 
00040 #define core_hdr(bfd) ((bfd)->tdata.sgi_core_data)
00041 #define core_signal(bfd) (core_hdr(bfd)->sig)
00042 #define core_command(bfd) (core_hdr(bfd)->cmd)
00043 
00044 #define irix_core_core_file_matches_executable_p generic_core_file_matches_executable_p
00045 
00046 static asection *make_bfd_asection
00047   (bfd *, const char *, flagword, bfd_size_type, bfd_vma, file_ptr);
00048 
00049 /* Helper function for irix_core_core_file_p:
00050    32-bit and 64-bit versions.  */
00051 
00052 #ifdef CORE_MAGIC64
00053 static int
00054 do_sections64 (bfd *abfd, struct coreout *coreout)
00055 {
00056   struct vmap64 vmap;
00057   char *secname;
00058   int i, val;
00059 
00060   for (i = 0; i < coreout->c_nvmap; i++)
00061     {
00062       val = bfd_bread ((PTR) &vmap, (bfd_size_type) sizeof vmap, abfd);
00063       if (val != sizeof vmap)
00064        break;
00065 
00066       switch (vmap.v_type)
00067        {
00068        case VDATA:
00069          secname = ".data";
00070          break;
00071        case VSTACK:
00072          secname = ".stack";
00073          break;
00074 #ifdef VMAPFILE
00075        case VMAPFILE:
00076          secname = ".mapfile";
00077          break;
00078 #endif
00079        default:
00080          continue;
00081        }
00082 
00083       /* A file offset of zero means that the
00084         section is not contained in the corefile.  */
00085       if (vmap.v_offset == 0)
00086        continue;
00087 
00088       if (!make_bfd_asection (abfd, secname,
00089                            SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
00090                            vmap.v_len, vmap.v_vaddr, vmap.v_offset))
00091        /* Fail.  */
00092        return 0;
00093     }
00094 
00095   return 1;
00096 }
00097 #endif
00098 
00099 /* 32-bit version.  */
00100 
00101 static int
00102 do_sections (bfd *abfd, struct coreout *coreout)
00103 {
00104   struct vmap vmap;
00105   char *secname;
00106   int i, val;
00107 
00108   for (i = 0; i < coreout->c_nvmap; i++)
00109     {
00110       val = bfd_bread ((PTR) &vmap, (bfd_size_type) sizeof vmap, abfd);
00111       if (val != sizeof vmap)
00112        break;
00113 
00114       switch (vmap.v_type)
00115        {
00116        case VDATA:
00117          secname = ".data";
00118          break;
00119        case VSTACK:
00120          secname = ".stack";
00121          break;
00122 #ifdef VMAPFILE
00123        case VMAPFILE:
00124          secname = ".mapfile";
00125          break;
00126 #endif
00127        default:
00128          continue;
00129        }
00130 
00131       /* A file offset of zero means that the
00132         section is not contained in the corefile.  */
00133       if (vmap.v_offset == 0)
00134        continue;
00135 
00136       if (!make_bfd_asection (abfd, secname,
00137                            SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
00138                            vmap.v_len, vmap.v_vaddr, vmap.v_offset))
00139        /* Fail.  */
00140        return 0;
00141     }
00142   return 1;
00143 }
00144 
00145 static asection *
00146 make_bfd_asection (bfd *abfd,
00147                    const char *name,
00148                    flagword flags,
00149                    bfd_size_type size,
00150                    bfd_vma vma,
00151                    file_ptr filepos)
00152 {
00153   asection *asect;
00154 
00155   asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
00156   if (!asect)
00157     return NULL;
00158 
00159   asect->size = size;
00160   asect->vma = vma;
00161   asect->filepos = filepos;
00162   asect->alignment_power = 4;
00163 
00164   return asect;
00165 }
00166 
00167 static const bfd_target *
00168 irix_core_core_file_p (bfd *abfd)
00169 {
00170   int val;
00171   struct coreout coreout;
00172   struct idesc *idg, *idf, *ids;
00173   bfd_size_type amt;
00174 
00175   val = bfd_bread ((PTR) &coreout, (bfd_size_type) sizeof coreout, abfd);
00176   if (val != sizeof coreout)
00177     {
00178       if (bfd_get_error () != bfd_error_system_call)
00179        bfd_set_error (bfd_error_wrong_format);
00180       return 0;
00181     }
00182 
00183   if (coreout.c_version != CORE_VERSION1)
00184     return 0;
00185 
00186   /* Have we got a corefile?  */
00187   switch (coreout.c_magic)
00188     {
00189     case CORE_MAGIC: break;
00190 #ifdef CORE_MAGIC64
00191     case CORE_MAGIC64:      break;
00192 #endif
00193 #ifdef CORE_MAGICN32
00194     case CORE_MAGICN32:     break;
00195 #endif
00196     default:         return 0;     /* Un-identifiable or not corefile.  */
00197     }
00198 
00199   amt = sizeof (struct sgi_core_struct);
00200   core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, amt);
00201   if (!core_hdr (abfd))
00202     return NULL;
00203 
00204   strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE);
00205   core_signal (abfd) = coreout.c_sigcause;
00206 
00207   if (bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET) != 0)
00208     goto fail;
00209 
00210   /* Process corefile sections.  */
00211 #ifdef CORE_MAGIC64
00212   if (coreout.c_magic == (int) CORE_MAGIC64)
00213     {
00214       if (! do_sections64 (abfd, & coreout))
00215        goto fail;
00216     }
00217   else
00218 #endif
00219     if (! do_sections (abfd, & coreout))
00220       goto fail;
00221 
00222   /* Make sure that the regs are contiguous within the core file.  */
00223 
00224   idg = &coreout.c_idesc[I_GPREGS];
00225   idf = &coreout.c_idesc[I_FPREGS];
00226   ids = &coreout.c_idesc[I_SPECREGS];
00227 
00228   if (idg->i_offset + idg->i_len != idf->i_offset
00229       || idf->i_offset + idf->i_len != ids->i_offset)
00230     goto fail;                     /* Can't deal with non-contig regs */
00231 
00232   if (bfd_seek (abfd, idg->i_offset, SEEK_SET) != 0)
00233     goto fail;
00234 
00235   if (!make_bfd_asection (abfd, ".reg",
00236                        SEC_HAS_CONTENTS,
00237                        idg->i_len + idf->i_len + ids->i_len,
00238                        0,
00239                        idg->i_offset))
00240     goto fail;
00241 
00242   /* OK, we believe you.  You're a core file (sure, sure).  */
00243   bfd_default_set_arch_mach (abfd, bfd_arch_mips, 0);
00244 
00245   return abfd->xvec;
00246 
00247  fail:
00248   bfd_release (abfd, core_hdr (abfd));
00249   core_hdr (abfd) = NULL;
00250   bfd_section_list_clear (abfd);
00251   return NULL;
00252 }
00253 
00254 static char *
00255 irix_core_core_file_failing_command (bfd *abfd)
00256 {
00257   return core_command (abfd);
00258 }
00259 
00260 static int
00261 irix_core_core_file_failing_signal (bfd *abfd)
00262 {
00263   return core_signal (abfd);
00264 }
00265 
00266 /* If somebody calls any byte-swapping routines, shoot them.  */
00267 static void
00268 swap_abort(void)
00269 {
00270   abort(); /* This way doesn't require any declaration for ANSI to fuck up */
00271 }
00272 
00273 #define       NO_GET ((bfd_vma (*) (const void *)) swap_abort)
00274 #define       NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
00275 #define       NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
00276 #define       NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
00277 #define       NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
00278 #define       NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
00279 
00280 const bfd_target irix_core_vec =
00281   {
00282     "irix-core",
00283     bfd_target_unknown_flavour,
00284     BFD_ENDIAN_BIG,         /* target byte order */
00285     BFD_ENDIAN_BIG,         /* target headers byte order */
00286     (HAS_RELOC | EXEC_P |   /* object flags */
00287      HAS_LINENO | HAS_DEBUG |
00288      HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
00289     (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
00290     0,                                                  /* symbol prefix */
00291     ' ',                                            /* ar_pad_char */
00292     16,                                                    /* ar_max_namelen */
00293     NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
00294     NO_GET, NO_GETS, NO_PUT,              /* 32 bit data */
00295     NO_GET, NO_GETS, NO_PUT,              /* 16 bit data */
00296     NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
00297     NO_GET, NO_GETS, NO_PUT,              /* 32 bit hdrs */
00298     NO_GET, NO_GETS, NO_PUT,              /* 16 bit hdrs */
00299 
00300     {                       /* bfd_check_format */
00301       _bfd_dummy_target,           /* unknown format */
00302       _bfd_dummy_target,           /* object file */
00303       _bfd_dummy_target,           /* archive */
00304       irix_core_core_file_p        /* a core file */
00305     },
00306     {                       /* bfd_set_format */
00307       bfd_false, bfd_false,
00308       bfd_false, bfd_false
00309     },
00310     {                       /* bfd_write_contents */
00311       bfd_false, bfd_false,
00312       bfd_false, bfd_false
00313     },
00314 
00315     BFD_JUMP_TABLE_GENERIC (_bfd_generic),
00316     BFD_JUMP_TABLE_COPY (_bfd_generic),
00317     BFD_JUMP_TABLE_CORE (irix_core),
00318     BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
00319     BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
00320     BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
00321     BFD_JUMP_TABLE_WRITE (_bfd_generic),
00322     BFD_JUMP_TABLE_LINK (_bfd_nolink),
00323     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00324 
00325     NULL,
00326 
00327     (PTR) 0                 /* backend_data */
00328   };
00329 
00330 #endif /* IRIX_CORE */