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) {}
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