mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
bugfixes, overlapping lanerecords check
This commit is contained in:
parent
04d28bcc4e
commit
ce0ab31576
7 changed files with 56 additions and 13 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue