[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     ! 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