#include "BasicInstructionHighlighter.h" #include /** * @brief Clear the basic instruction highlighting */ void BasicInstructionHighlighter::clear(RVA address, RVA size) { BasicInstructionIt it = biMap.lower_bound(address); if (it != biMap.begin()) { --it; } std::vector addrs; while (it != biMap.end() && it->first < address + size) { addrs.push_back(it->first); ++it; } // first and last entries may intersect, but not necessarily // be contained in [address, address + size), so we need to // check it and perhaps adjust their addresses. std::vector newInstructions; if (!addrs.empty()) { const BasicInstruction &prev = biMap[addrs.front()]; if (prev.address < address && prev.address + prev.size > address) { newInstructions.push_back({prev.address, address - prev.address, prev.color}); } const BasicInstruction &next = biMap[addrs.back()]; if (next.address < address + size && next.address + next.size > address + size) { const RVA offset = address + size - next.address; newInstructions.push_back({next.address + offset, next.size - offset, next.color}); } } for (RVA addr : addrs) { const BasicInstruction &bi = biMap[addr]; if (std::max(bi.address, address) < std::min(bi.address + bi.size, address + size)) { biMap.erase(addr); } } for (BasicInstruction newInstr : newInstructions) { biMap[newInstr.address] = newInstr; } } /** * @brief Highlight the basic instruction at address */ void BasicInstructionHighlighter::highlight(RVA address, RVA size, QColor color) { clear(address, size); biMap[address] = {address, size, color}; } /** * @brief Return a highlighted basic instruction * * If there is nothing to highlight at specified address, returns nullptr */ BasicInstruction *BasicInstructionHighlighter::getBasicInstruction(RVA address) { BasicInstructionIt it = biMap.upper_bound(address); if (it == biMap.begin()) { return nullptr; } BasicInstruction *bi = &(--it)->second; if (bi->address <= address && address < bi->address + bi->size) { return bi; } return nullptr; }