mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-08-08 07:40:39 -09:00
Merge remote-tracking branch
'origin/GP-6624_ghidravision_DecompileDebugXml_added_bitfields--SQUASHED' into patch (Closes #9049)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user