Merge remote-tracking branch 'origin/GP-5832_InlineOpTarget' into patch

(Closes #7383)
This commit is contained in:
Ryan Kurtz 2025-07-18 15:19:04 -04:00
commit db6b52b10f
5 changed files with 56 additions and 8 deletions

View file

@ -43,6 +43,7 @@ src/decompile/datatests/impliedfield.xml||GHIDRA||||END|
src/decompile/datatests/indproto.xml||GHIDRA||||END| src/decompile/datatests/indproto.xml||GHIDRA||||END|
src/decompile/datatests/injectoverride.xml||GHIDRA||||END| src/decompile/datatests/injectoverride.xml||GHIDRA||||END|
src/decompile/datatests/inline.xml||GHIDRA||||END| src/decompile/datatests/inline.xml||GHIDRA||||END|
src/decompile/datatests/inlinetarget.xml||GHIDRA||||END|
src/decompile/datatests/longdouble.xml||GHIDRA||||END| src/decompile/datatests/longdouble.xml||GHIDRA||||END|
src/decompile/datatests/loopcomment.xml||GHIDRA||||END| src/decompile/datatests/loopcomment.xml||GHIDRA||||END|
src/decompile/datatests/lzcount.xml||GHIDRA||||END| src/decompile/datatests/lzcount.xml||GHIDRA||||END|

View file

@ -198,6 +198,19 @@ PcodeOp *FlowInfo::branchTarget(PcodeOp *op) const
return target(addr); // Otherwise a normal address target return target(addr); // Otherwise a normal address target
} }
/// Replace any reference to the op being inlined with the first op of the inlined sequence.
/// \param oldOp is the p-code op being inlined
/// \param newOp is the first p-code op in the inlined sequence
void FlowInfo::updateTarget(PcodeOp *oldOp,PcodeOp *newOp)
{
map<Address,VisitStat>::iterator viter = visited.find(oldOp->getAddr());
if (viter != visited.end()) { // Check if -oldOp- is a possible branch target
if ((*viter).second.seqnum == oldOp->getSeqNum()) // (if injection op is the first op for its address)
(*viter).second.seqnum = newOp->getSeqNum(); // change the seqnum to the newOp
}
}
/// Check to see if the new target has been seen before. Otherwise /// Check to see if the new target has been seen before. Otherwise
/// add it to the list of addresses that need to be processed. /// add it to the list of addresses that need to be processed.
/// Also check range bounds and update basic block information. /// Also check range bounds and update basic block information.
@ -1189,11 +1202,7 @@ void FlowInfo::doInjection(InjectPayload *payload,InjectContext &icontext,PcodeO
obank.markIncidentalCopy(firstop, lastop); obank.markIncidentalCopy(firstop, lastop);
obank.moveSequenceDead(firstop,lastop,op); // Move the injection to right after the call obank.moveSequenceDead(firstop,lastop,op); // Move the injection to right after the call
map<Address,VisitStat>::iterator viter = visited.find(op->getAddr()); updateTarget(op,firstop); // Replace -op- with -firstop- in the target map
if (viter != visited.end()) { // Check if -op- is a possible branch target
if ((*viter).second.seqnum == op->getSeqNum()) // (if injection op is the first op for its address)
(*viter).second.seqnum = firstop->getSeqNum(); // change the seqnum to the first injected op
}
// Get rid of the original call // Get rid of the original call
data.opDestroyRaw(op); data.opDestroyRaw(op);
} }

View file

@ -148,6 +148,7 @@ public:
void clearFlags(uint4 val) { flags &= ~val; } ///< Disable a specific option void clearFlags(uint4 val) { flags &= ~val; } ///< Disable a specific option
PcodeOp *target(const Address &addr) const; ///< Return first p-code op for instruction at given address PcodeOp *target(const Address &addr) const; ///< Return first p-code op for instruction at given address
PcodeOp *branchTarget(PcodeOp *op) const; ///< Find the target referred to by a given BRANCH or CBRANCH PcodeOp *branchTarget(PcodeOp *op) const; ///< Find the target referred to by a given BRANCH or CBRANCH
void updateTarget(PcodeOp *oldOp,PcodeOp *newOp); ///< Update the branch target for an inlined p-code op
void generateOps(void); ///< Generate raw control-flow from the function's base address void generateOps(void); ///< Generate raw control-flow from the function's base address
void generateBlocks(void); ///< Generate basic blocks from the raw control-flow void generateBlocks(void); ///< Generate basic blocks from the raw control-flow
bool testHardInlineRestrictions(Funcdata *inlinefd,PcodeOp *op,Address &retaddr); bool testHardInlineRestrictions(Funcdata *inlinefd,PcodeOp *op,Address &retaddr);

View file

@ -880,8 +880,10 @@ int4 Funcdata::inlineFlow(Funcdata *inlinefd,FlowInfo &flow,PcodeOp *callop)
--oiter; --oiter;
PcodeOp *lastop = *oiter; PcodeOp *lastop = *oiter;
obank.moveSequenceDead(firstop,lastop,callop); // Move cloned sequence to right after callop obank.moveSequenceDead(firstop,lastop,callop); // Move cloned sequence to right after callop
if (callop->isBlockStart()) if (callop->isBlockStart()) {
firstop->setFlag(PcodeOp::startbasic); // First op of inline inherits callop's startbasic flag firstop->setFlag(PcodeOp::startbasic); // First op of inline inherits callop's startbasic flag
flow.updateTarget(callop, firstop);
}
else else
firstop->clearFlag(PcodeOp::startbasic); firstop->clearFlag(PcodeOp::startbasic);
} }

View file

@ -0,0 +1,35 @@
<decompilertest>
<binaryimage arch="PowerPC:BE:32:default:default">
<!--
Function with a BRANCH, overridden as a CALL, to an inlined function.
The BRANCH instruction is also a fallthru target.
-->
<bytechunk space="ram" offset="0x100003fc" readonly="true">
3821fff8
95e10000960100044e800020
</bytechunk>
<bytechunk space="ram" offset="0x10000410" readonly="true">
85e1000086010004382100087c0803a6
4e8000207c0802a64bffffd539e00000
2c0f000a4080001c1e0f00047e100214
7e0903a64e80042139ef00014280ffe4
4280ffc0
</bytechunk>
<symbol space="ram" offset="0x100003fc" name="prologue"/>
<symbol space="ram" offset="0x10000410" name="epilogue"/>
</binaryimage>
<script>
<com>option inline prologue</com>
<com>option inline epilogue</com>
<com>map fun r0x10000424 main</com>
<com>override flow r0x10000450 callreturn</com>
<com>lo fu main</com>
<com>decompile</com>
<com>print C</com>
<com>quit</com>
</script>
<stringmatch name="Inline target #1" min="1" max="1">Inlined function: prologue</stringmatch>
<stringmatch name="Inline target #2" min="1" max="1">Inlined function: epilogue</stringmatch>
<stringmatch name="Inline target #3" min="0" max="0">Could not find op at target</stringmatch>
<stringmatch name="Inline target #4" min="1" max="1">for \(iVar1 = 0; iVar1 &lt; 10; iVar1 = iVar1 \+ 1\)</stringmatch>
</decompilertest>