[BACK]Return to process_machdep.c CVS log [TXT][DIR] Up to [local] / sys / arch / alpha / alpha

Annotation of sys/arch/alpha/alpha/process_machdep.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: process_machdep.c,v 1.11 2005/12/12 19:44:30 miod Exp $       */
                      2: /*     $NetBSD: process_machdep.c,v 1.7 1996/07/11 20:14:21 cgd Exp $  */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1998 Doug Rabson
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  */
                     29: /*
                     30:  * Copyright (c) 1994 Christopher G. Demetriou
                     31:  * All rights reserved.
                     32:  *
                     33:  * Redistribution and use in source and binary forms, with or without
                     34:  * modification, are permitted provided that the following conditions
                     35:  * are met:
                     36:  * 1. Redistributions of source code must retain the above copyright
                     37:  *    notice, this list of conditions and the following disclaimer.
                     38:  * 2. Redistributions in binary form must reproduce the above copyright
                     39:  *    notice, this list of conditions and the following disclaimer in the
                     40:  *    documentation and/or other materials provided with the distribution.
                     41:  * 3. All advertising materials mentioning features or use of this software
                     42:  *    must display the following acknowledgement:
                     43:  *      This product includes software developed by Christopher G. Demetriou.
                     44:  * 4. The name of the author may not be used to endorse or promote products
                     45:  *    derived from this software without specific prior written permission
                     46:  *
                     47:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     48:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     49:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     50:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     51:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     52:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     53:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     54:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     55:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     56:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     57:  */
                     58:
                     59: /*
                     60:  * This file may seem a bit stylized, but that so that it's easier to port.
                     61:  * Functions to be implemented here are:
                     62:  *
                     63:  * process_read_regs(proc, regs)
                     64:  *     Get the current user-visible register set from the process
                     65:  *     and copy it into the regs structure (<machine/reg.h>).
                     66:  *     The process is stopped at the time read_regs is called.
                     67:  *
                     68:  * process_write_regs(proc, regs)
                     69:  *     Update the current register set from the passed in regs
                     70:  *     structure.  Take care to avoid clobbering special CPU
                     71:  *     registers or privileged bits in the PSL.
                     72:  *     The process is stopped at the time write_regs is called.
                     73:  *
                     74:  * process_sstep(proc)
                     75:  *     Arrange for the process to trap after executing a single instruction.
                     76:  *
                     77:  * process_set_pc(proc)
                     78:  *     Set the process's program counter.
                     79:  */
                     80:
                     81: #include <sys/param.h>
                     82: #include <sys/systm.h>
                     83: #include <sys/kernel.h>
                     84: #include <sys/proc.h>
                     85: #include <sys/user.h>
                     86: #include <sys/vnode.h>
                     87: #include <sys/ptrace.h>
                     88: #include <machine/reg.h>
                     89: #include <machine/frame.h>
                     90:
                     91: #include <alpha/alpha/db_instruction.h>
                     92:
                     93: #define        process_frame(p)        ((p)->p_md.md_tf)
                     94: #define        process_pcb(p)          (&(p)->p_addr->u_pcb)
                     95: #define        process_fpframe(p)      (&(process_pcb(p)->pcb_fp))
                     96:
                     97: int
                     98: process_read_regs(p, regs)
                     99:        struct proc *p;
                    100:        struct reg *regs;
                    101: {
                    102:
                    103:        frametoreg(process_frame(p), regs);
                    104:        regs->r_regs[R_ZERO] = process_frame(p)->tf_regs[FRAME_PC];
                    105:        regs->r_regs[R_SP] = process_pcb(p)->pcb_hw.apcb_usp;
                    106:        return (0);
                    107: }
                    108:
                    109: int
                    110: process_read_fpregs(p, regs)
                    111:        struct proc *p;
                    112:        struct fpreg *regs;
                    113: {
                    114:
                    115:        if (p == fpcurproc) {
                    116:                alpha_pal_wrfen(1);
                    117:                savefpstate(process_fpframe(p));
                    118:                alpha_pal_wrfen(0);
                    119:        }
                    120:
                    121:        bcopy(process_fpframe(p), regs, sizeof(struct fpreg));
                    122:        return (0);
                    123: }
                    124:
                    125: #ifdef PTRACE
                    126:
                    127: int
                    128: process_write_regs(p, regs)
                    129:        struct proc *p;
                    130:        struct reg *regs;
                    131: {
                    132:
                    133:        regtoframe(regs, process_frame(p));
                    134:        process_frame(p)->tf_regs[FRAME_PC] = regs->r_regs[R_ZERO];
                    135:        process_pcb(p)->pcb_hw.apcb_usp = regs->r_regs[R_SP];
                    136:        return (0);
                    137: }
                    138:
                    139: int
                    140: process_set_pc(p, addr)
                    141:        struct proc *p;
                    142:        caddr_t addr;
                    143: {
                    144:        struct trapframe *frame = process_frame(p);
                    145:
                    146:        frame->tf_regs[FRAME_PC] = (u_int64_t)addr;
                    147:        return (0);
                    148: }
                    149:
                    150: int
                    151: process_write_fpregs(p, regs)
                    152:        struct proc *p;
                    153:        struct fpreg *regs;
                    154: {
                    155:
                    156:        if (p->p_addr->u_pcb.pcb_fpcpu != NULL)
                    157:                fpusave_proc(p, 1);
                    158:
                    159:        bcopy(regs, process_fpframe(p), sizeof(struct fpreg));
                    160:        return (0);
                    161: }
                    162:
                    163: /*
                    164:  * Single stepping infrastructure.
                    165:  */
                    166: int ptrace_set_bpt(struct proc *p, struct mdbpt *bpt);
                    167: int ptrace_clear_bpt(struct proc *p, struct mdbpt *bpt);
                    168: int ptrace_read_int(struct proc *, vaddr_t, u_int32_t *);
                    169: int ptrace_write_int(struct proc *, vaddr_t, u_int32_t);
                    170: u_int64_t ptrace_read_register(struct proc *p, int regno);
                    171:
                    172: int
                    173: ptrace_read_int(struct proc *p, vaddr_t addr, u_int32_t *v)
                    174: {
                    175:        struct iovec iov;
                    176:        struct uio uio;
                    177:
                    178:        iov.iov_base = (caddr_t) v;
                    179:        iov.iov_len = sizeof(u_int32_t);
                    180:        uio.uio_iov = &iov;
                    181:        uio.uio_iovcnt = 1;
                    182:        uio.uio_offset = (off_t)addr;
                    183:        uio.uio_resid = sizeof(u_int32_t);
                    184:        uio.uio_segflg = UIO_SYSSPACE;
                    185:        uio.uio_rw = UIO_READ;
                    186:        uio.uio_procp = p;
                    187:        return process_domem(curproc, p, &uio, PT_READ_I);
                    188: }
                    189:
                    190: int
                    191: ptrace_write_int(struct proc *p, vaddr_t addr, u_int32_t v)
                    192: {
                    193:        struct iovec iov;
                    194:        struct uio uio;
                    195:
                    196:        iov.iov_base = (caddr_t) &v;
                    197:        iov.iov_len = sizeof(u_int32_t);
                    198:        uio.uio_iov = &iov;
                    199:        uio.uio_iovcnt = 1;
                    200:        uio.uio_offset = (off_t)addr;
                    201:        uio.uio_resid = sizeof(u_int32_t);
                    202:        uio.uio_segflg = UIO_SYSSPACE;
                    203:        uio.uio_rw = UIO_WRITE;
                    204:        uio.uio_procp = p;
                    205:        return process_domem(curproc, p, &uio, PT_WRITE_I);
                    206: }
                    207:
                    208: u_int64_t
                    209: ptrace_read_register(struct proc *p, int regno)
                    210: {
                    211:        static int reg_to_frame[32] = {
                    212:                FRAME_V0,
                    213:                FRAME_T0,
                    214:                FRAME_T1,
                    215:                FRAME_T2,
                    216:                FRAME_T3,
                    217:                FRAME_T4,
                    218:                FRAME_T5,
                    219:                FRAME_T6,
                    220:                FRAME_T7,
                    221:
                    222:                FRAME_S0,
                    223:                FRAME_S1,
                    224:                FRAME_S2,
                    225:                FRAME_S3,
                    226:                FRAME_S4,
                    227:                FRAME_S5,
                    228:                FRAME_S6,
                    229:
                    230:                FRAME_A0,
                    231:                FRAME_A1,
                    232:                FRAME_A2,
                    233:                FRAME_A3,
                    234:                FRAME_A4,
                    235:                FRAME_A5,
                    236:
                    237:                FRAME_T8,
                    238:                FRAME_T9,
                    239:                FRAME_T10,
                    240:                FRAME_T11,
                    241:                FRAME_RA,
                    242:                FRAME_T12,
                    243:                FRAME_AT,
                    244:                FRAME_GP,
                    245:                FRAME_SP,
                    246:                -1,             /* zero */
                    247:        };
                    248:
                    249:        if (regno == R_ZERO)
                    250:                return 0;
                    251:
                    252:        return p->p_md.md_tf->tf_regs[reg_to_frame[regno]];
                    253: }
                    254:
                    255: int
                    256: ptrace_clear_bpt(struct proc *p, struct mdbpt *bpt)
                    257: {
                    258:        return ptrace_write_int(p, bpt->addr, bpt->contents);
                    259: }
                    260:
                    261: int
                    262: ptrace_set_bpt(struct proc *p, struct mdbpt *bpt)
                    263: {
                    264:        int error;
                    265:        u_int32_t bpins = 0x00000080;
                    266:        error = ptrace_read_int(p, bpt->addr, &bpt->contents);
                    267:        if (error)
                    268:                return error;
                    269:        return ptrace_write_int(p, bpt->addr, bpins);
                    270: }
                    271:
                    272: int
                    273: process_sstep(struct proc *p, int sstep)
                    274: {
                    275:        int error;
                    276:        vaddr_t pc = p->p_md.md_tf->tf_regs[FRAME_PC];
                    277:        alpha_instruction ins;
                    278:        vaddr_t addr[2];
                    279:        int count = 0;
                    280:
                    281:        if (sstep == 0) {
                    282:                /* clearing the breakpoint */
                    283:                if (p->p_md.md_flags & MDP_STEP2) {
                    284:                        ptrace_clear_bpt(p, &p->p_md.md_sstep[1]);
                    285:                        ptrace_clear_bpt(p, &p->p_md.md_sstep[0]);
                    286:                        p->p_md.md_flags &= ~MDP_STEP2;
                    287:                } else if (p->p_md.md_flags & MDP_STEP1) {
                    288:                        ptrace_clear_bpt(p, &p->p_md.md_sstep[0]);
                    289:                        p->p_md.md_flags &= ~MDP_STEP1;
                    290:                }
                    291:                return (0);
                    292:        }
                    293: #ifdef DIAGNOSTIC
                    294:        if (p->p_md.md_flags & (MDP_STEP1|MDP_STEP2))
                    295:                panic("process_sstep: step breakpoints not removed");
                    296: #endif
                    297:        error = ptrace_read_int(p, pc, &ins.bits);
                    298:        if (error)
                    299:                return (error);
                    300:
                    301:        switch (ins.branch_format.opcode) {
                    302:        case op_j:
                    303:                /* Jump: target is register value */
                    304:                addr[0] = ptrace_read_register(p, ins.jump_format.rb) & ~3;
                    305:                count = 1;
                    306:                break;
                    307:
                    308:        case op_br:
                    309:        case op_fbeq:
                    310:        case op_fblt:
                    311:        case op_fble:
                    312:        case op_bsr:
                    313:        case op_fbne:
                    314:        case op_fbge:
                    315:        case op_fbgt:
                    316:        case op_blbc:
                    317:        case op_beq:
                    318:        case op_blt:
                    319:        case op_ble:
                    320:        case op_blbs:
                    321:        case op_bne:
                    322:        case op_bge:
                    323:        case op_bgt:
                    324:                /* Branch: target is pc+4+4*displacement */
                    325:                addr[0] = pc + 4;
                    326:                addr[1] = pc + 4 + 4 * ins.branch_format.displacement;
                    327:                count = 2;
                    328:                break;
                    329:
                    330:        default:
                    331:                addr[0] = pc + 4;
                    332:                count = 1;
                    333:        }
                    334:
                    335:        if (p->p_addr->u_pcb.pcb_fpcpu != NULL)
                    336:                fpusave_proc(p, 0);
                    337:        p->p_md.md_sstep[0].addr = addr[0];
                    338:        error = ptrace_set_bpt(p, &p->p_md.md_sstep[0]);
                    339:        if (error)
                    340:                return (error);
                    341:        if (count == 2) {
                    342:                p->p_md.md_sstep[1].addr = addr[1];
                    343:                error = ptrace_set_bpt(p, &p->p_md.md_sstep[1]);
                    344:                if (error) {
                    345:                        ptrace_clear_bpt(p, &p->p_md.md_sstep[0]);
                    346:                        return (error);
                    347:                }
                    348:                p->p_md.md_flags |= MDP_STEP2;
                    349:        } else
                    350:                p->p_md.md_flags |= MDP_STEP1;
                    351:
                    352:        return (0);
                    353: }
                    354:
                    355: #endif /* PTRACE */

CVSweb