static int do_sections64 (bfd *abfd, struct coreout *coreout) { struct vmap64 vmap; char *secname; int i, val; for (i = 0; i < coreout->c_nvmap; i++) { val = bfd_bread ((PTR) &vmap, (bfd_size_type) sizeof vmap, abfd); if (val != sizeof vmap) break; switch (vmap.v_type) { case VDATA: secname = ".data"; break; case VSTACK: secname = ".stack"; break; #ifdef VMAPFILE case VMAPFILE: secname = ".mapfile"; break; #endif default: continue; } /* A file offset of zero means that the section is not contained in the corefile. */ if (vmap.v_offset == 0) continue; if (!make_bfd_asection (abfd, secname, SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS, vmap.v_len, vmap.v_vaddr, vmap.v_offset)) /* Fail. */ return 0; } return 1; }
static const bfd_target * irix_core_core_file_p (bfd *abfd) { int val; struct coreout coreout; struct idesc *idg, *idf, *ids; bfd_size_type amt; val = bfd_bread ((PTR) &coreout, (bfd_size_type) sizeof coreout, abfd); if (val != sizeof coreout) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_wrong_format); return 0; } if (coreout.c_version != CORE_VERSION1) return 0; /* Have we got a corefile? */ switch (coreout.c_magic) { case CORE_MAGIC: break; #ifdef CORE_MAGIC64 case CORE_MAGIC64: break; #endif #ifdef CORE_MAGICN32 case CORE_MAGICN32: break; #endif default: return 0; /* Un-identifiable or not corefile. */ } amt = sizeof (struct sgi_core_struct); core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, amt); if (!core_hdr (abfd)) return NULL; strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE); core_signal (abfd) = coreout.c_sigcause; if (bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET) != 0) goto fail; /* Process corefile sections. */ #ifdef CORE_MAGIC64 if (coreout.c_magic == (int) CORE_MAGIC64) { if (! do_sections64 (abfd, & coreout)) goto fail; } else #endif if (! do_sections (abfd, & coreout)) goto fail; /* Make sure that the regs are contiguous within the core file. */ idg = &coreout.c_idesc[I_GPREGS]; idf = &coreout.c_idesc[I_FPREGS]; ids = &coreout.c_idesc[I_SPECREGS]; if (idg->i_offset + idg->i_len != idf->i_offset || idf->i_offset + idf->i_len != ids->i_offset) goto fail; /* Can't deal with non-contig regs */ if (bfd_seek (abfd, idg->i_offset, SEEK_SET) != 0) goto fail; if (!make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS, idg->i_len + idf->i_len + ids->i_len, 0, idg->i_offset)) goto fail; /* OK, we believe you. You're a core file (sure, sure). */ bfd_default_set_arch_mach (abfd, bfd_arch_mips, 0); return abfd->xvec; fail: bfd_release (abfd, core_hdr (abfd)); core_hdr (abfd) = NULL; bfd_section_list_clear (abfd); return NULL; }
const bfd_target * sco5_core_file_p (bfd *abfd) { int coffset_siz, val, nsecs, cheadoffs; int coresize; struct user *u; struct coreoffsets coffsets; struct coresecthead chead; char *secname; flagword flags; /* Read coreoffsets region at end of core (see core(FP)). */ { struct stat statbuf; if (bfd_stat (abfd, &statbuf) < 0) return NULL; coresize = statbuf.st_size; } /* Last long in core is sizeof struct coreoffsets, read it */ if ((bfd_seek (abfd, (file_ptr) (coresize - sizeof coffset_siz), SEEK_SET) != 0) || bfd_bread ((void *) &coffset_siz, (bfd_size_type) sizeof coffset_siz, abfd) != sizeof coffset_siz) { bfd_set_error (bfd_error_wrong_format); return NULL; } /* Use it to seek start of coreoffsets region, read it and determine validity */ if ((bfd_seek (abfd, (file_ptr) (coresize - coffset_siz), SEEK_SET) != 0) || (bfd_bread ((void *) &coffsets, (bfd_size_type) sizeof coffsets, abfd) != sizeof coffsets) || ((coffsets.u_info != 1) && (coffsets.u_info != C_VERSION))) { bfd_set_error (bfd_error_wrong_format); return NULL; } if (coffsets.u_info == 1) { /* Old version, no section heads, read info from user struct */ u = read_uarea (abfd, coffsets.u_user); if (! u) goto fail; if (!make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS, (bfd_size_type) coffsets.u_usize, 0 - (bfd_vma) u->u_ar0, (file_ptr) coffsets.u_user)) goto fail; if (!make_bfd_asection (abfd, ".data", SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, ((bfd_size_type) u->u_exdata.ux_dsize + u->u_exdata.ux_bsize), (bfd_vma) u->u_exdata.ux_datorg, (file_ptr) coffsets.u_data)) goto fail; if (!make_bfd_asection (abfd, ".stack", SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, (bfd_size_type) u->u_ssize * NBPC, (bfd_vma) u->u_sub, (file_ptr) coffsets.u_stack)) goto fail; return abfd->xvec; /* Done for version 1 */ } /* Immediately before coreoffsets region is a long with offset in core to first coresecthead (CORES_OFFSETS), the long before this is the number of section heads in the list. Read both longs and read the coresecthead and check its validity */ if ((bfd_seek (abfd, (file_ptr) (coresize - coffset_siz - 2 * sizeof coffset_siz), SEEK_SET) != 0) || (bfd_bread ((void *) &nsecs, (bfd_size_type) sizeof nsecs, abfd) != sizeof nsecs) || (bfd_bread ((void *) &cheadoffs, (bfd_size_type) sizeof cheadoffs, abfd) != sizeof cheadoffs) || (bfd_seek (abfd, (file_ptr) cheadoffs, SEEK_SET) != 0) || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd) != sizeof chead) || (chead.cs_stype != CORES_OFFSETS) || (chead.cs_x.csx_magic != COREMAGIC_NUMBER)) { bfd_set_error (bfd_error_wrong_format); goto fail; } /* OK, we believe you. You're a core file (sure, sure). */ /* Now loop over all regions and map them */ nsecs--; /* We've seen CORES_OFFSETS already */ for (; nsecs; nsecs--) { if ((bfd_seek (abfd, (file_ptr) chead.cs_hseek, SEEK_SET) != 0) || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd) != sizeof chead)) { bfd_set_error (bfd_error_wrong_format); goto fail; } switch (chead.cs_stype) { case CORES_MAGIC: /* Core header, check magic */ if (chead.cs_x.csx_magic != COREMAGIC_NUMBER) { bfd_set_error (bfd_error_wrong_format); goto fail; } secname = NULL; nsecs++; /* MAGIC not in section cnt!*/ break; case CORES_UAREA: /* U-area, read in tdata */ u = read_uarea (abfd, chead.cs_sseek); if (! u) goto fail; /* This is tricky. As the "register section", we give them the entire upage and stack. u.u_ar0 points to where "register 0" is stored. There are two tricks with this, though. One is that the rest of the registers might be at positive or negative (or both) displacements from *u_ar0. The other is that u_ar0 is sometimes an absolute address in kernel memory, and on other systems it is an offset from the beginning of the `struct user'. As a practical matter, we don't know where the registers actually are, so we have to pass the whole area to GDB. We encode the value of u_ar0 by setting the .regs section up so that its virtual memory address 0 is at the place pointed to by u_ar0 (by setting the vma of the start of the section to -u_ar0). GDB uses this info to locate the regs, using minor trickery to get around the offset-or-absolute-addr problem. */ chead.cs_vaddr = 0 - (bfd_vma) u->u_ar0; secname = ".reg"; flags = SEC_HAS_CONTENTS; break; case CORES_PREGION: /* A program region, map it */ switch (chead.cs_x.csx_preg.csxp_rtyp) { case PT_DATA: secname = ".data"; /* Data region. */ break; case PT_STACK: secname = ".stack"; /* Stack region. */ break; case PT_SHMEM: secname = ".shmem"; /* Shared memory */ break; case PT_LIBDAT: secname = ".libdat"; /* Shared library data */ break; case PT_V86: secname = ".virt86"; /* Virtual 8086 mode */ break; case PT_SHFIL: secname = ".mmfile"; /* Memory mapped file */ break; case PT_XDATA0: secname = ".Xdat0"; /* XENIX data region, virtual 0 */ break; default: secname = ""; } flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; break; case CORES_PROC: /* struct proc */ case CORES_ITIMER: /* interval timers */ case CORES_SCOUTSNAME: /* struct scoutsname */ secname = NULL; /* Ignore these */ break; default: (*_bfd_error_handler) ("Unhandled SCO core file section type %d\n", chead.cs_stype); continue; } if (secname && !make_bfd_asection (abfd, secname, flags, (bfd_size_type) chead.cs_vsize, (bfd_vma) chead.cs_vaddr, (file_ptr) chead.cs_sseek)) goto fail; } return abfd->xvec; fail: if (abfd->tdata.any) { bfd_release (abfd, abfd->tdata.any); abfd->tdata.any = NULL; } bfd_section_list_clear (abfd); return NULL; }
const bfd_target * lynx_core_file_p (bfd *abfd) { int secnum; struct pssentry pss; bfd_size_type tcontext_size; core_st_t *threadp; int pagesize; asection *newsect; bfd_size_type amt; pagesize = getpagesize (); /* Serious cross-target issue here... This really needs to come from a system-specific header file. */ /* Get the pss entry from the core file */ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return NULL; amt = sizeof pss; if (bfd_bread ((void *) &pss, amt, abfd) != amt) { /* Too small to be a core file */ if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_wrong_format); return NULL; } amt = sizeof (struct lynx_core_struct); core_hdr (abfd) = (struct lynx_core_struct *) bfd_zalloc (abfd, amt); if (!core_hdr (abfd)) return NULL; strncpy (core_command (abfd), pss.pname, PNMLEN + 1); /* Compute the size of the thread contexts */ tcontext_size = pss.threadcnt * sizeof (core_st_t); /* Allocate space for the thread contexts */ threadp = (core_st_t *) bfd_alloc (abfd, tcontext_size); if (!threadp) goto fail; /* Save thread contexts */ if (bfd_seek (abfd, (file_ptr) pagesize, SEEK_SET) != 0) goto fail; if (bfd_bread ((void *) threadp, tcontext_size, abfd) != tcontext_size) { /* Probably too small to be a core file */ if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_wrong_format); goto fail; } core_signal (abfd) = threadp->currsig; newsect = make_bfd_asection (abfd, ".stack", SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, pss.ssize, pss.slimit, pagesize + tcontext_size); if (!newsect) goto fail; newsect = make_bfd_asection (abfd, ".data", SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, pss.data_len + pss.bss_len, pss.data_start, pagesize + tcontext_size + pss.ssize #if defined (SPARC) || defined (__SPARC__) /* SPARC Lynx seems to start dumping the .data section at a page boundary. It's OK to check a #define like SPARC here because this file can only be compiled on a Lynx host. */ + pss.data_start % pagesize #endif ); if (!newsect) goto fail; /* And, now for the .reg/XXX pseudo sections. Each thread has it's own .reg/XXX section, where XXX is the thread id (without leading zeros). The currently running thread (at the time of the core dump) also has an alias called `.reg' (just to keep GDB happy). Note that we use `.reg/XXX' as opposed to `.regXXX' because GDB expects that .reg2 will be the floating- point registers. */ newsect = make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS, sizeof (core_st_t), 0, pagesize); if (!newsect) goto fail; for (secnum = 0; secnum < pss.threadcnt; secnum++) { char secname[100]; sprintf (secname, ".reg/%d", BUILDPID (0, threadp[secnum].tid)); newsect = make_bfd_asection (abfd, secname, SEC_HAS_CONTENTS, sizeof (core_st_t), 0, pagesize + secnum * sizeof (core_st_t)); if (!newsect) goto fail; } return abfd->xvec; fail: bfd_release (abfd, core_hdr (abfd)); core_hdr (abfd) = NULL; bfd_section_list_clear (abfd); return NULL; }
static const bfd_target * hppabsd_core_core_file_p (bfd *abfd) { int val; struct user u; struct hppabsd_core_struct *coredata; int clicksz; /* Try to read in the u-area. We will need information from this to know how to grok the rest of the core structures. */ val = bfd_bread ((void *) &u, (bfd_size_type) sizeof u, abfd); if (val != sizeof u) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_wrong_format); return NULL; } /* Get the page size out of the u structure. This will be different for PA 1.0 machines and PA 1.1 machines. Yuk! */ clicksz = u.u_pcb.pcb_pgsz; /* clicksz must be a power of two >= 2k. */ if (clicksz < 0x800 || clicksz != (clicksz & -clicksz)) { bfd_set_error (bfd_error_wrong_format); return NULL; } /* Sanity checks. Make sure the size of the core file matches the the size computed from information within the core itself. */ { struct stat statbuf; if (bfd_stat (abfd, &statbuf) < 0) return NULL; if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size) { bfd_set_error (bfd_error_file_truncated); return NULL; } if (clicksz * (UPAGES + u.u_dsize + u.u_ssize) < statbuf.st_size) { /* The file is too big. Maybe it's not a core file or we otherwise have bad values for u_dsize and u_ssize). */ bfd_set_error (bfd_error_wrong_format); return NULL; } } /* OK, we believe you. You're a core file (sure, sure). */ coredata = (struct hppabsd_core_struct *) bfd_zalloc (abfd, (bfd_size_type) sizeof (struct hppabsd_core_struct)); if (!coredata) return NULL; /* Make the core data and available via the tdata part of the BFD. */ abfd->tdata.hppabsd_core_data = coredata; /* Create the sections. */ core_stacksec (abfd) = make_bfd_asection (abfd, ".stack", SEC_ALLOC + SEC_HAS_CONTENTS, clicksz * u.u_ssize, NBPG * (USIZE + KSTAKSIZE) + clicksz * u.u_dsize, 2); if (core_stacksec (abfd) == NULL) goto fail; core_stacksec (abfd)->vma = USRSTACK; core_datasec (abfd) = make_bfd_asection (abfd, ".data", SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, clicksz * u.u_dsize, NBPG * (USIZE + KSTAKSIZE), 2); if (core_datasec (abfd) == NULL) goto fail; core_datasec (abfd)->vma = UDATASEG; core_regsec (abfd) = make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS, KSTAKSIZE * NBPG, NBPG * USIZE, 2); if (core_regsec (abfd) == NULL) goto fail; core_regsec (abfd)->vma = 0; strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1); core_signal (abfd) = u.u_code; return abfd->xvec; fail: bfd_release (abfd, abfd->tdata.any); abfd->tdata.any = NULL; bfd_section_list_clear (abfd); return NULL; }
static const bfd_target * osf_core_core_file_p (bfd *abfd) { int val; int i; char *secname; struct core_filehdr core_header; bfd_size_type amt; amt = sizeof core_header; val = bfd_bread (& core_header, amt, abfd); if (val != sizeof core_header) return NULL; if (! CONST_STRNEQ (core_header.magic, "Core")) return NULL; core_hdr (abfd) = (struct osf_core_struct *) bfd_zalloc (abfd, (bfd_size_type) sizeof (struct osf_core_struct)); if (!core_hdr (abfd)) return NULL; strncpy (core_command (abfd), core_header.name, MAXCOMLEN + 1); core_signal (abfd) = core_header.signo; for (i = 0; i < core_header.nscns; i++) { struct core_scnhdr core_scnhdr; flagword flags; amt = sizeof core_scnhdr; val = bfd_bread (& core_scnhdr, amt, abfd); if (val != sizeof core_scnhdr) break; /* Skip empty sections. */ if (core_scnhdr.size == 0 || core_scnhdr.scnptr == 0) continue; switch (core_scnhdr.scntype) { case SCNRGN: secname = ".data"; flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; break; case SCNSTACK: secname = ".stack"; flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; break; case SCNREGS: secname = ".reg"; flags = SEC_HAS_CONTENTS; break; default: (*_bfd_error_handler) (_("Unhandled OSF/1 core file section type %d\n"), core_scnhdr.scntype); continue; } if (!make_bfd_asection (abfd, secname, flags, (bfd_size_type) core_scnhdr.size, (bfd_vma) core_scnhdr.vaddr, (file_ptr) core_scnhdr.scnptr)) goto fail; } /* OK, we believe you. You're a core file (sure, sure). */ return abfd->xvec; fail: bfd_release (abfd, core_hdr (abfd)); core_hdr (abfd) = NULL; bfd_section_list_clear (abfd); return NULL; }
const bfd_target * rs6000coff_core_p (bfd *abfd) { CoreHdr core; struct stat statbuf; bfd_size_type size; char *tmpptr; /* 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; if (!read_hdr (abfd, &core)) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_wrong_format); return NULL; } /* This isn't the right handler for 64-bit core files on AIX 5.x. */ if (CORE_NEW (core) && CNEW_IS_CORE_DUMPXX (core)) { 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_dump.c_flag; c_stack = (file_ptr) core.new_dump.c_stack; c_size = core.new_dump.c_size; c_stackend = CNEW_STACKORG (core.new_dump) + c_size; c_lsize = CNEW_LSIZE (core.new_dump); c_loader = CNEW_LOADER (core.new_dump); #ifndef BFD64 proc64 = CNEW_PROC64 (core.new_dump); } else { c_flag = core.old.c_flag; c_stack = (file_ptr) (ptr_to_uint) core.old.c_stack; c_size = core.old.c_size; c_stackend = COLD_STACKEND; c_lsize = 0x7ffffff; c_loader = (file_ptr) (ptr_to_uint) COLD_LOADER (core.old); #endif proc64 = 0; } if (proc64) { c_regsize = sizeof (CNEW_CONTEXT64 (core.new_dump)); c_regptr = &CNEW_CONTEXT64 (core.new_dump); } else if (CORE_NEW (core)) { c_regsize = sizeof (CNEW_MSTSAVE (core.new_dump)); c_regptr = &CNEW_MSTSAVE (core.new_dump); } #ifndef BFD64 else { c_regsize = sizeof (COLD_MSTSAVE (core.old)); c_regptr = &COLD_MSTSAVE (core.old); } #endif c_regoff = (char *) c_regptr - (char *) &core; if (bfd_stat (abfd, &statbuf) < 0) { bfd_set_error (bfd_error_system_call); return NULL; } /* If the core file ulimit is too small, the system will first omit the data segment, then omit the stack, then decline to dump core altogether (as far as I know UBLOCK_VALID and LE_VALID are always set) (this is based on experimentation on AIX 3.2). Now, the thing is that GDB users will be surprised if segments just silently don't appear (well, maybe they would think to check "info files", I don't know). 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, 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 (!(c_flag & UBLOCK_VALID) || !(c_flag & LE_VALID)) { bfd_set_error (bfd_error_wrong_format); return NULL; } 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 (!(c_flag & (FULL_CORE | CORE_TRUNC))) { /* 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; } } /* Sanity check on the c_tab field. */ if (!CORE_NEW (core) && ( #ifndef BFD64 c_loader < (file_ptr) sizeof core.old #else c_loader < (file_ptr) sizeof core.new_dump #endif || c_loader >= statbuf.st_size || c_loader >= c_stack)) { bfd_set_error (bfd_error_wrong_format); return NULL; } /* Issue warning if the core file was truncated during writing. */ if (c_flag & CORE_TRUNC) _bfd_error_handler (_("%s: warning core file truncated"), bfd_get_filename (abfd)); /* Allocate core file header. */ #ifndef BFD64 size = CORE_NEW (core) ? sizeof (core.new_dump) : sizeof (core.old); #else size = sizeof (core.new_dump); #endif tmpptr = (char *) bfd_zalloc (abfd, (bfd_size_type) size); if (!tmpptr) return NULL; /* Copy core file header. */ 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_dump)) { 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, c_size, c_stackend - c_size, c_stack)) goto fail; /* .reg section for all registers. */ if (!make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS, c_regsize, (bfd_vma) 0, c_regoff)) goto fail; /* .ldinfo section. To actually find out how long this section is in this particular 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, c_lsize, (bfd_vma) 0, c_loader)) goto fail; #ifndef CORE_VERSION_1 /* .data section if present. 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 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) core.old.c_u.u_dsize, (bfd_vma) CDATA_ADDR (core.old.c_u.u_dsize), c_stack + c_size)) goto fail; } #endif #ifdef CORE_VERSION_1 /* AIX 4 adds data sections from loaded objects to the core file, which can be found by examining ldinfo, and anonymously mmapped regions. */ { LdInfo ldinfo; bfd_size_type ldi_datasize; file_ptr ldi_core; uint ldi_next; bfd_vma ldi_dataorg; bfd_vma core_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_dump); c_data = (file_ptr) core.new_dump.c_data; c_vmregions = core.new_dump.c_vmregions; c_vmm = (file_ptr) core.new_dump.c_vmm; } #ifndef BFD64 else { c_datasize = core.old.c_datasize; c_data = (file_ptr) (ptr_to_uint) core.old.c_data; c_vmregions = core.old.c_vmregions; c_vmm = (file_ptr) (ptr_to_uint) core.old.c_vmm; } #endif /* .data section from executable. */ if (c_datasize) { /* If Large Memory Model is used, then the .data segment should start from BDATAORG which has been defined in the system header files. */ if (c_flag & CORE_BIGDATA) core_dataorg = BDATAORG; else core_dataorg = CDATA_ADDR (c_datasize); if (!make_bfd_asection (abfd, ".data", SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS, c_datasize, (bfd_vma) core_dataorg, c_data)) goto fail; } /* .data sections from loaded objects. */ if (proc64) size = (unsigned long) ((LdInfo *) 0)->l64.ldinfo_filename; else size = (unsigned long) ((LdInfo *) 0)->l32.ldinfo_filename; while (1) { if (bfd_seek (abfd, c_loader, SEEK_SET) != 0) goto fail; if (bfd_bread (&ldinfo, size, abfd) != size) goto fail; if (proc64) { 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; } else { ldi_core = ldinfo.l32.ldinfo_core; ldi_datasize = ldinfo.l32.ldinfo_datasize; ldi_dataorg = (bfd_vma) (ptr_to_uint) 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)) goto fail; if (ldi_next == 0) break; c_loader += ldi_next; } /* .vmdata sections from anonymously mmapped regions. */ if (c_vmregions) { bfd_size_type i; if (bfd_seek (abfd, c_vmm, SEEK_SET) != 0) goto fail; for (i = 0; i < c_vmregions; i++) { VmInfo vminfo; bfd_size_type vminfo_size; file_ptr vminfo_offset; bfd_vma vminfo_addr; #ifndef BFD64 size = CORE_NEW (core) ? sizeof (vminfo.new_dump) : sizeof (vminfo.old); #else size = sizeof (vminfo.new_dump); #endif if (bfd_bread (&vminfo, size, abfd) != size) goto fail; if (CORE_NEW (core)) { vminfo_addr = (bfd_vma) vminfo.new_dump.vminfo_addr; vminfo_size = vminfo.new_dump.vminfo_size; vminfo_offset = vminfo.new_dump.vminfo_offset; } #ifndef BFD64 else { vminfo_addr = (bfd_vma) (ptr_to_uint) vminfo.old.vminfo_addr; vminfo_size = vminfo.old.vminfo_size; vminfo_offset = vminfo.old.vminfo_offset; } #endif if (vminfo_offset) if (!make_bfd_asection (abfd, ".vmdata", SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS, vminfo_size, vminfo_addr, vminfo_offset)) goto fail; } } } #endif return abfd->xvec; /* This is garbage for now. */ fail: bfd_release (abfd, abfd->tdata.any); abfd->tdata.any = NULL; bfd_section_list_clear (abfd); return NULL; }