* rs6000-core.c: Support 64-bit core files, support pre-4.3 core

files on AIX 4.3.
	(read_hdr): New function.
	(rs6000coff_core_p): Store mstsave or __context64 struct instead
	of trying to extract individual registers.  Set abfd->arch_info
	to match the architecture that created the core file.
	(rs6000coff_get_section_contents): Delete.
	* xcoff-target.h (rs6000coff_get_section_contents): Delete.
This commit is contained in:
Nicholas Duffek 2000-06-16 20:19:24 +00:00
parent b946ec34e6
commit 59d9f04945
3 changed files with 412 additions and 218 deletions

View File

@ -1,3 +1,14 @@
2000-06-16 Nicholas Duffek <nsd@redhat.com>
* rs6000-core.c: Support 64-bit core files, support pre-4.3 core
files on AIX 4.3.
(read_hdr): New function.
(rs6000coff_core_p): Store mstsave or __context64 struct instead
of trying to extract individual registers. Set abfd->arch_info
to match the architecture that created the core file.
(rs6000coff_get_section_contents): Delete.
* xcoff-target.h (rs6000coff_get_section_contents): Delete.
2000-06-14 H.J. Lu <hjl@gnu.org>
* vms-misc.c (_bfd_vms_next_record): Return -1 if PRIV(vms_rec)

View File

