Merge remote-tracking branch

'origin/GP-6624_ghidravision_DecompileDebugXml_added_bitfields--SQUASHED'
into patch (Closes #9049)
This commit is contained in:
Ryan Kurtz
2026-07-31 07:17:41 -04:00
3 changed files with 73 additions and 12 deletions

View File

@@ -226,14 +226,33 @@ public class DecompileDebugDataTypeManager {
return unionDT;
}
while (parser.peek().getName().equals("field")) {
XmlElement fieldElement = parser.start("field");
DataType fieldDT = parseDataTypeTag(parser, log);
unionDT.add(fieldDT, fieldDT.getLength(), key.name(), "");
parser.end(fieldElement);
while (parser.peek().getName().contains("field")) {
String fieldType = parser.peek().getName();
if (fieldType.equals("field")) {
XmlElement fieldElement = parser.start("field");
DataType fieldDT = parseDataTypeTag(parser, log);
unionDT.add(fieldDT, fieldDT.getLength(), key.name(), "");
parser.end(fieldElement);
}
else if (fieldType.equals("bitfield")) {
XmlElement bitFieldElement = parser.start("bitfield");
int bitFieldSize =
SpecXmlUtils.decodeInt(bitFieldElement.getAttribute(ATTRIB_SIZE.name()));
String componentName = bitFieldElement.getAttribute(ATTRIB_NAME.name());
DataType fieldDT = parseDataTypeTag(parser, log);
try {
unionDT.addBitField(fieldDT, bitFieldSize, componentName, null);
}
catch (InvalidDataTypeException e) {
log.appendException(e);
}
parser.end(bitFieldElement);
}
}
parser.end(unionElement);
return unionDT;
}
/**
@@ -295,8 +314,9 @@ public class DecompileDebugDataTypeManager {
DataType baseType = parseDataTypeTag(parser, log);
PointerTypedef relPointerDT =
new PointerTypedef(baseType.getName(), baseType, size, programDataManager, offset);
DataType resolved = resolveAndMapDataType(new DataTypeKey(baseType.getName()+"relptr", idHolder), relPointerDT);
DataType resolved = resolveAndMapDataType(
new DataTypeKey(baseType.getName() + "relptr", idHolder), relPointerDT);
parser.end(pointerRelElement);
return resolved;
@@ -331,7 +351,25 @@ public class DecompileDebugDataTypeManager {
return createdStruct;
}
while (parser.peek().getName().equals("field")) {
while (parser.peek().getName().contains("field")) {
handleStructFieldType(parser, createdStruct, log);
}
parser.end(structElement);
return createdStruct;
}
/**
* Parse and populate field and bit field types for created structs.
*
* @param parser XmlPullParser
* @param createdStruct Structure
* @param log XmlMessageLog
*/
private void handleStructFieldType(XmlPullParser parser, Structure createdStruct,
XmlMessageLog log) {
if (parser.peek().getName().equals("field")) {
XmlElement fieldElement = parser.start("field");
int fieldOffset =
SpecXmlUtils.decodeInt(fieldElement.getAttribute(ATTRIB_OFFSET.name()));
@@ -341,10 +379,27 @@ public class DecompileDebugDataTypeManager {
fieldElement.getAttribute(ATTRIB_NAME.name()), "");
parser.end(fieldElement);
}
parser.end(structElement);
return createdStruct;
else if (parser.peek().getName().equals("bitfield")) {
XmlElement bitFieldElement = parser.start("bitfield");
int bitFieldSize =
SpecXmlUtils.decodeInt(bitFieldElement.getAttribute(ATTRIB_SIZE.name()));
String componentName = bitFieldElement.getAttribute(ATTRIB_NAME.name());
int byteOffset =
SpecXmlUtils.decodeInt(bitFieldElement.getAttribute(ATTRIB_OFFSET.name()));
int bitOffset =
SpecXmlUtils.decodeInt(bitFieldElement.getAttribute(ATTRIB_FIRST.name()));
int byteWidth = Math.ceilDiv((bitOffset + bitFieldSize), 8);
DataType fieldDT = parseDataTypeTag(parser, log);
try {
createdStruct.insertBitFieldAt(byteOffset, byteWidth, bitOffset, fieldDT,
bitFieldSize, componentName, null);
}
catch (InvalidDataTypeException e) {
log.appendException(e);
}
parser.end(bitFieldElement);
}
}
/**

View File

@@ -123,11 +123,14 @@ public class DecompileDebugXmlLoaderTest extends AbstractGhidraHeadedIntegration
Iterator<Structure> structures = dtm.getAllStructures();
Structure struct = structures.next(); // there is only 1 struct in the example XML dump
assertEquals("Component count didn't match.", 20, struct.getNumComponents());
assertEquals("Component count didn't match.", 22, struct.getNumComponents());
assertEquals("Struct name is incorrect", "IMAGE_DOS_HEADER", struct.getName());
DataTypeComponent array = struct.getComponentAt(0); // the first component is an array
assertEquals("Array component name doesn't match", "e_magic", array.getFieldName());
assertEquals("Array wasn't sized right", 2, array.getLength());
DataTypeComponent bitField = struct.getComponentAt(65); // last component is a bitfield
assertEquals("Bitfield name doesn't match", "low_nibble", bitField.getFieldName());
assertEquals("Bitfield length doesn't match", "1", bitField.getLength() + "");
}
finally {
program.release(this);

View File

@@ -167,6 +167,9 @@ c4305fc3b907000000e8be03000090b9
<type name="byte" id="0xc00000000000007f" metatype="uint" size="1"/>
</type>
</field>
<bitfield name="low_nibble" id="0" offset="65" first="0" size="4">
<type name="byte" id="0xc00000000000007a" metatype="uint" size="1"/>
</bitfield>
</type>
</typegrp><db scopeidbyname="false">
<scope name="" id="0x0">