1 /* IBM RS/6000 "XCOFF" back-end for BFD.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
3    2001, 2002, 2004, 2006, 2007, 2008
4    Free Software Foundation, Inc.
5    Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, and John Gilmore.
6    Archive support from Damon A. Permezel.
7    Contributed by IBM Corporation and Cygnus Support.
8 
9    This file is part of BFD, the Binary File Descriptor library.
10 
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
24    MA 02110-1301, USA.  */
25 
26 
27 /* This port currently only handles reading object files, except when
28    compiled on an RS/6000 host.  -- no archive support, no core files.
29    In all cases, it does not support writing.
30 
31    This is in a separate file from coff-rs6000.c, because it includes
32    system include files that conflict with coff/rs6000.h.  */
33 
34 /* Internalcoff.h and coffcode.h modify themselves based on this flag.  */
35 #define RS6000COFF_C 1
36 
37 /* The AIX 4.1 kernel is obviously compiled with -D_LONG_LONG, so
38    we have to define _LONG_LONG for older versions of gcc to get the
39    proper alignments in the user structure.  */
40 #if defined(_AIX41) && !defined(_LONG_LONG)
41 #define _LONG_LONG
42 #endif
43 
44 #include "sysdep.h"
45 #include "bfd.h"
46 #include "libbfd.h"
47 
48 #ifdef AIX_CORE
49 
50 /* AOUTHDR is defined by the above.  We need another defn of it, from the
51    system include files.  Punt the old one and get us a new name for the
52    typedef in the system include files.  */
53 #ifdef AOUTHDR
54 #undef AOUTHDR
55 #endif
56 #define	AOUTHDR	second_AOUTHDR
57 
58 #undef	SCNHDR
59 
60 /* ------------------------------------------------------------------------ */
61 /*	Support for core file stuff..					    */
62 /* ------------------------------------------------------------------------ */
63 
64 #include <sys/user.h>
65 #define __LDINFO_PTRACE32__	/* for __ld_info32 */
66 #define __LDINFO_PTRACE64__	/* for __ld_info64 */
67 #include <sys/ldr.h>
68 #include <sys/core.h>
69 #include <sys/systemcfg.h>
70 
71 /* Borrowed from <sys/inttypes.h> on recent AIX versions.  */
72 typedef unsigned long ptr_to_uint;
73 
74 #define	core_hdr(bfd)		((CoreHdr *) bfd->tdata.any)
75 
76 /* AIX 4.1 changed the names and locations of a few items in the core file.
77    AIX 4.3 defined an entirely new structure, core_dumpx, but kept support for
78    the previous 4.1 structure, core_dump.
79 
80    AIX_CORE_DUMPX_CORE is defined (by configure) on AIX 4.3+, and
81    CORE_VERSION_1 is defined (by AIX core.h) as 2 on AIX 4.3+ and as 1 on AIX
82    4.1 and 4.2.  AIX pre-4.1 (aka 3.x) either doesn't define CORE_VERSION_1
83    or else defines it as 0.  */
84 
85 #if defined(CORE_VERSION_1) && !CORE_VERSION_1
86 # undef CORE_VERSION_1
87 #endif
88 
89 /* The following union and macros allow this module to compile on all AIX
90    versions and to handle both core_dumpx and core_dump on 4.3+.  CNEW_*()
91    and COLD_*() macros respectively retrieve core_dumpx and core_dump
92    values.  */
93 
94 /* Union of 32-bit and 64-bit versions of ld_info.  */
95 
96 typedef union {
97 #ifdef __ld_info32
98   struct __ld_info32 l32;
99   struct __ld_info64 l64;
100 #else
101   struct ld_info l32;
102   struct ld_info l64;
103 #endif
104 } LdInfo;
105 
106 /* Union of old and new core dump structures.  */
107 
108 typedef union {
109 #ifdef AIX_CORE_DUMPX_CORE
110   struct core_dumpx new;	/* new AIX 4.3+ core dump */
111 #else
112   struct core_dump new;		/* for simpler coding */
113 #endif
114   struct core_dump old;		/* old AIX 4.2- core dump, still used on
115 				   4.3+ with appropriate SMIT config */
116 } CoreHdr;
117 
118 /* Union of old and new vm_info structures.  */
119 
120 #ifdef CORE_VERSION_1
121 typedef union {
122 #ifdef AIX_CORE_DUMPX_CORE
123   struct vm_infox new;
124 #else
125   struct vm_info new;
126 #endif
127   struct vm_info old;
128 } VmInfo;
129 #endif
130 
131 /* Return whether CoreHdr C is in new or old format.  */
132 
133 #ifdef AIX_CORE_DUMPX_CORE
134 # define CORE_NEW(c)	(!(c).old.c_entries)
135 #else
136 # define CORE_NEW(c)	0
137 #endif
138 
139 /* Return whether CoreHdr C usese core_dumpxx structure.
140 
141    FIXME: the core file format version number used here definitely indicates
142    that struct core_dumpxx should be used to represent the core file header,
143    but that may not be the only such format version number.  */
144 
145 #ifdef AIX_5_CORE
146 # define CORE_DUMPXX_VERSION  	267312562
147 # define CNEW_IS_CORE_DUMPXX(c) ((c).new.c_version == CORE_DUMPXX_VERSION)
148 #else
149 # define CNEW_IS_CORE_DUMPXX(c) 0
150 #endif
151 
152 /* Return the c_stackorg field from struct core_dumpx C.  */
153 
154 #ifdef AIX_CORE_DUMPX_CORE
155 # define CNEW_STACKORG(c)	(c).c_stackorg
156 #else
157 # define CNEW_STACKORG(c)	0
158 #endif
159 
160 /* Return the offset to the loader region from struct core_dump C.  */
161 
162 #ifdef AIX_CORE_DUMPX_CORE
163 # define CNEW_LOADER(c)	(c).c_loader
164 #else
165 # define CNEW_LOADER(c)	0
166 #endif
167 
168 /* Return the offset to the loader region from struct core_dump C.  */
169 
170 #define COLD_LOADER(c)	(c).c_tab
171 
172 /* Return the c_lsize field from struct core_dumpx C.  */
173 
174 #ifdef AIX_CORE_DUMPX_CORE
175 # define CNEW_LSIZE(c)	(c).c_lsize
176 #else
177 # define CNEW_LSIZE(c)	0
178 #endif
179 
180 /* Return the c_dataorg field from struct core_dumpx C.  */
181 
182 #ifdef AIX_CORE_DUMPX_CORE
183 # define CNEW_DATAORG(c)	(c).c_dataorg
184 #else
185 # define CNEW_DATAORG(c)	0
186 #endif
187 
188 /* Return the c_datasize field from struct core_dumpx C.  */
189 
190 #ifdef AIX_CORE_DUMPX_CORE
191 # define CNEW_DATASIZE(c)	(c).c_datasize
192 #else
193 # define CNEW_DATASIZE(c)	0
194 #endif
195 
196 /* Return the c_impl field from struct core_dumpx C.  */
197 
198 #if defined (HAVE_ST_C_IMPL) || defined (AIX_5_CORE)
199 # define CNEW_IMPL(c)	(c).c_impl
200 #else
201 # define CNEW_IMPL(c)	0
202 #endif
203 
204 /* Return the command string from struct core_dumpx C.  */
205 
206 #ifdef AIX_CORE_DUMPX_CORE
207 # define CNEW_COMM(c)	(c).c_u.U_proc.pi_comm
208 #else
209 # define CNEW_COMM(c)	0
210 #endif
211 
212 /* Return the command string from struct core_dump C.  */
213 
214 #ifdef CORE_VERSION_1
215 # define COLD_COMM(c)	(c).c_u.U_comm
216 #else
217 # define COLD_COMM(c)	(c).c_u.u_comm
218 #endif
219 
220 /* Return the struct __context64 pointer from struct core_dumpx C.  */
221 
222 #ifdef AIX_CORE_DUMPX_CORE
223 # define CNEW_CONTEXT64(c)	(c).c_flt.hctx.r64
224 #else
225 # define CNEW_CONTEXT64(c)	c
226 #endif
227 
228 /* Return the struct mstsave pointer from struct core_dumpx C.  */
229 
230 #ifdef AIX_CORE_DUMPX_CORE
231 # define CNEW_MSTSAVE(c)	(c).c_flt.hctx.r32
232 #else
233 # define CNEW_MSTSAVE(c)	c
234 #endif
235 
236 /* Return the struct mstsave pointer from struct core_dump C.  */
237 
238 #ifdef CORE_VERSION_1
239 # define COLD_MSTSAVE(c)	(c).c_mst
240 #else
241 # define COLD_MSTSAVE(c)	(c).c_u.u_save
242 #endif
243 
244 /* Return whether struct core_dumpx is from a 64-bit process.  */
245 
246 #ifdef AIX_CORE_DUMPX_CORE
247 # define CNEW_PROC64(c)		IS_PROC64(&(c).c_u.U_proc)
248 #else
249 # define CNEW_PROC64(c)		0
250 #endif
251 
252 /* Magic end-of-stack addresses for old core dumps.  This is _very_ fragile,
253    but I don't see any easy way to get that info right now.  */
254 
255 #ifdef CORE_VERSION_1
256 # define COLD_STACKEND	0x2ff23000
257 #else
258 # define COLD_STACKEND	0x2ff80000
259 #endif
260 
261 /* Size of the leading portion that old and new core dump structures have in
262    common.  */
263 #define CORE_COMMONSZ	((int) &((struct core_dump *) 0)->c_entries \
264 			 + sizeof (((struct core_dump *) 0)->c_entries))
265 
266 /* Define prototypes for certain functions, to avoid a compiler warning
267    saying that they are missing.  */
268 
269 const bfd_target * rs6000coff_core_p (bfd *abfd);
270 bfd_boolean rs6000coff_core_file_matches_executable_p (bfd *core_bfd,
271                                                        bfd *exec_bfd);
272 char * rs6000coff_core_file_failing_command (bfd *abfd);
273 int rs6000coff_core_file_failing_signal (bfd *abfd);
274 
275 /* Try to read into CORE the header from the core file associated with ABFD.
276    Return success.  */
277 
278 static bfd_boolean
279 read_hdr (bfd *abfd, CoreHdr *core)
280 {
281   bfd_size_type size;
282 
283   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
284     return FALSE;
285 
286   /* Read the leading portion that old and new core dump structures have in
287      common.  */
288   size = CORE_COMMONSZ;
289   if (bfd_bread (core, size, abfd) != size)
290     return FALSE;
291 
292   /* Read the trailing portion of the structure.  */
293   if (CORE_NEW (*core))
294     size = sizeof (core->new);
295   else
296     size = sizeof (core->old);
297   size -= CORE_COMMONSZ;
298   return bfd_bread ((char *) core + CORE_COMMONSZ, size, abfd) == size;
299 }
300 
301 static asection *
302 make_bfd_asection (bfd *abfd, const char *name, flagword flags,
303 		   bfd_size_type size, bfd_vma vma, file_ptr filepos)
304 {
305   asection *asect;
306 
307   asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
308   if (!asect)
309     return NULL;
310 
311   asect->size = size;
312   asect->vma = vma;
313   asect->filepos = filepos;
314   asect->alignment_power = 8;
315 
316   return asect;
317 }
318 
319 /* Decide if a given bfd represents a `core' file or not. There really is no
320    magic number or anything like, in rs6000coff.  */
321 
322 const bfd_target *
323 rs6000coff_core_p (bfd *abfd)
324 {
325   CoreHdr core;
326   struct stat statbuf;
327   bfd_size_type size;
328   char *tmpptr;
329 
330   /* Values from new and old core structures.  */
331   int c_flag;
332   file_ptr c_stack, c_regoff, c_loader;
333   bfd_size_type c_size, c_regsize, c_lsize;
334   bfd_vma c_stackend;
335   void *c_regptr;
336   int proc64;
337 
338   if (!read_hdr (abfd, &core))
339     {
340       if (bfd_get_error () != bfd_error_system_call)
341 	bfd_set_error (bfd_error_wrong_format);
342       return NULL;
343     }
344 
345   /* This isn't the right handler for 64-bit core files on AIX 5.x.  */
346   if (CORE_NEW (core) && CNEW_IS_CORE_DUMPXX (core))
347     {
348       bfd_set_error (bfd_error_wrong_format);
349       return NULL;
350     }
351 
352   /* Copy fields from new or old core structure.  */
353   if (CORE_NEW (core))
354     {
355       c_flag = core.new.c_flag;
356       c_stack = (file_ptr) core.new.c_stack;
357       c_size = core.new.c_size;
358       c_stackend = CNEW_STACKORG (core.new) + c_size;
359       c_lsize = CNEW_LSIZE (core.new);
360       c_loader = CNEW_LOADER (core.new);
361       proc64 = CNEW_PROC64 (core.new);
362     }
363   else
364     {
365       c_flag = core.old.c_flag;
366       c_stack = (file_ptr) (ptr_to_uint) core.old.c_stack;
367       c_size = core.old.c_size;
368       c_stackend = COLD_STACKEND;
369       c_lsize = 0x7ffffff;
370       c_loader = (file_ptr) (ptr_to_uint) COLD_LOADER (core.old);
371       proc64 = 0;
372     }
373 
374   if (proc64)
375     {
376       c_regsize = sizeof (CNEW_CONTEXT64 (core.new));
377       c_regptr = &CNEW_CONTEXT64 (core.new);
378     }
379   else if (CORE_NEW (core))
380     {
381       c_regsize = sizeof (CNEW_MSTSAVE (core.new));
382       c_regptr = &CNEW_MSTSAVE (core.new);
383     }
384   else
385     {
386       c_regsize = sizeof (COLD_MSTSAVE (core.old));
387       c_regptr = &COLD_MSTSAVE (core.old);
388     }
389   c_regoff = (char *) c_regptr - (char *) &core;
390 
391   if (bfd_stat (abfd, &statbuf) < 0)
392     {
393       bfd_set_error (bfd_error_system_call);
394       return NULL;
395     }
396 
397   /* If the core file ulimit is too small, the system will first
398      omit the data segment, then omit the stack, then decline to
399      dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
400      are always set) (this is based on experimentation on AIX 3.2).
401      Now, the thing is that GDB users will be surprised
402      if segments just silently don't appear (well, maybe they would
403      think to check "info files", I don't know).
404 
405      For the data segment, we have no choice but to keep going if it's
406      not there, since the default behavior is not to dump it (regardless
407      of the ulimit, it's based on SA_FULLDUMP).  But for the stack segment,
408      if it's not there, we refuse to have anything to do with this core
409      file.  The usefulness of a core dump without a stack segment is pretty
410      limited anyway.  */
411 
412   if (!(c_flag & UBLOCK_VALID)
413       || !(c_flag & LE_VALID))
414     {
415       bfd_set_error (bfd_error_wrong_format);
416       return NULL;
417     }
418 
419   if (!(c_flag & USTACK_VALID))
420     {
421       bfd_set_error (bfd_error_file_truncated);
422       return NULL;
423     }
424 
425   /* Don't check the core file size for a full core, AIX 4.1 includes
426      additional shared library sections in a full core.  */
427   if (!(c_flag & (FULL_CORE | CORE_TRUNC)))
428     {
429       /* If the size is wrong, it means we're misinterpreting something.  */
430       if (c_stack + (file_ptr) c_size != statbuf.st_size)
431 	{
432 	  bfd_set_error (bfd_error_wrong_format);
433 	  return NULL;
434 	}
435     }
436 
437   /* Sanity check on the c_tab field.  */
438   if (!CORE_NEW (core) && (c_loader < (file_ptr) sizeof core.old ||
439 			   c_loader >= statbuf.st_size ||
440 			   c_loader >= c_stack))
441     {
442       bfd_set_error (bfd_error_wrong_format);
443       return NULL;
444     }
445 
446   /* Issue warning if the core file was truncated during writing.  */
447   if (c_flag & CORE_TRUNC)
448     (*_bfd_error_handler) (_("%s: warning core file truncated"),
449 			   bfd_get_filename (abfd));
450 
451   /* Allocate core file header.  */
452   size = CORE_NEW (core) ? sizeof (core.new) : sizeof (core.old);
453   tmpptr = (char *) bfd_zalloc (abfd, (bfd_size_type) size);
454   if (!tmpptr)
455     return NULL;
456 
457   /* Copy core file header.  */
458   memcpy (tmpptr, &core, size);
459   set_tdata (abfd, tmpptr);
460 
461   /* Set architecture.  */
462   if (CORE_NEW (core))
463     {
464       enum bfd_architecture arch;
465       unsigned long mach;
466 
467       switch (CNEW_IMPL (core.new))
468 	{
469 	case POWER_RS1:
470 	case POWER_RSC:
471 	case POWER_RS2:
472 	  arch = bfd_arch_rs6000;
473 	  mach = bfd_mach_rs6k;
474 	  break;
475 	default:
476 	  arch = bfd_arch_powerpc;
477 	  mach = bfd_mach_ppc;
478 	  break;
479 	}
480       bfd_default_set_arch_mach (abfd, arch, mach);
481     }
482 
483   /* .stack section.  */
484   if (!make_bfd_asection (abfd, ".stack",
485 			  SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
486 			  c_size, c_stackend - c_size, c_stack))
487     goto fail;
488 
489   /* .reg section for all registers.  */
490   if (!make_bfd_asection (abfd, ".reg",
491 			  SEC_HAS_CONTENTS,
492 			  c_regsize, (bfd_vma) 0, c_regoff))
493     goto fail;
494 
495   /* .ldinfo section.
496      To actually find out how long this section is in this particular
497      core dump would require going down the whole list of struct ld_info's.
498      See if we can just fake it.  */
499   if (!make_bfd_asection (abfd, ".ldinfo",
500 			  SEC_HAS_CONTENTS,
501 			  c_lsize, (bfd_vma) 0, c_loader))
502     goto fail;
503 
504 #ifndef CORE_VERSION_1
505   /* .data section if present.
506      AIX 3 dumps the complete data section and sets FULL_CORE if the
507      ulimit is large enough, otherwise the data section is omitted.
508      AIX 4 sets FULL_CORE even if the core file is truncated, we have
509      to examine core.c_datasize below to find out the actual size of
510      the .data section.  */
511   if (c_flag & FULL_CORE)
512     {
513       if (!make_bfd_asection (abfd, ".data",
514 			      SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
515 			      (bfd_size_type) core.old.c_u.u_dsize,
516 			      (bfd_vma)
517 				CDATA_ADDR (core.old.c_u.u_dsize),
518 			      c_stack + c_size))
519 	goto fail;
520     }
521 #endif
522 
523 #ifdef CORE_VERSION_1
524   /* AIX 4 adds data sections from loaded objects to the core file,
525      which can be found by examining ldinfo, and anonymously mmapped
526      regions.  */
527   {
528     LdInfo ldinfo;
529     bfd_size_type ldi_datasize;
530     file_ptr ldi_core;
531     uint ldi_next;
532     bfd_vma ldi_dataorg;
533 
534     /* Fields from new and old core structures.  */
535     bfd_size_type c_datasize, c_vmregions;
536     file_ptr c_data, c_vmm;
537 
538     if (CORE_NEW (core))
539       {
540 	c_datasize = CNEW_DATASIZE (core.new);
541 	c_data = (file_ptr) core.new.c_data;
542 	c_vmregions = core.new.c_vmregions;
543 	c_vmm = (file_ptr) core.new.c_vmm;
544       }
545     else
546       {
547 	c_datasize = core.old.c_datasize;
548 	c_data = (file_ptr) (ptr_to_uint) core.old.c_data;
549 	c_vmregions = core.old.c_vmregions;
550 	c_vmm = (file_ptr) (ptr_to_uint) core.old.c_vmm;
551       }
552 
553     /* .data section from executable.  */
554     if (c_datasize)
555       {
556 	if (!make_bfd_asection (abfd, ".data",
557 				SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
558 				c_datasize,
559 				(bfd_vma) CDATA_ADDR (c_datasize),
560 				c_data))
561 	  goto fail;
562       }
563 
564     /* .data sections from loaded objects.  */
565     if (proc64)
566       size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;
567     else
568       size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;
569 
570     while (1)
571       {
572 	if (bfd_seek (abfd, c_loader, SEEK_SET) != 0)
573 	  goto fail;
574 	if (bfd_bread (&ldinfo, size, abfd) != size)
575 	  goto fail;
576 
577 	if (proc64)
578 	  {
579 	    ldi_core = ldinfo.l64.ldinfo_core;
580 	    ldi_datasize = ldinfo.l64.ldinfo_datasize;
581 	    ldi_dataorg = (bfd_vma) ldinfo.l64.ldinfo_dataorg;
582 	    ldi_next = ldinfo.l64.ldinfo_next;
583 	  }
584 	else
585 	  {
586 	    ldi_core = ldinfo.l32.ldinfo_core;
587 	    ldi_datasize = ldinfo.l32.ldinfo_datasize;
588 	    ldi_dataorg = (bfd_vma) (long) ldinfo.l32.ldinfo_dataorg;
589 	    ldi_next = ldinfo.l32.ldinfo_next;
590 	  }
591 
592 	if (ldi_core)
593 	  if (!make_bfd_asection (abfd, ".data",
594 				  SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
595 				  ldi_datasize, ldi_dataorg, ldi_core))
596 	    goto fail;
597 
598 	if (ldi_next == 0)
599 	  break;
600 	c_loader += ldi_next;
601       }
602 
603     /* .vmdata sections from anonymously mmapped regions.  */
604     if (c_vmregions)
605       {
606 	bfd_size_type i;
607 
608 	if (bfd_seek (abfd, c_vmm, SEEK_SET) != 0)
609 	  goto fail;
610 
611 	for (i = 0; i < c_vmregions; i++)
612 	  {
613 	    VmInfo vminfo;
614 	    bfd_size_type vminfo_size;
615 	    file_ptr vminfo_offset;
616 	    bfd_vma vminfo_addr;
617 
618 	    size = CORE_NEW (core) ? sizeof (vminfo.new) : sizeof (vminfo.old);
619 	    if (bfd_bread (&vminfo, size, abfd) != size)
620 	      goto fail;
621 
622 	    if (CORE_NEW (core))
623 	      {
624 		vminfo_addr = (bfd_vma) vminfo.new.vminfo_addr;
625 		vminfo_size = vminfo.new.vminfo_size;
626 		vminfo_offset = vminfo.new.vminfo_offset;
627 	      }
628 	    else
629 	      {
630 		vminfo_addr = (bfd_vma) (long) vminfo.old.vminfo_addr;
631 		vminfo_size = vminfo.old.vminfo_size;
632 		vminfo_offset = vminfo.old.vminfo_offset;
633 	      }
634 
635 	    if (vminfo_offset)
636 	      if (!make_bfd_asection (abfd, ".vmdata",
637 				      SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
638 				      vminfo_size, vminfo_addr,
639 				      vminfo_offset))
640 		goto fail;
641 	  }
642       }
643   }
644 #endif
645 
646   return abfd->xvec;		/* This is garbage for now.  */
647 
648  fail:
649   bfd_release (abfd, abfd->tdata.any);
650   abfd->tdata.any = NULL;
651   bfd_section_list_clear (abfd);
652   return NULL;
653 }
654 
655 /* Return `TRUE' if given core is from the given executable.  */
656 
657 bfd_boolean
658 rs6000coff_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
659 {
660   CoreHdr core;
661   bfd_size_type size;
662   char *path, *s;
663   size_t alloc;
664   const char *str1, *str2;
665   bfd_boolean ret;
666   file_ptr c_loader;
667 
668   if (!read_hdr (core_bfd, &core))
669     return FALSE;
670 
671   if (CORE_NEW (core))
672     c_loader = CNEW_LOADER (core.new);
673   else
674     c_loader = (file_ptr) (ptr_to_uint) COLD_LOADER (core.old);
675 
676   if (CORE_NEW (core) && CNEW_PROC64 (core.new))
677     size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;
678   else
679     size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;
680 
681   if (bfd_seek (core_bfd, c_loader + size, SEEK_SET) != 0)
682     return FALSE;
683 
684   alloc = 100;
685   path = bfd_malloc ((bfd_size_type) alloc);
686   if (path == NULL)
687     return FALSE;
688   s = path;
689 
690   while (1)
691     {
692       if (bfd_bread (s, (bfd_size_type) 1, core_bfd) != 1)
693 	{
694 	  free (path);
695 	  return FALSE;
696 	}
697       if (*s == '\0')
698 	break;
699       ++s;
700       if (s == path + alloc)
701 	{
702 	  char *n;
703 
704 	  alloc *= 2;
705 	  n = bfd_realloc (path, (bfd_size_type) alloc);
706 	  if (n == NULL)
707 	    {
708 	      free (path);
709 	      return FALSE;
710 	    }
711 	  s = n + (path - s);
712 	  path = n;
713 	}
714     }
715 
716   str1 = strrchr (path, '/');
717   str2 = strrchr (exec_bfd->filename, '/');
718 
719   /* step over character '/' */
720   str1 = str1 != NULL ? str1 + 1 : path;
721   str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
722 
723   if (strcmp (str1, str2) == 0)
724     ret = TRUE;
725   else
726     ret = FALSE;
727 
728   free (path);
729 
730   return ret;
731 }
732 
733 char *
734 rs6000coff_core_file_failing_command (bfd *abfd)
735 {
736   CoreHdr *core = core_hdr (abfd);
737   char *com = CORE_NEW (*core) ?
738     CNEW_COMM (core->new) : COLD_COMM (core->old);
739 
740   if (*com)
741     return com;
742   else
743     return 0;
744 }
745 
746 int
747 rs6000coff_core_file_failing_signal (bfd *abfd)
748 {
749   CoreHdr *core = core_hdr (abfd);
750   return CORE_NEW (*core) ? core->new.c_signo : core->old.c_signo;
751 }
752 
753 #endif /* AIX_CORE */
754