Ejemplo n.º 1
0
void
FrameState::assertValidRegisterState() const
{
    Registers checkedFreeRegs;

    FrameEntry *tos = tosFe();
    for (uint32 i = 0; i < tracker.nentries; i++) {
        FrameEntry *fe = tracker[i];
        if (fe >= tos)
            continue;

        JS_ASSERT(i == fe->trackerIndex());
        JS_ASSERT_IF(fe->isCopy(),
                     fe->trackerIndex() > fe->copyOf()->trackerIndex());
        JS_ASSERT_IF(fe->isCopy(), !fe->type.inRegister() && !fe->data.inRegister());
        JS_ASSERT_IF(fe->isCopy(), fe->copyOf() < tos);
        JS_ASSERT_IF(fe->isCopy(), fe->copyOf()->isCopied());

        if (fe->isCopy())
            continue;
        if (fe->type.inRegister()) {
            checkedFreeRegs.takeReg(fe->type.reg());
            JS_ASSERT(regstate[fe->type.reg()].fe == fe);
        }
        if (fe->data.inRegister()) {
            checkedFreeRegs.takeReg(fe->data.reg());
            JS_ASSERT(regstate[fe->data.reg()].fe == fe);
        }
    }

    JS_ASSERT(checkedFreeRegs == freeRegs);
}
Ejemplo n.º 2
0
unsigned int Node::calculateTotalSize(const Registers& regs)const{
	unsigned int acum=0;
	for(Registers::iterator it=regs.begin();it!=regs.end();++it){
		acum+=(*it)->getSize();
	}
	return acum;
}
Ejemplo n.º 3
0
void
FrameState::syncAndKill(Registers kill, Uses uses, Uses ignore)
{
    /* Backwards, so we can allocate registers to backing slots better. */
    FrameEntry *tos = tosFe();
    FrameEntry *bottom = tos - uses.nuses;

    tos -= ignore.nuses;

    if (inTryBlock)
        bottom = NULL;

    for (uint32 i = tracker.nentries - 1; i < tracker.nentries; i--) {
        FrameEntry *fe = tracker[i];
        if (fe >= tos)
            continue;

        Address address = addressOf(fe);
        FrameEntry *backing = fe;
        if (fe->isCopy()) {
            if (!inTryBlock && fe < bottom)
                continue;
            backing = fe->copyOf();
        }

        JS_ASSERT_IF(i == 0, !fe->isCopy());

        bool killData = fe->data.inRegister() && kill.hasReg(fe->data.reg());
        if (!fe->data.synced() && (killData || fe >= bottom)) {
            if (backing != fe && backing->data.inMemory())
                tempRegForData(backing);
            syncData(backing, address, masm);
            fe->data.sync();
            if (fe->isConstant() && !fe->type.synced())
                fe->type.sync();
        }
        if (killData) {
            JS_ASSERT(backing == fe);
            JS_ASSERT(fe->data.synced());
            if (regstate[fe->data.reg()].fe)
                forgetReg(fe->data.reg());
            fe->data.setMemory();
        }
        bool killType = fe->type.inRegister() && kill.hasReg(fe->type.reg());
        if (!fe->type.synced() && (killType || fe >= bottom)) {
            if (backing != fe && backing->type.inMemory())
                tempRegForType(backing);
            syncType(backing, address, masm);
            fe->type.sync();
        }
        if (killType) {
            JS_ASSERT(backing == fe);
            JS_ASSERT(fe->type.synced());
            if (regstate[fe->type.reg()].fe)
                forgetReg(fe->type.reg());
            fe->type.setMemory();
        }
    }
}
Ejemplo n.º 4
0
        bool Liveness::SrcRegisterIs(const Registers& regs, myTemp reg) const
        {
            assert (reg != nullptr);
            assert (regs.size() >= 0 && regs.size() <= 1);

            if (regs.size() == 1)   return regs.at(0) == reg;
            else                    return false;
        }
