Merge remote-tracking branch 'origin/GP-4169_ExtractPrimitivesException'

into patch (Closes #6047, Closes #6068)
This commit is contained in:
Ryan Kurtz 2024-01-08 18:35:31 -05:00
commit 2848eb56a5
6 changed files with 55 additions and 44 deletions

View file

@ -130,6 +130,9 @@ public class ParamListStandard implements ParamList {
int[] status, ParameterPieces res)
{
if (dt.isZeroLength()) {
return AssignAction.FAIL;
}
for (ModelRule modelRule : modelRules) {
int responseCode = modelRule.assignAddress(dt, proto, pos, dtManager, status, res);
if (responseCode != AssignAction.FAIL) {
@ -178,8 +181,18 @@ public class ParamListStandard implements ParamList {
}
for (int i = 0; i < proto.intypes.size(); ++i) {
ParameterPieces store = new ParameterPieces();
assignAddress(proto.intypes.get(i), proto, i, dtManager, status, store);
res.add(store);
int resCode = assignAddress(proto.intypes.get(i), proto, i, dtManager, status, store);
if (resCode == AssignAction.FAIL) {
// Do not continue to assign after first failure
++i;
while (i < proto.intypes.size()) {
store = new ParameterPieces(); // Fill out with UNASSIGNED pieces
res.add(store);
++i;
}
return;
}
}
}

View file

@ -70,24 +70,23 @@ public interface DatatypeFilter {
* Extract an ordered list of primitive data-types making up the given data-type
*
* The primitive data-types are passed back in an ArrayList. If the given data-type is already
* primitive, it is passed back as is. Otherwise if it is composite, its components are recursively
* listed. If a filler data-type is provided, it is used to fill holes in structures. If
* a maximum number of extracted primitives is exceeded, or if no filler is provided and a hole
* is encountered, or if a non-primitive non-composite data-type is encountered, false is returned.
* primitive, it is passed back as is. Otherwise if it is composite, its components are
* recursively listed. If a maximum number of extracted primitives is exceeded, or if the
* primitives are not properly aligned, or if a non-primitive non-composite data-type is
* encountered, false is returned.
* @param dt is the given data-type to extract primitives from
* @param max is the maximum number of primitives to extract before giving up
* @param filler is the data-type to use as filler (or null)
* @param res will hold the list of primitives
* @return true if all primitives were extracted
*/
public static boolean extractPrimitives(DataType dt, int max, DataType filler,
ArrayList<DataType> res) {
public static boolean extractPrimitives(DataType dt, int max, ArrayList<DataType> res) {
if (dt instanceof TypeDef) {
dt = ((TypeDef) dt).getBaseDataType();
}
int metaType = PcodeDataTypeManager.getMetatype(dt);
switch (metaType) {
case PcodeDataTypeManager.TYPE_UNKNOWN:
return false; // Do not consider undefined data-types as primitive
case PcodeDataTypeManager.TYPE_INT:
case PcodeDataTypeManager.TYPE_UINT:
case PcodeDataTypeManager.TYPE_BOOL:
@ -104,7 +103,7 @@ public interface DatatypeFilter {
int numEls = ((Array) dt).getNumElements();
DataType base = ((Array) dt).getDataType();
for (int i = 0; i < numEls; ++i) {
if (!extractPrimitives(base, max, filler, res)) {
if (!extractPrimitives(base, max, res)) {
return false;
}
}
@ -116,26 +115,26 @@ public interface DatatypeFilter {
return false;
}
Structure structPtr = (Structure) dt;
boolean isPacked = structPtr.isPackingEnabled();
int curOff = 0;
DataTypeComponent[] components = structPtr.getDefinedComponents();
for (DataTypeComponent component : components) {
int nextOff = component.getOffset();
if (nextOff > curOff) {
if (filler == null) {
DataType compDT = component.getDataType();
if (!isPacked) {
int nextOff = component.getOffset();
int align = dt.getAlignment();
int rem = curOff % align;
if (rem != 0) {
curOff += (align - rem);
}
if (curOff != nextOff) {
return false;
}
while (curOff < nextOff) {
if (res.size() >= max) {
return false;
}
res.add(filler);
curOff += filler.getLength();
}
curOff = nextOff + compDT.getAlignedLength();
}
if (!extractPrimitives(component.getDataType(), max, filler, res)) {
if (!extractPrimitives(compDT, max, res)) {
return false;
}
curOff += component.getDataType().getLength();
}
return true;
}

View file

@ -68,7 +68,7 @@ public class HomogeneousAggregate extends SizeRestrictedFilter {
return false;
}
ArrayList<DataType> res = new ArrayList<>();
if (!DatatypeFilter.extractPrimitives(dt, MAX_PRIMITIVES, null, res)) {
if (!DatatypeFilter.extractPrimitives(dt, MAX_PRIMITIVES, res) || res.isEmpty()) {
return false;
}
DataType base = res.get(0);

View file

@ -78,7 +78,7 @@ public class MultiMemberAssign extends AssignAction {
ArrayList<Varnode> pieces = new ArrayList<>();
ParameterPieces param = new ParameterPieces();
ArrayList<DataType> primitives = new ArrayList<>();
if (!DatatypeFilter.extractPrimitives(dt, 16, null, primitives)) {
if (!DatatypeFilter.extractPrimitives(dt, 16, primitives) || primitives.isEmpty()) {
return FAIL;
}
for (int i = 0; i < primitives.size(); ++i) {