bugfixes, overlapping lanerecords check

This commit is contained in:
caheckman 2019-10-18 14:01:53 -04:00
parent 04d28bcc4e
commit ce0ab31576
7 changed files with 56 additions and 13 deletions

View file

@ -817,16 +817,33 @@ void Architecture::parseIncidentalCopy(const Element *el)
void Architecture::parseLaneSizes(const Element *el) void Architecture::parseLaneSizes(const Element *el)
{ {
const List &list(el->getChildren()); const List &childList(el->getChildren());
List::const_iterator iter; List::const_iterator iter;
LanedRegister lanedRegister; // Only allocate once LanedRegister lanedRegister; // Only allocate once
for(iter=list.begin();iter!=list.end();++iter) { for(iter=childList.begin();iter!=childList.end();++iter) {
if (lanedRegister.restoreXml(*iter, this)) { if (lanedRegister.restoreXml(*iter, this)) {
lanerecords.push_back(lanedRegister); lanerecords.push_back(lanedRegister);
} }
} }
if (lanerecords.empty()) return;
lanerecords.sort(); lanerecords.sort();
// Dedup records that are contained by (the following) records
list<LanedRegister>::const_iterator viter = lanerecords.begin();
list<LanedRegister>::const_iterator nextiter = viter;
++nextiter;
while(nextiter != lanerecords.end()) {
if ((*viter).contains(*nextiter)) {
lanerecords.erase(nextiter);
nextiter = viter;
++nextiter;
}
else {
++viter;
++nextiter;
}
}
} }
/// Create a stack space and a stack-pointer register from this \<stackpointer> element /// Create a stack space and a stack-pointer register from this \<stackpointer> element

View file