Ejemplo n.º 5
0
        Registers TwoOperandOperate::GetSrcRegs() const
        {
            Registers result = GetDstRegs();            

            if (srcRep.kind == BinaryUnion::Kind::Reg)
                result.push_back(srcRep.u.reg);

            return result;
        }
Ejemplo n.º 6
0
        void Liveness::SortOneRegisters(Registers& regs)
        {
            struct myTempComp
            {
                bool operator () (myTemp lhs, myTemp rhs)
                { return Temp_getTempNum(lhs) < Temp_getTempNum(rhs); }
            } tempComparator;

            sort(regs.begin(), regs.end(), tempComparator);
        }
Ejemplo n.º 7
0
// Compare register sets by name
static inline bool compareRegisterSet(const Registers &r1, const Registers &r2)
{
    if (r1.size() != r2.size())
        return false;
    const int size = r1.size();
    for (int r = 0; r < size; r++)
        if (r1.at(r).name != r2.at(r).name)
            return false;
    return true;
}
Ejemplo n.º 8
0
        //  NOTE:
        //      This function also recognize conditions when either of the destination
        //      register or the source register is used as a memory location:
        //          mov [reg], reg | mov [reg], [reg] | mov reg, [reg]
        //      On these conditions, the move instructions are not treated as move pairs.
        bool Liveness::IsTwoContentRegOperandMove(
            Node node, Registers& leftOperand, Registers& rightOperand) const
        {
            if (!cfGraph.IsMoveIns(node) ||
                leftOperand.size() != 1 || rightOperand.size() != 1)
                return false;

            //  check memory operand type from "[]" characters
            string insStr = cfGraph.GetNodeIns(node)->ToString();
            return insStr.find('[') == string::npos;
        }
Ejemplo n.º 9
0
        Registers Call::GetDstRegs() const
        {
            Registers result;
        
            //  caller-save contains eax register which is also the result value register.
            myTempList temps = Frame_callerSaveRegs();
            while (temps)
                result.push_back(temps->head),
                temps = temps->tail;

            return result;
        }
Ejemplo n.º 10
0
        Registers Liveness::GetSetDiff(Registers& lhs, Registers& rhs)
        {
            struct myTempComp
            {
                bool operator () (myTemp lhs, myTemp rhs)
                { return Temp_getTempNum(lhs) < Temp_getTempNum(rhs); }
            } tempComparator;

            Registers result;
            set_difference(
                lhs.begin(), lhs.end(), rhs.begin(), rhs.end(),
                back_inserter(result),
                tempComparator);
            return result;
        }
