MachineFunction* Disassembler::disassemble(unsigned Address) { MachineFunction *MF = getOrCreateFunction(Address); if (MF->size() == 0) { // Decode basic blocks until end of function unsigned Size = 0; MachineBasicBlock *MBB; do { unsigned MBBSize = 0; MBB = decodeBasicBlock(Address+Size, MF, MBBSize); Size += MBBSize; } while (Address+Size < CurSectionEnd && MBB->size() > 0 && !(MBB->instr_rbegin()->isReturn())); if (Address+Size < CurSectionEnd && MBB->size() > 0) { // FIXME: This can be shoved into the loop above to improve performance MachineFunction *NextMF = getNearestFunction(getDebugOffset(MBB->instr_rbegin()->getDebugLoc())); if (NextMF != NULL) { Functions.erase( getDebugOffset(NextMF->begin()->instr_begin()->getDebugLoc())); } } } Functions[Address] = MF; return MF; }
MachineBasicBlock* Disassembler::decodeBasicBlock(unsigned Address, MachineFunction* MF, unsigned &Size) { assert(MF && "Unable to decode basic block without Machine Function!"); uint64_t MFLoc = MF->getFunctionNumber(); // FIXME: Horrible, horrible hack uint64_t Off = Address-MFLoc; std::stringstream MBBName; MBBName << MF->getName().str() << "+" << Off; // Dummy holds the name. BasicBlock *Dummy = BasicBlock::Create(*MC->getContext(), MBBName.str()); MachineBasicBlock *MBB = MF->CreateMachineBasicBlock(Dummy); MF->push_back(MBB); // NOTE: Might also need SectAddr... Size = 0; while (Address+Size < (unsigned) CurSectionEnd) { unsigned CurAddr = Address+Size; Size += std::max(unsigned(1), decodeInstruction(CurAddr, MBB)); MachineInstr* MI = NULL; if (MBB->size() != 0) { MI = &(*MBB->instr_rbegin()); MachineInstructions[CurAddr] = MI; } if (MI != NULL && MI->isTerminator()) { break; } } if (Address >= CurSectionEnd) { printInfo("Reached end of current section!"); } return MBB; }