/* * Dump the machine specific header information at the start of a core dump. * First put all regs in PCB for debugging purposes. This is not an good * way to do this, but good for my purposes so far. */ int cpu_coredump(struct lwp *l, struct coredump_iostate *iocookie, struct core *chdr) { struct md_coredump md_core; struct coreseg cseg; int error; if (iocookie == NULL) { CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0); chdr->c_hdrsize = sizeof(struct core); chdr->c_seghdrsize = sizeof(struct coreseg); chdr->c_cpusize = sizeof(struct md_coredump); chdr->c_nseg++; return 0; } md_core.md_tf = *l->l_md.md_utf; /*XXX*/ CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU); cseg.c_addr = 0; cseg.c_size = chdr->c_cpusize; error = coredump_write(iocookie, UIO_SYSSPACE, &cseg, chdr->c_seghdrsize); if (error) return error; return coredump_write(iocookie, UIO_SYSSPACE, &md_core, sizeof(md_core)); }
/* * Write the machine-dependent part of a core dump. */ int cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred, struct core *chdr) { struct coreseg cseg; struct md_coredump md_core; int error; CORE_SETMAGIC(*chdr, COREMAGIC, MID_POWERPC, 0); chdr->c_hdrsize = ALIGN(sizeof *chdr); chdr->c_seghdrsize = ALIGN(sizeof cseg); chdr->c_cpusize = sizeof md_core; process_read_regs(p, &(md_core.regs)); CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_POWERPC, CORE_CPU); cseg.c_addr = 0; cseg.c_size = chdr->c_cpusize; error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize, (off_t)chdr->c_hdrsize, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p); if (error) return error; error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof md_core, (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p); if (error) return error; chdr->c_nseg++; return 0; }
/* * 32-bit version of cpu_coredump. */ int cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie, struct core32 *chdr) { int i, error; struct md_coredump32 md_core; struct coreseg32 cseg; if (iocookie == NULL) { CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0); chdr->c_hdrsize = ALIGN(sizeof(*chdr)); chdr->c_seghdrsize = ALIGN(sizeof(cseg)); chdr->c_cpusize = sizeof(md_core); chdr->c_nseg++; return 0; } /* Fake a v8 trapframe */ md_core.md_tf.tf_psr = TSTATECCR_TO_PSR(l->l_md.md_tf->tf_tstate); md_core.md_tf.tf_pc = l->l_md.md_tf->tf_pc; md_core.md_tf.tf_npc = l->l_md.md_tf->tf_npc; md_core.md_tf.tf_y = l->l_md.md_tf->tf_y; for (i=0; i<8; i++) { md_core.md_tf.tf_global[i] = l->l_md.md_tf->tf_global[i]; md_core.md_tf.tf_out[i] = l->l_md.md_tf->tf_out[i]; } if (l->l_md.md_fpstate) { fpusave_lwp(l, true); /* Copy individual fields */ for (i=0; i<32; i++) md_core.md_fpstate.fs_regs[i] = l->l_md.md_fpstate->fs_regs[i]; md_core.md_fpstate.fs_fsr = l->l_md.md_fpstate->fs_fsr; i = md_core.md_fpstate.fs_qsize = l->l_md.md_fpstate->fs_qsize; /* Should always be zero */ while (i--) md_core.md_fpstate.fs_queue[i] = l->l_md.md_fpstate->fs_queue[i]; } else memset(&md_core.md_fpstate, 0, sizeof(md_core.md_fpstate)); CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU); cseg.c_addr = 0; cseg.c_size = chdr->c_cpusize; error = coredump_write(iocookie, UIO_SYSSPACE, &cseg, chdr->c_seghdrsize); if (error) return error; return coredump_write(iocookie, UIO_SYSSPACE, &md_core, sizeof(md_core)); }
/* * cpu_dump: dump the machine-dependent kernel core dump headers. */ static int cpu_dump(void) { int (*dump)(dev_t, daddr_t, void *, size_t); kcore_seg_t seg; cpu_kcore_hdr_t cpuhdr; const struct bdevsw *bdev; bdev = bdevsw_lookup(dumpdev); if (bdev == NULL) return (ENXIO); dump = bdev->d_dump; /* * Generate a segment header. */ CORE_SETMAGIC(seg, KCORE_MAGIC, MID_MACHINE, CORE_CPU); seg.c_size = dump_header_size - ALIGN(sizeof(seg)); (void)dump_header_addbytes(&seg, ALIGN(sizeof(seg))); /* * Add the machine-dependent header info. */ cpuhdr.pdppaddr = PDPpaddr; cpuhdr.nmemsegs = dump_nmemsegs; (void)dump_header_addbytes(&cpuhdr, ALIGN(sizeof(cpuhdr))); /* * Write out the memory segment descriptors. */ return dump_seg_iter(dump_header_addseg); }
/* * Dump the machine-dependent dump header. */ u_int cpu_dump(int (*dump)(dev_t, daddr_t, caddr_t, size_t), daddr_t *blknop) { extern cpu_kcore_hdr_t cpu_kcore_hdr; char buf[dbtob(1)]; cpu_kcore_hdr_t *h; kcore_seg_t *kseg; int rc; #ifdef DIAGNOSTIC if (cpu_dumpsize() > btodb(sizeof buf)) { printf("buffer too small in cpu_dump, "); return (EINVAL); /* "aborted" */ } #endif bzero(buf, sizeof buf); kseg = (kcore_seg_t *)buf; h = (cpu_kcore_hdr_t *)(buf + ALIGN(sizeof(kcore_seg_t))); /* Create the segment header */ CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU); kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t)); bcopy(&cpu_kcore_hdr, h, sizeof(*h)); /* We can now fill kptp in the header... */ h->kcore_kptp = SH3_P1SEG_TO_PHYS((vaddr_t)pmap_kernel()->pm_ptp); rc = (*dump)(dumpdev, *blknop, buf, sizeof buf); *blknop += btodb(sizeof buf); return (rc); }
static int CORENAME(coredump_writesegs_netbsd)(struct proc *p, void *iocookie, struct uvm_coredump_state *us) { struct coredump_state *cs = us->cookie; struct CORENAME(coreseg) cseg; int flag, error; if (us->start == us->realend) return (0); if (us->flags & UVM_COREDUMP_STACK) flag = CORE_STACK; else flag = CORE_DATA; /* * Set up a new core file segment. */ CORE_SETMAGIC(cseg, CORESEGMAGIC, CORE_GETMID(cs->core), flag); cseg.c_addr = us->start; cseg.c_size = us->end - us->start; error = coredump_write(iocookie, UIO_SYSSPACE, &cseg, cs->core.c_seghdrsize); if (error) return (error); return coredump_write(iocookie, UIO_USERSPACE, (void *)(vaddr_t)us->start, cseg.c_size); }
int cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred, struct core *chdr) { int error; struct { struct reg regs; struct fpreg fpregs; } cpustate; struct coreseg cseg; CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0); chdr->c_hdrsize = ALIGN(sizeof(*chdr)); chdr->c_seghdrsize = ALIGN(sizeof(cseg)); chdr->c_cpusize = sizeof(cpustate); /* Save integer registers. */ error = process_read_regs(p, &cpustate.regs); if (error) return error; /* Save floating point registers. */ error = process_read_fpregs(p, &cpustate.fpregs); if (error) return error; CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU); cseg.c_addr = 0; cseg.c_size = chdr->c_cpusize; error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize, (off_t)chdr->c_hdrsize, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p); if (error) return error; error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cpustate, sizeof(cpustate), (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p); if (error) return error; chdr->c_nseg++; return error; }
int cpu_coredump(struct lwp *l, struct coredump_iostate *iocookie, struct core *chdr) { struct md_core md_core; struct coreseg cseg; int error; if (iocookie == NULL) { CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0); chdr->c_hdrsize = ALIGN(sizeof(*chdr)); chdr->c_seghdrsize = ALIGN(sizeof(cseg)); chdr->c_cpusize = sizeof(md_core); chdr->c_nseg++; return 0; } /* Save integer registers. */ error = process_read_regs(l, &md_core.intreg); if (error) return error; if (fputype) { /* Save floating point registers. */ error = process_read_fpregs(l, &md_core.freg, NULL); if (error) return error; } else { /* Make sure these are clear. */ memset((void *)&md_core.freg, 0, sizeof(md_core.freg)); } CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU); cseg.c_addr = 0; cseg.c_size = chdr->c_cpusize; error = coredump_write(iocookie, UIO_SYSSPACE, &cseg, chdr->c_seghdrsize); if (error) return error; return coredump_write(iocookie, UIO_SYSSPACE, &md_core, sizeof(md_core)); }
/* * Dump the machine specific segment at the start of a core dump. */ int cpu_coredump(struct lwp *l, struct coredump_iostate *iocookie, struct core *chdr) { int error; struct { struct reg regs; struct fpreg fpregs; } cpustate; struct coreseg cseg; if (iocookie == NULL) { CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0); chdr->c_hdrsize = ALIGN(sizeof(*chdr)); chdr->c_seghdrsize = ALIGN(sizeof(cseg)); chdr->c_cpusize = sizeof(cpustate); chdr->c_nseg++; return 0; } /* Save integer registers. */ error = process_read_regs(l, &cpustate.regs); if (error) return error; /* Save floating point registers. */ error = process_read_fpregs(l, &cpustate.fpregs, NULL); if (error) return error; CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU); cseg.c_addr = 0; cseg.c_size = chdr->c_cpusize; error = coredump_write(iocookie, UIO_SYSSPACE, &cseg, chdr->c_seghdrsize); if (error) return error; return coredump_write(iocookie, UIO_SYSSPACE, &cpustate, sizeof(cpustate)); }
int cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie, struct core32 *chdr) { struct md_core32 md_core; struct coreseg cseg; int error; if (iocookie == NULL) { CORE_SETMAGIC(*chdr, COREMAGIC, MID_I386, 0); chdr->c_hdrsize = ALIGN32(sizeof(*chdr)); chdr->c_seghdrsize = ALIGN32(sizeof(cseg)); chdr->c_cpusize = sizeof(md_core); chdr->c_nseg++; return 0; } /* Save integer registers. */ error = netbsd32_process_read_regs(l, &md_core.intreg); if (error) return error; /* Save floating point registers. */ error = netbsd32_process_read_fpregs(l, &md_core.freg, NULL); if (error) return error; CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_I386, CORE_CPU); cseg.c_addr = 0; cseg.c_size = chdr->c_cpusize; error = coredump_write(iocookie, UIO_SYSSPACE, &cseg, chdr->c_seghdrsize); if (error) return error; return coredump_write(iocookie, UIO_SYSSPACE, &md_core, sizeof(md_core)); }
/* * Dump the machine specific header information at the start of a core dump. */ int cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred, struct core *core) { struct md_coredump md_core; struct coreseg cseg; off_t off; int error; CORE_SETMAGIC(*core, COREMAGIC, MID_HPPA, 0); core->c_hdrsize = ALIGN(sizeof(*core)); core->c_seghdrsize = ALIGN(sizeof(cseg)); core->c_cpusize = sizeof(md_core); process_read_regs(p, &md_core.md_reg); process_read_fpregs(p, &md_core.md_fpreg); CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_HPPA, CORE_CPU); cseg.c_addr = 0; cseg.c_size = core->c_cpusize; #define write(vp, addr, n) \ vn_rdwr(UIO_WRITE, (vp), (caddr_t)(addr), (n), off, \ UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p) off = core->c_hdrsize; if ((error = write(vp, &cseg, core->c_seghdrsize))) return error; off += core->c_seghdrsize; if ((error = write(vp, &md_core, sizeof md_core))) return error; #undef write core->c_nseg++; return error; }
/* * Dump the machine specific header information at the start of a core dump. */ int cpu_coredump(struct lwp *l, void *iocookie, struct core *chdr) { int error; struct md_coredump cpustate; struct coreseg cseg; if (iocookie == NULL) { CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0); chdr->c_hdrsize = ALIGN(sizeof(*chdr)); chdr->c_seghdrsize = ALIGN(sizeof(cseg)); chdr->c_cpusize = sizeof(cpustate); chdr->c_nseg++; return 0; } cpustate.md_tf = *l->l_md.md_tf; cpustate.md_tf.tf_regs[FRAME_SP] = alpha_pal_rdusp(); /* XXX */ if (l->l_md.md_flags & MDP_FPUSED) { if (l->l_addr->u_pcb.pcb_fpcpu != NULL) fpusave_proc(l, 1); cpustate.md_fpstate = l->l_addr->u_pcb.pcb_fp; } else memset(&cpustate.md_fpstate, 0, sizeof(cpustate.md_fpstate)); CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU); cseg.c_addr = 0; cseg.c_size = chdr->c_cpusize; error = coredump_write(iocookie, UIO_SYSSPACE, &cseg, chdr->c_seghdrsize); if (error) return error; return coredump_write(iocookie, UIO_SYSSPACE, &cpustate, sizeof(cpustate)); }
/* * cpu_dump: dump the machine-dependent kernel core dump headers. */ int cpu_dump() { int (*dump)(dev_t, daddr_t, void *, size_t); char bf[dbtob(1)]; kcore_seg_t *segp; cpu_kcore_hdr_t *cpuhdrp; phys_ram_seg_t *memsegp; const struct bdevsw *bdev; int i; bdev = bdevsw_lookup(dumpdev); if (bdev == NULL) return (ENXIO); dump = bdev->d_dump; memset(bf, 0, sizeof bf); segp = (kcore_seg_t *)bf; cpuhdrp = (cpu_kcore_hdr_t *)&bf[ALIGN(sizeof(*segp))]; memsegp = (phys_ram_seg_t *)&bf[ ALIGN(sizeof(*segp)) + ALIGN(sizeof(*cpuhdrp))]; /* * Generate a segment header. */ CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU); segp->c_size = dbtob(1) - ALIGN(sizeof(*segp)); /* * Add the machine-dependent header info. */ cpuhdrp->version = 1; cpuhdrp->PAKernelL1Table = pmap_kernel_L1_addr(); cpuhdrp->UserL1TableSize = 0; cpuhdrp->nmemsegs = bootconfig.dramblocks; cpuhdrp->omemsegs = ALIGN(sizeof(*cpuhdrp)); /* * Fill in the memory segment descriptors. */ for (i = 0; i < bootconfig.dramblocks; i++) { memsegp[i].start = bootconfig.dram[i].address; memsegp[i].size = bootconfig.dram[i].pages * PAGE_SIZE; } return (dump(dumpdev, dumplo, bf, dbtob(1))); }
/* * cpu_dump: dump the machine-dependent kernel core dump headers. */ int cpu_dump(void) { int (*dump)(dev_t, daddr_t, caddr_t, size_t); char buf[dbtob(1)]; kcore_seg_t *segp; cpu_kcore_hdr_t *cpuhdrp; phys_ram_seg_t *memsegp; int i; dump = bdevsw[major(dumpdev)].d_dump; memset(buf, 0, sizeof buf); segp = (kcore_seg_t *)buf; cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp))]; memsegp = (phys_ram_seg_t *)&buf[ALIGN(sizeof(*segp)) + ALIGN(sizeof(*cpuhdrp))]; /* * Generate a segment header. */ CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU); segp->c_size = dbtob(1) - ALIGN(sizeof(*segp)); /* * Add the machine-dependent header info. */ cpuhdrp->ptdpaddr = PTDpaddr; cpuhdrp->nmemsegs = mem_cluster_cnt; /* * Fill in the memory segment descriptors. */ for (i = 0; i < mem_cluster_cnt; i++) { memsegp[i].start = mem_clusters[i].start; memsegp[i].size = mem_clusters[i].size & ~PAGE_MASK; } return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1))); }
void dumpsys() { const struct bdevsw *bdev; daddr_t blkno; int psize; int error; int addr; int block; int len; vaddr_t dumpspace; kcore_seg_t *kseg_p; cpu_kcore_hdr_t *chdr_p; char dump_hdr[dbtob(1)]; /* assumes header fits in one block */ /* Save registers. */ savectx(&dumppcb); /* flush everything out of caches */ cpu_dcache_wbinv_all(); cpu_sdcache_wbinv_all(); if (dumpdev == NODEV) return; if (dumpsize == 0) { dumpconf(); if (dumpsize == 0) return; } if (dumplo <= 0) { printf("\ndump to dev %u,%u not possible\n", major(dumpdev), minor(dumpdev)); return; } printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev), minor(dumpdev), dumplo); #ifdef UVM_SWAP_ENCRYPT uvm_swap_finicrypt_all(); #endif blkno = dumplo; dumpspace = (vaddr_t) memhook; bdev = bdevsw_lookup(dumpdev); if (bdev == NULL || bdev->d_psize == NULL) return; psize = (*bdev->d_psize)(dumpdev); printf("dump "); if (psize == -1) { printf("area unavailable\n"); return; } /* Setup the dump header */ kseg_p = (kcore_seg_t *)dump_hdr; chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))]; bzero(dump_hdr, sizeof(dump_hdr)); CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU); kseg_p->c_size = sizeof(dump_hdr) - ALIGN(sizeof(*kseg_p)); *chdr_p = cpu_kcore_hdr; error = (*bdev->d_dump)(dumpdev, blkno++, (caddr_t)dump_hdr, sizeof(dump_hdr)); if (error != 0) goto abort; len = 0; for (block = 0; block < bootconfig.dramblocks && error == 0; ++block) { addr = bootconfig.dram[block].address; for (;addr < (bootconfig.dram[block].address + (bootconfig.dram[block].pages * PAGE_SIZE)); addr += PAGE_SIZE) { if ((len % (1024*1024)) == 0) printf("%d ", len / (1024*1024)); pmap_kenter_pa(dumpspace, addr, PROT_READ); pmap_update(pmap_kernel()); error = (*bdev->d_dump)(dumpdev, blkno, (caddr_t) dumpspace, PAGE_SIZE); pmap_kremove(dumpspace, PAGE_SIZE); pmap_update(pmap_kernel()); if (error) break; blkno += btodb(PAGE_SIZE); len += PAGE_SIZE; } } abort: switch (error) { case ENXIO: printf("device bad\n"); break; case EFAULT: printf("device not ready\n"); break; case EINVAL: printf("area improper\n"); break; case EIO: printf("i/o error\n"); break; case EINTR: printf("aborted from console\n"); break; default: printf("succeeded\n"); break; } printf("\n\n"); delay(1000000); }
/* * cpu_coredump is called to write a core dump header. */ int cpu_coredump(struct lwp *l, void *iocookie, struct core *chdr) { int error; struct md_coredump md_core; struct coreseg cseg; if (iocookie == NULL) { CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0); chdr->c_hdrsize = ALIGN(sizeof(*chdr)); chdr->c_seghdrsize = ALIGN(sizeof(cseg)); chdr->c_cpusize = sizeof(md_core); chdr->c_nseg++; return 0; } /* Copy important fields over. */ md_core.md_tf.tf_tstate = l->l_md.md_tf->tf_tstate; md_core.md_tf.tf_pc = l->l_md.md_tf->tf_pc; md_core.md_tf.tf_npc = l->l_md.md_tf->tf_npc; md_core.md_tf.tf_y = l->l_md.md_tf->tf_y; md_core.md_tf.tf_tt = l->l_md.md_tf->tf_tt; md_core.md_tf.tf_pil = l->l_md.md_tf->tf_pil; md_core.md_tf.tf_oldpil = l->l_md.md_tf->tf_oldpil; md_core.md_tf.tf_global[0] = l->l_md.md_tf->tf_global[0]; md_core.md_tf.tf_global[1] = l->l_md.md_tf->tf_global[1]; md_core.md_tf.tf_global[2] = l->l_md.md_tf->tf_global[2]; md_core.md_tf.tf_global[3] = l->l_md.md_tf->tf_global[3]; md_core.md_tf.tf_global[4] = l->l_md.md_tf->tf_global[4]; md_core.md_tf.tf_global[5] = l->l_md.md_tf->tf_global[5]; md_core.md_tf.tf_global[6] = l->l_md.md_tf->tf_global[6]; md_core.md_tf.tf_global[7] = l->l_md.md_tf->tf_global[7]; md_core.md_tf.tf_out[0] = l->l_md.md_tf->tf_out[0]; md_core.md_tf.tf_out[1] = l->l_md.md_tf->tf_out[1]; md_core.md_tf.tf_out[2] = l->l_md.md_tf->tf_out[2]; md_core.md_tf.tf_out[3] = l->l_md.md_tf->tf_out[3]; md_core.md_tf.tf_out[4] = l->l_md.md_tf->tf_out[4]; md_core.md_tf.tf_out[5] = l->l_md.md_tf->tf_out[5]; md_core.md_tf.tf_out[6] = l->l_md.md_tf->tf_out[6]; md_core.md_tf.tf_out[7] = l->l_md.md_tf->tf_out[7]; #ifdef DEBUG md_core.md_tf.tf_local[0] = l->l_md.md_tf->tf_local[0]; md_core.md_tf.tf_local[1] = l->l_md.md_tf->tf_local[1]; md_core.md_tf.tf_local[2] = l->l_md.md_tf->tf_local[2]; md_core.md_tf.tf_local[3] = l->l_md.md_tf->tf_local[3]; md_core.md_tf.tf_local[4] = l->l_md.md_tf->tf_local[4]; md_core.md_tf.tf_local[5] = l->l_md.md_tf->tf_local[5]; md_core.md_tf.tf_local[6] = l->l_md.md_tf->tf_local[6]; md_core.md_tf.tf_local[7] = l->l_md.md_tf->tf_local[7]; md_core.md_tf.tf_in[0] = l->l_md.md_tf->tf_in[0]; md_core.md_tf.tf_in[1] = l->l_md.md_tf->tf_in[1]; md_core.md_tf.tf_in[2] = l->l_md.md_tf->tf_in[2]; md_core.md_tf.tf_in[3] = l->l_md.md_tf->tf_in[3]; md_core.md_tf.tf_in[4] = l->l_md.md_tf->tf_in[4]; md_core.md_tf.tf_in[5] = l->l_md.md_tf->tf_in[5]; md_core.md_tf.tf_in[6] = l->l_md.md_tf->tf_in[6]; md_core.md_tf.tf_in[7] = l->l_md.md_tf->tf_in[7]; #endif if (l->l_md.md_fpstate) { fpusave_lwp(l, true); md_core.md_fpstate = *l->l_md.md_fpstate; } else memset(&md_core.md_fpstate, 0, sizeof(md_core.md_fpstate)); CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU); cseg.c_addr = 0; cseg.c_size = chdr->c_cpusize; error = coredump_write(iocookie, UIO_SYSSPACE, &cseg, chdr->c_seghdrsize); if (error) return error; return coredump_write(iocookie, UIO_SYSSPACE, &md_core, sizeof(md_core)); }
/* * Doadump comes here after turning off memory management and * getting on the dump stack, either when called above, or by * the auto-restart code. */ void dumpsys() { int maj; int psize; daddr_t blkno; /* current block to write */ /* dump routine */ int (*dump)(dev_t, daddr_t, caddr_t, size_t); int pg; /* page being dumped */ paddr_t maddr; /* PA being dumped */ int error; /* error code from (*dump)() */ kcore_seg_t *kseg_p; cpu_kcore_hdr_t *chdr_p; char dump_hdr[dbtob(1)]; /* XXX assume hdr fits in 1 block */ extern int msgbufmapped; msgbufmapped = 0; /* Make sure dump device is valid. */ if (dumpdev == NODEV) return; if (dumpsize == 0) { dumpconf(); if (dumpsize == 0) return; } maj = major(dumpdev); if (dumplo < 0) { printf("\ndump to dev %u,%u not possible\n", maj, minor(dumpdev)); return; } dump = bdevsw[maj].d_dump; blkno = dumplo; printf("\ndumping to dev %u,%u offset %ld\n", maj, minor(dumpdev), dumplo); #ifdef UVM_SWAP_ENCRYPT uvm_swap_finicrypt_all(); #endif /* Setup the dump header */ kseg_p = (kcore_seg_t *)dump_hdr; chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))]; bzero(dump_hdr, sizeof(dump_hdr)); CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU); kseg_p->c_size = dbtob(1) - ALIGN(sizeof(*kseg_p)); *chdr_p = cpu_kcore_hdr; printf("dump "); psize = (*bdevsw[maj].d_psize)(dumpdev); if (psize == -1) { printf("area unavailable\n"); return; } /* Dump the header. */ error = (*dump)(dumpdev, blkno++, (caddr_t)dump_hdr, dbtob(1)); if (error != 0) goto abort; maddr = (paddr_t)0; for (pg = 0; pg < dumpsize; pg++) { #define NPGMB (1024 * 1024 / PAGE_SIZE) /* print out how many MBs we have dumped */ if (pg != 0 && (pg % NPGMB) == 0) printf("%d ", pg / NPGMB); #undef NPGMB error = (*dump)(dumpdev, blkno, (caddr_t)maddr, PAGE_SIZE); if (error == 0) { maddr += PAGE_SIZE; blkno += btodb(PAGE_SIZE); } else break; } abort: switch (error) { case 0: printf("succeeded\n"); break; case ENXIO: printf("device bad\n"); break; case EFAULT: printf("device not ready\n"); break; case EINVAL: printf("area improper\n"); break; case EIO: printf("i/o error\n"); break; case EINTR: printf("aborted from console\n"); break; default: printf("error %d\n", error); break; } }