mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-01-09 14:08:03 -05:00
Merge remote-tracking branch 'origin/GP-3834_JumptableByte'
(Closes #5494)
This commit is contained in:
@@ -1030,6 +1030,21 @@ PcodeOp *PathMeld::getEarliestOp(int4 pos) const
|
||||
return (PcodeOp *)0;
|
||||
}
|
||||
|
||||
/// Search for a Varnode in the common path, prior to the given point, defined by a LOAD operation.
|
||||
/// \param i is the given point in the path
|
||||
/// \return \b true if a LOAD is present
|
||||
bool PathMeld::isLoadInPath(int4 i) const
|
||||
|
||||
{
|
||||
while(i > 0) {
|
||||
i -= 1;
|
||||
Varnode *vn = commonVn[i];
|
||||
if (!vn->isWritten()) continue;
|
||||
if (vn->getDef()->code() == CPUI_LOAD) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Analyze CBRANCHs leading up to the given basic-block as a potential switch \e guard.
|
||||
///
|
||||
/// In general there is only one path to the switch, and the given basic-block will
|
||||
@@ -1180,8 +1195,10 @@ void JumpBasic::findSmallestNormal(uint4 matchsize)
|
||||
calcRange(pathMeld.getVarnode(i),rng);
|
||||
sz = rng.getSize();
|
||||
if (sz < maxsize) {
|
||||
// Don't let a 1-byte switch variable get thru without a guard
|
||||
if ((sz != 256)||(pathMeld.getVarnode(i)->getSize()!=1)) {
|
||||
// Don't accept a 1-byte switch variable unless there is an explicit guard
|
||||
// or a table lookup between the byte and the indirect jump.
|
||||
// "goto *(#const + byteVar)" should not be interpreted as 256 case switch
|
||||
if (sz != 256 || pathMeld.getVarnode(i)->getSize()!=1 || pathMeld.isLoadInPath(i)) {
|
||||
varnodeIndex = i;
|
||||
maxsize = sz;
|
||||
jrange->setRange(rng);
|
||||
|
||||
@@ -98,6 +98,7 @@ public:
|
||||
Varnode *getOpParent(int4 i) const { return commonVn[ opMeld[i].rootVn ]; } ///< Get the split-point for the i-th PcodeOp
|
||||
PcodeOp *getOp(int4 i) const { return opMeld[i].op; } ///< Get the i-th PcodeOp
|
||||
PcodeOp *getEarliestOp(int4 pos) const; ///< Find \e earliest PcodeOp that has a specific common Varnode as input
|
||||
bool isLoadInPath(int4 i) const; ///< Return \b true if a LOAD exists in the common path
|
||||
bool empty(void) const { return commonVn.empty(); } ///< Return \b true if \b this container holds no paths
|
||||
};
|
||||
|
||||
|
||||
@@ -4630,6 +4630,9 @@ void TypeFactory::decodeAlignmentMap(Decoder &decoder)
|
||||
alignMap[sz] = val;
|
||||
decoder.closeElement(mapId);
|
||||
}
|
||||
if (alignMap.empty())
|
||||
throw LowlevelError("Alignment map empty");
|
||||
alignMap[0] = 1;
|
||||
int4 curAlign = 1;
|
||||
for(int4 sz=1;sz < alignMap.size();++sz) {
|
||||
int4 tmpAlign = alignMap[sz];
|
||||
@@ -4644,7 +4647,7 @@ void TypeFactory::decodeAlignmentMap(Decoder &decoder)
|
||||
void TypeFactory::setDefaultAlignmentMap(void)
|
||||
|
||||
{
|
||||
alignMap.resize(9,0);
|
||||
alignMap.resize(9,1);
|
||||
alignMap[1] = 1;
|
||||
alignMap[2] = 2;
|
||||
alignMap[3] = 2;
|
||||
|
||||
Reference in New Issue
Block a user