12159047fSniklas /* IBM RS/6000 "XCOFF" back-end for BFD.
2b55d4692Sfgsch Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
3*c074d1c9Sdrahn 2001, 2002
4b305b0f1Sespie Free Software Foundation, Inc.
52159047fSniklas FIXME: Can someone provide a transliteration of this name into ASCII?
62159047fSniklas Using the following chars caused a compiler warning on HIUX (so I replaced
72159047fSniklas them with octal escapes), and isn't useful without an understanding of what
82159047fSniklas character set it is.
92159047fSniklas Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
102159047fSniklas and John Gilmore.
112159047fSniklas Archive support from Damon A. Permezel.
122159047fSniklas Contributed by IBM Corporation and Cygnus Support.
132159047fSniklas
142159047fSniklas This file is part of BFD, the Binary File Descriptor library.
152159047fSniklas
162159047fSniklas This program is free software; you can redistribute it and/or modify
172159047fSniklas it under the terms of the GNU General Public License as published by
182159047fSniklas the Free Software Foundation; either version 2 of the License, or
192159047fSniklas (at your option) any later version.
202159047fSniklas
212159047fSniklas This program is distributed in the hope that it will be useful,
222159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
232159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
242159047fSniklas GNU General Public License for more details.
252159047fSniklas
262159047fSniklas You should have received a copy of the GNU General Public License
272159047fSniklas along with this program; if not, write to the Free Software
282159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
292159047fSniklas
302159047fSniklas /* This port currently only handles reading object files, except when
312159047fSniklas compiled on an RS/6000 host. -- no archive support, no core files.
322159047fSniklas In all cases, it does not support writing.
332159047fSniklas
342159047fSniklas This is in a separate file from coff-rs6000.c, because it includes
35b55d4692Sfgsch system include files that conflict with coff/rs6000.h. */
362159047fSniklas
372159047fSniklas /* Internalcoff.h and coffcode.h modify themselves based on this flag. */
382159047fSniklas #define RS6000COFF_C 1
392159047fSniklas
40b305b0f1Sespie /* The AIX 4.1 kernel is obviously compiled with -D_LONG_LONG, so
41b305b0f1Sespie we have to define _LONG_LONG for older versions of gcc to get the
42b305b0f1Sespie proper alignments in the user structure. */
43b305b0f1Sespie #if defined(_AIX41) && !defined(_LONG_LONG)
44b305b0f1Sespie #define _LONG_LONG
45b305b0f1Sespie #endif
46b305b0f1Sespie
472159047fSniklas #include "bfd.h"
482159047fSniklas #include "sysdep.h"
492159047fSniklas #include "libbfd.h"
502159047fSniklas
512159047fSniklas #ifdef AIX_CORE
522159047fSniklas
532159047fSniklas /* AOUTHDR is defined by the above. We need another defn of it, from the
542159047fSniklas system include files. Punt the old one and get us a new name for the
552159047fSniklas typedef in the system include files. */
562159047fSniklas #ifdef AOUTHDR
572159047fSniklas #undef AOUTHDR
582159047fSniklas #endif
592159047fSniklas #define AOUTHDR second_AOUTHDR
602159047fSniklas
612159047fSniklas #undef SCNHDR
622159047fSniklas
632159047fSniklas /* ------------------------------------------------------------------------ */
642159047fSniklas /* Support for core file stuff.. */
652159047fSniklas /* ------------------------------------------------------------------------ */
662159047fSniklas
672159047fSniklas #include <sys/user.h>
68b55d4692Sfgsch #define __LDINFO_PTRACE32__ /* for __ld_info32 */
69b55d4692Sfgsch #define __LDINFO_PTRACE64__ /* for __ld_info64 */
702159047fSniklas #include <sys/ldr.h>
712159047fSniklas #include <sys/core.h>
72b55d4692Sfgsch #include <sys/systemcfg.h>
732159047fSniklas
74b55d4692Sfgsch #define core_hdr(bfd) ((CoreHdr *) bfd->tdata.any)
752159047fSniklas
76b55d4692Sfgsch /* AIX 4.1 changed the names and locations of a few items in the core file.
77b55d4692Sfgsch AIX 4.3 defined an entirely new structure, core_dumpx, but kept support for
78b55d4692Sfgsch the previous 4.1 structure, core_dump.
792159047fSniklas
80b55d4692Sfgsch AIX_CORE_DUMPX_CORE is defined (by configure) on AIX 4.3+, and
81b55d4692Sfgsch CORE_VERSION_1 is defined (by AIX core.h) as 2 on AIX 4.3+ and as 1 on AIX
82b55d4692Sfgsch 4.1 and 4.2. AIX pre-4.1 (aka 3.x) either doesn't define CORE_VERSION_1
83b55d4692Sfgsch or else defines it as 0. */
842159047fSniklas
85b55d4692Sfgsch #if defined(CORE_VERSION_1) && !CORE_VERSION_1
86b55d4692Sfgsch # undef CORE_VERSION_1
87b55d4692Sfgsch #endif
882159047fSniklas
89b55d4692Sfgsch /* The following union and macros allow this module to compile on all AIX
90b55d4692Sfgsch versions and to handle both core_dumpx and core_dump on 4.3+. CNEW_*()
91b55d4692Sfgsch and COLD_*() macros respectively retrieve core_dumpx and core_dump
92b55d4692Sfgsch values. */
932159047fSniklas
94b55d4692Sfgsch /* Union of 32-bit and 64-bit versions of ld_info. */
95b305b0f1Sespie
96b55d4692Sfgsch typedef union {
97b55d4692Sfgsch #ifdef __ld_info32
98b55d4692Sfgsch struct __ld_info32 l32;
99b55d4692Sfgsch struct __ld_info64 l64;
100b55d4692Sfgsch #else
101b55d4692Sfgsch struct ld_info l32;
102b55d4692Sfgsch struct ld_info l64;
103b55d4692Sfgsch #endif
104b55d4692Sfgsch } LdInfo;
105b55d4692Sfgsch
106b55d4692Sfgsch /* Union of old and new core dump structures. */
107b55d4692Sfgsch
108b55d4692Sfgsch typedef union {
109b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
110b55d4692Sfgsch struct core_dumpx new; /* new AIX 4.3+ core dump */
111b55d4692Sfgsch #else
112b55d4692Sfgsch struct core_dump new; /* for simpler coding */
113b55d4692Sfgsch #endif
114b55d4692Sfgsch struct core_dump old; /* old AIX 4.2- core dump, still used on
115b55d4692Sfgsch 4.3+ with appropriate SMIT config */
116b55d4692Sfgsch } CoreHdr;
117b55d4692Sfgsch
118b55d4692Sfgsch /* Union of old and new vm_info structures. */
119b55d4692Sfgsch
120b55d4692Sfgsch #ifdef CORE_VERSION_1
121b55d4692Sfgsch typedef union {
122b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
123b55d4692Sfgsch struct vm_infox new;
124b55d4692Sfgsch #else
125b55d4692Sfgsch struct vm_info new;
126b55d4692Sfgsch #endif
127b55d4692Sfgsch struct vm_info old;
128b55d4692Sfgsch } VmInfo;
129b55d4692Sfgsch #endif
130b55d4692Sfgsch
131b55d4692Sfgsch /* Return whether CoreHdr C is in new or old format. */
132b305b0f1Sespie
133b305b0f1Sespie #ifdef AIX_CORE_DUMPX_CORE
134b55d4692Sfgsch # define CORE_NEW(c) (!(c).old.c_entries)
135b305b0f1Sespie #else
136b55d4692Sfgsch # define CORE_NEW(c) 0
137b55d4692Sfgsch #endif
138b55d4692Sfgsch
139b55d4692Sfgsch /* Return the c_stackorg field from struct core_dumpx C. */
140b55d4692Sfgsch
141b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
142b55d4692Sfgsch # define CNEW_STACKORG(c) (c).c_stackorg
143b55d4692Sfgsch #else
144b55d4692Sfgsch # define CNEW_STACKORG(c) 0
145b55d4692Sfgsch #endif
146b55d4692Sfgsch
147b55d4692Sfgsch /* Return the offset to the loader region from struct core_dump C. */
148b55d4692Sfgsch
149b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
150b55d4692Sfgsch # define CNEW_LOADER(c) (c).c_loader
151b55d4692Sfgsch #else
152b55d4692Sfgsch # define CNEW_LOADER(c) 0
153b55d4692Sfgsch #endif
154b55d4692Sfgsch
155b55d4692Sfgsch /* Return the offset to the loader region from struct core_dump C. */
156b55d4692Sfgsch
157b55d4692Sfgsch #define COLD_LOADER(c) (c).c_tab
158b55d4692Sfgsch
159b55d4692Sfgsch /* Return the c_lsize field from struct core_dumpx C. */
160b55d4692Sfgsch
161b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
162b55d4692Sfgsch # define CNEW_LSIZE(c) (c).c_lsize
163b55d4692Sfgsch #else
164b55d4692Sfgsch # define CNEW_LSIZE(c) 0
165b55d4692Sfgsch #endif
166b55d4692Sfgsch
167b55d4692Sfgsch /* Return the c_dataorg field from struct core_dumpx C. */
168b55d4692Sfgsch
169b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
170b55d4692Sfgsch # define CNEW_DATAORG(c) (c).c_dataorg
171b55d4692Sfgsch #else
172b55d4692Sfgsch # define CNEW_DATAORG(c) 0
173b55d4692Sfgsch #endif
174b55d4692Sfgsch
175b55d4692Sfgsch /* Return the c_datasize field from struct core_dumpx C. */
176b55d4692Sfgsch
177b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
178b55d4692Sfgsch # define CNEW_DATASIZE(c) (c).c_datasize
179b55d4692Sfgsch #else
180b55d4692Sfgsch # define CNEW_DATASIZE(c) 0
181b55d4692Sfgsch #endif
182b55d4692Sfgsch
183b55d4692Sfgsch /* Return the c_impl field from struct core_dumpx C. */
184b55d4692Sfgsch
185*c074d1c9Sdrahn #if defined (HAVE_ST_C_IMPL) || defined (AIX_5_CORE)
186b55d4692Sfgsch # define CNEW_IMPL(c) (c).c_impl
187b55d4692Sfgsch #else
188b55d4692Sfgsch # define CNEW_IMPL(c) 0
189b55d4692Sfgsch #endif
190b55d4692Sfgsch
191b55d4692Sfgsch /* Return the command string from struct core_dumpx C. */
192b55d4692Sfgsch
193b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
194b55d4692Sfgsch # define CNEW_COMM(c) (c).c_u.U_proc.pi_comm
195b55d4692Sfgsch #else
196b55d4692Sfgsch # define CNEW_COMM(c) 0
197b55d4692Sfgsch #endif
198b55d4692Sfgsch
199b55d4692Sfgsch /* Return the command string from struct core_dump C. */
200b55d4692Sfgsch
2012159047fSniklas #ifdef CORE_VERSION_1
202b55d4692Sfgsch # define COLD_COMM(c) (c).c_u.U_comm
2032159047fSniklas #else
204b55d4692Sfgsch # define COLD_COMM(c) (c).c_u.u_comm
2052159047fSniklas #endif
2062159047fSniklas
207b55d4692Sfgsch /* Return the struct __context64 pointer from struct core_dumpx C. */
2082159047fSniklas
209b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
210b55d4692Sfgsch # define CNEW_CONTEXT64(c) (c).c_flt.hctx.r64
211b55d4692Sfgsch #else
212b55d4692Sfgsch # define CNEW_CONTEXT64(c) c
213b55d4692Sfgsch #endif
214b55d4692Sfgsch
215b55d4692Sfgsch /* Return the struct mstsave pointer from struct core_dumpx C. */
216b55d4692Sfgsch
217b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
218b55d4692Sfgsch # define CNEW_MSTSAVE(c) (c).c_flt.hctx.r32
219b55d4692Sfgsch #else
220b55d4692Sfgsch # define CNEW_MSTSAVE(c) c
221b55d4692Sfgsch #endif
222b55d4692Sfgsch
223b55d4692Sfgsch /* Return the struct mstsave pointer from struct core_dump C. */
224b55d4692Sfgsch
225b55d4692Sfgsch #ifdef CORE_VERSION_1
226b55d4692Sfgsch # define COLD_MSTSAVE(c) (c).c_mst
227b55d4692Sfgsch #else
228b55d4692Sfgsch # define COLD_MSTSAVE(c) (c).c_u.u_save
229b55d4692Sfgsch #endif
230b55d4692Sfgsch
231b55d4692Sfgsch /* Return whether struct core_dumpx is from a 64-bit process. */
232b55d4692Sfgsch
233b55d4692Sfgsch #ifdef AIX_CORE_DUMPX_CORE
234b55d4692Sfgsch # define CNEW_PROC64(c) IS_PROC64(&(c).c_u.U_proc)
235b55d4692Sfgsch #else
236b55d4692Sfgsch # define CNEW_PROC64(c) 0
237b55d4692Sfgsch #endif
238b55d4692Sfgsch
239b55d4692Sfgsch /* Magic end-of-stack addresses for old core dumps. This is _very_ fragile,
240b55d4692Sfgsch but I don't see any easy way to get that info right now. */
241b55d4692Sfgsch
242b55d4692Sfgsch #ifdef CORE_VERSION_1
243b55d4692Sfgsch # define COLD_STACKEND 0x2ff23000
244b55d4692Sfgsch #else
245b55d4692Sfgsch # define COLD_STACKEND 0x2ff80000
246b55d4692Sfgsch #endif
247b55d4692Sfgsch
248b55d4692Sfgsch /* Size of the leading portion that old and new core dump structures have in
249b55d4692Sfgsch common. */
250b55d4692Sfgsch #define CORE_COMMONSZ ((int) &((struct core_dump *) 0)->c_entries \
251b55d4692Sfgsch + sizeof (((struct core_dump *) 0)->c_entries))
252b55d4692Sfgsch
253b55d4692Sfgsch /* Try to read into CORE the header from the core file associated with ABFD.
254b55d4692Sfgsch Return success. */
255b55d4692Sfgsch
256*c074d1c9Sdrahn static bfd_boolean
read_hdr(bfd * abfd,CoreHdr * core)257b55d4692Sfgsch read_hdr (bfd *abfd, CoreHdr *core)
258b55d4692Sfgsch {
259b55d4692Sfgsch bfd_size_type size;
260b55d4692Sfgsch
261*c074d1c9Sdrahn if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
262*c074d1c9Sdrahn return FALSE;
263b55d4692Sfgsch
264b55d4692Sfgsch /* Read the leading portion that old and new core dump structures have in
265b55d4692Sfgsch common. */
266*c074d1c9Sdrahn size = CORE_COMMONSZ;
267*c074d1c9Sdrahn if (bfd_bread (core, size, abfd) != size)
268*c074d1c9Sdrahn return FALSE;
269b55d4692Sfgsch
270b55d4692Sfgsch /* Read the trailing portion of the structure. */
271*c074d1c9Sdrahn if (CORE_NEW (*core))
272*c074d1c9Sdrahn size = sizeof (core->new);
273*c074d1c9Sdrahn else
274*c074d1c9Sdrahn size = sizeof (core->old);
275*c074d1c9Sdrahn size -= CORE_COMMONSZ;
276*c074d1c9Sdrahn return bfd_bread ((char *) core + CORE_COMMONSZ, size, abfd) == size;
277b55d4692Sfgsch }
278b305b0f1Sespie
279b305b0f1Sespie static asection *
make_bfd_asection(abfd,name,flags,_raw_size,vma,filepos)280b305b0f1Sespie make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
281b305b0f1Sespie bfd *abfd;
282*c074d1c9Sdrahn const char *name;
283b305b0f1Sespie flagword flags;
284b305b0f1Sespie bfd_size_type _raw_size;
285b305b0f1Sespie bfd_vma vma;
286b305b0f1Sespie file_ptr filepos;
287b305b0f1Sespie {
288b305b0f1Sespie asection *asect;
289b305b0f1Sespie
290b305b0f1Sespie asect = bfd_make_section_anyway (abfd, name);
291b305b0f1Sespie if (!asect)
292b305b0f1Sespie return NULL;
293b305b0f1Sespie
294b305b0f1Sespie asect->flags = flags;
295b305b0f1Sespie asect->_raw_size = _raw_size;
296b305b0f1Sespie asect->vma = vma;
297b305b0f1Sespie asect->filepos = filepos;
298b305b0f1Sespie asect->alignment_power = 8;
299b305b0f1Sespie
300b305b0f1Sespie return asect;
301b305b0f1Sespie }
3022159047fSniklas
3032159047fSniklas /* Decide if a given bfd represents a `core' file or not. There really is no
3042159047fSniklas magic number or anything like, in rs6000coff. */
3052159047fSniklas
3062159047fSniklas const bfd_target *
rs6000coff_core_p(abfd)3072159047fSniklas rs6000coff_core_p (abfd)
3082159047fSniklas bfd *abfd;
3092159047fSniklas {
310b55d4692Sfgsch CoreHdr core;
3112159047fSniklas struct stat statbuf;
312b55d4692Sfgsch bfd_size_type size;
3132159047fSniklas char *tmpptr;
3142159047fSniklas
315b55d4692Sfgsch /* Values from new and old core structures. */
316b55d4692Sfgsch int c_flag;
317b55d4692Sfgsch file_ptr c_stack, c_regoff, c_loader;
318b55d4692Sfgsch bfd_size_type c_size, c_regsize, c_lsize;
319b55d4692Sfgsch bfd_vma c_stackend;
320b55d4692Sfgsch void *c_regptr;
321b55d4692Sfgsch int proc64;
3222159047fSniklas
323b55d4692Sfgsch if (!read_hdr (abfd, &core))
3242159047fSniklas {
325b305b0f1Sespie if (bfd_get_error () != bfd_error_system_call)
3262159047fSniklas bfd_set_error (bfd_error_wrong_format);
3272159047fSniklas return NULL;
3282159047fSniklas }
3292159047fSniklas
330b55d4692Sfgsch /* Copy fields from new or old core structure. */
331b55d4692Sfgsch if (CORE_NEW (core))
332b55d4692Sfgsch {
333b55d4692Sfgsch c_flag = core.new.c_flag;
334b55d4692Sfgsch c_stack = (file_ptr) core.new.c_stack;
335b55d4692Sfgsch c_size = core.new.c_size;
336b55d4692Sfgsch c_stackend = CNEW_STACKORG (core.new) + c_size;
337b55d4692Sfgsch c_lsize = CNEW_LSIZE (core.new);
338b55d4692Sfgsch c_loader = CNEW_LOADER (core.new);
339b55d4692Sfgsch proc64 = CNEW_PROC64 (core.new);
340b55d4692Sfgsch }
341b55d4692Sfgsch else
342b55d4692Sfgsch {
343b55d4692Sfgsch c_flag = core.old.c_flag;
344b55d4692Sfgsch c_stack = (file_ptr) core.old.c_stack;
345b55d4692Sfgsch c_size = core.old.c_size;
346b55d4692Sfgsch c_stackend = COLD_STACKEND;
347b55d4692Sfgsch c_lsize = 0x7ffffff;
348b55d4692Sfgsch c_loader = (file_ptr) COLD_LOADER (core.old);
349b55d4692Sfgsch proc64 = 0;
350b55d4692Sfgsch }
351b55d4692Sfgsch
352b55d4692Sfgsch if (proc64)
353b55d4692Sfgsch {
354b55d4692Sfgsch c_regsize = sizeof (CNEW_CONTEXT64 (core.new));
355b55d4692Sfgsch c_regptr = &CNEW_CONTEXT64 (core.new);
356b55d4692Sfgsch }
357b55d4692Sfgsch else if (CORE_NEW (core))
358b55d4692Sfgsch {
359b55d4692Sfgsch c_regsize = sizeof (CNEW_MSTSAVE (core.new));
360b55d4692Sfgsch c_regptr = &CNEW_MSTSAVE (core.new);
361b55d4692Sfgsch }
362b55d4692Sfgsch else
363b55d4692Sfgsch {
364b55d4692Sfgsch c_regsize = sizeof (COLD_MSTSAVE (core.old));
365b55d4692Sfgsch c_regptr = &COLD_MSTSAVE (core.old);
366b55d4692Sfgsch }
367b55d4692Sfgsch c_regoff = (char *) c_regptr - (char *) &core;
368b55d4692Sfgsch
369b305b0f1Sespie if (bfd_stat (abfd, &statbuf) < 0)
3702159047fSniklas {
3712159047fSniklas bfd_set_error (bfd_error_system_call);
3722159047fSniklas return NULL;
3732159047fSniklas }
3742159047fSniklas
3752159047fSniklas /* If the core file ulimit is too small, the system will first
3762159047fSniklas omit the data segment, then omit the stack, then decline to
3772159047fSniklas dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
3782159047fSniklas are always set) (this is based on experimentation on AIX 3.2).
3792159047fSniklas Now, the thing is that GDB users will be surprised
3802159047fSniklas if segments just silently don't appear (well, maybe they would
381b305b0f1Sespie think to check "info files", I don't know).
3822159047fSniklas
3832159047fSniklas For the data segment, we have no choice but to keep going if it's
3842159047fSniklas not there, since the default behavior is not to dump it (regardless
3852159047fSniklas of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
3862159047fSniklas if it's not there, we refuse to have anything to do with this core
3872159047fSniklas file. The usefulness of a core dump without a stack segment is pretty
3882159047fSniklas limited anyway. */
3892159047fSniklas
390b55d4692Sfgsch if (!(c_flag & UBLOCK_VALID)
391b55d4692Sfgsch || !(c_flag & LE_VALID))
3922159047fSniklas {
3932159047fSniklas bfd_set_error (bfd_error_wrong_format);
3942159047fSniklas return NULL;
3952159047fSniklas }
3962159047fSniklas
397b55d4692Sfgsch if (!(c_flag & USTACK_VALID))
3982159047fSniklas {
3992159047fSniklas bfd_set_error (bfd_error_file_truncated);
4002159047fSniklas return NULL;
4012159047fSniklas }
4022159047fSniklas
4032159047fSniklas /* Don't check the core file size for a full core, AIX 4.1 includes
4042159047fSniklas additional shared library sections in a full core. */
405b55d4692Sfgsch if (!(c_flag & (FULL_CORE | CORE_TRUNC)))
4062159047fSniklas {
4072159047fSniklas /* If the size is wrong, it means we're misinterpreting something. */
408b55d4692Sfgsch if (c_stack + (file_ptr) c_size != statbuf.st_size)
409b55d4692Sfgsch {
4102159047fSniklas bfd_set_error (bfd_error_wrong_format);
4112159047fSniklas return NULL;
4122159047fSniklas }
413b55d4692Sfgsch }
4142159047fSniklas
4152159047fSniklas /* Sanity check on the c_tab field. */
416b55d4692Sfgsch if (!CORE_NEW (core) && (c_loader < (file_ptr) sizeof core.old ||
417b55d4692Sfgsch c_loader >= statbuf.st_size ||
418b55d4692Sfgsch c_loader >= c_stack))
4192159047fSniklas {
4202159047fSniklas bfd_set_error (bfd_error_wrong_format);
4212159047fSniklas return NULL;
4222159047fSniklas }
4232159047fSniklas
424b305b0f1Sespie /* Issue warning if the core file was truncated during writing. */
425b55d4692Sfgsch if (c_flag & CORE_TRUNC)
426b305b0f1Sespie (*_bfd_error_handler) (_("%s: warning core file truncated"),
427b305b0f1Sespie bfd_get_filename (abfd));
428b305b0f1Sespie
429b305b0f1Sespie /* Allocate core file header. */
430b55d4692Sfgsch size = CORE_NEW (core) ? sizeof (core.new) : sizeof (core.old);
431*c074d1c9Sdrahn tmpptr = (char *) bfd_zalloc (abfd, (bfd_size_type) size);
4322159047fSniklas if (!tmpptr)
4332159047fSniklas return NULL;
4342159047fSniklas
435b55d4692Sfgsch /* Copy core file header. */
436b55d4692Sfgsch memcpy (tmpptr, &core, size);
4372159047fSniklas set_tdata (abfd, tmpptr);
4382159047fSniklas
439b55d4692Sfgsch /* Set architecture. */
440b55d4692Sfgsch if (CORE_NEW (core))
441b55d4692Sfgsch {
442b55d4692Sfgsch enum bfd_architecture arch;
443b55d4692Sfgsch unsigned long mach;
444b55d4692Sfgsch
445b55d4692Sfgsch switch (CNEW_IMPL (core.new))
446b55d4692Sfgsch {
447b55d4692Sfgsch case POWER_RS1:
448b55d4692Sfgsch case POWER_RSC:
449b55d4692Sfgsch case POWER_RS2:
450b55d4692Sfgsch arch = bfd_arch_rs6000;
451b55d4692Sfgsch mach = bfd_mach_rs6k;
452b55d4692Sfgsch break;
453b55d4692Sfgsch default:
454b55d4692Sfgsch arch = bfd_arch_powerpc;
455b55d4692Sfgsch mach = bfd_mach_ppc;
456b55d4692Sfgsch break;
457b55d4692Sfgsch }
458b55d4692Sfgsch bfd_default_set_arch_mach (abfd, arch, mach);
459b55d4692Sfgsch }
4602159047fSniklas
4612159047fSniklas /* .stack section. */
462b305b0f1Sespie if (!make_bfd_asection (abfd, ".stack",
463b305b0f1Sespie SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
464b55d4692Sfgsch c_size, c_stackend - c_size, c_stack))
465*c074d1c9Sdrahn goto fail;
4662159047fSniklas
467b55d4692Sfgsch /* .reg section for all registers. */
468b305b0f1Sespie if (!make_bfd_asection (abfd, ".reg",
469b305b0f1Sespie SEC_HAS_CONTENTS,
470b55d4692Sfgsch c_regsize, (bfd_vma) 0, c_regoff))
471*c074d1c9Sdrahn goto fail;
4722159047fSniklas
473b305b0f1Sespie /* .ldinfo section.
474b305b0f1Sespie To actually find out how long this section is in this particular
4752159047fSniklas core dump would require going down the whole list of struct ld_info's.
4762159047fSniklas See if we can just fake it. */
477b305b0f1Sespie if (!make_bfd_asection (abfd, ".ldinfo",
478b305b0f1Sespie SEC_HAS_CONTENTS,
479b55d4692Sfgsch c_lsize, (bfd_vma) 0, c_loader))
480*c074d1c9Sdrahn goto fail;
4812159047fSniklas
482b305b0f1Sespie #ifndef CORE_VERSION_1
483b305b0f1Sespie /* .data section if present.
484b305b0f1Sespie AIX 3 dumps the complete data section and sets FULL_CORE if the
485b305b0f1Sespie ulimit is large enough, otherwise the data section is omitted.
486b305b0f1Sespie AIX 4 sets FULL_CORE even if the core file is truncated, we have
487b55d4692Sfgsch to examine core.c_datasize below to find out the actual size of
488b305b0f1Sespie the .data section. */
489b55d4692Sfgsch if (c_flag & FULL_CORE)
4902159047fSniklas {
491b305b0f1Sespie if (!make_bfd_asection (abfd, ".data",
492b305b0f1Sespie SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
493b55d4692Sfgsch (bfd_size_type) core.old.c_u.u_dsize,
494b305b0f1Sespie (bfd_vma)
495b55d4692Sfgsch CDATA_ADDR (core.old.c_u.u_dsize),
496b55d4692Sfgsch c_stack + c_size))
497*c074d1c9Sdrahn goto fail;
4982159047fSniklas }
499b305b0f1Sespie #endif
500b305b0f1Sespie
501b305b0f1Sespie #ifdef CORE_VERSION_1
502b305b0f1Sespie /* AIX 4 adds data sections from loaded objects to the core file,
503b305b0f1Sespie which can be found by examining ldinfo, and anonymously mmapped
504b305b0f1Sespie regions. */
505b305b0f1Sespie {
506b55d4692Sfgsch LdInfo ldinfo;
507b55d4692Sfgsch bfd_size_type ldi_datasize;
508b55d4692Sfgsch file_ptr ldi_core;
509b55d4692Sfgsch uint ldi_next;
510b55d4692Sfgsch bfd_vma ldi_dataorg;
511b55d4692Sfgsch
512b55d4692Sfgsch /* Fields from new and old core structures. */
513b55d4692Sfgsch bfd_size_type c_datasize, c_vmregions;
514b55d4692Sfgsch file_ptr c_data, c_vmm;
515b55d4692Sfgsch
516b55d4692Sfgsch if (CORE_NEW (core))
517b55d4692Sfgsch {
518b55d4692Sfgsch c_datasize = CNEW_DATASIZE (core.new);
519b55d4692Sfgsch c_data = (file_ptr) core.new.c_data;
520b55d4692Sfgsch c_vmregions = core.new.c_vmregions;
521b55d4692Sfgsch c_vmm = (file_ptr) core.new.c_vmm;
522b55d4692Sfgsch }
523b55d4692Sfgsch else
524b55d4692Sfgsch {
525b55d4692Sfgsch c_datasize = core.old.c_datasize;
526b55d4692Sfgsch c_data = (file_ptr) core.old.c_data;
527b55d4692Sfgsch c_vmregions = core.old.c_vmregions;
528b55d4692Sfgsch c_vmm = (file_ptr) core.old.c_vmm;
529b55d4692Sfgsch }
530b305b0f1Sespie
531b305b0f1Sespie /* .data section from executable. */
532b55d4692Sfgsch if (c_datasize)
533b305b0f1Sespie {
534b305b0f1Sespie if (!make_bfd_asection (abfd, ".data",
535b305b0f1Sespie SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
536b55d4692Sfgsch c_datasize,
537b55d4692Sfgsch (bfd_vma) CDATA_ADDR (c_datasize),
538b55d4692Sfgsch c_data))
539*c074d1c9Sdrahn goto fail;
540b305b0f1Sespie }
541b305b0f1Sespie
542b305b0f1Sespie /* .data sections from loaded objects. */
543b55d4692Sfgsch if (proc64)
544b55d4692Sfgsch size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;
545b55d4692Sfgsch else
546b55d4692Sfgsch size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;
547b55d4692Sfgsch
548b305b0f1Sespie while (1)
549b305b0f1Sespie {
550b55d4692Sfgsch if (bfd_seek (abfd, c_loader, SEEK_SET) != 0)
551*c074d1c9Sdrahn goto fail;
552*c074d1c9Sdrahn if (bfd_bread (&ldinfo, size, abfd) != size)
553*c074d1c9Sdrahn goto fail;
554b55d4692Sfgsch
555b55d4692Sfgsch if (proc64)
556b305b0f1Sespie {
557b55d4692Sfgsch ldi_core = ldinfo.l64.ldinfo_core;
558b55d4692Sfgsch ldi_datasize = ldinfo.l64.ldinfo_datasize;
559b55d4692Sfgsch ldi_dataorg = (bfd_vma) ldinfo.l64.ldinfo_dataorg;
560b55d4692Sfgsch ldi_next = ldinfo.l64.ldinfo_next;
561b55d4692Sfgsch }
562b55d4692Sfgsch else
563b55d4692Sfgsch {
564b55d4692Sfgsch ldi_core = ldinfo.l32.ldinfo_core;
565b55d4692Sfgsch ldi_datasize = ldinfo.l32.ldinfo_datasize;
566b55d4692Sfgsch ldi_dataorg = (bfd_vma) (long) ldinfo.l32.ldinfo_dataorg;
567b55d4692Sfgsch ldi_next = ldinfo.l32.ldinfo_next;
568b55d4692Sfgsch }
569b55d4692Sfgsch
570b55d4692Sfgsch if (ldi_core)
571b305b0f1Sespie if (!make_bfd_asection (abfd, ".data",
572b305b0f1Sespie SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
573b55d4692Sfgsch ldi_datasize, ldi_dataorg, ldi_core))
574*c074d1c9Sdrahn goto fail;
575b55d4692Sfgsch
576b55d4692Sfgsch if (ldi_next == 0)
577b305b0f1Sespie break;
578b55d4692Sfgsch c_loader += ldi_next;
579b305b0f1Sespie }
580b305b0f1Sespie
581b305b0f1Sespie /* .vmdata sections from anonymously mmapped regions. */
582b55d4692Sfgsch if (c_vmregions)
583b305b0f1Sespie {
584b55d4692Sfgsch bfd_size_type i;
585b305b0f1Sespie
586b55d4692Sfgsch if (bfd_seek (abfd, c_vmm, SEEK_SET) != 0)
587*c074d1c9Sdrahn goto fail;
588b305b0f1Sespie
589b55d4692Sfgsch for (i = 0; i < c_vmregions; i++)
590b305b0f1Sespie {
591b55d4692Sfgsch VmInfo vminfo;
592b55d4692Sfgsch bfd_size_type vminfo_size;
593b55d4692Sfgsch file_ptr vminfo_offset;
594b55d4692Sfgsch bfd_vma vminfo_addr;
595b305b0f1Sespie
596b55d4692Sfgsch size = CORE_NEW (core) ? sizeof (vminfo.new) : sizeof (vminfo.old);
597*c074d1c9Sdrahn if (bfd_bread (&vminfo, size, abfd) != size)
598*c074d1c9Sdrahn goto fail;
599b55d4692Sfgsch
600b55d4692Sfgsch if (CORE_NEW (core))
601b305b0f1Sespie {
602b55d4692Sfgsch vminfo_addr = (bfd_vma) vminfo.new.vminfo_addr;
603b55d4692Sfgsch vminfo_size = vminfo.new.vminfo_size;
604b55d4692Sfgsch vminfo_offset = vminfo.new.vminfo_offset;
605b55d4692Sfgsch }
606b55d4692Sfgsch else
607b55d4692Sfgsch {
608b55d4692Sfgsch vminfo_addr = (bfd_vma) (long) vminfo.old.vminfo_addr;
609b55d4692Sfgsch vminfo_size = vminfo.old.vminfo_size;
610b55d4692Sfgsch vminfo_offset = vminfo.old.vminfo_offset;
611b55d4692Sfgsch }
612b55d4692Sfgsch
613b55d4692Sfgsch if (vminfo_offset)
614b305b0f1Sespie if (!make_bfd_asection (abfd, ".vmdata",
615b305b0f1Sespie SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
616b55d4692Sfgsch vminfo_size, vminfo_addr,
617b55d4692Sfgsch vminfo_offset))
618*c074d1c9Sdrahn goto fail;
619b305b0f1Sespie }
620b305b0f1Sespie }
621b305b0f1Sespie }
622b305b0f1Sespie #endif
6232159047fSniklas
624b55d4692Sfgsch return abfd->xvec; /* This is garbage for now. */
625*c074d1c9Sdrahn
626*c074d1c9Sdrahn fail:
627*c074d1c9Sdrahn bfd_release (abfd, abfd->tdata.any);
628*c074d1c9Sdrahn abfd->tdata.any = NULL;
629*c074d1c9Sdrahn bfd_section_list_clear (abfd);
630*c074d1c9Sdrahn return NULL;
6312159047fSniklas }
6322159047fSniklas
633*c074d1c9Sdrahn /* Return `TRUE' if given core is from the given executable. */
6342159047fSniklas
635*c074d1c9Sdrahn bfd_boolean
rs6000coff_core_file_matches_executable_p(core_bfd,exec_bfd)6362159047fSniklas rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
6372159047fSniklas bfd *core_bfd;
6382159047fSniklas bfd *exec_bfd;
6392159047fSniklas {
640b55d4692Sfgsch CoreHdr core;
641b305b0f1Sespie bfd_size_type size;
6420c6d0228Sniklas char *path, *s;
6430c6d0228Sniklas size_t alloc;
6442159047fSniklas const char *str1, *str2;
645*c074d1c9Sdrahn bfd_boolean ret;
646b55d4692Sfgsch file_ptr c_loader;
6472159047fSniklas
648b55d4692Sfgsch if (!read_hdr (core_bfd, &core))
649*c074d1c9Sdrahn return FALSE;
6502159047fSniklas
651b55d4692Sfgsch if (CORE_NEW (core))
652b55d4692Sfgsch c_loader = CNEW_LOADER (core.new);
653b55d4692Sfgsch else
654b55d4692Sfgsch c_loader = (file_ptr) COLD_LOADER (core.old);
6552159047fSniklas
656b55d4692Sfgsch if (CORE_NEW (core) && CNEW_PROC64 (core.new))
657b55d4692Sfgsch size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;
658b55d4692Sfgsch else
659b55d4692Sfgsch size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;
660b55d4692Sfgsch
661b55d4692Sfgsch if (bfd_seek (core_bfd, c_loader + size, SEEK_SET) != 0)
662*c074d1c9Sdrahn return FALSE;
6630c6d0228Sniklas
6640c6d0228Sniklas alloc = 100;
665*c074d1c9Sdrahn path = bfd_malloc ((bfd_size_type) alloc);
6660c6d0228Sniklas if (path == NULL)
667*c074d1c9Sdrahn return FALSE;
6680c6d0228Sniklas s = path;
6690c6d0228Sniklas
6700c6d0228Sniklas while (1)
6710c6d0228Sniklas {
672*c074d1c9Sdrahn if (bfd_bread (s, (bfd_size_type) 1, core_bfd) != 1)
6730c6d0228Sniklas {
6740c6d0228Sniklas free (path);
675*c074d1c9Sdrahn return FALSE;
6760c6d0228Sniklas }
6770c6d0228Sniklas if (*s == '\0')
6780c6d0228Sniklas break;
6790c6d0228Sniklas ++s;
6800c6d0228Sniklas if (s == path + alloc)
6810c6d0228Sniklas {
6820c6d0228Sniklas char *n;
6830c6d0228Sniklas
6840c6d0228Sniklas alloc *= 2;
685*c074d1c9Sdrahn n = bfd_realloc (path, (bfd_size_type) alloc);
6860c6d0228Sniklas if (n == NULL)
6870c6d0228Sniklas {
6880c6d0228Sniklas free (path);
689*c074d1c9Sdrahn return FALSE;
6900c6d0228Sniklas }
6910c6d0228Sniklas s = n + (path - s);
6920c6d0228Sniklas path = n;
6930c6d0228Sniklas }
6940c6d0228Sniklas }
6950c6d0228Sniklas
6960c6d0228Sniklas str1 = strrchr (path, '/');
6972159047fSniklas str2 = strrchr (exec_bfd->filename, '/');
6982159047fSniklas
6992159047fSniklas /* step over character '/' */
7000c6d0228Sniklas str1 = str1 != NULL ? str1 + 1 : path;
7010c6d0228Sniklas str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
7022159047fSniklas
7030c6d0228Sniklas if (strcmp (str1, str2) == 0)
704*c074d1c9Sdrahn ret = TRUE;
7050c6d0228Sniklas else
706*c074d1c9Sdrahn ret = FALSE;
7070c6d0228Sniklas
7080c6d0228Sniklas free (path);
7090c6d0228Sniklas
7100c6d0228Sniklas return ret;
7112159047fSniklas }
7122159047fSniklas
7132159047fSniklas char *
rs6000coff_core_file_failing_command(abfd)7142159047fSniklas rs6000coff_core_file_failing_command (abfd)
7152159047fSniklas bfd *abfd;
7162159047fSniklas {
717b55d4692Sfgsch CoreHdr *core = core_hdr (abfd);
718b55d4692Sfgsch char *com = CORE_NEW (*core) ?
719b55d4692Sfgsch CNEW_COMM (core->new) : COLD_COMM (core->old);
720b55d4692Sfgsch
7212159047fSniklas if (*com)
7222159047fSniklas return com;
7232159047fSniklas else
7242159047fSniklas return 0;
7252159047fSniklas }
7262159047fSniklas
7272159047fSniklas int
rs6000coff_core_file_failing_signal(abfd)7282159047fSniklas rs6000coff_core_file_failing_signal (abfd)
7292159047fSniklas bfd *abfd;
7302159047fSniklas {
731b55d4692Sfgsch CoreHdr *core = core_hdr (abfd);
732b55d4692Sfgsch return CORE_NEW (*core) ? core->new.c_signo : core->old.c_signo;
7332159047fSniklas }
7342159047fSniklas
7352159047fSniklas #endif /* AIX_CORE */
736