mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
Merge remote-tracking branch 'origin/GP-3385_emteere_EnumSizingToInt' into Ghidra_10.3
This commit is contained in:
commit
b6e73bb53d
5 changed files with 131 additions and 18 deletions
|
@ -741,8 +741,10 @@ public class DefineTable {
|
||||||
public void populateDefineEquate(DataTypeManager openDTMgrs[], DataTypeManager dtMgr, String category, String prefix, String defName, long value) {
|
public void populateDefineEquate(DataTypeManager openDTMgrs[], DataTypeManager dtMgr, String category, String prefix, String defName, long value) {
|
||||||
String enumName = prefix + defName;
|
String enumName = prefix + defName;
|
||||||
|
|
||||||
|
// Start the Enum at 8, then resize to fit the value
|
||||||
EnumDataType enuum = new EnumDataType(enumName, 8);
|
EnumDataType enuum = new EnumDataType(enumName, 8);
|
||||||
enuum.add(defName, value);
|
enuum.add(defName, value);
|
||||||
|
enuum.setLength(enuum.getMinimumPossibleLength());
|
||||||
|
|
||||||
String defPath = getDefinitionPath(defName);
|
String defPath = getDefinitionPath(defName);
|
||||||
String currentCategoryName = getFileName(defPath);
|
String currentCategoryName = getFileName(defPath);
|
||||||
|
|
|
@ -515,6 +515,39 @@ public class CParser {
|
||||||
return null;
|
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) {
|
private DataType getDef(Map<String, DataType> table, String name) {
|
||||||
return table.get(name);
|
return table.get(name);
|
||||||
}
|
}
|
||||||
|
@ -2198,27 +2231,15 @@ DataType EnumSpecifier() : {
|
||||||
LOOKAHEAD(3)
|
LOOKAHEAD(3)
|
||||||
[AttributeSpecList(dec)] [ t= <IDENTIFIER> ] "{" list= EnumeratorList() "}"
|
[AttributeSpecList(dec)] [ t= <IDENTIFIER> ] "{" list= EnumeratorList() "}"
|
||||||
{
|
{
|
||||||
String enumName= (t != null ? t.image : ("enum_" + cnt++));
|
dt = allocateEnumDT(t, list);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
t= <IDENTIFIER>
|
t= <IDENTIFIER>
|
||||||
{
|
{
|
||||||
dt= getEnumDef(t.image);
|
dt= getEnumDef(t.image);
|
||||||
|
// not defined yet, define an empty one
|
||||||
if (dt == null) {
|
if (dt == null) {
|
||||||
String enumName= (t != null ? t.image : ("enum_" + cnt++));
|
dt = allocateEnumDT(t, null);
|
||||||
EnumDataType enuum= new EnumDataType(getCurrentCategoryPath(), enumName, 4, dtMgr);
|
|
||||||
dt= enuum;
|
|
||||||
dt= addDef(enums, enumName, enuum);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -437,13 +437,89 @@ public class PreProcessorTest extends AbstractGenericTest {
|
||||||
assertEquals("fprintf (stderr, \"%s!\\n\" , \"I have args\")", defval);
|
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) {
|
String defname) {
|
||||||
DataType dataType = dtMgr.getDataType(path, "define_" + defname);
|
DataType dataType = dtMgr.getDataType(path, "define_" + defname);
|
||||||
String msg = "Define Enum " + defname;
|
String msg = "Define Enum " + defname;
|
||||||
assertNotNull(msg, dataType);
|
assertNotNull(msg, dataType);
|
||||||
assertTrue(msg, dataType instanceof Enum);
|
assertTrue(msg, dataType instanceof Enum);
|
||||||
assertEquals(msg, value, ((Enum) dataType).getValue(defname));
|
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,
|
private void checkNotDefine(StandAloneDataTypeManager dtMgr, CategoryPath path,
|
||||||
|
|
|
@ -249,6 +249,21 @@ int TEST_FAILED;
|
||||||
|
|
||||||
#define ImOctal 01234567
|
#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
|
** Test for recursive definitions, Should not cause an infinite loop
|
||||||
**/
|
**/
|
||||||
|
|
|
@ -565,8 +565,7 @@ public class DataTypeWriter {
|
||||||
private void writeEnum(Enum enumm, TaskMonitor monitor) throws IOException {
|
private void writeEnum(Enum enumm, TaskMonitor monitor) throws IOException {
|
||||||
|
|
||||||
String enumName = enumm.getDisplayName();
|
String enumName = enumm.getDisplayName();
|
||||||
if (enumName.startsWith("define_") && enumName.length() > 7 && enumm.getCount() == 1 &&
|
if (enumName.startsWith("define_") && enumName.length() > 7 && enumm.getCount() == 1) {
|
||||||
enumm.getLength() == 8) {
|
|
||||||
long val = enumm.getValues()[0];
|
long val = enumm.getValues()[0];
|
||||||
writer.append("#define " + enumName.substring(7) + " " + Long.toString(val));
|
writer.append("#define " + enumName.substring(7) + " " + Long.toString(val));
|
||||||
writer.write(EOL);
|
writer.write(EOL);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue