From 593d4861851f5137f2834a2fbf34aed3be129bd0 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Mon, 15 Jan 2024 18:55:55 +0100 Subject: [PATCH] fxos: fix basic block duplication bug --- lib/function.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/function.cpp b/lib/function.cpp index 751d406..d7a5152 100644 --- a/lib/function.cpp +++ b/lib/function.cpp @@ -172,7 +172,8 @@ struct Superblock }; // TODO: Unclear what the exit status of the superblock is in case of error -static Superblock exploreSuperblock(Function &function, u32 entry, bool *error) +static Superblock exploreSuperblock(Function &function, + std::vector const &blocks, u32 entry, bool *error) { Superblock sb; sb.addresses.reserve(32); @@ -182,6 +183,7 @@ static Superblock exploreSuperblock(Function &function, u32 entry, bool *error) VirtualSpace &vspace = function.parentBinary().vspace(); bool inDelaySlot = false; bool terminatorFound = false; + bool ranIntoAnotherBlock = false; u32 pc = entry; /* Determine how much space the vspace covers at this address to know if we @@ -195,7 +197,11 @@ static Superblock exploreSuperblock(Function &function, u32 entry, bool *error) return sb; } - while(!terminatorFound || inDelaySlot) { + /* Break after either finding a terminator or finding an instruction + already explored as part of another superblock, unless we are in a delay + slot, because (1) delay slots go with terminators, (2) if another block + starts at the delay slot there will be trouble, so duplicate it. */ + while((!terminatorFound && !ranIntoAnotherBlock) || inDelaySlot) { sb.addresses.push_back(pc); /* Read the next instruction from memory */ @@ -238,6 +244,13 @@ static Superblock exploreSuperblock(Function &function, u32 entry, bool *error) terminatorFound = terminatorFound || opcode.isBlockTerminator(); inDelaySlot = !inDelaySlot && opcode.hasDelaySlot(); pc += 2; + + for(auto const &other: blocks) { + if(other.addresses[0] == pc) { + ranIntoAnotherBlock = true; + break; + } + } } if(*error) @@ -289,7 +302,7 @@ bool Function::exploreFunctionAt(u32 functionAddress) continue; bool error = false; - Superblock sb = exploreSuperblock(*this, entry, &error); + Superblock sb = exploreSuperblock(*this, blocks, entry, &error); if(error) return false;