Exemple #1
0
int
proc_bkptset(struct proc_handle *phdl, uintptr_t address,
             unsigned long *saved)
{
    struct ptrace_io_desc piod;
    unsigned long paddr, caddr;
    int ret = 0;

    *saved = 0;
    if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD ||
            phdl->status == PS_IDLE) {
        errno = ENOENT;
        return (-1);
    }

    DPRINTFX("adding breakpoint at 0x%lx", address);

    if (phdl->status != PS_STOP)
        if (proc_stop(phdl) != 0)
            return (-1);

    /*
     * Read the original instruction.
     */
    caddr = address;
    paddr = 0;
    piod.piod_op = PIOD_READ_I;
    piod.piod_offs = (void *)caddr;
    piod.piod_addr = &paddr;
    piod.piod_len  = BREAKPOINT_INSTR_SZ;
    if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) {
        DPRINTF("ERROR: couldn't read instruction at address 0x%"
                PRIuPTR, address);
        ret = -1;
        goto done;
    }
    *saved = paddr;
    /*
     * Write a breakpoint instruction to that address.
     */
    caddr = address;
    paddr = BREAKPOINT_INSTR;
    piod.piod_op = PIOD_WRITE_I;
    piod.piod_offs = (void *)caddr;
    piod.piod_addr = &paddr;
    piod.piod_len  = BREAKPOINT_INSTR_SZ;
    if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) {
        DPRINTF("ERROR: couldn't write instruction at address 0x%"
                PRIuPTR, address);
        ret = -1;
        goto done;
    }

