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 @@
-
+