Merge remote-tracking branch 'origin/GP-5367_ghintern_aggregate_filter--SQUASHED'

This commit is contained in:
Ryan Kurtz 2025-07-14 14:06:30 -04:00
commit 5acdc3b522
7 changed files with 67 additions and 20 deletions

View file

@ -1254,7 +1254,8 @@ AttributeId ATTRIB_WORDSIZE = AttributeId("wordsize",26);
AttributeId ATTRIB_STORAGE = AttributeId("storage",149); AttributeId ATTRIB_STORAGE = AttributeId("storage",149);
AttributeId ATTRIB_STACKSPILL = AttributeId("stackspill",150); AttributeId ATTRIB_STACKSPILL = AttributeId("stackspill",150);
AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",152); // Number serves as next open index AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",154); // Number serves as next open index
ElementId ELEM_DATA = ElementId("data",1); ElementId ELEM_DATA = ElementId("data",1);
ElementId ELEM_INPUT = ElementId("input",2); ElementId ELEM_INPUT = ElementId("input",2);

View file

@ -19,6 +19,7 @@
namespace ghidra { namespace ghidra {
AttributeId ATTRIB_SIZES = AttributeId("sizes",151); AttributeId ATTRIB_SIZES = AttributeId("sizes",151);
AttributeId ATTRIB_MAX_PRIMITIVES = AttributeId("maxprimitives", 153);
ElementId ELEM_DATATYPE = ElementId("datatype",273); ElementId ELEM_DATATYPE = ElementId("datatype",273);
ElementId ELEM_CONSUME = ElementId("consume",274); ElementId ELEM_CONSUME = ElementId("consume",274);
@ -224,7 +225,7 @@ bool PrimitiveExtractor::extract(Datatype *dt,int4 max,int4 offset)
if (!extract(compDt,max,curOff)) if (!extract(compDt,max,curOff))
return false; return false;
expectedOff = curOff + compDt->getAlignSize(); expectedOff = curOff + compDt->getAlignSize();
} }
return true; return true;
} }
@ -385,11 +386,11 @@ HomogeneousAggregate::HomogeneousAggregate(type_metatype meta)
{ {
metaType = meta; metaType = meta;
maxPrimitives = 2; maxPrimitives = 4;
} }
HomogeneousAggregate::HomogeneousAggregate(type_metatype meta,int4 maxPrim,int4 min,int4 max) HomogeneousAggregate::HomogeneousAggregate(type_metatype meta,int4 maxPrim,int4 minSize,int4 maxSize)
: SizeRestrictedFilter(min,max) : SizeRestrictedFilter(minSize, maxSize)
{ {
metaType = meta; metaType = meta;
maxPrimitives = maxPrim; maxPrimitives = maxPrim;
@ -408,7 +409,7 @@ bool HomogeneousAggregate::filter(Datatype *dt) const
type_metatype meta = dt->getMetatype(); type_metatype meta = dt->getMetatype();
if (meta != TYPE_ARRAY && meta != TYPE_STRUCT) if (meta != TYPE_ARRAY && meta != TYPE_STRUCT)
return false; return false;
PrimitiveExtractor primitives(dt,true,0,4); PrimitiveExtractor primitives(dt,true,0,maxPrimitives);
if (!primitives.isValid() || primitives.size() == 0 || primitives.containsUnknown() if (!primitives.isValid() || primitives.size() == 0 || primitives.containsUnknown()
|| !primitives.isAligned() || primitives.containsHoles()) || !primitives.isAligned() || primitives.containsHoles())
return false; return false;
@ -422,6 +423,21 @@ bool HomogeneousAggregate::filter(Datatype *dt) const
return true; return true;
} }
void HomogeneousAggregate::decode(Decoder &decoder)
{
SizeRestrictedFilter::decode(decoder);
decoder.rewindAttributes();
for(;;) {
uint4 attribId = decoder.getNextAttributeId();
if (attribId == 0) break;
if (attribId == ATTRIB_MAX_PRIMITIVES) {
uint4 xmlMaxPrim = decoder.readUnsignedInteger();
if (xmlMaxPrim > 0) maxPrimitives = xmlMaxPrim;
}
}
}
/// If the next element is a qualifier filter, decode it from the stream and return it. /// If the next element is a qualifier filter, decode it from the stream and return it.
/// Otherwise return null /// Otherwise return null
/// \param decoder is the given stream decoder /// \param decoder is the given stream decoder

View file