done:
    if (phdl->status != PS_STOP)
        /* Restart the process if we had to stop it. */
        proc_cont(phdl);

    return (ret);
}
Exemple #2
0
void
process_stoptrace(void)
{
	struct lwp *l = curlwp;
	struct proc *p = l->l_proc, *pp;

	mutex_enter(proc_lock);
	mutex_enter(p->p_lock);
	pp = p->p_pptr;
	if (pp->p_pid == 1) {
		CLR(p->p_slflag, PSL_SYSCALL);	/* XXXSMP */
		mutex_exit(p->p_lock);
		mutex_exit(proc_lock);
		return;
	}

	p->p_xstat = SIGTRAP;
	proc_stop(p, 1, SIGSTOP);
	mutex_exit(proc_lock);

	/*
	 * Call issignal() once only, to have it take care of the
	 * pending stop.  Signal processing will take place as usual
	 * from userret().
	 */
	KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
	(void)issignal(l);
	mutex_exit(p->p_lock);
	KERNEL_LOCK(l->l_biglocks, l);
}
u32 procwrap_stop(union trapped_args *args, void *pr_ctxt)
{
    u32 ret;

    ret = proc_stop(((struct process_context *)pr_ctxt)->processor);

    return ret;
}
/*
** atexit.
*/
static void    quit_ftrace(int i)
{
  tracer_quit = i = 1;
  if (!tracee.proc)
    exit(0);
  else if (tracee.status == RUN)
    {
      if (proc_stop(tracee.proc) == -1)
	errexit("ftrace: proc_stop, %s", ftrace_strerror(errno));
    }
}
Exemple #5
0
int
proc_bkptdel(struct proc_handle *phdl, uintptr_t address,
    unsigned long saved)
{
	struct ptrace_io_desc piod;
	uintptr_t caddr;
	int ret = 0, stopped;
	instr_t instr;

	if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD ||
	    phdl->status == PS_IDLE) {
		errno = ENOENT;
		return (-1);
	}

	DPRINTFX("removing breakpoint at 0x%lx", address);

	stopped = 0;
	if (phdl->status != PS_STOP) {
		if (proc_stop(phdl) != 0)
			return (-1);
		stopped = 1;
	}

	/*
	 * Overwrite the breakpoint instruction that we setup previously.
	 */
	caddr = address;
	instr = saved;
	piod.piod_op = PIOD_WRITE_I;
	piod.piod_offs = (void *)caddr;
	piod.piod_addr = &instr;
	piod.piod_len  = BREAKPOINT_INSTR_SZ;
	if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) {
		DPRINTF("ERROR: couldn't write instruction at address 0x%"
		    PRIuPTR, address);
		ret = -1;
	}

	if (stopped)
		/* Restart the process if we had to stop it. */
		proc_continue(phdl);
 
	return (ret);
}
Exemple #6
0
static int tool_procedural_iter(goxel_t *goxel, const inputs_t *inputs,
                                int state, const vec2_t *view_size,
                                bool inside)
{
    int snaped = 0;
    vec3_t pos, normal;
    box_t box;
    gox_proc_t *proc = &goxel->proc;
    const bool down = inputs->mouse_down[0];

    if (proc->state == PROC_PARSE_ERROR) return 0;

    // XXX: duplicate code with tool_brush_iter.
    if (inside)
        snaped = goxel_unproject(
                goxel, view_size, &inputs->mouse_pos,
                goxel->painter.op == OP_ADD && !goxel->snap_offset,
                &pos, &normal);
    if (snaped) {
        if (goxel->tool == TOOL_BRUSH && goxel->snap_offset)
            vec3_iaddk(&pos, normal, goxel->snap_offset * goxel->tool_radius);
        pos.x = round(pos.x - 0.5) + 0.5;
        pos.y = round(pos.y - 0.5) + 0.5;
        pos.z = round(pos.z - 0.5) + 0.5;
        box = bbox_from_extents(pos, 0.5, 0.5, 0.5);
        render_box(&goxel->rend, &box, false, NULL, false);
    }
    if (state == STATE_IDLE) {
        if (snaped) state = STATE_SNAPED;
    }
    if (state == STATE_SNAPED) {
        if (!snaped) return STATE_IDLE;
        if (down) {
            image_history_push(goxel->image);
            proc_stop(proc);
            proc_start(proc, &box);
            state = STATE_PAINT;
        }
    }
    if (state == STATE_PAINT) {
        if (!down) state = STATE_IDLE;
    }
    return state;
}
Exemple #7
0
static void *get_executable_mappings(pid_t pid, unsigned int *size)
{
	unsigned long long start;
	unsigned long long end;
	unsigned long long offset;
	char permr;
	char permw;
	char permx;
	char filename[PATH_MAX + 2];
	char nl;
	FILE *in;
	struct xmap *xmap = NULL;
	void *xmap_base = NULL;
	unsigned int xmap_size = 0;

	proc_stop(pid);

	*size = 0;

	snprintf(filename, sizeof(filename)-1, "/proc/%d/maps", pid);

	in = fopen(filename, "r");
	if (!in)
		return NULL;

	while(fscanf(in, "%llx-%llx %c%c%c%*c %llx %*x:%*x %*u%*64[ ]%c", &start, &end, &permr, &permw, &permx, &offset, filename) == 7) {
		size_t flen;
		size_t xmap_off;

		if (*filename != '\n') {
			if (fscanf(in, "%" STR(PATH_MAX) "[^\n]%c", filename + 1, &nl) != 2)
				break;
			if (nl != '\n')
				break;
		}
		else
			*filename = 0;

		if (*filename != '[' && *filename != 0) {
			struct stat statbuf;

			if (stat(filename, &statbuf) < 0)
				continue;

			if (S_ISCHR(statbuf.st_mode))
				continue;
		
			flen = strlen(filename);
		}
		else
			flen = 0;

		if (permx != 'x' || permr != 'r' || permw == 'w')
			continue;

		xmap_off = (void *)xmap - xmap_base;

		if (xmap_off + XMAP_ALIGN(flen + 1) > xmap_size) {
			xmap_size += 4096 + XMAP_ALIGN(flen + 1);
			xmap_base = realloc(xmap_base, xmap_size);
			xmap = (struct xmap *)(xmap_base + xmap_off);
		}

		xmap->start = start;
		xmap->end = end;
		xmap->offset = offset;

		xmap->flen = flen;
		strncpy(xmap->fname, filename, flen);
		xmap->fname[flen] = 0;

#if 0
fprintf(stderr, "start: %llx end: %llx offset: %llx flen: %u fname: %s\n",
		xmap->start,
		xmap->end,
		xmap->offset,
		xmap->flen,
		xmap->fname);
#endif

		xmap = XMAP_NEXT(xmap, flen + 1);
	}
	fclose(in);

	*size = (void *)xmap - xmap_base;

	return xmap_base;
}
Exemple #8
0
static int
procfs_control(struct proc *curp, struct lwp *lp, int op)
{
	struct proc *p = lp->lwp_proc;
	int error;

	ASSERT_LWKT_TOKEN_HELD(&p->p_token);
	ASSERT_LWKT_TOKEN_HELD(&proc_token);

	/* Can't trace a process that's currently exec'ing. */ 
	if ((p->p_flags & P_INEXEC) != 0)
		return EAGAIN;
	/*
	 * Authorization check: rely on normal debugging protection, except
	 * allow processes to disengage debugging on a process onto which
	 * they have previously attached, but no longer have permission to
	 * debug.
	 */
	if (op != PROCFS_CTL_DETACH) {
		if (securelevel > 0 && p->p_pid == 1)
			return (EPERM);

		if (!CHECKIO(curp, p) || p_trespass(curp->p_ucred, p->p_ucred))
			return (EPERM);
	}

	/*
	 * Attach - attaches the target process for debugging
	 * by the calling process.
	 */
	if (op == PROCFS_CTL_ATTACH) {
		/* check whether already being traced */
		if (p->p_flags & P_TRACED)
			return (EBUSY);

		/* can't trace yourself! */
		if (p->p_pid == curp->p_pid)
			return (EINVAL);

		/*
		 * Go ahead and set the trace flag.
		 * Save the old parent (it's reset in
		 *   _DETACH, and also in kern_exit.c:wait4()
		 * Reparent the process so that the tracing
		 *   proc gets to see all the action.
		 * Stop the target.
		 */
		p->p_flags |= P_TRACED;
		faultin(p);
		p->p_xstat = 0;		/* XXX ? */
		if (p->p_pptr != curp) {
			p->p_oppid = p->p_pptr->p_pid;
			proc_reparent(p, curp);
		}
		proc_stop(p);
		return (0);
	}

	/*
	 * Target process must be stopped, owned by (curp) and
	 * be set up for tracing (P_TRACED flag set).
	 * Allow DETACH to take place at any time for sanity.
	 * Allow WAIT any time, of course.
	 */
	switch (op) {
	case PROCFS_CTL_DETACH:
	case PROCFS_CTL_WAIT:
		break;

	default:
		if (!TRACE_WAIT_P(curp, p))
			return (EBUSY);
	}


#ifdef FIX_SSTEP
	/*
	 * do single-step fixup if needed
	 */
	FIX_SSTEP(lp);
#endif

	/*
	 * Don't deliver any signal by default.
	 * To continue with a signal, just send
	 * the signal name to the ctl file
	 */
	p->p_xstat = 0;

	switch (op) {
	/*
	 * Detach.  Cleans up the target process, reparent it if possible
	 * and set it running once more.
	 */
	case PROCFS_CTL_DETACH:
		/* if not being traced, then this is a painless no-op */
		if ((p->p_flags & P_TRACED) == 0)
			return (0);

		/* not being traced any more */
		p->p_flags &= ~P_TRACED;

		/* remove pending SIGTRAP, else the process will die */
		spin_lock(&lp->lwp_spin);
		lwp_delsig(lp, SIGTRAP);
		spin_unlock(&lp->lwp_spin);

		/* give process back to original parent */
		if (p->p_oppid != p->p_pptr->p_pid) {
			struct proc *pp;

			pp = pfs_pfind(p->p_oppid);
			if (pp) {
				proc_reparent(p, pp);
				pfs_pdone(pp);
			}
		}

		p->p_oppid = 0;
		p->p_flags &= ~P_WAITED;	/* XXX ? */
		wakeup((caddr_t) curp);		/* XXX for CTL_WAIT below ? */

		break;

	/*
	 * Step.  Let the target process execute a single instruction.
	 */
	case PROCFS_CTL_STEP:
		LWPHOLD(lp);
		error = procfs_sstep(lp);
		LWPRELE(lp);
		if (error)
			return (error);
		break;

	/*
	 * Run.  Let the target process continue running until a breakpoint
	 * or some other trap.
	 */
	case PROCFS_CTL_RUN:
		break;

	/*
	 * Wait for the target process to stop.
	 * If the target is not being traced then just wait
	 * to enter
	 */
	case PROCFS_CTL_WAIT:
		error = 0;
		if (p->p_flags & P_TRACED) {
			while (error == 0 &&
					p->p_stat != SSTOP &&
					(p->p_flags & P_TRACED) &&
					(p->p_pptr == curp)) {
				error = tsleep((caddr_t) p,
						PCATCH, "procfsx", 0);
			}
			if (error == 0 && !TRACE_WAIT_P(curp, p))
				error = EBUSY;
		} else {
			while (error == 0 && p->p_stat != SSTOP) {
				error = tsleep((caddr_t) p,
						PCATCH, "procfs", 0);
			}
		}
		return (error);

	default:
		panic("procfs_control");
	}

	/*
	 * If the process is in a stopped state, make it runnable again.
	 * Do not set LWP_MP_BREAKTSLEEP - that is, do not break a tsleep
	 * that might be in progress.
	 */
	if (p->p_stat == SSTOP)
		proc_unstop(p);
	return (0);
}