Exemple #1
0
void do_syscall(struct syscallrecord *rec)
{
	struct syscallentry *entry;
	struct msg_syscallprep scmsg;
	struct childdata *child = this_child();
	unsigned int call;

	init_msgchildhdr(&scmsg.hdr, SYSCALL_PREP, pids[child->num], child->num);
	scmsg.sequence_nr = child->op_nr;
	scmsg.nr = rec->nr;
	scmsg.is32bit = rec->do32bit;
	scmsg.a1 = rec->a1;
	scmsg.a2 = rec->a2;
	scmsg.a3 = rec->a3;
	scmsg.a4 = rec->a4;
	scmsg.a5 = rec->a5;
	scmsg.a6 = rec->a6;
	rec->tp = scmsg.hdr.tp;
	sendudp((char *) &scmsg, sizeof(scmsg));

	call = rec->nr;
	entry = syscalls[call].entry;

	if (entry->flags & EXTRA_FORK)
		do_extrafork(rec);
	else
		 /* common-case, do the syscall in this child process. */
		__do_syscall(rec, BEFORE);

	/* timestamp again for when we returned */
	clock_gettime(CLOCK_MONOTONIC, &rec->tp);
}
Exemple #2
0
int
hal_syscall_handler(void)
{
    int func, arg1, arg2, arg3, arg4;
    int err, res, sig;

    func = get_register(R7);
    arg1 = get_register(R8);
    arg2 = get_register(R9);
    arg3 = get_register(R10);
    arg4 = get_register(R11);

    if (func == SYS_interrupt) {
	//  A console interrupt landed us here.
	//  Invoke the debug agent so as to cause a SIGINT.
        return SIGINT;
    }

    if ((res = __do_syscall(func, arg1, arg2, arg3, arg4, &err, &sig)) != 0) {
        // Skip over trap instruction
        put_register(PC, get_register(PC)+4);
        put_register(R8, err);
	return sig;
    }

    return SIGTRAP;
}
Exemple #3
0
int
hal_syscall_handler(void)
{
    CYG_ADDRWORD func, arg1, arg2, arg3, arg4;
    CYG_ADDRWORD err;

    func = get_register(ER0);
    arg1 = get_register(ER1);
    arg2 = get_register(ER2);
    arg3 = get_register(ER3);
    arg4 = 0;
 
    if (func == SYS_interrupt) {
	//  A console interrupt landed us here.
	//  Invoke the debug agent so as to cause a SIGINT.
        return SIGINT;
    }

    if (__do_syscall(func, arg1, arg2, arg3, arg4, &err)) {
        put_register(D0, err);
	return 0;
    }

    return SIGTRAP;
}
Exemple #4
0
int
hal_syscall_handler(void)
{
    CYG_ADDRWORD func, arg1, arg2, arg3, arg4;
    CYG_ADDRWORD err, sig;

    func = get_register(EAX);
    arg1 = get_register(EBX);
    arg2 = get_register(ECX);
    arg3 = get_register(EDX);
    arg4 = 0;

    switch (func) {
      case 1:
	func = SYS_exit;
	break;
      case 3:
	func = SYS_read;
	break;
      case 4:
	func = SYS_write;
	break;
      case 37:
	func = SYS_kill;
	break;

      case 48: // install signal handler
	// FIXME!
        put_register(EAX, 0);
	return 0;

      case 184: // get program arguments
	// FIXME!
	*(int *)arg1 = 0;
	put_register(EAX, 0);
	return 0;

      default:
	return SIGTRAP;
    }

    if (func == SYS_exit) {
	// We want to stop in exit so that the user may poke around
	//  to see why his app exited.
        return SIGTRAP;
    }

    if (__do_syscall(func, arg1, arg2, arg3, arg4, &err, &sig)) {
        put_register(EAX, err);
	return (int)sig;
    }

    return SIGTRAP;
}
Exemple #5
0
int
hal_syscall_handler(void)
{
    int func, arg1, arg2, arg3, arg4;
    int err, sig;

    func = get_register(R4);
    arg1 = get_register(R5);
    arg2 = get_register(R6);
    arg3 = get_register(R7);
    arg4 = *(unsigned int *)(get_register(SP));

    switch (func) {
    case _shnewlib_SYS_read:
        func = SYS_read;
        break;
    case _shnewlib_SYS_write:
        func = SYS_write;
        break;
    case _shnewlib_SYS_open:
        func = SYS_open;
        break;
    case _shnewlib_SYS_close:
        func = SYS_close;
        break;
    case _shnewlib_SYS_lseek:
        func = SYS_lseek;
        break;
    case _shnewlib_SYS_utime:
        func = SYS_utime;
    default:
        return SIGTRAP;
    }

    if (func == SYS_interrupt) {
	//  A console interrupt landed us here.
	//  Invoke the debug agent so as to cause a SIGINT.
        return SIGINT;
    }

    if (__do_syscall(func, arg1, arg2, arg3, arg4, &err, &sig)) {
        // R0 is normally result register, but newlib's trap
        // code looks in R1 for the return value
        put_register(R1, err);
	return sig;
    }

    return SIGTRAP;
}
Exemple #6
0
int
hal_syscall_handler(void)
{
    CYG_ADDRWORD func, arg1, arg2, arg3, arg4;
    CYG_ADDRWORD err, sig;
    int retreg;
    target_register_t sr = get_register(REG_SR);

    if ((sr & CYGARC_SR_PM) == 0 || (sr & CYGARC_SR_BS) == 0) {
	// bank zero regs
	func = get_register(REG_B0R0);
	arg1 = get_register(REG_B0R1);
	arg2 = get_register(REG_B0R2);
	arg3 = get_register(REG_B0R3);
	arg4 = 0;
	retreg = REG_B0R0;
    } else {
	func = get_register(REG_B1R0);
	arg1 = get_register(REG_B1R1);
	arg2 = get_register(REG_B1R2);
	arg3 = get_register(REG_B1R3);
	retreg = REG_B1R0;
    }
 
    set_pc(get_pc()+2);

    if (func == SYS_exit) {
	// We want to stop in exit so that the user may poke around
	//  to see why his app exited.
        return SIGTRAP;
    }

    if (func == SYS_interrupt) {
	//  A console interrupt landed us here.
	//  Invoke the debug agent so as to cause a SIGINT.
        return SIGINT;
    }

    if (__do_syscall(func, arg1, arg2, arg3, arg4, &err, &sig)) {
        put_register(retreg, err);
	return (int)sig;
    }

    return SIGTRAP;
}
Exemple #7
0
/* This is a special case for things like execve, which would replace our
 * child process with something unknown to us. We use a 'throwaway' process
 * to do the execve in, and let it run for a max of a second before we kill it
 */
static void do_extrafork(struct syscallrecord *rec)
{
	pid_t pid = 0;
	pid_t extrapid;

	extrapid = fork();
	if (extrapid == 0) {
		/* grand-child */
		char childname[]="trinity-subchild";
		prctl(PR_SET_NAME, (unsigned long) &childname);

		__do_syscall(rec, GOING_AWAY);
		/* if this was for eg. an successful execve, we should never get here.
		 * if it failed though... */
		_exit(EXIT_SUCCESS);
	}

	/* misc failure. */
	if (extrapid == -1) {
		//debugf("Couldn't fork grandchild: %s\n", strerror(errno));
		return;
	}

	/* small pause to let grandchild do some work. */
	if (pid_alive(extrapid) == TRUE)
		usleep(100);

	/* We take the rec lock here even though we don't obviously use it.
	 * The reason, is that the grandchild is using it. */
	lock(&rec->lock);
	while (pid == 0) {
		int childstatus;

		pid = waitpid(extrapid, &childstatus, WUNTRACED | WCONTINUED | WNOHANG);
		if (pid_alive(extrapid) == TRUE)
			kill(extrapid, SIGKILL);
		usleep(1000);
	}
	unlock(&rec->lock);
}