@ -29,6 +29,7 @@ class ParamEntry;
class ParamActive; class ParamActive;
extern AttributeId ATTRIB_SIZES; ///< Marshaling attribute "sizes" extern AttributeId ATTRIB_SIZES; ///< Marshaling attribute "sizes"
extern AttributeId ATTRIB_MAX_PRIMITIVES; ///< Marshaling attribute "maxprimitives"
extern ElementId ELEM_DATATYPE; ///< Marshaling element \<datatype> extern ElementId ELEM_DATATYPE; ///< Marshaling element \<datatype>
extern ElementId ELEM_CONSUME; ///< Marshaling element \<consume> extern ElementId ELEM_CONSUME; ///< Marshaling element \<consume>
@ -151,10 +152,11 @@ class HomogeneousAggregate : public SizeRestrictedFilter {
int4 maxPrimitives; ///< Maximum number of primitives in the aggregate int4 maxPrimitives; ///< Maximum number of primitives in the aggregate
public: public:
HomogeneousAggregate(type_metatype meta); ///< Constructor for use with decode() HomogeneousAggregate(type_metatype meta); ///< Constructor for use with decode()
HomogeneousAggregate(type_metatype meta,int4 maxPrim,int4 min,int4 max); ///< Constructor HomogeneousAggregate(type_metatype meta,int4 maxPrim,int4 minSize,int4 maxSize); ///< Constructor
HomogeneousAggregate(const HomogeneousAggregate &op2); ///< Copy constructor HomogeneousAggregate(const HomogeneousAggregate &op2); ///< Copy constructor
virtual DatatypeFilter *clone(void) const { return new HomogeneousAggregate(*this); } virtual DatatypeFilter *clone(void) const { return new HomogeneousAggregate(*this); }
virtual bool filter(Datatype *dt) const; virtual bool filter(Datatype *dt) const;
virtual void decode(Decoder &decoder);
}; };
/// \brief A filter on some aspect of a specific function prototype /// \brief A filter on some aspect of a specific function prototype

View file

@ -344,6 +344,7 @@
<define name="model_datatype_type"> <define name="model_datatype_type">
<attribute name="name"/> <attribute name="name"/>
<optional><attribute name="maxprimitives"/></optional>
<optional><attribute name="minsize"/></optional> <optional><attribute name="minsize"/></optional>
<optional><attribute name="maxsize"/></optional> <optional><attribute name="maxsize"/></optional>
<optional><attribute name="sizes"/></optional> <optional><attribute name="sizes"/></optional>

View file