@ -514,8 +514,8 @@ bool ActionLaneDivide::processVarnode(Funcdata &data,Varnode *vn,const LanedRegi
++iter; ++iter;
if (op->code() != CPUI_SUBPIECE) continue; if (op->code() != CPUI_SUBPIECE) continue;
int4 curSize = op->getOut()->getSize(); int4 curSize = op->getOut()->getSize();
if (lanedRegister.contains(curSize)) { if (lanedRegister.allowedLane(curSize)) {
if (checkedLanes.contains(curSize)) continue; if (checkedLanes.allowedLane(curSize)) continue;
checkedLanes.addSize(curSize); // Only check this scheme once checkedLanes.addSize(curSize); // Only check this scheme once
LaneDescription description(lanedRegister.getStorage().size,curSize); // Lane scheme dictated by curSize LaneDescription description(lanedRegister.getStorage().size,curSize); // Lane scheme dictated by curSize
int4 bytePos = (int4)(lanedRegister.getStorage().offset - vn->getOffset()); int4 bytePos = (int4)(lanedRegister.getStorage().offset - vn->getOffset());
@ -552,11 +552,11 @@ void ActionLaneDivide::processLane(Funcdata &data,const LanedRegister &lanedRegi
++iter; ++iter;
if (lastAddress < vn->getAddr()) if (lastAddress < vn->getAddr())
break; break;
if (vn->getSize() <= 8) // Varnode not big enough to be vector register
continue;
int4 diff = (int4)(vn->getOffset() - startAddress.getOffset()); int4 diff = (int4)(vn->getOffset() - startAddress.getOffset());
if (diff + vn->getSize() > fullSize) // Must be contained by full register if (diff + vn->getSize() > fullSize) // Must be contained by full register
continue; continue;
if (diff != 0 && diff != fullSize/2) // Must be all or half of full register
continue;
if (processVarnode(data,vn,lanedRegister)) { if (processVarnode(data,vn,lanedRegister)) {
// If changes were made, iterator may no longer be valid, generate a new one // If changes were made, iterator may no longer be valid, generate a new one
iter = data.beginLoc(startAddress); iter = data.beginLoc(startAddress);

View file

@ -42,3 +42,14 @@ void VarnodeData::restoreXml(const Element *el,const AddrSpaceManager *manage)
} }
} }
/// Return \b true, if \b this, as an address range, contains the other address range
/// \param op2 is the other VarnodeData to test for containment
/// \return \b true if \b this contains the other
bool VarnodeData::contains(const VarnodeData &op2) const
{
if (space != op2.space) return false;
if (op2.offset < offset) return false;
if ((offset + (size-1)) < (op2.offset + (op2.size-1))) return false;
return true;
}

View file

@ -43,6 +43,9 @@ struct VarnodeData {
/// Recover this object from an XML tag /// Recover this object from an XML tag
void restoreXml(const Element *el,const AddrSpaceManager *manage); void restoreXml(const Element *el,const AddrSpaceManager *manage);
/// Does \b this container another given VarnodeData
bool contains(const VarnodeData &op2) const;
}; };
/// VarnodeData can be sorted in terms of the space its in /// VarnodeData can be sorted in terms of the space its in

View file

@ -1964,9 +1964,8 @@ void LaneDivide::buildUnaryOp(OpCode opc,PcodeOp *op,TransformVar *inVars,Transf
{ {
for(int4 i=0;i<numLanes;++i) { for(int4 i=0;i<numLanes;++i) {
TransformVar *outVn = outVars + i;
TransformOp *rop = newOpReplace(1, opc, op); TransformOp *rop = newOpReplace(1, opc, op);
opSetOutput(rop, outVn); opSetOutput(rop, outVars + i);
opSetInput(rop,inVars + i,0); opSetInput(rop,inVars + i,0);
} }
} }
@ -2203,7 +2202,7 @@ bool LaneDivide::traceForward(TransformVar *rvn,int4 numLanes,int4 skipLanes)
return false; return false;
if (outLanes == 1) { if (outLanes == 1) {
TransformOp *rop = newPreexistingOp(1, CPUI_COPY, op); TransformOp *rop = newPreexistingOp(1, CPUI_COPY, op);
opSetInput(rop,rvn + (outLanes-skipLanes), 0); opSetInput(rop,rvn + (outSkip-skipLanes), 0);
} }
else { else {
TransformVar *outRvn = setReplacement(outvn,outLanes,outSkip); TransformVar *outRvn = setReplacement(outvn,outLanes,outSkip);

View file

@ -102,14 +102,14 @@ int4 LaneDescription::getBoundary(int4 bytePos) const
return lanePosition.size(); return lanePosition.size();
int4 min = 0; int4 min = 0;
int4 max = lanePosition.size() - 1; int4 max = lanePosition.size() - 1;
while(min < max) { while(min <= max) {
int4 index = (min + max) / 2; int4 index = (min + max) / 2;
int4 pos = lanePosition[index]; int4 pos = lanePosition[index];
if (pos == bytePos) return index; if (pos == bytePos) return index;
if (pos < bytePos) if (pos < bytePos)
min = pos + 1; min = index + 1;
else else
max = pos - 1; max = index - 1;
} }
return -1; return -1;
} }
@ -304,6 +304,18 @@ bool LanedRegister::restoreXml(const Element *el,const AddrSpaceManager *manage)
return true; return true;
} }
/// In order to return \b true, the storage for \b this must contain the storage for the other
/// LanedRegister, and every lane scheme of the other LanedRegister must also be a lane scheme
/// for \b this.
/// \param op2 is the other LanedRegister to check for containment
/// \return \b true if \b this contains the other register
bool LanedRegister::contains(const LanedRegister &op2) const
{
if (!storage.contains(op2.storage)) return false;
return ((sizeBitMask & op2.sizeBitMask) == op2.sizeBitMask); // Check for containment of lane size sets
}
TransformManager::~TransformManager(void) TransformManager::~TransformManager(void)
{ {

View file

@ -93,7 +93,8 @@ public:
bool restoreXml(const Element *el,const AddrSpaceManager *manage); ///< Restore object from XML stream bool restoreXml(const Element *el,const AddrSpaceManager *manage); ///< Restore object from XML stream
const VarnodeData &getStorage(void) const { return storage; } ///< Get VarnodeData for storage const VarnodeData &getStorage(void) const { return storage; } ///< Get VarnodeData for storage
void addSize(int4 size) { sizeBitMask |= ((uint4)1 << size); } ///< Add a new \e size to the allowed list void addSize(int4 size) { sizeBitMask |= ((uint4)1 << size); } ///< Add a new \e size to the allowed list
bool contains(int4 size) const { return (((sizeBitMask >> size) & 1) != 0); } ///< Is \e size among the allowed lane sizes bool allowedLane(int4 size) const { return (((sizeBitMask >> size) & 1) != 0); } ///< Is \e size among the allowed lane sizes
bool contains(const LanedRegister &op2) const; ///< Does \b this contain the given register and its possible lanes
bool operator<(const LanedRegister &op2) const { return (storage < op2.storage); } ///< Compare based on VarnodeData bool operator<(const LanedRegister &op2) const { return (storage < op2.storage); } ///< Compare based on VarnodeData
}; };