Merge remote-tracking branch 'origin/GP-3385_emteere_EnumSizingToInt' into Ghidra_10.3

This commit is contained in:
Ryan Kurtz 2023-05-03 19:33:29 -04:00
commit b6e73bb53d
5 changed files with 131 additions and 18 deletions

View file

@ -741,8 +741,10 @@ public class DefineTable {
public void populateDefineEquate(DataTypeManager openDTMgrs[], DataTypeManager dtMgr, String category, String prefix, String defName, long value) {
String enumName = prefix + defName;
// Start the Enum at 8, then resize to fit the value
EnumDataType enuum = new EnumDataType(enumName, 8);
enuum.add(defName, value);
enuum.setLength(enuum.getMinimumPossibleLength());
String defPath = getDefinitionPath(defName);
String currentCategoryName = getFileName(defPath);

View file

@ -514,6 +514,39 @@ public class CParser {
return null;
}
private DataType allocateEnumDT(Token t, ArrayList<EnumMember> list) {
String enumName = (t != null ? t.image : ("enum_" + cnt++));
// get the normal enum size, which is an int
// TODO: allow for packing of enum to smallest value with either dataOrganization, or packing flag
int normalEnumLen = (dtMgr != null ? dtMgr.getDataOrganization().getIntegerSize() : 4);
// create an initial enum and add all new members
EnumDataType enumDT= new EnumDataType(getCurrentCategoryPath(), enumName, 8, dtMgr);
if (list != null) {
for (EnumMember member : list) {
try {
enumDT.add(member.name, member.value);
} catch (IllegalArgumentException exc) {
addNearParseMessage("duplicate enum value: " + enumName + " : " + member.name + " : " + member.value);
}
}
// get the minimum length to represent the values and resize if too big
int minLen = enumDT.getMinimumPossibleLength();
if (minLen > normalEnumLen) {
enumDT.setLength(minLen);
} else {
enumDT.setLength(normalEnumLen);
}
} else {
// length doesn't really matter, forward declaration with no values
enumDT.setLength(normalEnumLen);
}
return addDef(enums, enumDT.getName(), enumDT);
}
private DataType getDef(Map<String, DataType> table, String name) {
return table.get(name);
@ -2198,27 +2231,15 @@ DataType EnumSpecifier() : {
LOOKAHEAD(3)
[AttributeSpecList(dec)] [ t= <IDENTIFIER> ] "{" list= EnumeratorList() "}"
{
String enumName= (t != null ? t.image : ("enum_" + cnt++));
EnumDataType enuum= new EnumDataType(getCurrentCategoryPath(), enumName, 4, dtMgr);
for (EnumMember member : list) {
try {
enuum.add(member.name, member.value);
} catch (IllegalArgumentException exc) {
addNearParseMessage("duplicate enum value: " + enumName + " : " + member.name + " : " + member.value);
}
}
dt= enuum;
dt= addDef(enums, enumName, enuum);
dt = allocateEnumDT(t, list);
}
|
t= <IDENTIFIER>
{
dt= getEnumDef(t.image);
// not defined yet, define an empty one
if (dt == null) {
String enumName= (t != null ? t.image : ("enum_" + cnt++));
EnumDataType enuum= new EnumDataType(getCurrentCategoryPath(), enumName, 4, dtMgr);
dt= enuum;
dt= addDef(enums, enumName, enuum);
dt = allocateEnumDT(t, null);
}
}
)

View file

@ -437,13 +437,89 @@ public class PreProcessorTest extends AbstractGenericTest {
assertEquals("fprintf (stderr, \"%s!\\n\" , \"I have args\")", defval);
}
private void checkDefine(StandAloneDataTypeManager dtMgr, CategoryPath path, long value,
@Test
public void testDefinesEnumLength() {
defname = "BYTE_LEN_1";
value = 1;
int length = 1;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_8";
value = 8;
length = 1;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_1F";
value = 0x1f;
length = 1;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_FF";
value = 0xff;
length = 1;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_1FF";
value = 0x1ff;
length = 2;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_7FFF";
value = 0x7fff;
length = 2;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_10000";
value = 0x10000;
length = 4;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_1000000";
value = 0x1000000;
length = 4;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_100000000";
value = 0x100000000L;
length = 8;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_10000000000";
value = 0x10000000000L;
length = 8;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_1000000000000";
value = 0x1000000000000L;
length = 8;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_100000000000000";
value = 0x100000000000000L;
length = 8;
checkDefineEnumLength(dtMgr, path, value, defname, length);
defname = "BYTE_LEN_neg1";
value = -1;
length = 1;
checkDefineEnumLength(dtMgr, path, value, defname, length);
}
private DataType checkDefine(StandAloneDataTypeManager dtMgr, CategoryPath path, long value,
String defname) {
DataType dataType = dtMgr.getDataType(path, "define_" + defname);
String msg = "Define Enum " + defname;
assertNotNull(msg, dataType);
assertTrue(msg, dataType instanceof Enum);
assertEquals(msg, value, ((Enum) dataType).getValue(defname));
return dataType;
}
private void checkDefineEnumLength(StandAloneDataTypeManager dtMgr, CategoryPath path, long value,
String defname, int length) {
DataType dt = checkDefine(dtMgr, path, value, defname);
assertEquals("Expected " + defname + " length " + length, length, dt.getLength());
}
private void checkNotDefine(StandAloneDataTypeManager dtMgr, CategoryPath path,

View file

@ -249,6 +249,21 @@ int TEST_FAILED;
#define ImOctal 01234567
#define BYTE_LEN_1 0x1
#define BYTE_LEN_8 0x8
#define BYTE_LEN_1F 0x1F
#define BYTE_LEN_FF 0xFF
#define BYTE_LEN_1FF 0x1FF
#define BYTE_LEN_7FFF 0x7FFF
#define BYTE_LEN_10000 0x10000
#define BYTE_LEN_1000000 0x1000000
#define BYTE_LEN_100000000 0x100000000
#define BYTE_LEN_10000000000 0x10000000000
#define BYTE_LEN_1000000000000 0x1000000000000
#define BYTE_LEN_100000000000000 0x100000000000000
#define BYTE_LEN_neg1 -1
/**
** Test for recursive definitions, Should not cause an infinite loop
**/

View file

@ -565,8 +565,7 @@ public class DataTypeWriter {
private void writeEnum(Enum enumm, TaskMonitor monitor) throws IOException {
String enumName = enumm.getDisplayName();
if (enumName.startsWith("define_") && enumName.length() > 7 && enumm.getCount() == 1 &&
enumm.getLength() == 8) {
if (enumName.startsWith("define_") && enumName.length() > 7 && enumm.getCount() == 1) {
long val = enumm.getValues()[0];
writer.append("#define " + enumName.substring(7) + " " + Long.toString(val));
writer.write(EOL);