@ -78,9 +78,9 @@ public interface DatatypeFilter {
if (nm.equals(SizeRestrictedFilter.NAME)) { if (nm.equals(SizeRestrictedFilter.NAME)) {
filter = new SizeRestrictedFilter(); filter = new SizeRestrictedFilter();
} }
else if (nm.equals(HomogeneousAggregate.NAME_FLOAT4)) { else if (nm.equals(HomogeneousAggregate.NAME_FLOAT)) {
filter = new HomogeneousAggregate(HomogeneousAggregate.NAME_FLOAT4, filter = new HomogeneousAggregate(HomogeneousAggregate.NAME_FLOAT,
PcodeDataTypeManager.TYPE_FLOAT, 4, 0, 0); PcodeDataTypeManager.TYPE_FLOAT, HomogeneousAggregate.DEFAULT_MAX_PRIMITIVES, 0, 0);
} }
else { else {
// If no other name matches, assume this is a decompiler metatype // If no other name matches, assume this is a decompiler metatype

View file

@ -19,10 +19,13 @@ import static ghidra.program.model.pcode.AttributeId.*;
import static ghidra.program.model.pcode.ElementId.*; import static ghidra.program.model.pcode.ElementId.*;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator;
import java.util.Map.Entry;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.pcode.Encoder; import ghidra.program.model.pcode.Encoder;
import ghidra.program.model.pcode.PcodeDataTypeManager; import ghidra.program.model.pcode.PcodeDataTypeManager;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.*; import ghidra.xml.*;
/** /**
@ -31,8 +34,8 @@ import ghidra.xml.*;
*/ */
public class HomogeneousAggregate extends SizeRestrictedFilter { public class HomogeneousAggregate extends SizeRestrictedFilter {
public static final String NAME_FLOAT4 = "homogeneous-float-aggregate"; public static final String NAME_FLOAT = "homogeneous-float-aggregate";
public static final int MAX_PRIMITIVES = 4; // Maximum number of primitives in aggregate data-type public static final int DEFAULT_MAX_PRIMITIVES = 4; // Maximum number of primitives in aggregate data-type
private String name; private String name;
private int metaType; // The expected meta-type private int metaType; // The expected meta-type
private int maxPrimitives; // Maximum number of primitives in the aggregate private int maxPrimitives; // Maximum number of primitives in the aggregate
@ -45,11 +48,11 @@ public class HomogeneousAggregate extends SizeRestrictedFilter {
public HomogeneousAggregate(String nm, int meta) { public HomogeneousAggregate(String nm, int meta) {
name = nm; name = nm;
metaType = meta; metaType = meta;
maxPrimitives = 2; maxPrimitives = DEFAULT_MAX_PRIMITIVES;
} }
public HomogeneousAggregate(String nm, int meta, int maxPrim, int min, int max) { public HomogeneousAggregate(String nm, int meta, int maxPrim, int minSize, int maxSize) {
super(min, max); super(minSize, maxSize);
name = nm; name = nm;
metaType = meta; metaType = meta;
maxPrimitives = maxPrim; maxPrimitives = maxPrim;
@ -77,7 +80,7 @@ public class HomogeneousAggregate extends SizeRestrictedFilter {
if (meta != PcodeDataTypeManager.TYPE_ARRAY && meta != PcodeDataTypeManager.TYPE_STRUCT) { if (meta != PcodeDataTypeManager.TYPE_ARRAY && meta != PcodeDataTypeManager.TYPE_STRUCT) {
return false; return false;
} }
PrimitiveExtractor primitives = new PrimitiveExtractor(dt, true, 0, MAX_PRIMITIVES); PrimitiveExtractor primitives = new PrimitiveExtractor(dt, true, 0, maxPrimitives);
if (!primitives.isValid() || primitives.size() == 0 || primitives.containsUnknown() || if (!primitives.isValid() || primitives.size() == 0 || primitives.containsUnknown() ||
!primitives.isAligned() || primitives.containsHoles()) { !primitives.isAligned() || primitives.containsHoles()) {
return false; return false;
@ -95,6 +98,12 @@ public class HomogeneousAggregate extends SizeRestrictedFilter {
return true; return true;
} }
@Override
protected void encodeAttributes(Encoder encoder) throws IOException {
super.encodeAttributes(encoder);
encoder.writeUnsignedInteger(ATTRIB_MAX_PRIMITIVES, maxPrimitives);
}
@Override @Override
public void encode(Encoder encoder) throws IOException { public void encode(Encoder encoder) throws IOException {
encoder.openElement(ELEM_DATATYPE); encoder.openElement(ELEM_DATATYPE);
@ -103,6 +112,22 @@ public class HomogeneousAggregate extends SizeRestrictedFilter {
encoder.closeElement(ELEM_DATATYPE); encoder.closeElement(ELEM_DATATYPE);
} }
@Override
protected void restoreAttributesXml(XmlElement el) throws XmlParseException {
super.restoreAttributesXml(el);
Iterator<Entry<String, String>> iter = el.getAttributes().entrySet().iterator();
while (iter.hasNext()) {
Entry<String, String> attrib = iter.next();
String nm = attrib.getKey();
if (nm.equals(ATTRIB_MAX_PRIMITIVES.name())) {
int xmlMaxPrim = SpecXmlUtils.decodeInt(attrib.getValue());
if (xmlMaxPrim > 0) {
maxPrimitives = xmlMaxPrim;
}
}
}
}
@Override @Override
public void restoreXml(XmlPullParser parser) throws XmlParseException { public void restoreXml(XmlPullParser parser) throws XmlParseException {
XmlElement elem = parser.start(ELEM_DATATYPE.name()); XmlElement elem = parser.start(ELEM_DATATYPE.name());

View file

@ -248,5 +248,7 @@ public record AttributeId(String name, int id) {
public static final AttributeId ATTRIB_SIZES = new AttributeId("sizes", 151); public static final AttributeId ATTRIB_SIZES = new AttributeId("sizes", 151);
public static final AttributeId ATTRIB_BACKFILL = new AttributeId("backfill", 152); public static final AttributeId ATTRIB_BACKFILL = new AttributeId("backfill", 152);
public static final AttributeId ATTRIB_UNKNOWN = new AttributeId("XMLunknown", 153); public static final AttributeId ATTRIB_MAX_PRIMITIVES = new AttributeId("maxprimitives", 153);
public static final AttributeId ATTRIB_UNKNOWN = new AttributeId("XMLunknown", 154);
} }