From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nick Duffek To: binutils@sourceware.cygnus.com Subject: [PATCH] 64-bit AIX core files (revised) Date: Thu, 08 Jun 2000 18:38:00 -0000 Message-id: <200006090142.e591gF631271@rtl.cygnus.com> X-SW-Source: 2000-06/msg00178.html The appended patch adds 64-bit support to bfd/rs6000-core.c. In addition, it adds support for pre-4.3 core dumps on AIX 4.3+, which can generate such dumps with the appropriate SMIT setting. Last month, I submitted a similar patch, which Nick Clifton approved. I postponed committing the patch until I was ready to commit corresponding GDB patches. In the meantime, I updated the patch to set the architecture in the bfd passed to rs6000coff_core_p(), so I'm resubmitting the patch for approval. Okay to apply? Nick Duffek nsd@redhat.com 2000-06-08 Nicholas Duffek * 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. Index: bfd/rs6000-core.c =================================================================== diff -u bfd/rs6000-core.c bfd/rs6000-core.c --- bfd/rs6000-core.c Mon Jun 5 12:36:34 2000 +++ bfd/rs6000-core.c Mon Jun 5 12:36:26 2000 @@ -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 @@ 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,208 @@ /* ------------------------------------------------------------------------ */ -/* Support for core file stuff.. */ +/* Support for core file stuff.. */ /* ------------------------------------------------------------------------ */ #include +#define __LDINFO_PTRACE32__ /* for __ld_info32 */ +#define __LDINFO_PTRACE64__ /* for __ld_info64 */ #include #include +#include + +#define core_hdr(bfd) ((CoreHdr *) bfd->tdata.any) + +/* 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. + + AIX_CORE_DUMPX_CORE is defined (by configure) on AIX 4.3+, and + CORE_VERSION_1 is defined (by AIX core.h) on AIX 4.1+. + + 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. */ + +/* 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_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. */ -/* 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. */ - -#define NUM_OF_SPEC_REGS 7 - -#define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr) - -/* 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. - - 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. */ - -#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 +#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 -#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 +# define COLD_COMM(c) (c).c_u.U_comm +#else +# define COLD_COMM(c) (c).c_u.u_comm #endif + +/* Return the struct __context64 pointer from struct core_dumpx C. */ + +#ifdef AIX_CORE_DUMPX_CORE +# define CNEW_CONTEXT64(c) (c).c_flt.hctx.r64 +#else +# define CNEW_CONTEXT64(c) 0 #endif -/* These are stored in the bfd's tdata */ -typedef struct { - struct CORE_DUMP hdr; /* core file header */ -} Rs6kCorData; +/* 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) 0 +#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 asection *make_bfd_asection PARAMS ((bfd *, CONST char *, flagword, - bfd_size_type, bfd_vma, file_ptr)); +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 +296,65 @@ 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 = 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 +371,92 @@ 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 +464,8 @@ 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 +473,16 @@ 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 +492,119 @@ 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 = core.new.c_data; + c_vmregions = core.new.c_vmregions; + c_vmm = 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 = ldinfo.l64.ldinfo_dataorg; + ldi_next = ldinfo.l64.ldinfo_next; + } + 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 (ldinfo.ldinfo_next == 0) + + 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)) + { + vminfo_addr = vminfo.new.vminfo_addr; + vminfo_size = vminfo.new.vminfo_size; + vminfo_offset = vminfo.new.vminfo_offset; + } + else { - 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)(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 +621,28 @@ 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); + + if (CORE_NEW (core) && CNEW_PROC64 (core.new)) + size = (int)((LdInfo *)0)->l64.ldinfo_filename; + else + size = (int)((LdInfo *)0)->l32.ldinfo_filename; - size = (char *) &ldinfo.ldinfo_filename[0] - (char *) &ldinfo.ldinfo_next; - if (bfd_read (&ldinfo, size, 1, core_bfd) != size) + if (bfd_seek (core_bfd, c_loader + size, SEEK_SET) != 0) return false; alloc = 100; @@ -441,7 +676,7 @@ path = n; } } - + str1 = strrchr (path, '/'); str2 = strrchr (exec_bfd->filename, '/'); @@ -463,7 +698,10 @@ 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 +712,8 @@ 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 */ Index: bfd/xcoff-target.h =================================================================== diff -u bfd/xcoff-target.h bfd/xcoff-target.h --- bfd/xcoff-target.h Mon Jun 5 12:36:40 2000 +++ bfd/xcoff-target.h Mon Jun 5 12:36:26 2000 @@ -57,7 +57,6 @@ #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 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