mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-5832 Update inline target op when inlining a subfunction
This commit is contained in:
parent
0bd8870da3
commit
80d66023a9
5 changed files with 56 additions and 8 deletions
|
@ -198,6 +198,19 @@ PcodeOp *FlowInfo::branchTarget(PcodeOp *op) const
|
|||
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
|
||||
/// add it to the list of addresses that need to be processed.
|
||||
/// 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.moveSequenceDead(firstop,lastop,op); // Move the injection to right after the call
|
||||
|
||||
map<Address,VisitStat>::iterator viter = visited.find(op->getAddr());
|
||||
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
|
||||
}
|
||||
updateTarget(op,firstop); // Replace -op- with -firstop- in the target map
|
||||
// Get rid of the original call
|
||||
data.opDestroyRaw(op);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -148,6 +148,7 @@ public:
|
|||
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 *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 generateBlocks(void); ///< Generate basic blocks from the raw control-flow
|
||||
bool testHardInlineRestrictions(Funcdata *inlinefd,PcodeOp *op,Address &retaddr);
|
||||
|
|
|
@ -880,8 +880,10 @@ int4 Funcdata::inlineFlow(Funcdata *inlinefd,FlowInfo &flow,PcodeOp *callop)
|
|||
--oiter;
|
||||
PcodeOp *lastop = *oiter;
|
||||
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
|
||||
flow.updateTarget(callop, firstop);
|
||||
}
|
||||
else
|
||||
firstop->clearFlag(PcodeOp::startbasic);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue