Default for maximum number of instructions

This commit is contained in:
caheckman 2020-03-27 15:55:39 -04:00
parent d9bd93c36b
commit a8dcc7266b
8 changed files with 34 additions and 11 deletions

View file

@ -16,6 +16,7 @@
// Set up decompiler for specific architectures // Set up decompiler for specific architectures
#include "coreaction.hh" #include "coreaction.hh"
#include "flow.hh"
#ifdef CPUI_RULECOMPILE #ifdef CPUI_RULECOMPILE
#include "rulecompile.hh" #include "rulecompile.hh"
#endif #endif
@ -1253,7 +1254,8 @@ void Architecture::resetDefaultsInternal(void)
max_implied_ref = 2; // 2 is best, in specific cases a higher number might be good max_implied_ref = 2; // 2 is best, in specific cases a higher number might be good
max_term_duplication = 2; // 2 and 3 (4) are reasonable max_term_duplication = 2; // 2 and 3 (4) are reasonable
max_basetype_size = 10; // Needs to be 8 or bigger max_basetype_size = 10; // Needs to be 8 or bigger
flowoptions = 0; flowoptions = FlowInfo::error_toomanyinstructions;
max_instructions = 100000;
infer_pointers = true; infer_pointers = true;
readonlypropagate = false; readonlypropagate = false;
alias_block_level = 2; // Block structs and arrays by default alias_block_level = 2; // Block structs and arrays by default

View file

@ -130,6 +130,7 @@ public:
vector<AddrSpace *> inferPtrSpaces; ///< Set of address spaces in which a pointer constant is inferable vector<AddrSpace *> inferPtrSpaces; ///< Set of address spaces in which a pointer constant is inferable
int4 funcptr_align; ///< How many bits of alignment a function ptr has int4 funcptr_align; ///< How many bits of alignment a function ptr has
uint4 flowoptions; ///< options passed to flow following engine uint4 flowoptions; ///< options passed to flow following engine
uint4 max_instructions; ///< Maximum instructions that can be processed in one function
int4 alias_block_level; ///< Aliases blocked by 0=none, 1=struct, 2=array, 3=all int4 alias_block_level; ///< Aliases blocked by 0=none, 1=struct, 2=array, 3=all
vector<Rule *> extra_pool_rules; ///< Extra rules that go in the main pool (cpu specific, experimental) vector<Rule *> extra_pool_rules; ///< Extra rules that go in the main pool (cpu specific, experimental)

View file

@ -136,7 +136,7 @@ void Funcdata::startProcessing(void)
warningHeader("This is an inlined function"); warningHeader("This is an inlined function");
Address baddr(baseaddr.getSpace(),0); Address baddr(baseaddr.getSpace(),0);
Address eaddr(baseaddr.getSpace(),~((uintb)0)); Address eaddr(baseaddr.getSpace(),~((uintb)0));
followFlow(baddr,eaddr,0); followFlow(baddr,eaddr);
structureReset(); structureReset();
sortCallSpecs(); // Must come after structure reset sortCallSpecs(); // Must come after structure reset
heritage.buildInfoList(); heritage.buildInfoList();

View file

@ -160,7 +160,7 @@ public:
void startCleanUp(void) { clean_up_index = vbank.getCreateIndex(); } ///< Start \e clean-up phase void startCleanUp(void) { clean_up_index = vbank.getCreateIndex(); } ///< Start \e clean-up phase
uint4 getCleanUpIndex(void) const { return clean_up_index; } ///< Get creation index at the start of \b clean-up phase uint4 getCleanUpIndex(void) const { return clean_up_index; } ///< Get creation index at the start of \b clean-up phase
void followFlow(const Address &baddr,const Address &eadddr,uint4 insn_max); void followFlow(const Address &baddr,const Address &eadddr);
void truncatedFlow(const Funcdata *fd,const FlowInfo *flow); void truncatedFlow(const Funcdata *fd,const FlowInfo *flow);
bool inlineFlow(Funcdata *inlinefd,FlowInfo &flow,PcodeOp *callop); bool inlineFlow(Funcdata *inlinefd,FlowInfo &flow,PcodeOp *callop);
void overrideFlow(const Address &addr,uint4 type); void overrideFlow(const Address &addr,uint4 type);

View file

