From 9cb6a7a12e2b1a99e34f3dc44288de27ba41268c Mon Sep 17 00:00:00 2001 From: ghizard <50744617+ghizard@users.noreply.github.com> Date: Fri, 19 May 2023 14:40:00 -0400 Subject: [PATCH] GP-3449 - Fix Win32 8-byte type alignment and update test utils --- .../DataTypePreviewPluginTest.java | 9 ++-- .../model/data/DataOrganizationImpl.java | 47 ++++++++++--------- .../model/data/DataOrganizationTestUtils.java | 34 +++++++++++++- .../x86/data/languages/x86win.cspec | 2 +- 4 files changed, 63 insertions(+), 29 deletions(-) diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datapreview/DataTypePreviewPluginTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datapreview/DataTypePreviewPluginTest.java index 9bfa4df093..bdb017a757 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datapreview/DataTypePreviewPluginTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datapreview/DataTypePreviewPluginTest.java @@ -105,8 +105,9 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe int id = program.startTransaction("add"); try { - struct = (Structure) program.getDataTypeManager().addDataType(struct, - DataTypeConflictHandler.REPLACE_HANDLER); + struct = (Structure) program.getDataTypeManager() + .addDataType(struct, + DataTypeConflictHandler.REPLACE_HANDLER); } finally { 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("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("72h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 2-byte short at offset 12 + assertEquals("6700720061004Dh", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 8-byte long at offset 8 + assertEquals("69h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 2-byte short at offset 16 env.close(program); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataOrganizationImpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataOrganizationImpl.java index 0c3090979b..4b7029bdb9 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataOrganizationImpl.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataOrganizationImpl.java @@ -30,7 +30,7 @@ import ghidra.xml.XmlElement; 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. */ 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 * 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. - * @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. */ public static DataOrganizationImpl getDefaultOrganization(Language language) { @@ -107,7 +108,7 @@ public class DataOrganizationImpl implements DataOrganization { dataOrganization.setSizeAlignment(1, 1); dataOrganization.setSizeAlignment(2, 2); dataOrganization.setSizeAlignment(4, 4); - dataOrganization.setSizeAlignment(8, 4); + dataOrganization.setSizeAlignment(8, 8); if (language != null) { // NOTE: Ensure that saveXml always saves pointer size 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 - * structure, union, array, pointer, type definition, and whose size isn't in the + * 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 * 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. */ @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 - * structure, union, array, pointer, type definition, and whose size isn't in the + * 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 * 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. */ 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 * minimumOffset will be return. * @param alignment the desired alignment (positive value) @@ -598,7 +599,7 @@ public class DataOrganizationImpl implements DataOrganization { dataMap.delete(key); } } - + if (dataOrg.isBigEndian()) { // default is little-endian dataMap.put(keyPrefix + BIG_ENDIAN_NAME, Boolean.TRUE.toString()); } @@ -708,7 +709,7 @@ public class DataOrganizationImpl implements DataOrganization { throws IOException { DataOrganizationImpl dataOrg = new DataOrganizationImpl(); - + dataOrg.bigEndian = dataMap.getBoolean(BIG_ENDIAN_NAME, false); dataOrg.absoluteMaxAlignment = @@ -723,7 +724,7 @@ public class DataOrganizationImpl implements DataOrganization { dataOrg.defaultPointerAlignment = dataMap.getInt(keyPrefix + ELEM_DEFAULT_POINTER_ALIGNMENT.name(), - dataOrg.defaultPointerAlignment); + dataOrg.defaultPointerAlignment); 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 { encoder.openElement(ELEM_DATA_ORGANIZATION); - - // NOTE: endianess intentionally omitted from output - + + // NOTE: endianess intentionally omitted from output + if (absoluteMaxAlignment != NO_MAXIMUM_ALIGNMENT) { encoder.openElement(ELEM_ABSOLUTE_MAX_ALIGNMENT); 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 - * <data_organization> start tag. The XML is designed to override existing language-specific - * 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 + * 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 + * 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 * in the XML. * @param parser is the XML stream */ public void restoreXml(XmlPullParser parser) { - - // NOTE: endianess intentionally omitted from XML. - + + // NOTE: endianess intentionally omitted from XML. + parser.start(); while (parser.peek().isStart()) { String name = parser.peek().getName(); diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/data/DataOrganizationTestUtils.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/data/DataOrganizationTestUtils.java index 70ee03a02c..9a311a2662 100644 --- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/data/DataOrganizationTestUtils.java +++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/data/DataOrganizationTestUtils.java @@ -17,7 +17,7 @@ package ghidra.program.model.data; /** * DataOrganizationTestUtils 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. */ public class DataOrganizationTestUtils { @@ -57,6 +57,37 @@ public class DataOrganizationTestUtils { 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 * @param dataOrg data organization @@ -82,6 +113,7 @@ public class DataOrganizationTestUtils { dataOrg.setSizeAlignment(2, 2); dataOrg.setSizeAlignment(4, 4); dataOrg.setSizeAlignment(8, 8); + dataOrg.setSizeAlignment(16, 16); BitFieldPackingImpl bitFieldPacking = new BitFieldPackingImpl(); // use defaults dataOrg.setBitFieldPacking(bitFieldPacking); diff --git a/Ghidra/Processors/x86/data/languages/x86win.cspec b/Ghidra/Processors/x86/data/languages/x86win.cspec index c07b7e4d33..d9072fe238 100644 --- a/Ghidra/Processors/x86/data/languages/x86win.cspec +++ b/Ghidra/Processors/x86/data/languages/x86win.cspec @@ -19,7 +19,7 @@ - +