Ejemplo n.º 11
0
void RegisterHandler::setAndMarkRegisters(const Registers &registers)
{
    if (!compareRegisterSet(m_registers, registers)) {
        setRegisters(registers);
        return;
    }
    const int size = m_registers.size();
    for (int r = 0; r != size; ++r) {
        const QModelIndex regIndex = index(r, 1, QModelIndex());
        if (m_registers.at(r).value != registers.at(r).value) {
            // Indicate red if values change, keep changed.
            m_registers[r].changed = m_registers.at(r).changed
                || !m_registers.at(r).value.isEmpty();
            m_registers[r].value = registers.at(r).value;
            emit dataChanged(regIndex, regIndex);
        }
        emit registerSet(regIndex); // Notify attached memory views.
    }
}
Ejemplo n.º 12
0
std::string gdbmiRegisters(CIDebugRegisters *regs,
                           CIDebugControl *control,
                           bool humanReadable,
                           unsigned flags,
                           std::string *errorMessage)
{
    if (regs == 0 || control == 0) {
        *errorMessage = "Required interfaces missing for registers dump.";
        return std::string();
    }

    const Registers registers = getRegisters(regs, flags, errorMessage);
    if (registers.empty())
        return std::string();

    std::ostringstream str;
    str << '[';
    if (humanReadable)
        str << '\n';
    const Registers::size_type size = registers.size();
    for (Registers::size_type r = 0; r < size; ++r) {
        const Register &reg = registers.at(r);
        if (r)
            str << ',';
        str << "{number=\"" << r << "\",name=\"" << gdbmiWStringFormat(reg.name) << '"';
        if (!reg.description.empty())
            str << ",description=\"" << gdbmiWStringFormat(reg.description) << '"';
        if (reg.subRegister)
            str << ",subregister=\"true\"";
        if (reg.pseudoRegister)
            str << ",pseudoregister=\"true\"";
        str << ",value=\"";
        formatDebugValue(str, reg.value, control);
        str << "\"}";
        if (humanReadable)
            str << '\n';
    }
    str << ']';
    if (humanReadable)
        str << '\n';
    return str.str();
}
Ejemplo n.º 13
0
        void Liveness::GenerateMovePairs()
        {
            for (auto oneNode : cfGraph.GetDirectedGraph().GetNodes())
            {
                Registers leftOperand = cfGraph.GetNodeIns(oneNode)->GetDstRegs();
                Registers rightOperand = cfGraph.GetNodeIns(oneNode)->GetSrcRegs();

                if (IsTwoContentRegOperandMove(oneNode, leftOperand, rightOperand) &&
                    !IsSelfMove(leftOperand, rightOperand))
                {
                    assert (leftOperand.at(0) != nullptr && rightOperand.at(0) != nullptr);

                    Node leftNode = interferenceGraph.GetRegNode(leftOperand.at(0));
                    Node rightNode = interferenceGraph.GetRegNode(rightOperand.at(0));

                    if(!MovePairContains(leftNode, rightNode))
                        movePairs.push_back(Edge(leftNode, rightNode));
                }
            }
        }
Ejemplo n.º 14
0
 bool Liveness::IsSelfMove(Registers& leftOperand, Registers& rightOperand) const
 {
     assert (leftOperand.size() == 1 && rightOperand.size() == 1);
     return leftOperand.at(0) == rightOperand.at(0);
 }
