Ejemplo n.º 1
0
static void
syscall_RSIM_transaction(RSIM_Thread *t, int callno)
{
    int cmd = t->syscall_arg(0);
    uint32_t regs_va = t->syscall_arg(1);
    int result = -ENOSYS;
    RSIM_Process *proc = t->get_process();
    std::string transaction_name = "specimen-initiated transaction " + StringUtility::addrToString(regs_va);

    switch (cmd) {
        case 0: {        // start
            if (32 == t->get_process()->wordSize()) {
                pt_regs_32 regs_guest = t->get_regs().get_pt_regs_32();
                if (sizeof(regs_guest)!=proc->mem_write(&regs_guest, regs_va, sizeof regs_guest)) {
                    result = -EFAULT;
                } else {
                    result = proc->mem_transaction_start(transaction_name); // total number of transactions
                    assert(-1==result || result>0);
                }
            } else {
                FIXME("[Robb P. Matzke 2015-05-28]: 64-bit not supported yet");
            }
            break;
        }

        case 1: {       // rollback
            if (32 == t->get_process()->wordSize()) {
                pt_regs_32 regs_guest;
                if (sizeof(regs_guest)!=proc->mem_read(&regs_guest, regs_va, sizeof regs_guest)) {
                    result = -EFAULT;
                } else if (0>=(result = t->get_process()->mem_transaction_rollback(transaction_name))) {
                    // error; don't initialize registers; this syscall will return without doing anything
                    if (0==result)
                        result = -EINVAL; // no such transaction
                } else {
                    // success.  The syscall will return as if we had called transaction start, but with zero to distinguish it
                    // from transaction start.
                    result = 0;
                    t->init_regs(PtRegs(regs_guest));
                }
            } else {
                FIXME("[Robb P. Matzke 2015-05-28]: 64-bit not supported yet");
            }
            break;
        }

        case 2:
            // not implemented yet
            break;
    }
    t->syscall_return(result);
}