@ -700,12 +700,10 @@ void Funcdata::markIndirectCreation(PcodeOp *indop,bool possibleOutput)
/// \brief Generate raw p-code for the function /// \brief Generate raw p-code for the function
/// ///
/// Follow flow from the entry point generating PcodeOps for each instruction encountered. /// Follow flow from the entry point generating PcodeOps for each instruction encountered.
/// The caller can provide a bounding range that constrains where control can flow to /// The caller can provide a bounding range that constrains where control can flow to.
/// and can also provide a maximum number of instructions that will be followed.
/// \param baddr is the beginning of the constraining range /// \param baddr is the beginning of the constraining range
/// \param eaddr is the end of the constraining range /// \param eaddr is the end of the constraining range
/// \param insn_max is the maximum number of instructions to follow void Funcdata::followFlow(const Address &baddr,const Address &eaddr)
void Funcdata::followFlow(const Address &baddr,const Address &eaddr,uint4 insn_max)
{ {
if (!obank.empty()) { if (!obank.empty()) {
@ -719,8 +717,7 @@ void Funcdata::followFlow(const Address &baddr,const Address &eaddr,uint4 insn_m
FlowInfo flow(*this,obank,bblocks,qlst); FlowInfo flow(*this,obank,bblocks,qlst);
flow.setRange(baddr,eaddr); flow.setRange(baddr,eaddr);
flow.setFlags(fl); flow.setFlags(fl);
if (insn_max != 0) flow.setMaximumInstructions(glb->max_instructions);
flow.setMaximumInstructions(insn_max);
flow.generateOps(); flow.generateOps();
size = flow.getSize(); size = flow.getSize();
// Cannot keep track of function sizes in general because of non-contiguous functions // Cannot keep track of function sizes in general because of non-contiguous functions

View file

@ -360,10 +360,10 @@ static void IfcFollowFlow(ostream &s,IfaceDecompData *dcp,const Address &offset,
if (size==0) { if (size==0) {
Address baddr(dcp->fd->getAddress().getSpace(),0); Address baddr(dcp->fd->getAddress().getSpace(),0);
Address eaddr(dcp->fd->getAddress().getSpace(),dcp->fd->getAddress().getSpace()->getHighest()); Address eaddr(dcp->fd->getAddress().getSpace(),dcp->fd->getAddress().getSpace()->getHighest());
dcp->fd->followFlow(baddr,eaddr,0); dcp->fd->followFlow(baddr,eaddr);
} }
else else
dcp->fd->followFlow(offset,offset+size,0); dcp->fd->followFlow(offset,offset+size);
s << "Function " << dcp->fd->getName() << ": "; s << "Function " << dcp->fd->getName() << ": ";
dcp->fd->getAddress().printRaw(s); dcp->fd->getAddress().printRaw(s);
s << endl; s << endl;

View file

@ -80,6 +80,7 @@ OptionDatabase::OptionDatabase(Architecture *g)
registerOption(new OptionJumpLoad()); registerOption(new OptionJumpLoad());
registerOption(new OptionToggleRule()); registerOption(new OptionToggleRule());
registerOption(new OptionAliasBlock()); registerOption(new OptionAliasBlock());
registerOption(new OptionMaxInstruction());
} }
OptionDatabase::~OptionDatabase(void) OptionDatabase::~OptionDatabase(void)
@ -816,3 +817,19 @@ string OptionAliasBlock::apply(Architecture *glb,const string &p1,const string &
return "Alias block level unchanged"; return "Alias block level unchanged";
return "Alias block level set to " + p1; return "Alias block level set to " + p1;
} }
string OptionMaxInstruction::apply(Architecture *glb,const string &p1,const string &p2,const string &p3) const
{
if (p1.size() == 0)
throw ParseError("Must specify number of instructions");
int4 newMax = -1;
istringstream s1(p1);
s1.unsetf(ios::dec | ios::hex | ios::oct); // Let user specify base
s1 >> newMax;
if (newMax < 0)
throw ParseError("Bad maxinstruction parameter");
glb->max_instructions = newMax;
return "Maximum instructions per function set";
}

View file

@ -264,4 +264,10 @@ public:
virtual string apply(Architecture *glb,const string &p1,const string &p2,const string &p3) const; virtual string apply(Architecture *glb,const string &p1,const string &p2,const string &p3) const;
}; };
class OptionMaxInstruction : public ArchOption {
public:
OptionMaxInstruction(void) { name="maxinstruction"; } ///< Constructor
virtual string apply(Architecture *glb,const string &p1,const string &p2,const string &p3) const;
};
#endif #endif