Ejemplo n.º 15
0
Registers getRegisters(CIDebugRegisters *regs,
                       unsigned flags,
                       std::string *errorMessage)
{
    enum { bufSize= 128 };
    WCHAR buf[bufSize];

    ULONG registerCount = 0;
    HRESULT hr = regs->GetNumberRegisters(&registerCount);
    if (FAILED(hr)) {
        *errorMessage = msgDebugEngineComFailed("GetNumberRegisters", hr);
        return Registers();
    }
    ULONG pseudoRegisterCount = 0;
    if (flags & IncludePseudoRegisters) {
        hr = regs->GetNumberPseudoRegisters(&pseudoRegisterCount);
        if (FAILED(hr)) {
            *errorMessage = msgDebugEngineComFailed("GetNumberPseudoRegisters", hr);
            return Registers();
        }
    }

    Registers rc;
    rc.reserve(registerCount + pseudoRegisterCount);

    // Standard registers
    DEBUG_REGISTER_DESCRIPTION description;
    DEBUG_VALUE value;
    for (ULONG r = 0; r < registerCount; ++r) {
        hr = regs->GetDescriptionWide(r, buf, bufSize, NULL, &description);
        if (FAILED(hr)) {
            *errorMessage = msgDebugEngineComFailed("GetDescription", hr);
            return Registers();
        }
        hr = regs->GetValue(r, &value);
        if (FAILED(hr)) {
            *errorMessage = msgDebugEngineComFailed("GetValue", hr);
            return Registers();
        }
        const bool isSubRegister = (description.Flags & DEBUG_REGISTER_SUB_REGISTER);
        if (!isSubRegister || (flags & IncludeSubRegisters)) {
            Register reg;
            reg.name = buf;
            reg.description = registerDescription(description);
            reg.subRegister = isSubRegister;
            reg.value = value;
            rc.push_back(reg);
        }
    }

    // Pseudo
    for (ULONG r = 0; r < pseudoRegisterCount; ++r) {
        ULONG type;
        hr = regs->GetPseudoDescriptionWide(r, buf, bufSize, NULL, NULL, &type);
        if (FAILED(hr))
            continue; // Fails for some pseudo registers
        hr = regs->GetValue(r, &value);
        if (FAILED(hr))
            continue; // Fails for some pseudo registers
        Register reg;
        reg.pseudoRegister = true;
        reg.name = buf;
        reg.description = valueType(type);
        reg.value = value;
        rc.push_back(reg);
    }
    return rc;
}
Ejemplo n.º 16
0
static void general_signal_handler(int signum, siginfo_t* info, void* context)
{
    Registers regs;

    if (!context)
        return;

    // Convert OS context to Registers
    port_thread_context_to_regs(&regs, (ucontext_t*)context);
    void* fault_addr = info ? info->si_addr : NULL;

    // Check if SIGSEGV is produced by port_read/write_memory
    port_tls_data_t* tlsdata = get_private_tls_data();
    if (tlsdata && tlsdata->violation_flag)
    {
        tlsdata->violation_flag = 0;
        regs.set_ip(tlsdata->restart_address);
        return;
    }

    if (!tlsdata) // Tread is not attached - attach thread temporarily
    {
        int res;
        tlsdata = (port_tls_data_t*)STD_MALLOC(sizeof(port_tls_data_t));

        if (tlsdata) // Try to attach the thread
            res = port_thread_attach_local(tlsdata, TRUE, TRUE, 0);

        if (!tlsdata || res != 0)
        {   // Can't process correctly; perform default actions
            if (FLAG_DBG)
            {
                bool result = gdb_crash_handler(&regs);
                _exit(-1); // Exit process if not sucessful...
            }

            if (FLAG_CORE &&
                    signum != SIGABRT) // SIGABRT can't be rethrown
            {
                signal(signum, SIG_DFL); // setup default handler
                return;
            }

            _exit(-1);
        }

        // SIGSEGV can represent SO which can't be processed out of signal handler
        if (signum == SIGSEGV && // This can occur only when a user set an alternative stack
                is_stack_overflow(tlsdata, fault_addr))
        {
            int result = port_process_signal(PORT_SIGNAL_STACK_OVERFLOW, &regs, fault_addr, FALSE);

            if (result == 0)
            {
                if (port_thread_detach_temporary() == 0)
                    STD_FREE(tlsdata);
                return;
            }

            if (result > 0)
                tlsdata->debugger = TRUE;
            else
            {
                if (FLAG_CORE)
                {   // Rethrow crash to generate core
                    signal(signum, SIG_DFL); // setup default handler
                    return;
                }
                _exit(-1);
            }
        }
    }

    if (tlsdata->debugger)
    {
        bool result = gdb_crash_handler(&regs);
        _exit(-1); // Exit process if not sucessful...
    }

    if (signum == SIGABRT && // SIGABRT can't be trown again from c_handler
            FLAG_DBG)
    {   // So attaching GDB right here
        bool result = gdb_crash_handler(&regs);
        _exit(-1); // Exit process if not sucessful...
    }

    if (signum == SIGSEGV &&
            is_stack_overflow(tlsdata, fault_addr))
    {
        // Second SO while previous SO is not processed yet - is GPF
        if (tlsdata->restore_guard_page)
            tlsdata->restore_guard_page = FALSE;
        else
        {   // To process signal on protected stack area
            port_thread_clear_guard_page();
            // Note: the call above does not disable alternative stack
            // It can't be made while we are on alternative stack
            // Alt stack will be disabled explicitly in c_handler()
            tlsdata->restore_guard_page = TRUE;
        }
    }

    // Prepare registers for transfering control out of signal handler
    void* callback = (void*)&c_handler;

    port_set_longjump_regs(callback, &regs, 3,
                           &regs, (void*)(size_t)signum, fault_addr);

    // Convert prepared Registers back to OS context
    port_thread_regs_to_context((ucontext_t*)context, &regs);
    // Return from signal handler to go to C handler
}