175fd0b74Schristos /* IBM RS/6000 "XCOFF" back-end for BFD.
2*e992f068Schristos Copyright (C) 1990-2022 Free Software Foundation, Inc.
375fd0b74Schristos Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, and John Gilmore.
475fd0b74Schristos Archive support from Damon A. Permezel.
575fd0b74Schristos Contributed by IBM Corporation and Cygnus Support.
675fd0b74Schristos
775fd0b74Schristos This file is part of BFD, the Binary File Descriptor library.
875fd0b74Schristos
975fd0b74Schristos This program is free software; you can redistribute it and/or modify
1075fd0b74Schristos it under the terms of the GNU General Public License as published by
1175fd0b74Schristos the Free Software Foundation; either version 3 of the License, or
1275fd0b74Schristos (at your option) any later version.
1375fd0b74Schristos
1475fd0b74Schristos This program is distributed in the hope that it will be useful,
1575fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1675fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1775fd0b74Schristos GNU General Public License for more details.
1875fd0b74Schristos
1975fd0b74Schristos You should have received a copy of the GNU General Public License
2075fd0b74Schristos along with this program; if not, write to the Free Software
2175fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2275fd0b74Schristos MA 02110-1301, USA. */
2375fd0b74Schristos
2475fd0b74Schristos
2575fd0b74Schristos /* This port currently only handles reading object files, except when
2675fd0b74Schristos compiled on an RS/6000 host. -- no archive support, no core files.
2775fd0b74Schristos In all cases, it does not support writing.
2875fd0b74Schristos
2975fd0b74Schristos This is in a separate file from coff-rs6000.c, because it includes
3075fd0b74Schristos system include files that conflict with coff/rs6000.h. */
3175fd0b74Schristos
3275fd0b74Schristos /* Internalcoff.h and coffcode.h modify themselves based on this flag. */
3375fd0b74Schristos #define RS6000COFF_C 1
3475fd0b74Schristos
3575fd0b74Schristos /* The AIX 4.1 kernel is obviously compiled with -D_LONG_LONG, so
3675fd0b74Schristos we have to define _LONG_LONG for older versions of gcc to get the
3775fd0b74Schristos proper alignments in the user structure. */
3875fd0b74Schristos #if defined(_AIX41) && !defined(_LONG_LONG)
3975fd0b74Schristos #define _LONG_LONG
4075fd0b74Schristos #endif
4175fd0b74Schristos
4275fd0b74Schristos #include "sysdep.h"
4375fd0b74Schristos #include "bfd.h"
4475fd0b74Schristos #include "libbfd.h"
4575fd0b74Schristos
4675fd0b74Schristos #ifdef AIX_CORE
4775fd0b74Schristos
4875fd0b74Schristos /* AOUTHDR is defined by the above. We need another defn of it, from the
4975fd0b74Schristos system include files. Punt the old one and get us a new name for the
5075fd0b74Schristos typedef in the system include files. */
5175fd0b74Schristos #ifdef AOUTHDR
5275fd0b74Schristos #undef AOUTHDR
5375fd0b74Schristos #endif
5475fd0b74Schristos #define AOUTHDR second_AOUTHDR
5575fd0b74Schristos
5675fd0b74Schristos #undef SCNHDR
5775fd0b74Schristos
5875fd0b74Schristos /* Support for core file stuff. */
5975fd0b74Schristos
6075fd0b74Schristos #include <sys/user.h>
6175fd0b74Schristos #define __LDINFO_PTRACE32__ /* for __ld_info32 */
6275fd0b74Schristos #define __LDINFO_PTRACE64__ /* for __ld_info64 */
6375fd0b74Schristos #include <sys/ldr.h>
6475fd0b74Schristos #include <sys/core.h>
6575fd0b74Schristos #include <sys/systemcfg.h>
6675fd0b74Schristos
6775fd0b74Schristos /* Borrowed from <sys/inttypes.h> on recent AIX versions. */
6875fd0b74Schristos typedef unsigned long ptr_to_uint;
6975fd0b74Schristos
7075fd0b74Schristos #define core_hdr(bfd) ((CoreHdr *) bfd->tdata.any)
7175fd0b74Schristos
7275fd0b74Schristos /* AIX 4.1 changed the names and locations of a few items in the core file.
7375fd0b74Schristos AIX 4.3 defined an entirely new structure, core_dumpx, but kept support for
7475fd0b74Schristos the previous 4.1 structure, core_dump.
7575fd0b74Schristos
7675fd0b74Schristos AIX_CORE_DUMPX_CORE is defined (by configure) on AIX 4.3+, and
7775fd0b74Schristos CORE_VERSION_1 is defined (by AIX core.h) as 2 on AIX 4.3+ and as 1 on AIX
7875fd0b74Schristos 4.1 and 4.2. AIX pre-4.1 (aka 3.x) either doesn't define CORE_VERSION_1
7975fd0b74Schristos or else defines it as 0. */
8075fd0b74Schristos
8175fd0b74Schristos #if defined(CORE_VERSION_1) && !CORE_VERSION_1
8275fd0b74Schristos # undef CORE_VERSION_1
8375fd0b74Schristos #endif
8475fd0b74Schristos
8575fd0b74Schristos /* The following union and macros allow this module to compile on all AIX
8675fd0b74Schristos versions and to handle both core_dumpx and core_dump on 4.3+. CNEW_*()
8775fd0b74Schristos and COLD_*() macros respectively retrieve core_dumpx and core_dump
8875fd0b74Schristos values. */
8975fd0b74Schristos
9075fd0b74Schristos /* Union of 32-bit and 64-bit versions of ld_info. */
9175fd0b74Schristos
9275fd0b74Schristos typedef union
9375fd0b74Schristos {
9475fd0b74Schristos #if defined (__ld_info32) || defined (__ld_info64)
9575fd0b74Schristos struct __ld_info32 l32;
9675fd0b74Schristos struct __ld_info64 l64;
9775fd0b74Schristos #else
9875fd0b74Schristos struct ld_info l32;
9975fd0b74Schristos struct ld_info l64;
10075fd0b74Schristos #endif
10175fd0b74Schristos } LdInfo;
10275fd0b74Schristos
10375fd0b74Schristos /* Union of old and new core dump structures. */
10475fd0b74Schristos
10575fd0b74Schristos typedef union
10675fd0b74Schristos {
10775fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
10875fd0b74Schristos struct core_dumpx new_dump; /* New AIX 4.3+ core dump. */
10975fd0b74Schristos #else
11075fd0b74Schristos struct core_dump new_dump; /* For simpler coding. */
11175fd0b74Schristos #endif
11275fd0b74Schristos #ifndef BFD64 /* Use old only if gdb is 32-bit. */
11375fd0b74Schristos struct core_dump old; /* Old AIX 4.2- core dump, still used on
11475fd0b74Schristos 4.3+ with appropriate SMIT config. */
11575fd0b74Schristos #endif
11675fd0b74Schristos } CoreHdr;
11775fd0b74Schristos
11875fd0b74Schristos /* Union of old and new vm_info structures. */
11975fd0b74Schristos
12075fd0b74Schristos #ifdef CORE_VERSION_1
12175fd0b74Schristos typedef union
12275fd0b74Schristos {
12375fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
12475fd0b74Schristos struct vm_infox new_dump;
12575fd0b74Schristos #else
12675fd0b74Schristos struct vm_info new_dump;
12775fd0b74Schristos #endif
12875fd0b74Schristos #ifndef BFD64
12975fd0b74Schristos struct vm_info old;
13075fd0b74Schristos #endif
13175fd0b74Schristos } VmInfo;
13275fd0b74Schristos #endif
13375fd0b74Schristos
13475fd0b74Schristos /* Return whether CoreHdr C is in new or old format. */
13575fd0b74Schristos
13675fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
13775fd0b74Schristos # ifndef BFD64
13875fd0b74Schristos # define CORE_NEW(c) (!(c).old.c_entries)
13975fd0b74Schristos # else
140ede78133Schristos # define CORE_NEW(c) 1
14175fd0b74Schristos # endif
14275fd0b74Schristos #else
14375fd0b74Schristos # define CORE_NEW(c) 0
14475fd0b74Schristos #endif
14575fd0b74Schristos
14675fd0b74Schristos /* Return whether CoreHdr C usese core_dumpxx structure.
14775fd0b74Schristos
14875fd0b74Schristos FIXME: the core file format version number used here definitely indicates
14975fd0b74Schristos that struct core_dumpxx should be used to represent the core file header,
15075fd0b74Schristos but that may not be the only such format version number. */
15175fd0b74Schristos
15275fd0b74Schristos #ifdef AIX_5_CORE
15375fd0b74Schristos # define CORE_DUMPXX_VERSION 267312562
15475fd0b74Schristos # define CNEW_IS_CORE_DUMPXX(c) ((c).new_dump.c_version == CORE_DUMPXX_VERSION)
15575fd0b74Schristos #else
15675fd0b74Schristos # define CNEW_IS_CORE_DUMPXX(c) 0
15775fd0b74Schristos #endif
15875fd0b74Schristos
15975fd0b74Schristos /* Return the c_stackorg field from struct core_dumpx C. */
16075fd0b74Schristos
16175fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
16275fd0b74Schristos # define CNEW_STACKORG(c) (c).c_stackorg
16375fd0b74Schristos #else
16475fd0b74Schristos # define CNEW_STACKORG(c) 0
16575fd0b74Schristos #endif
16675fd0b74Schristos
16775fd0b74Schristos /* Return the offset to the loader region from struct core_dump C. */
16875fd0b74Schristos
16975fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
17075fd0b74Schristos # define CNEW_LOADER(c) (c).c_loader
17175fd0b74Schristos #else
17275fd0b74Schristos # define CNEW_LOADER(c) 0
17375fd0b74Schristos #endif
17475fd0b74Schristos
17575fd0b74Schristos /* Return the offset to the loader region from struct core_dump C. */
17675fd0b74Schristos
17775fd0b74Schristos #define COLD_LOADER(c) (c).c_tab
17875fd0b74Schristos
17975fd0b74Schristos /* Return the c_lsize field from struct core_dumpx C. */
18075fd0b74Schristos
18175fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
18275fd0b74Schristos # define CNEW_LSIZE(c) (c).c_lsize
18375fd0b74Schristos #else
18475fd0b74Schristos # define CNEW_LSIZE(c) 0
18575fd0b74Schristos #endif
18675fd0b74Schristos
18775fd0b74Schristos /* Return the c_dataorg field from struct core_dumpx C. */
18875fd0b74Schristos
18975fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
19075fd0b74Schristos # define CNEW_DATAORG(c) (c).c_dataorg
19175fd0b74Schristos #else
19275fd0b74Schristos # define CNEW_DATAORG(c) 0
19375fd0b74Schristos #endif
19475fd0b74Schristos
19575fd0b74Schristos /* Return the c_datasize field from struct core_dumpx C. */
19675fd0b74Schristos
19775fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
19875fd0b74Schristos # define CNEW_DATASIZE(c) (c).c_datasize
19975fd0b74Schristos #else
20075fd0b74Schristos # define CNEW_DATASIZE(c) 0
20175fd0b74Schristos #endif
20275fd0b74Schristos
20375fd0b74Schristos /* Return the c_impl field from struct core_dumpx C. */
20475fd0b74Schristos
20575fd0b74Schristos #if defined (HAVE_ST_C_IMPL) || defined (AIX_5_CORE)
20675fd0b74Schristos # define CNEW_IMPL(c) (c).c_impl
20775fd0b74Schristos #else
20875fd0b74Schristos # define CNEW_IMPL(c) 0
20975fd0b74Schristos #endif
21075fd0b74Schristos
21175fd0b74Schristos /* Return the command string from struct core_dumpx C. */
21275fd0b74Schristos
21375fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
21475fd0b74Schristos # define CNEW_COMM(c) (c).c_u.U_proc.pi_comm
21575fd0b74Schristos #else
21675fd0b74Schristos # define CNEW_COMM(c) 0
21775fd0b74Schristos #endif
21875fd0b74Schristos
21975fd0b74Schristos /* Return the command string from struct core_dump C. */
22075fd0b74Schristos
22175fd0b74Schristos #ifdef CORE_VERSION_1
22275fd0b74Schristos # define COLD_COMM(c) (c).c_u.U_comm
22375fd0b74Schristos #else
22475fd0b74Schristos # define COLD_COMM(c) (c).c_u.u_comm
22575fd0b74Schristos #endif
22675fd0b74Schristos
22775fd0b74Schristos /* Return the struct __context64 pointer from struct core_dumpx C. */
22875fd0b74Schristos
22975fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
23075fd0b74Schristos # define CNEW_CONTEXT64(c) (c).c_flt.hctx.r64
23175fd0b74Schristos #else
23275fd0b74Schristos # define CNEW_CONTEXT64(c) c
23375fd0b74Schristos #endif
23475fd0b74Schristos
23575fd0b74Schristos /* Return the struct mstsave pointer from struct core_dumpx C. */
23675fd0b74Schristos
23775fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
23875fd0b74Schristos # define CNEW_MSTSAVE(c) (c).c_flt.hctx.r32
23975fd0b74Schristos #else
24075fd0b74Schristos # define CNEW_MSTSAVE(c) c
24175fd0b74Schristos #endif
24275fd0b74Schristos
24375fd0b74Schristos /* Return the struct mstsave pointer from struct core_dump C. */
24475fd0b74Schristos
24575fd0b74Schristos #ifdef CORE_VERSION_1
24675fd0b74Schristos # define COLD_MSTSAVE(c) (c).c_mst
24775fd0b74Schristos #else
24875fd0b74Schristos # define COLD_MSTSAVE(c) (c).c_u.u_save
24975fd0b74Schristos #endif
25075fd0b74Schristos
25175fd0b74Schristos /* Return whether struct core_dumpx is from a 64-bit process. */
25275fd0b74Schristos
25375fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
25475fd0b74Schristos # define CNEW_PROC64(c) IS_PROC64(&(c).c_u.U_proc)
25575fd0b74Schristos #else
25675fd0b74Schristos # define CNEW_PROC64(c) 0
25775fd0b74Schristos #endif
25875fd0b74Schristos
25975fd0b74Schristos /* Magic end-of-stack addresses for old core dumps. This is _very_ fragile,
26075fd0b74Schristos but I don't see any easy way to get that info right now. */
26175fd0b74Schristos
26275fd0b74Schristos #ifdef CORE_VERSION_1
26375fd0b74Schristos # define COLD_STACKEND 0x2ff23000
26475fd0b74Schristos #else
26575fd0b74Schristos # define COLD_STACKEND 0x2ff80000
26675fd0b74Schristos #endif
26775fd0b74Schristos
26875fd0b74Schristos /* Size of the leading portion that old and new core dump structures have in
26975fd0b74Schristos common. */
27075fd0b74Schristos #ifdef AIX_CORE_DUMPX_CORE
27175fd0b74Schristos #define CORE_COMMONSZ ((long) &((struct core_dumpx *) 0)->c_entries \
27275fd0b74Schristos + sizeof (((struct core_dumpx *) 0)->c_entries))
27375fd0b74Schristos #else
27475fd0b74Schristos #define CORE_COMMONSZ ((int) &((struct core_dump *) 0)->c_entries \
275012573ebSchristos + sizeof (((struct core_dump *) 0)->c_entries))
27675fd0b74Schristos #endif
27775fd0b74Schristos /* Define prototypes for certain functions, to avoid a compiler warning
27875fd0b74Schristos saying that they are missing. */
27975fd0b74Schristos
280*e992f068Schristos bfd_cleanup rs6000coff_core_p (bfd *abfd);
281*e992f068Schristos bool rs6000coff_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd);
28275fd0b74Schristos char * rs6000coff_core_file_failing_command (bfd *abfd);
28375fd0b74Schristos int rs6000coff_core_file_failing_signal (bfd *abfd);
28475fd0b74Schristos
28575fd0b74Schristos /* Try to read into CORE the header from the core file associated with ABFD.
28675fd0b74Schristos Return success. */
28775fd0b74Schristos
288*e992f068Schristos static bool
read_hdr(bfd * abfd,CoreHdr * core)28975fd0b74Schristos read_hdr (bfd *abfd, CoreHdr *core)
29075fd0b74Schristos {
29175fd0b74Schristos bfd_size_type size;
29275fd0b74Schristos
29375fd0b74Schristos if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
294*e992f068Schristos return false;
29575fd0b74Schristos
29675fd0b74Schristos /* Read the leading portion that old and new core dump structures have in
29775fd0b74Schristos common. */
29875fd0b74Schristos size = CORE_COMMONSZ;
29975fd0b74Schristos if (bfd_bread (core, size, abfd) != size)
300*e992f068Schristos return false;
30175fd0b74Schristos
30275fd0b74Schristos /* Read the trailing portion of the structure. */
30375fd0b74Schristos if (CORE_NEW (*core))
30475fd0b74Schristos size = sizeof (core->new_dump);
30575fd0b74Schristos #ifndef BFD64
30675fd0b74Schristos else
30775fd0b74Schristos size = sizeof (core->old);
30875fd0b74Schristos #endif
30975fd0b74Schristos size -= CORE_COMMONSZ;
31075fd0b74Schristos return bfd_bread ((char *) core + CORE_COMMONSZ, size, abfd) == size;
31175fd0b74Schristos }
31275fd0b74Schristos
31375fd0b74Schristos static asection *
make_bfd_asection(bfd * abfd,const char * name,flagword flags,bfd_size_type size,bfd_vma vma,file_ptr filepos)31475fd0b74Schristos make_bfd_asection (bfd *abfd, const char *name, flagword flags,
31575fd0b74Schristos bfd_size_type size, bfd_vma vma, file_ptr filepos)
31675fd0b74Schristos {
31775fd0b74Schristos asection *asect;
31875fd0b74Schristos
31975fd0b74Schristos asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
32075fd0b74Schristos if (!asect)
32175fd0b74Schristos return NULL;
32275fd0b74Schristos
32375fd0b74Schristos asect->size = size;
32475fd0b74Schristos asect->vma = vma;
32575fd0b74Schristos asect->filepos = filepos;
32675fd0b74Schristos asect->alignment_power = 8;
32775fd0b74Schristos
32875fd0b74Schristos return asect;
32975fd0b74Schristos }
33075fd0b74Schristos
33175fd0b74Schristos /* Decide if a given bfd represents a `core' file or not. There really is no
33275fd0b74Schristos magic number or anything like, in rs6000coff. */
33375fd0b74Schristos
334*e992f068Schristos bfd_cleanup
rs6000coff_core_p(bfd * abfd)33575fd0b74Schristos rs6000coff_core_p (bfd *abfd)
33675fd0b74Schristos {
33775fd0b74Schristos CoreHdr core;
33875fd0b74Schristos struct stat statbuf;
33975fd0b74Schristos bfd_size_type size;
34075fd0b74Schristos char *tmpptr;
34175fd0b74Schristos
34275fd0b74Schristos /* Values from new and old core structures. */
34375fd0b74Schristos int c_flag;
34475fd0b74Schristos file_ptr c_stack, c_regoff, c_loader;
34575fd0b74Schristos bfd_size_type c_size, c_regsize, c_lsize;
34675fd0b74Schristos bfd_vma c_stackend;
34775fd0b74Schristos void *c_regptr;
34875fd0b74Schristos int proc64;
34975fd0b74Schristos
35075fd0b74Schristos if (!read_hdr (abfd, &core))
35175fd0b74Schristos {
35275fd0b74Schristos if (bfd_get_error () != bfd_error_system_call)
35375fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
35475fd0b74Schristos return NULL;
35575fd0b74Schristos }
35675fd0b74Schristos
35775fd0b74Schristos /* This isn't the right handler for 64-bit core files on AIX 5.x. */
35875fd0b74Schristos if (CORE_NEW (core) && CNEW_IS_CORE_DUMPXX (core))
35975fd0b74Schristos {
36075fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
36175fd0b74Schristos return NULL;
36275fd0b74Schristos }
36375fd0b74Schristos
36475fd0b74Schristos /* Copy fields from new or old core structure. */
36575fd0b74Schristos if (CORE_NEW (core))
36675fd0b74Schristos {
36775fd0b74Schristos c_flag = core.new_dump.c_flag;
36875fd0b74Schristos c_stack = (file_ptr) core.new_dump.c_stack;
36975fd0b74Schristos c_size = core.new_dump.c_size;
37075fd0b74Schristos c_stackend = CNEW_STACKORG (core.new_dump) + c_size;
37175fd0b74Schristos c_lsize = CNEW_LSIZE (core.new_dump);
37275fd0b74Schristos c_loader = CNEW_LOADER (core.new_dump);
37375fd0b74Schristos #ifndef BFD64
37475fd0b74Schristos proc64 = CNEW_PROC64 (core.new_dump);
37575fd0b74Schristos }
37675fd0b74Schristos else
37775fd0b74Schristos {
37875fd0b74Schristos c_flag = core.old.c_flag;
37975fd0b74Schristos c_stack = (file_ptr) (ptr_to_uint) core.old.c_stack;
38075fd0b74Schristos c_size = core.old.c_size;
38175fd0b74Schristos c_stackend = COLD_STACKEND;
38275fd0b74Schristos c_lsize = 0x7ffffff;
38375fd0b74Schristos c_loader = (file_ptr) (ptr_to_uint) COLD_LOADER (core.old);
38475fd0b74Schristos #endif
38575fd0b74Schristos proc64 = 0;
38675fd0b74Schristos }
38775fd0b74Schristos
38875fd0b74Schristos if (proc64)
38975fd0b74Schristos {
39075fd0b74Schristos c_regsize = sizeof (CNEW_CONTEXT64 (core.new_dump));
39175fd0b74Schristos c_regptr = &CNEW_CONTEXT64 (core.new_dump);
39275fd0b74Schristos }
39375fd0b74Schristos else if (CORE_NEW (core))
39475fd0b74Schristos {
39575fd0b74Schristos c_regsize = sizeof (CNEW_MSTSAVE (core.new_dump));
39675fd0b74Schristos c_regptr = &CNEW_MSTSAVE (core.new_dump);
39775fd0b74Schristos }
39875fd0b74Schristos #ifndef BFD64
39975fd0b74Schristos else
40075fd0b74Schristos {
40175fd0b74Schristos c_regsize = sizeof (COLD_MSTSAVE (core.old));
40275fd0b74Schristos c_regptr = &COLD_MSTSAVE (core.old);
40375fd0b74Schristos }
40475fd0b74Schristos #endif
40575fd0b74Schristos c_regoff = (char *) c_regptr - (char *) &core;
40675fd0b74Schristos
40775fd0b74Schristos if (bfd_stat (abfd, &statbuf) < 0)
40875fd0b74Schristos {
40975fd0b74Schristos bfd_set_error (bfd_error_system_call);
41075fd0b74Schristos return NULL;
41175fd0b74Schristos }
41275fd0b74Schristos
41375fd0b74Schristos /* If the core file ulimit is too small, the system will first
41475fd0b74Schristos omit the data segment, then omit the stack, then decline to
41575fd0b74Schristos dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
41675fd0b74Schristos are always set) (this is based on experimentation on AIX 3.2).
41775fd0b74Schristos Now, the thing is that GDB users will be surprised
41875fd0b74Schristos if segments just silently don't appear (well, maybe they would
41975fd0b74Schristos think to check "info files", I don't know).
42075fd0b74Schristos
42175fd0b74Schristos For the data segment, we have no choice but to keep going if it's
42275fd0b74Schristos not there, since the default behavior is not to dump it (regardless
42375fd0b74Schristos of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
42475fd0b74Schristos if it's not there, we refuse to have anything to do with this core
42575fd0b74Schristos file. The usefulness of a core dump without a stack segment is pretty
42675fd0b74Schristos limited anyway. */
42775fd0b74Schristos
42875fd0b74Schristos if (!(c_flag & UBLOCK_VALID)
42975fd0b74Schristos || !(c_flag & LE_VALID))
43075fd0b74Schristos {
43175fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
43275fd0b74Schristos return NULL;
43375fd0b74Schristos }
43475fd0b74Schristos
43575fd0b74Schristos if (!(c_flag & USTACK_VALID))
43675fd0b74Schristos {
43775fd0b74Schristos bfd_set_error (bfd_error_file_truncated);
43875fd0b74Schristos return NULL;
43975fd0b74Schristos }
44075fd0b74Schristos
44175fd0b74Schristos /* Don't check the core file size for a full core, AIX 4.1 includes
44275fd0b74Schristos additional shared library sections in a full core. */
44375fd0b74Schristos if (!(c_flag & (FULL_CORE | CORE_TRUNC)))
44475fd0b74Schristos {
44575fd0b74Schristos /* If the size is wrong, it means we're misinterpreting something. */
44675fd0b74Schristos if (c_stack + (file_ptr) c_size != statbuf.st_size)
44775fd0b74Schristos {
44875fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
44975fd0b74Schristos return NULL;
45075fd0b74Schristos }
45175fd0b74Schristos }
45275fd0b74Schristos
45375fd0b74Schristos /* Sanity check on the c_tab field. */
45475fd0b74Schristos if (!CORE_NEW (core)
45575fd0b74Schristos && (
45675fd0b74Schristos #ifndef BFD64
45775fd0b74Schristos c_loader < (file_ptr) sizeof core.old
45875fd0b74Schristos #else
45975fd0b74Schristos c_loader < (file_ptr) sizeof core.new_dump
46075fd0b74Schristos #endif
46175fd0b74Schristos || c_loader >= statbuf.st_size
46275fd0b74Schristos || c_loader >= c_stack))
46375fd0b74Schristos {
46475fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
46575fd0b74Schristos return NULL;
46675fd0b74Schristos }
46775fd0b74Schristos
46875fd0b74Schristos /* Issue warning if the core file was truncated during writing. */
46975fd0b74Schristos if (c_flag & CORE_TRUNC)
470ede78133Schristos _bfd_error_handler (_("%pB: warning core file truncated"), abfd);
47175fd0b74Schristos
47275fd0b74Schristos /* Allocate core file header. */
47375fd0b74Schristos #ifndef BFD64
47475fd0b74Schristos size = CORE_NEW (core) ? sizeof (core.new_dump) : sizeof (core.old);
47575fd0b74Schristos #else
47675fd0b74Schristos size = sizeof (core.new_dump);
47775fd0b74Schristos #endif
47875fd0b74Schristos tmpptr = (char *) bfd_zalloc (abfd, (bfd_size_type) size);
47975fd0b74Schristos if (!tmpptr)
48075fd0b74Schristos return NULL;
48175fd0b74Schristos
48275fd0b74Schristos /* Copy core file header. */
48375fd0b74Schristos memcpy (tmpptr, &core, size);
48475fd0b74Schristos set_tdata (abfd, tmpptr);
48575fd0b74Schristos
48675fd0b74Schristos /* Set architecture. */
48775fd0b74Schristos if (CORE_NEW (core))
48875fd0b74Schristos {
48975fd0b74Schristos enum bfd_architecture arch;
49075fd0b74Schristos unsigned long mach;
49175fd0b74Schristos
49275fd0b74Schristos switch (CNEW_IMPL (core.new_dump))
49375fd0b74Schristos {
49475fd0b74Schristos case POWER_RS1:
49575fd0b74Schristos case POWER_RSC:
49675fd0b74Schristos case POWER_RS2:
49775fd0b74Schristos arch = bfd_arch_rs6000;
49875fd0b74Schristos mach = bfd_mach_rs6k;
49975fd0b74Schristos break;
50075fd0b74Schristos default:
50175fd0b74Schristos arch = bfd_arch_powerpc;
50275fd0b74Schristos mach = bfd_mach_ppc;
50375fd0b74Schristos break;
50475fd0b74Schristos }
50575fd0b74Schristos bfd_default_set_arch_mach (abfd, arch, mach);
50675fd0b74Schristos }
50775fd0b74Schristos
50875fd0b74Schristos /* .stack section. */
50975fd0b74Schristos if (!make_bfd_asection (abfd, ".stack",
51075fd0b74Schristos SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
51175fd0b74Schristos c_size, c_stackend - c_size, c_stack))
51275fd0b74Schristos goto fail;
51375fd0b74Schristos
51475fd0b74Schristos /* .reg section for all registers. */
51575fd0b74Schristos if (!make_bfd_asection (abfd, ".reg",
51675fd0b74Schristos SEC_HAS_CONTENTS,
51775fd0b74Schristos c_regsize, (bfd_vma) 0, c_regoff))
51875fd0b74Schristos goto fail;
51975fd0b74Schristos
52075fd0b74Schristos /* .ldinfo section.
52175fd0b74Schristos To actually find out how long this section is in this particular
52275fd0b74Schristos core dump would require going down the whole list of struct ld_info's.
52375fd0b74Schristos See if we can just fake it. */
52475fd0b74Schristos if (!make_bfd_asection (abfd, ".ldinfo",
52575fd0b74Schristos SEC_HAS_CONTENTS,
52675fd0b74Schristos c_lsize, (bfd_vma) 0, c_loader))
52775fd0b74Schristos goto fail;
52875fd0b74Schristos
52975fd0b74Schristos #ifndef CORE_VERSION_1
53075fd0b74Schristos /* .data section if present.
53175fd0b74Schristos AIX 3 dumps the complete data section and sets FULL_CORE if the
53275fd0b74Schristos ulimit is large enough, otherwise the data section is omitted.
53375fd0b74Schristos AIX 4 sets FULL_CORE even if the core file is truncated, we have
53475fd0b74Schristos to examine core.c_datasize below to find out the actual size of
53575fd0b74Schristos the .data section. */
53675fd0b74Schristos if (c_flag & FULL_CORE)
53775fd0b74Schristos {
53875fd0b74Schristos if (!make_bfd_asection (abfd, ".data",
53975fd0b74Schristos SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
54075fd0b74Schristos (bfd_size_type) core.old.c_u.u_dsize,
54175fd0b74Schristos (bfd_vma)
54275fd0b74Schristos CDATA_ADDR (core.old.c_u.u_dsize),
54375fd0b74Schristos c_stack + c_size))
54475fd0b74Schristos goto fail;
54575fd0b74Schristos }
54675fd0b74Schristos #endif
54775fd0b74Schristos
54875fd0b74Schristos #ifdef CORE_VERSION_1
54975fd0b74Schristos /* AIX 4 adds data sections from loaded objects to the core file,
55075fd0b74Schristos which can be found by examining ldinfo, and anonymously mmapped
55175fd0b74Schristos regions. */
55275fd0b74Schristos {
55375fd0b74Schristos LdInfo ldinfo;
55475fd0b74Schristos bfd_size_type ldi_datasize;
55575fd0b74Schristos file_ptr ldi_core;
55675fd0b74Schristos uint ldi_next;
55775fd0b74Schristos bfd_vma ldi_dataorg;
55875fd0b74Schristos bfd_vma core_dataorg;
55975fd0b74Schristos
56075fd0b74Schristos /* Fields from new and old core structures. */
56175fd0b74Schristos bfd_size_type c_datasize, c_vmregions;
56275fd0b74Schristos file_ptr c_data, c_vmm;
56375fd0b74Schristos
56475fd0b74Schristos if (CORE_NEW (core))
56575fd0b74Schristos {
56675fd0b74Schristos c_datasize = CNEW_DATASIZE (core.new_dump);
56775fd0b74Schristos c_data = (file_ptr) core.new_dump.c_data;
56875fd0b74Schristos c_vmregions = core.new_dump.c_vmregions;
56975fd0b74Schristos c_vmm = (file_ptr) core.new_dump.c_vmm;
57075fd0b74Schristos }
57175fd0b74Schristos #ifndef BFD64
57275fd0b74Schristos else
57375fd0b74Schristos {
57475fd0b74Schristos c_datasize = core.old.c_datasize;
57575fd0b74Schristos c_data = (file_ptr) (ptr_to_uint) core.old.c_data;
57675fd0b74Schristos c_vmregions = core.old.c_vmregions;
57775fd0b74Schristos c_vmm = (file_ptr) (ptr_to_uint) core.old.c_vmm;
57875fd0b74Schristos }
57975fd0b74Schristos #endif
58075fd0b74Schristos
58175fd0b74Schristos /* .data section from executable. */
58275fd0b74Schristos if (c_datasize)
58375fd0b74Schristos {
58475fd0b74Schristos /* If Large Memory Model is used, then the .data segment should start from
58575fd0b74Schristos BDATAORG which has been defined in the system header files. */
58675fd0b74Schristos
58775fd0b74Schristos if (c_flag & CORE_BIGDATA)
58875fd0b74Schristos core_dataorg = BDATAORG;
58975fd0b74Schristos else
59075fd0b74Schristos core_dataorg = CDATA_ADDR (c_datasize);
59175fd0b74Schristos
59275fd0b74Schristos if (!make_bfd_asection (abfd, ".data",
59375fd0b74Schristos SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
59475fd0b74Schristos c_datasize,
59575fd0b74Schristos (bfd_vma) core_dataorg,
59675fd0b74Schristos c_data))
59775fd0b74Schristos goto fail;
59875fd0b74Schristos }
59975fd0b74Schristos
60075fd0b74Schristos /* .data sections from loaded objects. */
60175fd0b74Schristos if (proc64)
60275fd0b74Schristos size = (unsigned long) ((LdInfo *) 0)->l64.ldinfo_filename;
60375fd0b74Schristos else
60475fd0b74Schristos size = (unsigned long) ((LdInfo *) 0)->l32.ldinfo_filename;
60575fd0b74Schristos
60675fd0b74Schristos while (1)
60775fd0b74Schristos {
60875fd0b74Schristos if (bfd_seek (abfd, c_loader, SEEK_SET) != 0)
60975fd0b74Schristos goto fail;
61075fd0b74Schristos if (bfd_bread (&ldinfo, size, abfd) != size)
61175fd0b74Schristos goto fail;
61275fd0b74Schristos
61375fd0b74Schristos if (proc64)
61475fd0b74Schristos {
61575fd0b74Schristos ldi_core = ldinfo.l64.ldinfo_core;
61675fd0b74Schristos ldi_datasize = ldinfo.l64.ldinfo_datasize;
61775fd0b74Schristos ldi_dataorg = (bfd_vma) ldinfo.l64.ldinfo_dataorg;
61875fd0b74Schristos ldi_next = ldinfo.l64.ldinfo_next;
61975fd0b74Schristos }
62075fd0b74Schristos else
62175fd0b74Schristos {
62275fd0b74Schristos ldi_core = ldinfo.l32.ldinfo_core;
62375fd0b74Schristos ldi_datasize = ldinfo.l32.ldinfo_datasize;
62475fd0b74Schristos ldi_dataorg = (bfd_vma) (ptr_to_uint) ldinfo.l32.ldinfo_dataorg;
62575fd0b74Schristos ldi_next = ldinfo.l32.ldinfo_next;
62675fd0b74Schristos }
62775fd0b74Schristos
62875fd0b74Schristos if (ldi_core)
62975fd0b74Schristos if (!make_bfd_asection (abfd, ".data",
63075fd0b74Schristos SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
63175fd0b74Schristos ldi_datasize, ldi_dataorg, ldi_core))
63275fd0b74Schristos goto fail;
63375fd0b74Schristos
63475fd0b74Schristos if (ldi_next == 0)
63575fd0b74Schristos break;
63675fd0b74Schristos c_loader += ldi_next;
63775fd0b74Schristos }
63875fd0b74Schristos
63975fd0b74Schristos /* .vmdata sections from anonymously mmapped regions. */
64075fd0b74Schristos if (c_vmregions)
64175fd0b74Schristos {
64275fd0b74Schristos bfd_size_type i;
64375fd0b74Schristos
64475fd0b74Schristos if (bfd_seek (abfd, c_vmm, SEEK_SET) != 0)
64575fd0b74Schristos goto fail;
64675fd0b74Schristos
64775fd0b74Schristos for (i = 0; i < c_vmregions; i++)
64875fd0b74Schristos {
64975fd0b74Schristos VmInfo vminfo;
65075fd0b74Schristos bfd_size_type vminfo_size;
65175fd0b74Schristos file_ptr vminfo_offset;
65275fd0b74Schristos bfd_vma vminfo_addr;
65375fd0b74Schristos
65475fd0b74Schristos #ifndef BFD64
65575fd0b74Schristos size = CORE_NEW (core) ? sizeof (vminfo.new_dump) : sizeof (vminfo.old);
65675fd0b74Schristos #else
65775fd0b74Schristos size = sizeof (vminfo.new_dump);
65875fd0b74Schristos #endif
65975fd0b74Schristos if (bfd_bread (&vminfo, size, abfd) != size)
66075fd0b74Schristos goto fail;
66175fd0b74Schristos
66275fd0b74Schristos if (CORE_NEW (core))
66375fd0b74Schristos {
66475fd0b74Schristos vminfo_addr = (bfd_vma) vminfo.new_dump.vminfo_addr;
66575fd0b74Schristos vminfo_size = vminfo.new_dump.vminfo_size;
66675fd0b74Schristos vminfo_offset = vminfo.new_dump.vminfo_offset;
66775fd0b74Schristos }
66875fd0b74Schristos #ifndef BFD64
66975fd0b74Schristos else
67075fd0b74Schristos {
67175fd0b74Schristos vminfo_addr = (bfd_vma) (ptr_to_uint) vminfo.old.vminfo_addr;
67275fd0b74Schristos vminfo_size = vminfo.old.vminfo_size;
67375fd0b74Schristos vminfo_offset = vminfo.old.vminfo_offset;
67475fd0b74Schristos }
67575fd0b74Schristos #endif
67675fd0b74Schristos
67775fd0b74Schristos if (vminfo_offset)
67875fd0b74Schristos if (!make_bfd_asection (abfd, ".vmdata",
67975fd0b74Schristos SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
68075fd0b74Schristos vminfo_size, vminfo_addr,
68175fd0b74Schristos vminfo_offset))
68275fd0b74Schristos goto fail;
68375fd0b74Schristos }
68475fd0b74Schristos }
68575fd0b74Schristos }
68675fd0b74Schristos #endif
68775fd0b74Schristos
688*e992f068Schristos return _bfd_no_cleanup;
68975fd0b74Schristos
69075fd0b74Schristos fail:
69175fd0b74Schristos bfd_release (abfd, abfd->tdata.any);
69275fd0b74Schristos abfd->tdata.any = NULL;
69375fd0b74Schristos bfd_section_list_clear (abfd);
69475fd0b74Schristos return NULL;
69575fd0b74Schristos }
69675fd0b74Schristos
69775fd0b74Schristos /* Return `TRUE' if given core is from the given executable. */
69875fd0b74Schristos
699*e992f068Schristos bool
rs6000coff_core_file_matches_executable_p(bfd * core_bfd,bfd * exec_bfd)70075fd0b74Schristos rs6000coff_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
70175fd0b74Schristos {
70275fd0b74Schristos CoreHdr core;
70375fd0b74Schristos bfd_size_type size;
70475fd0b74Schristos char *path, *s;
70575fd0b74Schristos size_t alloc;
70675fd0b74Schristos const char *str1, *str2;
707*e992f068Schristos bool ret;
70875fd0b74Schristos file_ptr c_loader;
70975fd0b74Schristos
71075fd0b74Schristos if (!read_hdr (core_bfd, &core))
711*e992f068Schristos return false;
71275fd0b74Schristos
71375fd0b74Schristos if (CORE_NEW (core))
71475fd0b74Schristos c_loader = CNEW_LOADER (core.new_dump);
71575fd0b74Schristos #ifndef BFD64
71675fd0b74Schristos else
71775fd0b74Schristos c_loader = (file_ptr) (ptr_to_uint) COLD_LOADER (core.old);
71875fd0b74Schristos #endif
71975fd0b74Schristos
72075fd0b74Schristos if (CORE_NEW (core) && CNEW_PROC64 (core.new_dump))
72175fd0b74Schristos size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;
72275fd0b74Schristos else
72375fd0b74Schristos size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;
72475fd0b74Schristos
72575fd0b74Schristos if (bfd_seek (core_bfd, c_loader + size, SEEK_SET) != 0)
726*e992f068Schristos return false;
72775fd0b74Schristos
72875fd0b74Schristos alloc = 100;
72975fd0b74Schristos path = bfd_malloc ((bfd_size_type) alloc);
73075fd0b74Schristos if (path == NULL)
731*e992f068Schristos return false;
73275fd0b74Schristos s = path;
73375fd0b74Schristos
73475fd0b74Schristos while (1)
73575fd0b74Schristos {
73675fd0b74Schristos if (bfd_bread (s, (bfd_size_type) 1, core_bfd) != 1)
73775fd0b74Schristos {
73875fd0b74Schristos free (path);
739*e992f068Schristos return false;
74075fd0b74Schristos }
74175fd0b74Schristos if (*s == '\0')
74275fd0b74Schristos break;
74375fd0b74Schristos ++s;
74475fd0b74Schristos if (s == path + alloc)
74575fd0b74Schristos {
74675fd0b74Schristos char *n;
74775fd0b74Schristos
74875fd0b74Schristos alloc *= 2;
74975fd0b74Schristos n = bfd_realloc (path, (bfd_size_type) alloc);
75075fd0b74Schristos if (n == NULL)
75175fd0b74Schristos {
75275fd0b74Schristos free (path);
753*e992f068Schristos return false;
75475fd0b74Schristos }
75575fd0b74Schristos s = n + (path - s);
75675fd0b74Schristos path = n;
75775fd0b74Schristos }
75875fd0b74Schristos }
75975fd0b74Schristos
76075fd0b74Schristos str1 = strrchr (path, '/');
761*e992f068Schristos str2 = strrchr (bfd_get_filename (exec_bfd), '/');
76275fd0b74Schristos
76375fd0b74Schristos /* step over character '/' */
76475fd0b74Schristos str1 = str1 != NULL ? str1 + 1 : path;
765*e992f068Schristos str2 = str2 != NULL ? str2 + 1 : bfd_get_filename (exec_bfd);
76675fd0b74Schristos
76775fd0b74Schristos if (strcmp (str1, str2) == 0)
768*e992f068Schristos ret = true;
76975fd0b74Schristos else
770*e992f068Schristos ret = false;
77175fd0b74Schristos
77275fd0b74Schristos free (path);
77375fd0b74Schristos
77475fd0b74Schristos return ret;
77575fd0b74Schristos }
77675fd0b74Schristos
77775fd0b74Schristos char *
rs6000coff_core_file_failing_command(bfd * abfd)77875fd0b74Schristos rs6000coff_core_file_failing_command (bfd *abfd)
77975fd0b74Schristos {
78075fd0b74Schristos CoreHdr *core = core_hdr (abfd);
78175fd0b74Schristos #ifndef BFD64
78275fd0b74Schristos char *com = CORE_NEW (*core) ?
78375fd0b74Schristos CNEW_COMM (core->new_dump) : COLD_COMM (core->old);
78475fd0b74Schristos #else
78575fd0b74Schristos char *com = CNEW_COMM (core->new_dump);
78675fd0b74Schristos #endif
78775fd0b74Schristos
78875fd0b74Schristos if (*com)
78975fd0b74Schristos return com;
79075fd0b74Schristos else
79175fd0b74Schristos return 0;
79275fd0b74Schristos }
79375fd0b74Schristos
79475fd0b74Schristos int
rs6000coff_core_file_failing_signal(bfd * abfd)79575fd0b74Schristos rs6000coff_core_file_failing_signal (bfd *abfd)
79675fd0b74Schristos {
79775fd0b74Schristos CoreHdr *core = core_hdr (abfd);
79875fd0b74Schristos #ifndef BFD64
79975fd0b74Schristos return CORE_NEW (*core) ? core->new_dump.c_signo : core->old.c_signo;
80075fd0b74Schristos #else
80175fd0b74Schristos return core->new_dump.c_signo;
80275fd0b74Schristos #endif
80375fd0b74Schristos }
80475fd0b74Schristos
80575fd0b74Schristos #endif /* AIX_CORE */
806