Back to index

cell-binutils  2.17cvs20070401
rs6000-core.c
Go to the documentation of this file.
00001 /* IBM RS/6000 "XCOFF" back-end for BFD.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
00003    2001, 2002, 2004, 2006
00004    Free Software Foundation, Inc.
00005    FIXME: Can someone provide a transliteration of this name into ASCII?
00006    Using the following chars caused a compiler warning on HIUX (so I replaced
00007    them with octal escapes), and isn't useful without an understanding of what
00008    character set it is.
00009    Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
00010      and John Gilmore.
00011    Archive support from Damon A. Permezel.
00012    Contributed by IBM Corporation and Cygnus Support.
00013 
00014    This file is part of BFD, the Binary File Descriptor library.
00015 
00016    This program is free software; you can redistribute it and/or modify
00017    it under the terms of the GNU General Public License as published by
00018    the Free Software Foundation; either version 2 of the License, or
00019    (at your option) any later version.
00020 
00021    This program is distributed in the hope that it will be useful,
00022    but WITHOUT ANY WARRANTY; without even the implied warranty of
00023    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024    GNU General Public License for more details.
00025 
00026    You should have received a copy of the GNU General Public License
00027    along with this program; if not, write to the Free Software
00028    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00029 
00030 /* This port currently only handles reading object files, except when
00031    compiled on an RS/6000 host.  -- no archive support, no core files.
00032    In all cases, it does not support writing.
00033 
00034    This is in a separate file from coff-rs6000.c, because it includes
00035    system include files that conflict with coff/rs6000.h.  */
00036 
00037 /* Internalcoff.h and coffcode.h modify themselves based on this flag.  */
00038 #define RS6000COFF_C 1
00039 
00040 /* The AIX 4.1 kernel is obviously compiled with -D_LONG_LONG, so
00041    we have to define _LONG_LONG for older versions of gcc to get the
00042    proper alignments in the user structure.  */
00043 #if defined(_AIX41) && !defined(_LONG_LONG)
00044 #define _LONG_LONG
00045 #endif
00046 
00047 #include "bfd.h"
00048 #include "sysdep.h"
00049 #include "libbfd.h"
00050 
00051 #ifdef AIX_CORE
00052 
00053 /* AOUTHDR is defined by the above.  We need another defn of it, from the
00054    system include files.  Punt the old one and get us a new name for the
00055    typedef in the system include files.  */
00056 #ifdef AOUTHDR
00057 #undef AOUTHDR
00058 #endif
00059 #define       AOUTHDR       second_AOUTHDR
00060 
00061 #undef SCNHDR
00062 
00063 /* ------------------------------------------------------------------------ */
00064 /*     Support for core file stuff..                                      */
00065 /* ------------------------------------------------------------------------ */
00066 
00067 #include <sys/user.h>
00068 #define __LDINFO_PTRACE32__ /* for __ld_info32 */
00069 #define __LDINFO_PTRACE64__ /* for __ld_info64 */
00070 #include <sys/ldr.h>
00071 #include <sys/core.h>
00072 #include <sys/systemcfg.h>
00073 
00074 /* Borrowed from <sys/inttypes.h> on recent AIX versions.  */
00075 typedef unsigned long ptr_to_uint;
00076 
00077 #define       core_hdr(bfd)        ((CoreHdr *) bfd->tdata.any)
00078 
00079 /* AIX 4.1 changed the names and locations of a few items in the core file.
00080    AIX 4.3 defined an entirely new structure, core_dumpx, but kept support for
00081    the previous 4.1 structure, core_dump.
00082 
00083    AIX_CORE_DUMPX_CORE is defined (by configure) on AIX 4.3+, and
00084    CORE_VERSION_1 is defined (by AIX core.h) as 2 on AIX 4.3+ and as 1 on AIX
00085    4.1 and 4.2.  AIX pre-4.1 (aka 3.x) either doesn't define CORE_VERSION_1
00086    or else defines it as 0.  */
00087 
00088 #if defined(CORE_VERSION_1) && !CORE_VERSION_1
00089 # undef CORE_VERSION_1
00090 #endif
00091 
00092 /* The following union and macros allow this module to compile on all AIX
00093    versions and to handle both core_dumpx and core_dump on 4.3+.  CNEW_*()
00094    and COLD_*() macros respectively retrieve core_dumpx and core_dump
00095    values.  */
00096 
00097 /* Union of 32-bit and 64-bit versions of ld_info.  */
00098 
00099 typedef union {
00100 #ifdef __ld_info32
00101   struct __ld_info32 l32;
00102   struct __ld_info64 l64;
00103 #else
00104   struct ld_info l32;
00105   struct ld_info l64;
00106 #endif
00107 } LdInfo;
00108 
00109 /* Union of old and new core dump structures.  */
00110 
00111 typedef union {
00112 #ifdef AIX_CORE_DUMPX_CORE
00113   struct core_dumpx new;    /* new AIX 4.3+ core dump */
00114 #else
00115   struct core_dump new;            /* for simpler coding */
00116 #endif
00117   struct core_dump old;            /* old AIX 4.2- core dump, still used on
00118                                4.3+ with appropriate SMIT config */
00119 } CoreHdr;
00120 
00121 /* Union of old and new vm_info structures.  */
00122 
00123 #ifdef CORE_VERSION_1
00124 typedef union {
00125 #ifdef AIX_CORE_DUMPX_CORE
00126   struct vm_infox new;
00127 #else
00128   struct vm_info new;
00129 #endif
00130   struct vm_info old;
00131 } VmInfo;
00132 #endif
00133 
00134 /* Return whether CoreHdr C is in new or old format.  */
00135 
00136 #ifdef AIX_CORE_DUMPX_CORE
00137 # define CORE_NEW(c) (!(c).old.c_entries)
00138 #else
00139 # define CORE_NEW(c) 0
00140 #endif
00141 
00142 /* Return the c_stackorg field from struct core_dumpx C.  */
00143 
00144 #ifdef AIX_CORE_DUMPX_CORE
00145 # define CNEW_STACKORG(c)   (c).c_stackorg
00146 #else
00147 # define CNEW_STACKORG(c)   0
00148 #endif
00149 
00150 /* Return the offset to the loader region from struct core_dump C.  */
00151 
00152 #ifdef AIX_CORE_DUMPX_CORE
00153 # define CNEW_LOADER(c)     (c).c_loader
00154 #else
00155 # define CNEW_LOADER(c)     0
00156 #endif
00157 
00158 /* Return the offset to the loader region from struct core_dump C.  */
00159 
00160 #define COLD_LOADER(c)      (c).c_tab
00161 
00162 /* Return the c_lsize field from struct core_dumpx C.  */
00163 
00164 #ifdef AIX_CORE_DUMPX_CORE
00165 # define CNEW_LSIZE(c)      (c).c_lsize
00166 #else
00167 # define CNEW_LSIZE(c)      0
00168 #endif
00169 
00170 /* Return the c_dataorg field from struct core_dumpx C.  */
00171 
00172 #ifdef AIX_CORE_DUMPX_CORE
00173 # define CNEW_DATAORG(c)    (c).c_dataorg
00174 #else
00175 # define CNEW_DATAORG(c)    0
00176 #endif
00177 
00178 /* Return the c_datasize field from struct core_dumpx C.  */
00179 
00180 #ifdef AIX_CORE_DUMPX_CORE
00181 # define CNEW_DATASIZE(c)   (c).c_datasize
00182 #else
00183 # define CNEW_DATASIZE(c)   0
00184 #endif
00185 
00186 /* Return the c_impl field from struct core_dumpx C.  */
00187 
00188 #if defined (HAVE_ST_C_IMPL) || defined (AIX_5_CORE)
00189 # define CNEW_IMPL(c)       (c).c_impl
00190 #else
00191 # define CNEW_IMPL(c)       0
00192 #endif
00193 
00194 /* Return the command string from struct core_dumpx C.  */
00195 
00196 #ifdef AIX_CORE_DUMPX_CORE
00197 # define CNEW_COMM(c)       (c).c_u.U_proc.pi_comm
00198 #else
00199 # define CNEW_COMM(c)       0
00200 #endif
00201 
00202 /* Return the command string from struct core_dump C.  */
00203 
00204 #ifdef CORE_VERSION_1
00205 # define COLD_COMM(c)       (c).c_u.U_comm
00206 #else
00207 # define COLD_COMM(c)       (c).c_u.u_comm
00208 #endif
00209 
00210 /* Return the struct __context64 pointer from struct core_dumpx C.  */
00211 
00212 #ifdef AIX_CORE_DUMPX_CORE
00213 # define CNEW_CONTEXT64(c)  (c).c_flt.hctx.r64
00214 #else
00215 # define CNEW_CONTEXT64(c)  c
00216 #endif
00217 
00218 /* Return the struct mstsave pointer from struct core_dumpx C.  */
00219 
00220 #ifdef AIX_CORE_DUMPX_CORE
00221 # define CNEW_MSTSAVE(c)    (c).c_flt.hctx.r32
00222 #else
00223 # define CNEW_MSTSAVE(c)    c
00224 #endif
00225 
00226 /* Return the struct mstsave pointer from struct core_dump C.  */
00227 
00228 #ifdef CORE_VERSION_1
00229 # define COLD_MSTSAVE(c)    (c).c_mst
00230 #else
00231 # define COLD_MSTSAVE(c)    (c).c_u.u_save
00232 #endif
00233 
00234 /* Return whether struct core_dumpx is from a 64-bit process.  */
00235 
00236 #ifdef AIX_CORE_DUMPX_CORE
00237 # define CNEW_PROC64(c)            IS_PROC64(&(c).c_u.U_proc)
00238 #else
00239 # define CNEW_PROC64(c)            0
00240 #endif
00241 
00242 /* Magic end-of-stack addresses for old core dumps.  This is _very_ fragile,
00243    but I don't see any easy way to get that info right now.  */
00244 
00245 #ifdef CORE_VERSION_1
00246 # define COLD_STACKEND      0x2ff23000
00247 #else
00248 # define COLD_STACKEND      0x2ff80000
00249 #endif
00250 
00251 /* Size of the leading portion that old and new core dump structures have in
00252    common.  */
00253 #define CORE_COMMONSZ       ((int) &((struct core_dump *) 0)->c_entries \
00254                       + sizeof (((struct core_dump *) 0)->c_entries))
00255 
00256 /* Define prototypes for certain functions, to avoid a compiler warning
00257    saying that they are missing.  */
00258 
00259 const bfd_target * rs6000coff_core_p (bfd *abfd);
00260 bfd_boolean rs6000coff_core_file_matches_executable_p (bfd *core_bfd,
00261                                                        bfd *exec_bfd);
00262 char * rs6000coff_core_file_failing_command (bfd *abfd);
00263 int rs6000coff_core_file_failing_signal (bfd *abfd);
00264 
00265 /* Try to read into CORE the header from the core file associated with ABFD.
00266    Return success.  */
00267 
00268 static bfd_boolean
00269 read_hdr (bfd *abfd, CoreHdr *core)
00270 {
00271   bfd_size_type size;
00272 
00273   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
00274     return FALSE;
00275 
00276   /* Read the leading portion that old and new core dump structures have in
00277      common.  */
00278   size = CORE_COMMONSZ;
00279   if (bfd_bread (core, size, abfd) != size)
00280     return FALSE;
00281 
00282   /* Read the trailing portion of the structure.  */
00283   if (CORE_NEW (*core))
00284     size = sizeof (core->new);
00285   else
00286     size = sizeof (core->old);
00287   size -= CORE_COMMONSZ;
00288   return bfd_bread ((char *) core + CORE_COMMONSZ, size, abfd) == size;
00289 }
00290 
00291 static asection *
00292 make_bfd_asection (bfd *abfd, const char *name, flagword flags,
00293                  bfd_size_type size, bfd_vma vma, file_ptr filepos)
00294 {
00295   asection *asect;
00296 
00297   asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
00298   if (!asect)
00299     return NULL;
00300 
00301   asect->size = size;
00302   asect->vma = vma;
00303   asect->filepos = filepos;
00304   asect->alignment_power = 8;
00305 
00306   return asect;
00307 }
00308 
00309 /* Decide if a given bfd represents a `core' file or not. There really is no
00310    magic number or anything like, in rs6000coff.  */
00311 
00312 const bfd_target *
00313 rs6000coff_core_p (bfd *abfd)
00314 {
00315   CoreHdr core;
00316   struct stat statbuf;
00317   bfd_size_type size;
00318   char *tmpptr;
00319 
00320   /* Values from new and old core structures.  */
00321   int c_flag;
00322   file_ptr c_stack, c_regoff, c_loader;
00323   bfd_size_type c_size, c_regsize, c_lsize;
00324   bfd_vma c_stackend;
00325   void *c_regptr;
00326   int proc64;
00327 
00328   if (!read_hdr (abfd, &core))
00329     {
00330       if (bfd_get_error () != bfd_error_system_call)
00331        bfd_set_error (bfd_error_wrong_format);
00332       return NULL;
00333     }
00334 
00335   /* Copy fields from new or old core structure.  */
00336   if (CORE_NEW (core))
00337     {
00338       c_flag = core.new.c_flag;
00339       c_stack = (file_ptr) core.new.c_stack;
00340       c_size = core.new.c_size;
00341       c_stackend = CNEW_STACKORG (core.new) + c_size;
00342       c_lsize = CNEW_LSIZE (core.new);
00343       c_loader = CNEW_LOADER (core.new);
00344       proc64 = CNEW_PROC64 (core.new);
00345     }
00346   else
00347     {
00348       c_flag = core.old.c_flag;
00349       c_stack = (file_ptr) (ptr_to_uint) core.old.c_stack;
00350       c_size = core.old.c_size;
00351       c_stackend = COLD_STACKEND;
00352       c_lsize = 0x7ffffff;
00353       c_loader = (file_ptr) (ptr_to_uint) COLD_LOADER (core.old);
00354       proc64 = 0;
00355     }
00356 
00357   if (proc64)
00358     {
00359       c_regsize = sizeof (CNEW_CONTEXT64 (core.new));
00360       c_regptr = &CNEW_CONTEXT64 (core.new);
00361     }
00362   else if (CORE_NEW (core))
00363     {
00364       c_regsize = sizeof (CNEW_MSTSAVE (core.new));
00365       c_regptr = &CNEW_MSTSAVE (core.new);
00366     }
00367   else
00368     {
00369       c_regsize = sizeof (COLD_MSTSAVE (core.old));
00370       c_regptr = &COLD_MSTSAVE (core.old);
00371     }
00372   c_regoff = (char *) c_regptr - (char *) &core;
00373 
00374   if (bfd_stat (abfd, &statbuf) < 0)
00375     {
00376       bfd_set_error (bfd_error_system_call);
00377       return NULL;
00378     }
00379 
00380   /* If the core file ulimit is too small, the system will first
00381      omit the data segment, then omit the stack, then decline to
00382      dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
00383      are always set) (this is based on experimentation on AIX 3.2).
00384      Now, the thing is that GDB users will be surprised
00385      if segments just silently don't appear (well, maybe they would
00386      think to check "info files", I don't know).
00387 
00388      For the data segment, we have no choice but to keep going if it's
00389      not there, since the default behavior is not to dump it (regardless
00390      of the ulimit, it's based on SA_FULLDUMP).  But for the stack segment,
00391      if it's not there, we refuse to have anything to do with this core
00392      file.  The usefulness of a core dump without a stack segment is pretty
00393      limited anyway.  */
00394 
00395   if (!(c_flag & UBLOCK_VALID)
00396       || !(c_flag & LE_VALID))
00397     {
00398       bfd_set_error (bfd_error_wrong_format);
00399       return NULL;
00400     }
00401 
00402   if (!(c_flag & USTACK_VALID))
00403     {
00404       bfd_set_error (bfd_error_file_truncated);
00405       return NULL;
00406     }
00407 
00408   /* Don't check the core file size for a full core, AIX 4.1 includes
00409      additional shared library sections in a full core.  */
00410   if (!(c_flag & (FULL_CORE | CORE_TRUNC)))
00411     {
00412       /* If the size is wrong, it means we're misinterpreting something.  */
00413       if (c_stack + (file_ptr) c_size != statbuf.st_size)
00414        {
00415          bfd_set_error (bfd_error_wrong_format);
00416          return NULL;
00417        }
00418     }
00419 
00420   /* Sanity check on the c_tab field.  */
00421   if (!CORE_NEW (core) && (c_loader < (file_ptr) sizeof core.old ||
00422                         c_loader >= statbuf.st_size ||
00423                         c_loader >= c_stack))
00424     {
00425       bfd_set_error (bfd_error_wrong_format);
00426       return NULL;
00427     }
00428 
00429   /* Issue warning if the core file was truncated during writing.  */
00430   if (c_flag & CORE_TRUNC)
00431     (*_bfd_error_handler) (_("%s: warning core file truncated"),
00432                         bfd_get_filename (abfd));
00433 
00434   /* Allocate core file header.  */
00435   size = CORE_NEW (core) ? sizeof (core.new) : sizeof (core.old);
00436   tmpptr = (char *) bfd_zalloc (abfd, (bfd_size_type) size);
00437   if (!tmpptr)
00438     return NULL;
00439 
00440   /* Copy core file header.  */
00441   memcpy (tmpptr, &core, size);
00442   set_tdata (abfd, tmpptr);
00443 
00444   /* Set architecture.  */
00445   if (CORE_NEW (core))
00446     {
00447       enum bfd_architecture arch;
00448       unsigned long mach;
00449 
00450       switch (CNEW_IMPL (core.new))
00451        {
00452        case POWER_RS1:
00453        case POWER_RSC:
00454        case POWER_RS2:
00455          arch = bfd_arch_rs6000;
00456          mach = bfd_mach_rs6k;
00457          break;
00458        default:
00459          arch = bfd_arch_powerpc;
00460          mach = bfd_mach_ppc;
00461          break;
00462        }
00463       bfd_default_set_arch_mach (abfd, arch, mach);
00464     }
00465 
00466   /* .stack section.  */
00467   if (!make_bfd_asection (abfd, ".stack",
00468                        SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
00469                        c_size, c_stackend - c_size, c_stack))
00470     goto fail;
00471 
00472   /* .reg section for all registers.  */
00473   if (!make_bfd_asection (abfd, ".reg",
00474                        SEC_HAS_CONTENTS,
00475                        c_regsize, (bfd_vma) 0, c_regoff))
00476     goto fail;
00477 
00478   /* .ldinfo section.
00479      To actually find out how long this section is in this particular
00480      core dump would require going down the whole list of struct ld_info's.
00481      See if we can just fake it.  */
00482   if (!make_bfd_asection (abfd, ".ldinfo",
00483                        SEC_HAS_CONTENTS,
00484                        c_lsize, (bfd_vma) 0, c_loader))
00485     goto fail;
00486 
00487 #ifndef CORE_VERSION_1
00488   /* .data section if present.
00489      AIX 3 dumps the complete data section and sets FULL_CORE if the
00490      ulimit is large enough, otherwise the data section is omitted.
00491      AIX 4 sets FULL_CORE even if the core file is truncated, we have
00492      to examine core.c_datasize below to find out the actual size of
00493      the .data section.  */
00494   if (c_flag & FULL_CORE)
00495     {
00496       if (!make_bfd_asection (abfd, ".data",
00497                            SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
00498                            (bfd_size_type) core.old.c_u.u_dsize,
00499                            (bfd_vma)
00500                             CDATA_ADDR (core.old.c_u.u_dsize),
00501                            c_stack + c_size))
00502        goto fail;
00503     }
00504 #endif
00505 
00506 #ifdef CORE_VERSION_1
00507   /* AIX 4 adds data sections from loaded objects to the core file,
00508      which can be found by examining ldinfo, and anonymously mmapped
00509      regions.  */
00510   {
00511     LdInfo ldinfo;
00512     bfd_size_type ldi_datasize;
00513     file_ptr ldi_core;
00514     uint ldi_next;
00515     bfd_vma ldi_dataorg;
00516 
00517     /* Fields from new and old core structures.  */
00518     bfd_size_type c_datasize, c_vmregions;
00519     file_ptr c_data, c_vmm;
00520 
00521     if (CORE_NEW (core))
00522       {
00523        c_datasize = CNEW_DATASIZE (core.new);
00524        c_data = (file_ptr) core.new.c_data;
00525        c_vmregions = core.new.c_vmregions;
00526        c_vmm = (file_ptr) core.new.c_vmm;
00527       }
00528     else
00529       {
00530        c_datasize = core.old.c_datasize;
00531        c_data = (file_ptr) (ptr_to_uint) core.old.c_data;
00532        c_vmregions = core.old.c_vmregions;
00533        c_vmm = (file_ptr) (ptr_to_uint) core.old.c_vmm;
00534       }
00535 
00536     /* .data section from executable.  */
00537     if (c_datasize)
00538       {
00539        if (!make_bfd_asection (abfd, ".data",
00540                             SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
00541                             c_datasize,
00542                             (bfd_vma) CDATA_ADDR (c_datasize),
00543                             c_data))
00544          goto fail;
00545       }
00546 
00547     /* .data sections from loaded objects.  */
00548     if (proc64)
00549       size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;
00550     else
00551       size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;
00552 
00553     while (1)
00554       {
00555        if (bfd_seek (abfd, c_loader, SEEK_SET) != 0)
00556          goto fail;
00557        if (bfd_bread (&ldinfo, size, abfd) != size)
00558          goto fail;
00559 
00560        if (proc64)
00561          {
00562            ldi_core = ldinfo.l64.ldinfo_core;
00563            ldi_datasize = ldinfo.l64.ldinfo_datasize;
00564            ldi_dataorg = (bfd_vma) ldinfo.l64.ldinfo_dataorg;
00565            ldi_next = ldinfo.l64.ldinfo_next;
00566          }
00567        else
00568          {
00569            ldi_core = ldinfo.l32.ldinfo_core;
00570            ldi_datasize = ldinfo.l32.ldinfo_datasize;
00571            ldi_dataorg = (bfd_vma) (long) ldinfo.l32.ldinfo_dataorg;
00572            ldi_next = ldinfo.l32.ldinfo_next;
00573          }
00574 
00575        if (ldi_core)
00576          if (!make_bfd_asection (abfd, ".data",
00577                               SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
00578                               ldi_datasize, ldi_dataorg, ldi_core))
00579            goto fail;
00580 
00581        if (ldi_next == 0)
00582          break;
00583        c_loader += ldi_next;
00584       }
00585 
00586     /* .vmdata sections from anonymously mmapped regions.  */
00587     if (c_vmregions)
00588       {
00589        bfd_size_type i;
00590 
00591        if (bfd_seek (abfd, c_vmm, SEEK_SET) != 0)
00592          goto fail;
00593 
00594        for (i = 0; i < c_vmregions; i++)
00595          {
00596            VmInfo vminfo;
00597            bfd_size_type vminfo_size;
00598            file_ptr vminfo_offset;
00599            bfd_vma vminfo_addr;
00600 
00601            size = CORE_NEW (core) ? sizeof (vminfo.new) : sizeof (vminfo.old);
00602            if (bfd_bread (&vminfo, size, abfd) != size)
00603              goto fail;
00604 
00605            if (CORE_NEW (core))
00606              {
00607               vminfo_addr = (bfd_vma) vminfo.new.vminfo_addr;
00608               vminfo_size = vminfo.new.vminfo_size;
00609               vminfo_offset = vminfo.new.vminfo_offset;
00610              }
00611            else
00612              {
00613               vminfo_addr = (bfd_vma) (long) vminfo.old.vminfo_addr;
00614               vminfo_size = vminfo.old.vminfo_size;
00615               vminfo_offset = vminfo.old.vminfo_offset;
00616              }
00617 
00618            if (vminfo_offset)
00619              if (!make_bfd_asection (abfd, ".vmdata",
00620                                   SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
00621                                   vminfo_size, vminfo_addr,
00622                                   vminfo_offset))
00623               goto fail;
00624          }
00625       }
00626   }
00627 #endif
00628 
00629   return abfd->xvec;        /* This is garbage for now.  */
00630 
00631  fail:
00632   bfd_release (abfd, abfd->tdata.any);
00633   abfd->tdata.any = NULL;
00634   bfd_section_list_clear (abfd);
00635   return NULL;
00636 }
00637 
00638 /* Return `TRUE' if given core is from the given executable.  */
00639 
00640 bfd_boolean
00641 rs6000coff_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
00642 {
00643   CoreHdr core;
00644   bfd_size_type size;
00645   char *path, *s;
00646   size_t alloc;
00647   const char *str1, *str2;
00648   bfd_boolean ret;
00649   file_ptr c_loader;
00650 
00651   if (!read_hdr (core_bfd, &core))
00652     return FALSE;
00653 
00654   if (CORE_NEW (core))
00655     c_loader = CNEW_LOADER (core.new);
00656   else
00657     c_loader = (file_ptr) (ptr_to_uint) COLD_LOADER (core.old);
00658 
00659   if (CORE_NEW (core) && CNEW_PROC64 (core.new))
00660     size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;
00661   else
00662     size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;
00663 
00664   if (bfd_seek (core_bfd, c_loader + size, SEEK_SET) != 0)
00665     return FALSE;
00666 
00667   alloc = 100;
00668   path = bfd_malloc ((bfd_size_type) alloc);
00669   if (path == NULL)
00670     return FALSE;
00671   s = path;
00672 
00673   while (1)
00674     {
00675       if (bfd_bread (s, (bfd_size_type) 1, core_bfd) != 1)
00676        {
00677          free (path);
00678          return FALSE;
00679        }
00680       if (*s == '\0')
00681        break;
00682       ++s;
00683       if (s == path + alloc)
00684        {
00685          char *n;
00686 
00687          alloc *= 2;
00688          n = bfd_realloc (path, (bfd_size_type) alloc);
00689          if (n == NULL)
00690            {
00691              free (path);
00692              return FALSE;
00693            }
00694          s = n + (path - s);
00695          path = n;
00696        }
00697     }
00698 
00699   str1 = strrchr (path, '/');
00700   str2 = strrchr (exec_bfd->filename, '/');
00701 
00702   /* step over character '/' */
00703   str1 = str1 != NULL ? str1 + 1 : path;
00704   str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
00705 
00706   if (strcmp (str1, str2) == 0)
00707     ret = TRUE;
00708   else
00709     ret = FALSE;
00710 
00711   free (path);
00712 
00713   return ret;
00714 }
00715 
00716 char *
00717 rs6000coff_core_file_failing_command (bfd *abfd)
00718 {
00719   CoreHdr *core = core_hdr (abfd);
00720   char *com = CORE_NEW (*core) ?
00721     CNEW_COMM (core->new) : COLD_COMM (core->old);
00722 
00723   if (*com)
00724     return com;
00725   else
00726     return 0;
00727 }
00728 
00729 int
00730 rs6000coff_core_file_failing_signal (bfd *abfd)
00731 {
00732   CoreHdr *core = core_hdr (abfd);
00733   return CORE_NEW (*core) ? core->new.c_signo : core->old.c_signo;
00734 }
00735 
00736 #endif /* AIX_CORE */