Back to index

cell-binutils  2.17cvs20070401
aix386-core.c
Go to the documentation of this file.
00001 /* BFD back-end for AIX on PS/2 core files.
00002    This was based on trad-core.c, which was written by John Gilmore of
00003         Cygnus Support.
00004    Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2000,
00005    2001, 2002, 2004, 2006
00006    Free Software Foundation, Inc.
00007    Written by Minh Tran-Le <TRANLE@INTELLICORP.COM>.
00008    Converted to back end form by Ian Lance Taylor <ian@cygnus.com>.
00009 
00010 This file is part of BFD, the Binary File Descriptor library.
00011 
00012 This program is free software; you can redistribute it and/or modify
00013 it under the terms of the GNU General Public License as published by
00014 the Free Software Foundation; either version 2 of the License, or
00015 (at your option) any later version.
00016 
00017 This program is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 GNU General Public License for more details.
00021 
00022 You should have received a copy of the GNU General Public License
00023 along with this program; if not, write to the Free Software
00024 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00025 
00026 #include "bfd.h"
00027 #include "sysdep.h"
00028 #include "libbfd.h"
00029 #include "coff/i386.h"
00030 #include "coff/internal.h"
00031 #include "libcoff.h"
00032 
00033 #include <signal.h>
00034 
00035 #if defined (_AIX) && defined (_I386)
00036 #define NOCHECKS            /* This is for coredump.h.  */
00037 #define _h_USER                    /* Avoid including user.h from coredump.h.  */
00038 #include <uinfo.h>
00039 #include <sys/i386/coredump.h>
00040 #endif /* _AIX && _I386 */
00041 
00042 /* Maybe this could work on some other i386 but I have not tried it
00043  * mtranle@paris - Tue Sep 24 12:49:35 1991
00044  */
00045 
00046 #ifndef COR_MAGIC
00047 # define COR_MAGIC "core"
00048 #endif
00049 
00050 /* Need this cast because ptr is really void *.  */
00051 #define core_hdr(bfd) \
00052     (((bfd->tdata.trad_core_data))->hdr)
00053 #define core_section(bfd,n) \
00054     (((bfd)->tdata.trad_core_data)->sections[n])
00055 #define core_regsec(bfd) \
00056     (((bfd)->tdata.trad_core_data)->reg_section)
00057 #define core_reg2sec(bfd) \
00058     (((bfd)->tdata.trad_core_data)->reg2_section)
00059 
00060 /* These are stored in the bfd's tdata.  */
00061 struct trad_core_struct {
00062   struct corehdr *hdr;             /* core file header */
00063   asection *reg_section;
00064   asection *reg2_section;
00065   asection *sections[MAX_CORE_SEGS];
00066 };
00067 
00068 static void swap_abort PARAMS ((void));
00069 
00070 static const bfd_target *
00071 aix386_core_file_p (abfd)
00072      bfd *abfd;
00073 {
00074   int i, n;
00075   unsigned char longbuf[4]; /* Raw bytes of various header fields */
00076   bfd_size_type core_size = sizeof (struct corehdr);
00077   bfd_size_type amt;
00078   struct corehdr *core;
00079   struct mergem {
00080     struct trad_core_struct coredata;
00081     struct corehdr internal_core;
00082   } *mergem;
00083   flagword flags;
00084 
00085   amt = sizeof (longbuf);
00086   if (bfd_bread ((PTR) longbuf, amt, abfd) != amt)
00087     {
00088       if (bfd_get_error () != bfd_error_system_call)
00089        bfd_set_error (bfd_error_wrong_format);
00090       return 0;
00091     }
00092 
00093   if (strncmp (longbuf, COR_MAGIC, 4))
00094     return 0;
00095 
00096   if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
00097     return 0;
00098 
00099   amt = sizeof (struct mergem);
00100   mergem = (struct mergem *) bfd_zalloc (abfd, amt);
00101   if (mergem == NULL)
00102     return 0;
00103 
00104   core = &mergem->internal_core;
00105 
00106   if ((bfd_bread ((PTR) core, core_size, abfd)) != core_size)
00107     {
00108       if (bfd_get_error () != bfd_error_system_call)
00109        bfd_set_error (bfd_error_wrong_format);
00110     loser:
00111       bfd_release (abfd, (char *) mergem);
00112       abfd->tdata.any = NULL;
00113       bfd_section_list_clear (abfd);
00114       return 0;
00115     }
00116 
00117   set_tdata (abfd, &mergem->coredata);
00118   core_hdr (abfd) = core;
00119 
00120   /* Create the sections.  */
00121   flags = SEC_HAS_CONTENTS;
00122   core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg",
00123                                                     flags);
00124   if (core_regsec (abfd) == NULL)
00125     goto loser;
00126 
00127   core_regsec (abfd)->size = sizeof (core->cd_regs);
00128   core_regsec (abfd)->vma = (bfd_vma) -1;
00129 
00130   /* We'll access the regs afresh in the core file, like any section.  */
00131   core_regsec (abfd)->filepos =
00132     (file_ptr) offsetof (struct corehdr, cd_regs[0]);
00133 
00134   flags = SEC_HAS_CONTENTS;
00135   core_reg2sec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg2",
00136                                                      flags);
00137   if (core_reg2sec (abfd) == NULL)
00138     /* bfd_release frees everything allocated after it's arg.  */
00139     goto loser;
00140 
00141   core_reg2sec (abfd)->size = sizeof (core->cd_fpregs);
00142   core_reg2sec (abfd)->vma = (bfd_vma) -1;
00143   core_reg2sec (abfd)->filepos =
00144     (file_ptr) offsetof (struct corehdr, cd_fpregs);
00145 
00146   for (i = 0, n = 0; (i < MAX_CORE_SEGS) && (core->cd_segs[i].cs_type); i++)
00147     {
00148       const char *sname;
00149       flagword flags;
00150 
00151       if (core->cd_segs[i].cs_offset == 0)
00152        continue;
00153 
00154       switch (core->cd_segs[i].cs_type)
00155        {
00156        case COR_TYPE_DATA:
00157          sname = ".data";
00158          flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
00159          break;
00160        case COR_TYPE_STACK:
00161          sname = ".stack";
00162          flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
00163          break;
00164        case COR_TYPE_LIBDATA:
00165          sname = ".libdata";
00166          flags = SEC_ALLOC + SEC_HAS_CONTENTS;
00167          break;
00168        case COR_TYPE_WRITE:
00169          sname = ".writeable";
00170          flags = SEC_ALLOC + SEC_HAS_CONTENTS;
00171          break;
00172        case COR_TYPE_MSC:
00173          sname = ".misc";
00174          flags = SEC_ALLOC + SEC_HAS_CONTENTS;
00175          break;
00176        default:
00177          sname = ".unknown";
00178          flags = SEC_ALLOC + SEC_HAS_CONTENTS;
00179          break;
00180        }
00181       core_section (abfd, n) = bfd_make_section_anyway_with_flags (abfd,
00182                                                            sname,
00183                                                            flags);
00184       if (core_section (abfd, n) == NULL)
00185        goto loser;
00186 
00187       core_section (abfd, n)->size = core->cd_segs[i].cs_len;
00188       core_section (abfd, n)->vma       = core->cd_segs[i].cs_address;
00189       core_section (abfd, n)->filepos   = core->cd_segs[i].cs_offset;
00190       core_section (abfd, n)->alignment_power = 2;
00191       n++;
00192     }
00193 
00194   return abfd->xvec;
00195 }
00196 
00197 static char *
00198 aix386_core_file_failing_command (abfd)
00199      bfd *abfd;
00200 {
00201   return core_hdr (abfd)->cd_comm;
00202 }
00203 
00204 static int
00205 aix386_core_file_failing_signal (abfd)
00206      bfd *abfd;
00207 {
00208   return core_hdr (abfd)->cd_cursig;
00209 }
00210 
00211 #define aix386_core_file_matches_executable_p generic_core_file_matches_executable_p
00212 
00213 /* If somebody calls any byte-swapping routines, shoot them.  */
00214 
00215 static void
00216 swap_abort ()
00217 {
00218   /* This way doesn't require any declaration for ANSI to fuck up.  */
00219   abort ();
00220 }
00221 
00222 #define       NO_GET ((bfd_vma (*) (const void *)) swap_abort)
00223 #define       NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
00224 #define       NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
00225 #define       NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
00226 #define       NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
00227 #define       NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
00228 
00229 const bfd_target aix386_core_vec = {
00230   "aix386-core",
00231   bfd_target_unknown_flavour,
00232   BFD_ENDIAN_BIG,           /* target byte order */
00233   BFD_ENDIAN_BIG,           /* target headers byte order */
00234   (HAS_RELOC | EXEC_P |            /* object flags */
00235    HAS_LINENO | HAS_DEBUG |
00236    HAS_SYMS | HAS_LOCALS | WP_TEXT),
00237 
00238   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
00239   0,                        /* leading underscore */
00240   ' ',                      /* ar_pad_char */
00241   16,                       /* ar_max_namelen */
00242   NO_GET64, NO_GETS64, NO_PUT64,
00243   NO_GET, NO_GETS, NO_PUT,
00244   NO_GET, NO_GETS, NO_PUT,  /* data */
00245   NO_GET64, NO_GETS64, NO_PUT64,
00246   NO_GET, NO_GETS, NO_PUT,
00247   NO_GET, NO_GETS, NO_PUT,  /* hdrs */
00248 
00249   {_bfd_dummy_target, _bfd_dummy_target,
00250    _bfd_dummy_target, aix386_core_file_p},
00251   {bfd_false, bfd_false,    /* bfd_create_object */
00252    bfd_false, bfd_false},
00253   {bfd_false, bfd_false,    /* bfd_write_contents */
00254    bfd_false, bfd_false},
00255 
00256   BFD_JUMP_TABLE_GENERIC (_bfd_generic),
00257   BFD_JUMP_TABLE_COPY (_bfd_generic),
00258   BFD_JUMP_TABLE_CORE (aix386),
00259   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
00260   BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
00261   BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
00262   BFD_JUMP_TABLE_WRITE (_bfd_generic),
00263   BFD_JUMP_TABLE_LINK (_bfd_nolink),
00264   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00265 
00266   NULL,
00267 
00268   (PTR) 0
00269 };