fix function inlining with more than one function

This commit is contained in:
Random06457 2023-09-24 21:28:42 +02:00
parent 6508088623
commit c188880f86
3 changed files with 20 additions and 7 deletions

View File

@ -1082,6 +1082,21 @@ void FlowInfo::inlineEZClone(const FlowInfo &inlineflow,const Address &calladdr)
// address, we don't touch unprocessed, addrlist, or visited
}
/// Checks whether the function has already been inlined
/// \param inlinefd is the function being in-lined into \b this flow
/// \param op is CALL instruction at the site of the in-line
bool FlowInfo::testAlreadyInlined(Funcdata *inlinefd, PcodeOp *op)
{
if (inline_recursion->find( inlinefd->getAddress() ) != inline_recursion->end()) {
// This function has already been included with current inlining
inline_head->warning("Could not inline here",op->getAddr());
return false;
}
inline_recursion->insert(inlinefd->getAddress());
return true;
}
/// \brief For in-lining using the \e hard model, make sure some restrictions are met
///
/// - Can only in-line the function once.
@ -1096,12 +1111,6 @@ void FlowInfo::inlineEZClone(const FlowInfo &inlineflow,const Address &calladdr)
bool FlowInfo::testHardInlineRestrictions(Funcdata *inlinefd,PcodeOp *op,Address &retaddr)
{
if (inline_recursion->find( inlinefd->getAddress() ) != inline_recursion->end()) {
// This function has already been included with current inlining
inline_head->warning("Could not inline here",op->getAddr());
return false;
}
if (!inlinefd->getFuncProto().isNoReturn()) {
list<PcodeOp *>::iterator iter = op->getInsertIter();
++iter;
@ -1119,7 +1128,6 @@ bool FlowInfo::testHardInlineRestrictions(Funcdata *inlinefd,PcodeOp *op,Address
data.opMarkStartBasic(nextop);
}
inline_recursion->insert(inlinefd->getAddress());
return true;
}

View File

@ -151,6 +151,7 @@ public:
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);
bool testAlreadyInlined(Funcdata *inlinefd, PcodeOp *op);
bool checkEZModel(void) const; ///< Check if \b this flow matches the EX in-lining model
void injectPcode(void); ///< Perform substitution on any op that requires \e injection
void forwardRecursion(const FlowInfo &op2); ///< Pull in-lining recursion information from another flow

View File

@ -808,6 +808,10 @@ void Funcdata::truncatedFlow(const Funcdata *fd,const FlowInfo *flow)
bool Funcdata::inlineFlow(Funcdata *inlinefd,FlowInfo &flow,PcodeOp *callop)
{
// checks that the function has not already been inlined
if (!flow.testAlreadyInlined(inlinefd, callop))
return false;
inlinefd->getArch()->clearAnalysis(inlinefd);
FlowInfo inlineflow(*inlinefd,inlinefd->obank,inlinefd->bblocks,inlinefd->qlst);
inlinefd->obank.setUniqId( obank.getUniqId() );