[BACK]Return to md-sparc.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / gcore

Annotation of src/usr.bin/gcore/md-sparc.c, Revision 1.1.1.1

1.1       deraadt     1: /*      $NetBSD: md-sparc.c,v 1.2 1995/09/05 02:51:08 tls Exp $      */
                      2:
                      3: /*-
                      4:  * Copyright (c) 1992, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
                      6:  *
                      7:  * This software was developed by the Computer Systems Engineering group
                      8:  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
                      9:  * contributed to Berkeley.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the University of
                     22:  *     California, Berkeley and its contributors.
                     23:  * 4. Neither the name of the University nor the names of its contributors
                     24:  *    may be used to endorse or promote products derived from this software
                     25:  *    without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     28:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     29:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     30:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     31:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     32:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     33:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     34:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     35:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     36:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     37:  * SUCH DAMAGE.
                     38:  */
                     39:
                     40: #ifndef lint
                     41: #if 0
                     42: static char sccsid[] = "@(#)md-sparc.c 8.1 (Berkeley) 6/6/93";
                     43: #else
                     44: static char rcsid[] = "$NetBSD: md-sparc.c,v 1.2 1995/09/05 02:51:08 tls Exp $";
                     45: #endif
                     46: #endif /* not lint */
                     47:
                     48: #include <sys/param.h>
                     49: #include <sys/time.h>
                     50: #include <sys/file.h>
                     51: #include <sys/stat.h>
                     52: #include <sys/proc.h>
                     53: #include <sys/user.h>
                     54: #include <sys/sysctl.h>
                     55: #include <machine/vmparam.h>
                     56:
                     57: #include <kvm.h>
                     58: #include <unistd.h>
                     59: #include <stdio.h>
                     60: #include <string.h>
                     61: #include "extern.h"
                     62:
                     63: #ifndef offsetof
                     64: #define        offsetof(s, f) ((int)&((s *)0)->f)
                     65: #endif
                     66:
                     67: static void
                     68: shift_page(fd, off, ssize)
                     69:        register int fd;
                     70:        register off_t off;
                     71:        register int ssize;
                     72: {
                     73:        char buffer[NBPG];
                     74:
                     75:        (void)lseek(fd, (off_t)-NBPG, SEEK_END);
                     76:        for (; ssize > 0; ssize -= NBPG) {
                     77:                (void)read(fd, buffer, NBPG);
                     78:                (void)write(fd, buffer, NBPG);
                     79:                (void)lseek(fd, (off_t)-2 * NBPG, SEEK_CUR);
                     80:        }
                     81: }
                     82:
                     83: /*
                     84:  * Fix up the core image for the sparc.  We need to flush any register
                     85:  * windows that are cached in the pcb out to the user stack.
                     86:  * Also, we need to get the trap frame and possible floating point state
                     87:  * from the top of the kernel stack and store it in the pcb.
                     88:  */
                     89: void
                     90: md_core(kd, fd, ki)
                     91:        kvm_t *kd;
                     92:        int fd;
                     93:        struct kinfo_proc *ki;
                     94: {
                     95:        register struct rwindow *rw;
                     96:        register int nsaved, cc, ssize;
                     97:        register off_t off, s;
                     98:        register u_long sp;
                     99:        struct pcb pcb;
                    100:        struct trapframe tf;
                    101:
                    102:        /*
                    103:         * Before anything else read the trapframe.  Synchronizing here
                    104:         * is impossible if the process is running.
                    105:         */
                    106:        cc = kvm_read(kd, (u_long)ki->kp_proc.p_md.md_tf,
                    107:                      /* XXX */
                    108:                      (void *)&tf, sizeof(tf));
                    109:        if (cc < 0)
                    110:                err(1, "kvm_read: %s (reading kernel trapframe)",
                    111:                      kvm_geterr(kd));
                    112:        if (cc != sizeof(tf))
                    113:                err(1, "cannot read kernel trapframe");
                    114:
                    115:        /*
                    116:         * Write out the real trap frame.
                    117:         */
                    118:        off = offsetof(struct user, u_md);
                    119:        off += offsetof(struct md_coredump, md_tf);
                    120:        if (lseek(fd, off, SEEK_SET) == -1)
                    121:                err(1, "lseek: %s", strerror(errno));
                    122:        (void)write(fd, &tf, sizeof(tf));
                    123:
                    124:        if (ki->kp_proc.p_md.md_fpstate != 0) {
                    125:                /*
                    126:                 * If floating point state is present, write it out too.
                    127:                 * It comes right after the trapframe so we don't need to seek.
                    128:                 */
                    129:                struct fpstate fs;
                    130:                cc = kvm_read(kd, (u_long)ki->kp_proc.p_md.md_fpstate,
                    131:                              (void *)&fs, sizeof(fs));
                    132:                if (cc < 0)
                    133:                        err(1, "kvm_read: %s (fpu state)", kvm_geterr(kd));
                    134:                if (cc != sizeof(fs))
                    135:                        err(1, "cannot read fpu state");
                    136:                (void)write(fd, (char *)&fs, sizeof(fs));
                    137:        }
                    138:        /*
                    139:         * Read pcb.
                    140:         */
                    141:        if (lseek(fd, (off_t)offsetof(struct user, u_pcb), SEEK_SET) == -1)
                    142:                err(1, "lseek: %s", strerror(errno));
                    143:        cc = read(fd, (char *)&pcb, sizeof(pcb));
                    144:        if (cc != sizeof(pcb)) {
                    145:                if (cc < 0)
                    146:                        err(1, "read: %s", strerror(errno));
                    147:                err(1, "couldn't read pcb from core file");
                    148:        }
                    149:
                    150:        /*
                    151:         * Write any unsaved windows to the appropriate stack locations.
                    152:         */
                    153:        nsaved = pcb.pcb_nsaved;
                    154:        if (nsaved == 0)
                    155:                return;
                    156:
                    157:        rw = &pcb.pcb_rw[0];
                    158:        off = ctob(UPAGES + ki->kp_eproc.e_vm.vm_dsize);
                    159:        ssize = ctob(ki->kp_eproc.e_vm.vm_ssize);
                    160:        sp = tf.tf_out[6];
                    161:        for (; --nsaved >= 0; ++rw) {
                    162:                /*
                    163:                 * Copy register window into appropriate stack location.
                    164:                 */
                    165:                s = ssize - (USRSTACK - sp);
                    166:                if (s < 0) {
                    167:                        if (s < -NBPG)
                    168:                                err(1, "cannot copy pcb windows to stack");
                    169:                        /*
                    170:                         * It's possible to be missing the bottomost
                    171:                         * page because a stack page hasn't been allocated
                    172:                         * for the register save area.  Shift over
                    173:                         * the stack segment by a page, and update
                    174:                         * the u-area to reflect the new stack size.  YECH!
                    175:                         */
                    176:                        shift_page(fd, off, ssize);
                    177:                        ssize += NBPG;
                    178:                        s += NBPG;
                    179:                        ++ki->kp_eproc.e_vm.vm_ssize;
                    180:                        (void)lseek(fd,
                    181:                            (off_t)offsetof(struct user, u_kproc.kp_eproc.e_vm),
                    182:                            SEEK_SET);
                    183:                        (void)write(fd,
                    184:                            &ki->kp_eproc.e_vm, sizeof(ki->kp_eproc.e_vm));
                    185:                }
                    186:                if (lseek(fd, off + s, SEEK_SET) == -1)
                    187:                        err(1, "cannot copy pcb windows to stack");
                    188:
                    189:                (void)write(fd, rw, sizeof(*rw));
                    190:                sp = rw->rw_in[6];
                    191:        }
                    192: }