@ -5,7 +5,7 @@
Using the following chars caused a compiler warning on HIUX (so I replaced
them with octal escapes), and isn't useful without an understanding of what
character set it is.
Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
and John Gilmore.
Archive support from Damon A. Permezel.
Contributed by IBM Corporation and Cygnus Support.
@ -30,8 +30,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
compiled on an RS/6000 host. -- no archive support, no core files.
In all cases, it does not support writing.
FIXMEmgo comments are left from Metin Ozisik's original port.
This is in a separate file from coff-rs6000.c, because it includes
system include files that conflict with coff/rs6000.h.
*/
@ -64,68 +62,214 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ------------------------------------------------------------------------ */
/* Support for core file stuff.. */
/* Support for core file stuff.. */
/* ------------------------------------------------------------------------ */
#include <sys/user.h>
#define __LDINFO_PTRACE32__ /* for __ld_info32 */
#define __LDINFO_PTRACE64__ /* for __ld_info64 */
#include <sys/ldr.h>
#include <sys/core.h>
#include <sys/systemcfg.h>
#define core_hdr(bfd) ((CoreHdr *) bfd->tdata.any)
/* Number of special purpose registers supported by gdb. This value
should match `tm.h' in gdb directory. Clean this mess up and use
the macros in sys/reg.h. FIXMEmgo. */
/* AIX 4.1 changed the names and locations of a few items in the core file.
AIX 4.3 defined an entirely new structure, core_dumpx, but kept support for
the previous 4.1 structure, core_dump.
#define NUM_OF_SPEC_REGS 7
AIX_CORE_DUMPX_CORE is defined (by configure) on AIX 4.3+, and
CORE_VERSION_1 is defined (by AIX core.h) as 2 on AIX 4.3+ and as 1 on AIX
4.1 and 4.2. AIX pre-4.1 (aka 3.x) either doesn't define CORE_VERSION_1
or else defines it as 0. */
#define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr)
#if defined(CORE_VERSION_1) && !CORE_VERSION_1
# undef CORE_VERSION_1
#endif
/* AIX 4.1 Changed the names and locations of a few items in the core file,
this seems to be the quickest/easiest way to deal with it.
/* The following union and macros allow this module to compile on all AIX
versions and to handle both core_dumpx and core_dump on 4.3+. CNEW_*()
and COLD_*() macros respectively retrieve core_dumpx and core_dump
values. */
Note however that encoding magic addresses (STACK_END_ADDR) is going
to be _very_ fragile. But I don't see any easy way to get that info
right now.
AIX 4.3 defines an entirely new structure (core_dumpx). Yet the
basic logic stays the same and we can still use our macro
redefinition mechanism to effect the necessary changes. */
/* Union of 32-bit and 64-bit versions of ld_info. */
typedef union {
#ifdef __ld_info32
struct __ld_info32 l32;
struct __ld_info64 l64;
#else
struct ld_info l32;
struct ld_info l64;
#endif
} LdInfo;
/* Union of old and new core dump structures. */
typedef union {
#ifdef AIX_CORE_DUMPX_CORE
struct core_dumpx new; /* new AIX 4.3+ core dump */
#else
struct core_dump new; /* for simpler coding */
#endif
struct core_dump old; /* old AIX 4.2- core dump, still used on
4.3+ with appropriate SMIT config */
} CoreHdr;
/* Union of old and new vm_info structures. */
typedef union {
#ifdef AIX_CORE_DUMPX_CORE
struct vm_infox new;
#else
struct vm_info new;
#endif
struct vm_info old;
} VmInfo;
/* Return whether CoreHdr C is in new or old format. */
#ifdef AIX_CORE_DUMPX_CORE
#define CORE_DATA_SIZE_FIELD c_dataorg
#define CORE_COMM_FIELD c_u.U_proc.pi_comm
#define SAVE_FIELD c_flt.hctx.r32
#define STACK_END_ADDR coredata.c_stackorg + coredata.c_size
#define LOADER_OFFSET_FIELD c_loader
#define LOADER_REGION_SIZE coredata.c_lsize
#define CORE_DUMP core_dumpx
# define CORE_NEW(c) (!(c).old.c_entries)
#else
# define CORE_NEW(c) 0
#endif
/* Return the c_stackorg field from struct core_dumpx C. */
#ifdef AIX_CORE_DUMPX_CORE
# define CNEW_STACKORG(c) (c).c_stackorg
#else
# define CNEW_STACKORG(c) 0
#endif
/* Return the offset to the loader region from struct core_dump C. */
#ifdef AIX_CORE_DUMPX_CORE
# define CNEW_LOADER(c) (c).c_loader
#else
# define CNEW_LOADER(c) 0
#endif
/* Return the offset to the loader region from struct core_dump C. */
#define COLD_LOADER(c) (c).c_tab
/* Return the c_lsize field from struct core_dumpx C. */
#ifdef AIX_CORE_DUMPX_CORE
# define CNEW_LSIZE(c) (c).c_lsize
#else
# define CNEW_LSIZE(c) 0
#endif
/* Return the c_dataorg field from struct core_dumpx C. */
#ifdef AIX_CORE_DUMPX_CORE
# define CNEW_DATAORG(c) (c).c_dataorg
#else
# define CNEW_DATAORG(c) 0
#endif
/* Return the c_datasize field from struct core_dumpx C. */
#ifdef AIX_CORE_DUMPX_CORE
# define CNEW_DATASIZE(c) (c).c_datasize
#else
# define CNEW_DATASIZE(c) 0
#endif
/* Return the c_impl field from struct core_dumpx C. */
#ifdef AIX_CORE_DUMPX_CORE
# define CNEW_IMPL(c) (c).c_impl
#else
# define CNEW_IMPL(c) 0
#endif
/* Return the command string from struct core_dumpx C. */
#ifdef AIX_CORE_DUMPX_CORE
# define CNEW_COMM(c) (c).c_u.U_proc.pi_comm
#else
# define CNEW_COMM(c) 0
#endif
/* Return the command string from struct core_dump C. */
#ifdef CORE_VERSION_1
#define CORE_DATA_SIZE_FIELD c_u.U_dsize
#define CORE_COMM_FIELD c_u.U_comm
#define SAVE_FIELD c_mst
#define STACK_END_ADDR 0x2ff23000
#define LOADER_OFFSET_FIELD c_tab
#define LOADER_REGION_SIZE 0x7ffffff
#define CORE_DUMP core_dump
# define COLD_COMM(c) (c).c_u.U_comm
#else
#define CORE_DATA_SIZE_FIELD c_u.u_dsize
#define CORE_COMM_FIELD c_u.u_comm
#define SAVE_FIELD c_u.u_save
#define STACK_END_ADDR 0x2ff80000
#define LOADER_OFFSET_FIELD c_tab
#define LOADER_REGION_SIZE 0x7ffffff
#define CORE_DUMP core_dump
#endif
# define COLD_COMM(c) (c).c_u.u_comm
#endif
/* These are stored in the bfd's tdata */
typedef struct {
struct CORE_DUMP hdr; /* core file header */
} Rs6kCorData;
/* Return the struct __context64 pointer from struct core_dumpx C. */
static asection *make_bfd_asection PARAMS ((bfd *, CONST char *, flagword,
bfd_size_type, bfd_vma, file_ptr));
#ifdef AIX_CORE_DUMPX_CORE
# define CNEW_CONTEXT64(c) (c).c_flt.hctx.r64
#else
# define CNEW_CONTEXT64(c) c
#endif
/* Return the struct mstsave pointer from struct core_dumpx C. */
#ifdef AIX_CORE_DUMPX_CORE
# define CNEW_MSTSAVE(c) (c).c_flt.hctx.r32
#else
# define CNEW_MSTSAVE(c) c
#endif
/* Return the struct mstsave pointer from struct core_dump C. */
#ifdef CORE_VERSION_1
# define COLD_MSTSAVE(c) (c).c_mst
#else
# define COLD_MSTSAVE(c) (c).c_u.u_save
#endif
/* Return whether struct core_dumpx is from a 64-bit process. */
#ifdef AIX_CORE_DUMPX_CORE
# define CNEW_PROC64(c) IS_PROC64(&(c).c_u.U_proc)
#else
# define CNEW_PROC64(c) 0
#endif
/* Magic end-of-stack addresses for old core dumps. This is _very_ fragile,
but I don't see any easy way to get that info right now. */
#ifdef CORE_VERSION_1
# define COLD_STACKEND 0x2ff23000
#else
# define COLD_STACKEND 0x2ff80000
#endif
/* Size of the leading portion that old and new core dump structures have in
common. */
#define CORE_COMMONSZ ((int)&((struct core_dump *)0)->c_entries + \
sizeof (((struct core_dump *)0)->c_entries))
/* Try to read into CORE the header from the core file associated with ABFD.
Return success. */
static boolean
read_hdr (bfd *abfd, CoreHdr *core)
{
bfd_size_type size;
if (bfd_seek (abfd, 0, SEEK_SET) != 0)
return false;
/* Read the leading portion that old and new core dump structures have in
common. */
if (bfd_read (core, CORE_COMMONSZ, 1, abfd) != CORE_COMMONSZ)
return false;
/* Read the trailing portion of the structure. */
size = CORE_NEW (*core) ? sizeof (core->new) : sizeof (core->old)
- CORE_COMMONSZ;
return bfd_read ((char *)core + CORE_COMMONSZ, size, 1, abfd) == size;
}
static asection *
make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
@ -158,22 +302,65 @@ const bfd_target *
rs6000coff_core_p (abfd)
bfd *abfd;
{
struct CORE_DUMP coredata;
CoreHdr core;
struct stat statbuf;
bfd_size_type nread;
bfd_size_type size;
char *tmpptr;
if (bfd_seek (abfd, 0, SEEK_SET) != 0)
return NULL;
/* Values from new and old core structures. */
int c_flag;
file_ptr c_stack, c_regoff, c_loader;
bfd_size_type c_size, c_regsize, c_lsize;
bfd_vma c_stackend;
void *c_regptr;
int proc64;
nread = bfd_read (&coredata, 1, sizeof (struct CORE_DUMP), abfd);
if (nread != sizeof (struct CORE_DUMP))
if (!read_hdr (abfd, &core))
{
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
/* Copy fields from new or old core structure. */
if (CORE_NEW (core))
{
c_flag = core.new.c_flag;
c_stack = (file_ptr) core.new.c_stack;
c_size = core.new.c_size;
c_stackend = CNEW_STACKORG (core.new) + c_size;
c_lsize = CNEW_LSIZE (core.new);
c_loader = CNEW_LOADER (core.new);
proc64 = CNEW_PROC64 (core.new);
}
else
{
c_flag = core.old.c_flag;
c_stack = (file_ptr) core.old.c_stack;
c_size = core.old.c_size;
c_stackend = COLD_STACKEND;
c_lsize = 0x7ffffff;
c_loader = (file_ptr) COLD_LOADER (core.old);
proc64 = 0;
}
if (proc64)
{
c_regsize = sizeof (CNEW_CONTEXT64 (core.new));
c_regptr = &CNEW_CONTEXT64 (core.new);
}
else if (CORE_NEW (core))
{
c_regsize = sizeof (CNEW_MSTSAVE (core.new));
c_regptr = &CNEW_MSTSAVE (core.new);
}
else
{
c_regsize = sizeof (COLD_MSTSAVE (core.old));
c_regptr = &COLD_MSTSAVE (core.old);
}
c_regoff = (char *)c_regptr - (char *)&core;
if (bfd_stat (abfd, &statbuf) < 0)
{
bfd_set_error (bfd_error_system_call);
@ -190,92 +377,92 @@ rs6000coff_core_p (abfd)
For the data segment, we have no choice but to keep going if it's
not there, since the default behavior is not to dump it (regardless
of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
if it's not there, we refuse to have anything to do with this core
file. The usefulness of a core dump without a stack segment is pretty
limited anyway. */
if (!(coredata.c_flag & UBLOCK_VALID)
|| !(coredata.c_flag & LE_VALID))
if (!(c_flag & UBLOCK_VALID)
|| !(c_flag & LE_VALID))
{
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
if (!(coredata.c_flag & USTACK_VALID))
if (!(c_flag & USTACK_VALID))
{
bfd_set_error (bfd_error_file_truncated);
return NULL;
}
/* Don't check the core file size for a full core, AIX 4.1 includes
additional shared library sections in a full core. */
if (!(coredata.c_flag & (FULL_CORE | CORE_TRUNC))
&& ((bfd_vma)coredata.c_stack + coredata.c_size) != statbuf.st_size)
additional shared library sections in a full core. */
if (!(c_flag & (FULL_CORE | CORE_TRUNC)))
{
/* If the size is wrong, it means we're misinterpreting something. */
bfd_set_error (bfd_error_wrong_format);
return NULL;
/* If the size is wrong, it means we're misinterpreting something. */
if (c_stack + (file_ptr) c_size != statbuf.st_size)
{
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
}
#ifdef AIX_CORE_DUMPX_CORE
/* For the core_dumpx format, make sure c_entries == 0 If it does
not, the core file uses the old format */
if (coredata.c_entries != 0)
{
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
#else
/* Sanity check on the c_tab field. */
if ((u_long) coredata.c_tab < sizeof coredata ||
(u_long) coredata.c_tab >= statbuf.st_size ||
(long) coredata.c_tab >= (long)coredata.c_stack)
if (!CORE_NEW (core) && (c_loader < (file_ptr) sizeof core.old ||
c_loader >= statbuf.st_size ||
c_loader >= c_stack))
{
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
#endif
/* Issue warning if the core file was truncated during writing. */
if (coredata.c_flag & CORE_TRUNC)
if (c_flag & CORE_TRUNC)
(*_bfd_error_handler) (_("%s: warning core file truncated"),
bfd_get_filename (abfd));
/* Allocate core file header. */
tmpptr = (char*) bfd_zalloc (abfd, sizeof (Rs6kCorData));
/* Allocate core file header. */
size = CORE_NEW (core) ? sizeof (core.new) : sizeof (core.old);
tmpptr = (char*) bfd_zalloc (abfd, size);
if (!tmpptr)
return NULL;
set_tdata (abfd, tmpptr);
/* Copy core file header. */
core_hdr (abfd) = coredata;
memcpy (tmpptr, &core, size);
set_tdata (abfd, tmpptr);
/* Set architecture. */
if (CORE_NEW (core))
{
enum bfd_architecture arch;
unsigned long mach;
switch (CNEW_IMPL (core.new))
{
case POWER_RS1:
case POWER_RSC:
case POWER_RS2:
arch = bfd_arch_rs6000;
mach = bfd_mach_rs6k;
break;
default:
arch = bfd_arch_powerpc;
mach = bfd_mach_ppc;
break;
}
bfd_default_set_arch_mach (abfd, arch, mach);
}
/* .stack section. */
if (!make_bfd_asection (abfd, ".stack",
SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
(bfd_size_type) coredata.c_size,
(bfd_vma) (STACK_END_ADDR - coredata.c_size),
(file_ptr) coredata.c_stack))
SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
c_size, c_stackend - c_size, c_stack))
return NULL;
/* .reg section for GPRs and special registers. */
/* .reg section for all registers. */
if (!make_bfd_asection (abfd, ".reg",
SEC_HAS_CONTENTS,
(bfd_size_type) ((32 + NUM_OF_SPEC_REGS) * 4),
(bfd_vma) 0,
(file_ptr) ((char *) &coredata.SAVE_FIELD
- (char *) &coredata)))
return NULL;
/* .reg2 section for FPRs (floating point registers). */
if (!make_bfd_asection (abfd, ".reg2",
SEC_HAS_CONTENTS,
(bfd_size_type) 8 * 32, /* 32 FPRs. */
(bfd_vma) 0,
(file_ptr) ((char *) &coredata.SAVE_FIELD.fpr[0]
- (char *) &coredata)))
SEC_HAS_CONTENTS,
c_regsize, (bfd_vma) 0, c_regoff))
return NULL;
/* .ldinfo section.
@ -283,10 +470,8 @@ rs6000coff_core_p (abfd)
core dump would require going down the whole list of struct ld_info's.
See if we can just fake it. */
if (!make_bfd_asection (abfd, ".ldinfo",
SEC_HAS_CONTENTS,
(bfd_size_type) LOADER_REGION_SIZE,
(bfd_vma) 0,
(file_ptr) coredata.LOADER_OFFSET_FIELD))
SEC_HAS_CONTENTS,
c_lsize, (bfd_vma) 0, c_loader))
return NULL;
#ifndef CORE_VERSION_1
@ -294,16 +479,16 @@ rs6000coff_core_p (abfd)
AIX 3 dumps the complete data section and sets FULL_CORE if the
ulimit is large enough, otherwise the data section is omitted.
AIX 4 sets FULL_CORE even if the core file is truncated, we have
to examine coredata.c_datasize below to find out the actual size of
the .data section. */
if (coredata.c_flag & FULL_CORE)
to examine core.c_datasize below to find out the actual size of
the .data section. */
if (c_flag & FULL_CORE)
{
if (!make_bfd_asection (abfd, ".data",
SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
(bfd_size_type) coredata.CORE_DATA_SIZE_FIELD,
(bfd_size_type) core.old.c_u.u_dsize,
(bfd_vma)
CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD),
(file_ptr) coredata.c_stack + coredata.c_size))
CDATA_ADDR (core.old.c_u.u_dsize),
c_stack + c_size))
return NULL;
}
#endif
@ -313,68 +498,119 @@ rs6000coff_core_p (abfd)
which can be found by examining ldinfo, and anonymously mmapped
regions. */
{
struct ld_info ldinfo;
bfd_size_type ldinfo_size;
file_ptr ldinfo_offset = (file_ptr) coredata.LOADER_OFFSET_FIELD;
LdInfo ldinfo;
bfd_size_type ldi_datasize;
file_ptr ldi_core;
uint ldi_next;
bfd_vma ldi_dataorg;
/* Fields from new and old core structures. */
bfd_size_type c_datasize, c_vmregions;
file_ptr c_data, c_vmm;
if (CORE_NEW (core))
{
c_datasize = CNEW_DATASIZE (core.new);
c_data = (file_ptr) core.new.c_data;
c_vmregions = core.new.c_vmregions;
c_vmm = (file_ptr) core.new.c_vmm;
}
else
{
c_datasize = core.old.c_datasize;
c_data = (file_ptr) core.old.c_data;
c_vmregions = core.old.c_vmregions;
c_vmm = (file_ptr) core.old.c_vmm;
}
/* .data section from executable. */
if (coredata.c_datasize)
if (c_datasize)
{
if (!make_bfd_asection (abfd, ".data",
SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
(bfd_size_type) coredata.c_datasize,
(bfd_vma)
CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD),
(file_ptr) coredata.c_data))
c_datasize,
(bfd_vma) CDATA_ADDR (c_datasize),
c_data))
return NULL;
}
/* .data sections from loaded objects. */
ldinfo_size = (char *) &ldinfo.ldinfo_filename[0]
- (char *) &ldinfo.ldinfo_next;
if (proc64)
size = (int)((LdInfo *)0)->l64.ldinfo_filename;
else
size = (int)((LdInfo *)0)->l32.ldinfo_filename;
while (1)
{
if (bfd_seek (abfd, ldinfo_offset, SEEK_SET) != 0)
if (bfd_seek (abfd, c_loader, SEEK_SET) != 0)
return NULL;
if (bfd_read (&ldinfo, ldinfo_size, 1, abfd) != ldinfo_size)
if (bfd_read (&ldinfo, size, 1, abfd) != size)
return NULL;
if (ldinfo.ldinfo_core)
if (proc64)
{
if (!make_bfd_asection (abfd, ".data",
SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
(bfd_size_type) ldinfo.ldinfo_datasize,
(bfd_vma) ldinfo.ldinfo_dataorg,
(file_ptr) ldinfo.ldinfo_core))
return NULL;
ldi_core = ldinfo.l64.ldinfo_core;
ldi_datasize = ldinfo.l64.ldinfo_datasize;
ldi_dataorg = (bfd_vma) ldinfo.l64.ldinfo_dataorg;
ldi_next = ldinfo.l64.ldinfo_next;
}
if (ldinfo.ldinfo_next == 0)
else
{
ldi_core = ldinfo.l32.ldinfo_core;
ldi_datasize = ldinfo.l32.ldinfo_datasize;
ldi_dataorg = (bfd_vma)(long) ldinfo.l32.ldinfo_dataorg;
ldi_next = ldinfo.l32.ldinfo_next;
}
if (ldi_core)
if (!make_bfd_asection (abfd, ".data",
SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
ldi_datasize, ldi_dataorg, ldi_core))
return NULL;
if (ldi_next == 0)
break;
ldinfo_offset += ldinfo.ldinfo_next;
c_loader += ldi_next;
}
/* .vmdata sections from anonymously mmapped regions. */
if (coredata.c_vmregions)
if (c_vmregions)
{
int i;
bfd_size_type i;
if (bfd_seek (abfd, (file_ptr) coredata.c_vmm, SEEK_SET) != 0)
if (bfd_seek (abfd, c_vmm, SEEK_SET) != 0)
return NULL;
for (i = 0; i < coredata.c_vmregions; i++)
for (i = 0; i < c_vmregions; i++)
{
struct vm_info vminfo;
VmInfo vminfo;
bfd_size_type vminfo_size;
file_ptr vminfo_offset;
bfd_vma vminfo_addr;
if (bfd_read (&vminfo, sizeof (vminfo), 1, abfd) != sizeof (vminfo))
size = CORE_NEW (core) ? sizeof (vminfo.new) : sizeof (vminfo.old);
if (bfd_read (&vminfo, size, 1, abfd) != size)
return NULL;
if (vminfo.vminfo_offset)
if (CORE_NEW (core))
{
if (!make_bfd_asection (abfd, ".vmdata",
SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
(bfd_size_type) vminfo.vminfo_size,
(bfd_vma) vminfo.vminfo_addr,
(file_ptr) vminfo.vminfo_offset))
return NULL;
vminfo_addr = (bfd_vma) vminfo.new.vminfo_addr;
vminfo_size = vminfo.new.vminfo_size;
vminfo_offset = vminfo.new.vminfo_offset;
}
else
{
vminfo_addr = (bfd_vma)(long) vminfo.old.vminfo_addr;
vminfo_size = vminfo.old.vminfo_size;
vminfo_offset = vminfo.old.vminfo_offset;
}
if (vminfo_offset)
if (!make_bfd_asection (abfd, ".vmdata",
SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
vminfo_size, vminfo_addr,
vminfo_offset))
return NULL;
}
}
}
@ -391,23 +627,28 @@ rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
bfd *core_bfd;
bfd *exec_bfd;
{
struct CORE_DUMP coredata;
struct ld_info ldinfo;
CoreHdr core;
bfd_size_type size;
char *path, *s;
size_t alloc;
const char *str1, *str2;
boolean ret;
file_ptr c_loader;
if (bfd_seek (core_bfd, 0, SEEK_SET) != 0
|| bfd_read (&coredata, sizeof coredata, 1, core_bfd) != sizeof coredata)
if (!read_hdr (core_bfd, &core))
return false;
if (bfd_seek (core_bfd, (long) coredata.LOADER_OFFSET_FIELD, SEEK_SET) != 0)
return false;
if (CORE_NEW (core))
c_loader = CNEW_LOADER (core.new);
else
c_loader = (file_ptr) COLD_LOADER (core.old);
size = (char *) &ldinfo.ldinfo_filename[0] - (char *) &ldinfo.ldinfo_next;
if (bfd_read (&ldinfo, size, 1, core_bfd) != size)
if (CORE_NEW (core) && CNEW_PROC64 (core.new))
size = (int)((LdInfo *)0)->l64.ldinfo_filename;
else
size = (int)((LdInfo *)0)->l32.ldinfo_filename;
if (bfd_seek (core_bfd, c_loader + size, SEEK_SET) != 0)
return false;
alloc = 100;
@ -441,7 +682,7 @@ rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
path = n;
}
}
str1 = strrchr (path, '/');
str2 = strrchr (exec_bfd->filename, '/');
@ -463,7 +704,10 @@ char *
rs6000coff_core_file_failing_command (abfd)
bfd *abfd;
{
char *com = core_hdr (abfd).CORE_COMM_FIELD;
CoreHdr *core = core_hdr (abfd);
char *com = CORE_NEW (*core) ?
CNEW_COMM (core->new) : COLD_COMM (core->old);
if (*com)
return com;
else
@ -474,65 +718,8 @@ int
rs6000coff_core_file_failing_signal (abfd)
bfd *abfd;
{
return core_hdr (abfd).c_signo;
}
boolean
rs6000coff_get_section_contents (abfd, section, location, offset, count)
bfd *abfd;
sec_ptr section;
PTR location;
file_ptr offset;
bfd_size_type count;
{
if (count == 0)
return true;
/* Reading a core file's sections will be slightly different. For the
rest of them we can use bfd_generic_get_section_contents () I suppose. */
/* Make sure this routine works for any bfd and any section. FIXMEmgo. */
if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) {
struct mstsave mstatus;
int regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus;
/* Assert that the only way this code will be executed is reading the
whole section. */
if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS)))
(*_bfd_error_handler)
(_("ERROR! in rs6000coff_get_section_contents()\n"));
/* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
in the core file. */
/* read GPR's into the location. */
if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
|| bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr))
return (false); /* on error */
/* increment location to the beginning of special registers in the section,
reset register offset value to the beginning of first special register
in mstsave structure, and read special registers. */
location = (PTR) ((char*)location + sizeof (mstatus.gpr));
regoffset = (char*)&mstatus.iar - (char*)&mstatus;
if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
|| bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) !=
4 * NUM_OF_SPEC_REGS)
return (false); /* on error */
/* increment location address, and read the special registers.. */
/* FIXMEmgo */
return (true);
}
/* else, use default bfd section content transfer. */
else
return _bfd_generic_get_section_contents
(abfd, section, location, offset, count);
CoreHdr *core = core_hdr (abfd);
return CORE_NEW (*core) ? core->new.c_signo : core->old.c_signo;
}
#endif /* AIX_CORE */

View File

@ -57,7 +57,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#undef CORE_FILE_P
#define CORE_FILE_P rs6000coff_core_p
extern const bfd_target * rs6000coff_core_p ();
extern boolean rs6000coff_get_section_contents ();
extern boolean rs6000coff_core_file_matches_executable_p ();
#undef coff_core_file_matches_executable_p
@ -71,9 +70,6 @@ extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd));
extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd));
#undef coff_core_file_failing_signal
#define coff_core_file_failing_signal rs6000coff_core_file_failing_signal
#undef coff_get_section_contents
#define coff_get_section_contents rs6000coff_get_section_contents
#endif /* AIX_CORE */
#ifdef LYNX_CORE