Ejemplo n.º 1
0
	DisassemblerCore(
			const CboValidator::Result &validationResult,
			Allocator &allocator,
			InputStream &cboStream,
			OutputStream &outputStream):
		mValue32Table(validationResult.mValue32Count, Value32(), Value32Table::allocator_type(&allocator)),
		mValue64Table(validationResult.mValue64Count, Value64(), Value64Table::allocator_type(&allocator)),
		mStringTable(validationResult.mStringCount, StringView(), StringTable::allocator_type(&allocator)),
		mStringBytes(validationResult.mStringByteCount + validationResult.mStringCount, char(), StringBytes::allocator_type(&allocator)),
		mQualifiedNameTable(validationResult.mQualifiedNameCount, QualifiedName(), QualifiedNameTable::allocator_type(&allocator)),
		mQualifiedNameElementTable(validationResult.mQualifiedNameElementCount + validationResult.mQualifiedNameCount, nullptr, QualifiedNameElementTable::allocator_type(&allocator)),
		mValidationResult(validationResult),
		mCboStream(cboStream),
		mOutStream(outputStream)
	{}
Ejemplo n.º 2
0
void CR_ModuleEx::CreateFlowGraph32(CR_Addr32 entrance) {
    auto cf = Info32()->CodeFuncFromAddr(entrance);
    assert(cf);

    CR_Addr32Set leaders;
    leaders.insert(entrance);

    // insert jumpees
    auto& jumpees = cf->Jumpees();
    leaders.insert(jumpees.begin(), jumpees.end());

    // insert exits' next
    auto& exits = cf->Exits();
    for (auto addr : exits) {
        auto op_code = Info32()->OpCodeFromAddr(addr);
        auto size = op_code->Codes().size();
        auto next_addr = static_cast<CR_Addr32>(addr + size);
        leaders.insert(next_addr);
    }

    // insert jumpers next
    auto& jumpers = cf->Jumpers();
    for (auto addr : jumpers) {
        auto op_code = Info32()->OpCodeFromAddr(addr);
        auto size = op_code->Codes().size();
        auto next_addr = static_cast<CR_Addr32>(addr + size);
        leaders.insert(next_addr);
    }

    // sort
    std::vector<CR_Addr32> vecLeaders(leaders.begin(), leaders.end());
    std::sort(vecLeaders.begin(), vecLeaders.end());

    // store leaders
    cf->Leaders() = std::move(leaders);

    const size_t size = vecLeaders.size() - 1;
    for (size_t i = 0; i < size; ++i) {
        // for every pair of two adjacent leaders
        auto addr1 = vecLeaders[i], addr2 = vecLeaders[i + 1];
        // prepare a basic block
        CR_BasicBlock32 block;
        block.m_addr = addr1;
        CR_Addr32 next_addr = cr_invalid_addr32;
        for (auto addr = addr1; addr < addr2; ) {
            if (cf->Leaders().count(addr)) {
                // set label at each leader
                block.AddLeaderLabel(addr);
            }
            // op.code from addr
            auto op_code = Info32()->OpCodeFromAddr(addr);
            if (op_code == NULL) {
                break;
            }
            auto type = op_code->OpCodeType();
            if (type == cr_OCT_JMP) {
                // jump
                auto oper = op_code->Operand(0);
                if (oper->GetOperandType() == cr_DF_IMM) {
                    block.m_jump_to = oper->Value32();  // jump to
                }
                next_addr = cr_invalid_addr32;
            } else if (type == cr_OCT_RETURN) {
                next_addr = cr_invalid_addr32;
            } else if (type == cr_OCT_JCC || type == cr_OCT_LOOP) {
                // conditional jump or loop
                auto oper = op_code->Operand(0);
                if (oper->GetOperandType() == cr_DF_IMM) {
                    block.m_jump_to = oper->Value32();  // jump to
                }
                block.m_cond_code = op_code->CondCode();
                next_addr =
                    static_cast<CR_Addr32>(addr + op_code->Codes().size());
            } else {
                next_addr =
                    static_cast<CR_Addr32>(addr + op_code->Codes().size());
            }
            // add op.code
            block.m_stmts.emplace_back(*op_code);
            // go to next addr
            addr += static_cast<CR_Addr32>(op_code->Codes().size());
        }
        // add label at last
        block.AddLeaderLabel(addr2);
        // set next addr
        block.m_next_addr = next_addr;
        // add block
        cf->BasicBlocks().emplace_back(block);
    }
} // CR_ModuleEx::CreateFlowGraph32