GP-3449 - Fix Win32 8-byte type alignment and update test utils

This commit is contained in:
ghizard 2023-05-19 14:40:00 -04:00
parent 3cbd416d6d
commit 9cb6a7a12e
4 changed files with 63 additions and 29 deletions

View file

@ -105,8 +105,9 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe
int id = program.startTransaction("add"); int id = program.startTransaction("add");
try { try {
struct = (Structure) program.getDataTypeManager().addDataType(struct, struct = (Structure) program.getDataTypeManager()
DataTypeConflictHandler.REPLACE_HANDLER); .addDataType(struct,
DataTypeConflictHandler.REPLACE_HANDLER);
} }
finally { finally {
program.endTransaction(id, true); program.endTransaction(id, true);
@ -206,8 +207,8 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe
assertEquals("54h", model.getValueAt(2, DTPPTableModel.PREVIEW_COL));// 2-byte short assertEquals("54h", model.getValueAt(2, DTPPTableModel.PREVIEW_COL));// 2-byte short
assertEquals("680054h", model.getValueAt(3, DTPPTableModel.PREVIEW_COL));// 4-byte int at offset 0 assertEquals("680054h", model.getValueAt(3, DTPPTableModel.PREVIEW_COL));// 4-byte int at offset 0
assertEquals("61004D00200065h", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 8-byte long at offset 4 assertEquals("6700720061004Dh", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 8-byte long at offset 8
assertEquals("72h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 2-byte short at offset 12 assertEquals("69h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 2-byte short at offset 16
env.close(program); env.close(program);

View file

@ -30,7 +30,7 @@ import ghidra.xml.XmlElement;
import ghidra.xml.XmlPullParser; import ghidra.xml.XmlPullParser;
/** /**
* DataOrganization provides a single place for determining size and alignment information * DataOrganization provides a single place for determining size and alignment information
* for data types within an archive or a program. * for data types within an archive or a program.
*/ */
public class DataOrganizationImpl implements DataOrganization { public class DataOrganizationImpl implements DataOrganization {
@ -99,7 +99,8 @@ public class DataOrganizationImpl implements DataOrganization {
* Creates a new default DataOrganization. This has a mapping which defines the alignment * Creates a new default DataOrganization. This has a mapping which defines the alignment
* of a data type based on its size. The map defines pairs for data types that are * of a data type based on its size. The map defines pairs for data types that are
* 1, 2, 4, and 8 bytes in length. * 1, 2, 4, and 8 bytes in length.
* @param language optional language used to initialize defaults (pointer size, endianess, etc.) (may be null) * @param language optional language used to initialize defaults (pointer size, endianess, etc.)
* (may be null)
* @return a new default DataOrganization. * @return a new default DataOrganization.
*/ */
public static DataOrganizationImpl getDefaultOrganization(Language language) { public static DataOrganizationImpl getDefaultOrganization(Language language) {
@ -107,7 +108,7 @@ public class DataOrganizationImpl implements DataOrganization {
dataOrganization.setSizeAlignment(1, 1); dataOrganization.setSizeAlignment(1, 1);
dataOrganization.setSizeAlignment(2, 2); dataOrganization.setSizeAlignment(2, 2);
dataOrganization.setSizeAlignment(4, 4); dataOrganization.setSizeAlignment(4, 4);
dataOrganization.setSizeAlignment(8, 4); dataOrganization.setSizeAlignment(8, 8);
if (language != null) { if (language != null) {
// NOTE: Ensure that saveXml always saves pointer size // NOTE: Ensure that saveXml always saves pointer size
dataOrganization.setPointerSize(language.getDefaultSpace().getPointerSize()); dataOrganization.setPointerSize(language.getDefaultSpace().getPointerSize());
@ -352,10 +353,10 @@ public class DataOrganizationImpl implements DataOrganization {
} }
/** /**
* Gets the default alignment to be used for any data type that isn't a * Gets the default alignment to be used for any data type that isn't a
* structure, union, array, pointer, type definition, and whose size isn't in the * structure, union, array, pointer, type definition, and whose size isn't in the
* size/alignment map. * size/alignment map.
* @return the default alignment to be used if no other alignment can be * @return the default alignment to be used if no other alignment can be
* determined for a data type. * determined for a data type.
*/ */
@Override @Override
@ -391,10 +392,10 @@ public class DataOrganizationImpl implements DataOrganization {
} }
/** /**
* Sets the default alignment to be used for any data type that isn't a * Sets the default alignment to be used for any data type that isn't a
* structure, union, array, pointer, type definition, and whose size isn't in the * structure, union, array, pointer, type definition, and whose size isn't in the
* size/alignment map. * size/alignment map.
* @param defaultAlignment the default alignment to be used if no other alignment can be * @param defaultAlignment the default alignment to be used if no other alignment can be
* determined for a data type. * determined for a data type.
*/ */
public void setDefaultAlignment(int defaultAlignment) { public void setDefaultAlignment(int defaultAlignment) {
@ -536,7 +537,7 @@ public class DataOrganizationImpl implements DataOrganization {
} }
/** /**
* Determines the first offset that is equal to or greater than the minimum offset which * Determines the first offset that is equal to or greater than the minimum offset which
* has the specified alignment. If a non-positive alignment is specified the origina * has the specified alignment. If a non-positive alignment is specified the origina
* minimumOffset will be return. * minimumOffset will be return.
* @param alignment the desired alignment (positive value) * @param alignment the desired alignment (positive value)
@ -598,7 +599,7 @@ public class DataOrganizationImpl implements DataOrganization {
dataMap.delete(key); dataMap.delete(key);
} }
} }
if (dataOrg.isBigEndian()) { // default is little-endian if (dataOrg.isBigEndian()) { // default is little-endian
dataMap.put(keyPrefix + BIG_ENDIAN_NAME, Boolean.TRUE.toString()); dataMap.put(keyPrefix + BIG_ENDIAN_NAME, Boolean.TRUE.toString());
} }
@ -708,7 +709,7 @@ public class DataOrganizationImpl implements DataOrganization {
throws IOException { throws IOException {
DataOrganizationImpl dataOrg = new DataOrganizationImpl(); DataOrganizationImpl dataOrg = new DataOrganizationImpl();
dataOrg.bigEndian = dataMap.getBoolean(BIG_ENDIAN_NAME, false); dataOrg.bigEndian = dataMap.getBoolean(BIG_ENDIAN_NAME, false);
dataOrg.absoluteMaxAlignment = dataOrg.absoluteMaxAlignment =
@ -723,7 +724,7 @@ public class DataOrganizationImpl implements DataOrganization {
dataOrg.defaultPointerAlignment = dataOrg.defaultPointerAlignment =
dataMap.getInt(keyPrefix + ELEM_DEFAULT_POINTER_ALIGNMENT.name(), dataMap.getInt(keyPrefix + ELEM_DEFAULT_POINTER_ALIGNMENT.name(),
dataOrg.defaultPointerAlignment); dataOrg.defaultPointerAlignment);
dataOrg.pointerSize = dataOrg.pointerSize =
dataMap.getInt(keyPrefix + ELEM_POINTER_SIZE.name(), dataOrg.pointerSize); dataMap.getInt(keyPrefix + ELEM_POINTER_SIZE.name(), dataOrg.pointerSize);
@ -790,9 +791,9 @@ public class DataOrganizationImpl implements DataOrganization {
*/ */
public void encode(Encoder encoder) throws IOException { public void encode(Encoder encoder) throws IOException {
encoder.openElement(ELEM_DATA_ORGANIZATION); encoder.openElement(ELEM_DATA_ORGANIZATION);
// NOTE: endianess intentionally omitted from output // NOTE: endianess intentionally omitted from output
if (absoluteMaxAlignment != NO_MAXIMUM_ALIGNMENT) { if (absoluteMaxAlignment != NO_MAXIMUM_ALIGNMENT) {
encoder.openElement(ELEM_ABSOLUTE_MAX_ALIGNMENT); encoder.openElement(ELEM_ABSOLUTE_MAX_ALIGNMENT);
encoder.writeSignedInteger(ATTRIB_VALUE, absoluteMaxAlignment); encoder.writeSignedInteger(ATTRIB_VALUE, absoluteMaxAlignment);
@ -890,17 +891,17 @@ public class DataOrganizationImpl implements DataOrganization {
} }
/** /**
* Restore settings from an XML stream. This expects to see parser positioned on the * Restore settings from an XML stream. This expects to see parser positioned on the
* <data_organization> start tag. The XML is designed to override existing language-specific * <data_organization> start tag. The XML is designed to override existing language-specific
* default settings which are pre-populated with {@link #getDefaultOrganization(Language)}. This * default settings which are pre-populated with {@link #getDefaultOrganization(Language)}. This
* will will ensure that the endianess setting is properly established since it is not included * will will ensure that the endianess setting is properly established since it is not included
* in the XML. * in the XML.
* @param parser is the XML stream * @param parser is the XML stream
*/ */
public void restoreXml(XmlPullParser parser) { public void restoreXml(XmlPullParser parser) {
// NOTE: endianess intentionally omitted from XML. // NOTE: endianess intentionally omitted from XML.
parser.start(); parser.start();
while (parser.peek().isStart()) { while (parser.peek().isStart()) {
String name = parser.peek().getName(); String name = parser.peek().getName();

View file

@ -17,7 +17,7 @@ package ghidra.program.model.data;
/** /**
* <code>DataOrganizationTestUtils</code> provides various methods for modifying * <code>DataOrganizationTestUtils</code> provides various methods for modifying
* a DataOrganization to reflect a specific processor/compiler spec. This can be used * a DataOrganization to reflect a specific processor/compiler spec. This can be used
* when only the DataOrganization is needed and not the Language/CompilerSpec. * when only the DataOrganization is needed and not the Language/CompilerSpec.
*/ */
public class DataOrganizationTestUtils { public class DataOrganizationTestUtils {
@ -57,6 +57,37 @@ public class DataOrganizationTestUtils {
dataOrg.setBitFieldPacking(bitFieldPacking); dataOrg.setBitFieldPacking(bitFieldPacking);
} }
/**
* Initialize data organization to reflect x86gcc.cspec specification
* @param dataOrg data organization
*/
public static void initDataOrganizationGcc32BitX86(DataOrganizationImpl dataOrg) {
dataOrg.setBigEndian(false);
dataOrg.setAbsoluteMaxAlignment(0);
dataOrg.setMachineAlignment(2);
dataOrg.setDefaultAlignment(1);
dataOrg.setDefaultPointerAlignment(4);
dataOrg.setPointerSize(4);
dataOrg.setWideCharSize(4);
dataOrg.setShortSize(2);
dataOrg.setIntegerSize(4);
dataOrg.setLongSize(4);
dataOrg.setLongLongSize(8);
dataOrg.setFloatSize(4);
dataOrg.setDoubleSize(8);
dataOrg.setLongDoubleSize(16);
dataOrg.setSizeAlignment(1, 1);
dataOrg.setSizeAlignment(2, 2);
dataOrg.setSizeAlignment(4, 4);
dataOrg.setSizeAlignment(8, 4);
dataOrg.setSizeAlignment(16, 16);
BitFieldPackingImpl bitFieldPacking = new BitFieldPackingImpl(); // use defaults
dataOrg.setBitFieldPacking(bitFieldPacking);
}
/** /**
* Initialize data organization to reflect x86-64-gcc.cspec specification * Initialize data organization to reflect x86-64-gcc.cspec specification
* @param dataOrg data organization * @param dataOrg data organization
@ -82,6 +113,7 @@ public class DataOrganizationTestUtils {
dataOrg.setSizeAlignment(2, 2); dataOrg.setSizeAlignment(2, 2);
dataOrg.setSizeAlignment(4, 4); dataOrg.setSizeAlignment(4, 4);
dataOrg.setSizeAlignment(8, 8); dataOrg.setSizeAlignment(8, 8);
dataOrg.setSizeAlignment(16, 16);
BitFieldPackingImpl bitFieldPacking = new BitFieldPackingImpl(); // use defaults BitFieldPackingImpl bitFieldPacking = new BitFieldPackingImpl(); // use defaults
dataOrg.setBitFieldPacking(bitFieldPacking); dataOrg.setBitFieldPacking(bitFieldPacking);

View file

@ -19,7 +19,7 @@
<entry size="1" alignment="1" /> <entry size="1" alignment="1" />
<entry size="2" alignment="2" /> <entry size="2" alignment="2" />
<entry size="4" alignment="4" /> <entry size="4" alignment="4" />
<entry size="8" alignment="4" /> <entry size="8" alignment="8" />
</size_alignment_map> </size_alignment_map>
<bitfield_packing> <bitfield_packing>
<use_MS_convention value="true"/> <use_MS_convention value="true"/>