* Copyright (c) 1992 Regents of the University of California.
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
* %sccs.include.redist.c%
#include <sys/kinfo_proc.h>
#include <machine/vmparam.h>
#define offsetof(s, f) ((int)&((s *)0)->f)
shift_page(fd
, off
, ssize
)
(void)lseek(fd
, -NBPG
, SEEK_END
);
for (; ssize
> 0; ssize
-= NBPG
) {
(void)lseek(fd
, -2 * NBPG
, SEEK_CUR
);
* Fix up the core image for the sparc. We need to flush any register
* windows that are cached in the pcb out to the user stack.
* Also, we need to get the trap frame and possible floating point state
* from the top of the kernel stack and store it in the pcb.
register struct rwindow
*rw
;
register int nsaved
, cc
, ssize
;
* Before anything else read the trapframe. Synchronizing here
* is impossible if the process is running.
cc
= kvm_read(kd
, (u_long
)ki
->kp_proc
.p_md
.md_tf
,
(void *)&tf
, sizeof(tf
));
error("kvm_read: %s (reading kernel trapframe)",
error("cannot read kernel trapframe");
* Write out the real trap frame.
off
= offsetof(struct user
, u_md
);
off
+= offsetof(struct md_coredump
, md_tf
);
if (lseek(fd
, off
, SEEK_SET
) == -1) {
(void)write(fd
, (char *)&tf
, sizeof(tf
));
if (ki
->kp_proc
.p_md
.md_fpstate
!= 0) {
* If floating point state is present, write it out too.
* It comes right after the trapframe so we don't need to seek.
cc
= kvm_read(kd
, (u_long
)ki
->kp_proc
.p_md
.md_fpstate
,
(void *)&fs
, sizeof(fs
));
error("kvm_read: %s (fpu state)", kvm_geterr(kd
));
error("cannot read fpu state");
(void)write(fd
, (char *)&fs
, sizeof(fs
));
if (lseek(fd
, offsetof(struct user
, u_pcb
), SEEK_SET
) == -1) {
cc
= read(fd
, (char *)&pcb
, sizeof(pcb
));
error("couldn't read pcb from core file");
* Write any unsaved windows to the appropriate stack locations.
off
= ctob(UPAGES
+ ki
->kp_eproc
.e_vm
.vm_dsize
);
ssize
= ctob(ki
->kp_eproc
.e_vm
.vm_ssize
);
for (; --nsaved
>= 0; ++rw
) {
* Copy register window into appropriate stack location.
s
= ssize
- (USRSTACK
- sp
);
error("cannot copy pcb windows to stack");
* It's possible to be missing the bottomost
* page because a stack page hasn't been allocated
* for the register save area. Shift over
* the stack segment by a page, and update
* the u-area to reflect the new stack size. YECH!
shift_page(fd
, off
, ssize
);
++ki
->kp_eproc
.e_vm
.vm_ssize
;
(void)lseek(fd
, offsetof(struct user
,
(void)write(fd
, (char *)&ki
->kp_eproc
.e_vm
,
sizeof(ki
->kp_eproc
.e_vm
));
if (lseek(fd
, off
+ s
, SEEK_SET
) == -1)
error("cannot copy pcb windows to stack");
write(fd
, (char *)rw
, sizeof(*rw
));