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) {
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
**/
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue